{"record":{"id":"a8556916c50fdd28","repo":"ruvnet/RuView","slug":"refusing-cli-access-readme-does-not-identify-a-ru-a85569","errorCode":null,"errorMessage":"Refusing CLI access: README does not identify a RuView checkout","messagePattern":"Refusing CLI access: README does not identify a RuView checkout","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"harness/ruview/src/repo-trust.js","lineNumber":21,"sourceCode":"import { isAbsolute, join, relative } from 'node:path';\nconst REQUIRED_MARKERS = ['.git', 'README.md', 'v2'];\nconst RUVIEW_MARKERS = ['firmware', 'wifi_densepose'];\nfunction isWithin(parent, child) {\n  const rel = relative(parent, child);\n  return rel === '' || (!rel.startsWith('..') && !isAbsolute(rel));\n}\nexport function assertTrustedRuViewRepo(repoRoot, { trustedRoot = repoRoot } = {}) {\n  if (!repoRoot || !trustedRoot) throw new TypeError('repoRoot and trustedRoot are required');\n  const root = realpathSync(repoRoot);\n  const trustAnchor = realpathSync(trustedRoot);\n  if (!isWithin(trustAnchor, root) || root !== trustAnchor) throw new Error('Refusing CLI access: repository does not match the configured trusted root');\n  if (!statSync(root).isDirectory()) throw new Error('Refusing CLI access: trusted root is not a directory');\n  const missing = REQUIRED_MARKERS.filter((marker) => !existsSync(join(root, marker)));\n  if (missing.length || !RUVIEW_MARKERS.some((marker) => existsSync(join(root, marker)))) {\n    throw new Error(`Refusing CLI access: RuView repository markers are missing${missing.length ? ` (${missing.join(', ')})` : ''}`);\n  }\n  const readme = readFileSync(join(root, 'README.md'), 'utf8').slice(0, 131_072);\n  if (!/\\b(?:RuView|wifi[- ]densepose)\\b/i.test(readme)) throw new Error('Refusing CLI access: README does not identify a RuView checkout');\n  return root;\n}\n","sourceCodeStart":3,"sourceCodeEnd":24,"githubUrl":"https://github.com/ruvnet/RuView/blob/4685618388a5e49fad5b3005806f3bdd6a7c25c3/harness/ruview/src/repo-trust.js#L3-L24","documentation":"The final repo-trust check reads the first 131072 bytes (128 KiB) of README.md and requires the case-insensitive word-boundary regex /\\b(?:RuView|wifi[- ]densepose)\\b/ to match. A README that never says 'RuView' or 'wifi densepose' as a standalone word, or only says it past 128 KiB, fails the gate.","triggerScenarios":"A vendored/forked copy whose README was rebranded or replaced; the identity words appearing only beyond the first 128 KiB of a very long README; the words glued into a larger token (e.g. 'RuViewProject') so the \\b boundary never matches.","commonSituations":"Rebranding the README without keeping the project identity; template READMEs that lead with badges/changelog for hundreds of KiB; downstream forks renaming the product everywhere.","solutions":["Ensure README.md mentions 'RuView' (or 'wifi densepose'/'wifi-densepose') as a standalone word within its first 128 KiB.","If you maintain a fork, add one line early in the README: 'Fork of RuView (WiFi-DensePose)'.","Verify locally: head -c 131072 README.md | grep -icE '\\b(RuView|wifi[- ]densepose)\\b' should print >= 1."],"exampleFix":"# before (README.md of your vendored copy starts with 'MyProduct docs...')\n# after — add near the top of README.md:\n# MyProduct — a fork of RuView (WiFi-DensePose).","handlingStrategy":"validation","validationCode":"import { readFileSync } from 'node:fs';\nconst head = readFileSync(join(repoRoot, 'README.md'), 'utf8').slice(0, 131072);\nif (!/\\b(?:RuView|wifi[- ]densepose)\\b/i.test(head)) {\n  throw new Error('README does not identify a RuView checkout within the first 128 KiB');\n}","typeGuard":null,"tryCatchPattern":"try {\n  await runCodex({ prompt, repoRoot });\n} catch (e) {\n  if (e instanceof Error && e.message.includes('README does not identify')) {\n    throw new Error('trust gate: keep a standalone \"RuView\" or \"wifi densepose\" mention in the first 128 KiB of README.md');\n  }\n  throw e;\n}","preventionTips":["Keep the project identity word ('RuView') near the top of README.md.","In forks, add a one-line 'Fork of RuView (WiFi-DensePose)' statement early.","After big README rewrites, run the 128 KiB regex check in CI."],"tags":["security","fail-closed","readme","trust-gate","ruview-harness"],"backgroundTag":null,"analyzedSha":"4685618388a5e49fad5b3005806f3bdd6a7c25c3","analyzedAt":"2026-08-16T06:09:40.886Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}