docs: bring the root documentation in line with the shipped product (#950) - #1071
Conversation
…950) The files a first-time user or contributor opens described something that does not exist. CONTRIBUTING.md taught the dead v1 auth model — get_current_user, db.user_has_project_access(), /api/projects/{id} — none of which are in the codebase, and linked four paths that are not either (docs/architecture/, docs/authentication.md, codeframe/providers/base.py, codeframe/tasks/test_runner.py). Rewritten around what actually enforces auth: router-level dependencies=_AUTH in server.py, require_auth accepting a JWT or an X-API-Key, CODEFRAME_AUTH_REQUIRED read at request time, real scopes from the user row, get_v2_workspace enforcing the WORKSPACE_ROOT allowlist, and single-use stream tickets instead of a JWT in a URL. The headline for a contributor is that a new v2 router is protected by HOW IT IS MOUNTED and by nothing else. The provider/adapter sections now point at adapters/llm/base.py and core/adapters/agent_adapter.py, which exist. README contradicted itself: PROVE and SHIP listed web gates, glitch capture and PR status tracking as pending while the Web UI section marked the same things shipped. Verified each against the components — GateRunPanel, CaptureGlitchModal, /proof/[req_id], PRStatusPanel with its ci_checks rendering — and flipped the four stale boxes. Also 0.9.0 -> 0.9.1 to match pyproject, and the DATABASE_PATH default from "in-memory SQLite" to ./.codeframe/state.db, which is what the code does. CHANGELOG's Unreleased listed 1 of 212 commits since v0.9.1. Since SECURITY.md supports only the latest release, that omission mattered most for the security work: WORKSPACE_ROOT failing closed (#896), the bootstrap registration gate (#897), real scopes and tenancy (#898), the untrusted-repo boundaries (#903/#904/#905/#895), subprocess containment (#906/#907/#899/#721/#996), stream tickets (#745), dispatch-time webhook SSRF vetting (#746), credential handling (#772/#790/#718) — several of which change defaults and need configuration on an existing deploy, so they are called out as such. Phases 5.1–5.5 and the merge gate are summarized alongside. TESTING.md was ~400 lines of Sprint-1 checklist importing codeframe.agents.providers.anthropic_provider and starting the server with a long-renamed command. Replaced with the current suite: the one gate command, the directory layout, which markers change what runs, the enforced coverage floor, and how to run the lifecycle and Playwright suites. AC5 — the link/import check — is tests/test_root_docs_950.py, in the default gate. Every relative link in a root doc must resolve; every codeframe module named in a fenced python block must be importable; the README version must equal pyproject's; the coverage floor TESTING.md quotes must equal .coveragerc's; every test directory and marker TESTING.md lists must exist. The roadmap checks pair each claim with the component that proves it, so a box cannot be flipped back without deleting the file. It carries its own guards too: a non-empty-links assertion (all of zero links resolve) and a test that the import check still rejects the deleted module it was written for. 19 of the 43 fail against the pre-fix tree.
|
Claude finished @frankbria's task in 6m 27s —— View job 🔍 Bug-hunting review completeScoped to concrete defects only (logic errors, null/unhandled-error paths, security, data loss, contract breaks, resource leaks). The only code in the PR is
Result: no defects found. Verified against the checked-out tree — every file/path/version/marker the new tests assert on resolves, the documented auth pattern matches A separate general-purpose review covers style, architecture, naming, and coverage. |
|
✅ GLM bug-hunting review: no defects found. Scoped to concrete defects only (logic errors, null/unhandled-error paths, security, data loss, contract breaks, resource leaks). The only code in the PR is Verified against the checked-out tree:
A separate general-purpose review covers style, architecture, naming, and coverage. |
|
Claude finished @frankbria's task in 3m 32s —— View job 🔍 GLM bug-hunting review (re-run on synchronize)Scoped to concrete defects only (logic errors, null/unhandled-error paths, security, data loss, contract breaks, resource leaks). Style, architecture, naming, and coverage are covered by the general-purpose review.
✅ GLM review: no defects found. What the synchronize actually was: I re-derived the verdict independently against the checked-out tree rather than trusting the prior pass:
Two latent fragilities I considered and discarded as out-of-scope (both fail loudly — safe direction — and neither trips on current content): the |
Closes #950.
The files a first-time user or contributor opens described something that does not exist.
CONTRIBUTING.md taught a dead auth model (AC1)
It documented
get_current_user,db.user_has_project_access()and/api/projects/{id}— none of which are in the codebase — and linked four paths that are not either:docs/architecture/,docs/authentication.md,codeframe/providers/base.py,codeframe/tasks/test_runner.py.Rewritten around what actually enforces auth today:
dependencies=_AUTHinserver.py— a new v2 router is protected by how it is mounted, and by nothing else, which is the one thing a contributor needs to knowrequire_authaccepting a JWT or anX-API-Key, gated byCODEFRAME_AUTH_REQUIREDread at request timerequire_scope(SCOPE_ADMIN)shown on the actual merge handlerget_v2_workspaceas the tenancy boundary rather than hand-rolled ownership checksThe provider and adapter sections now point at
codeframe/adapters/llm/base.pyandcodeframe/core/adapters/agent_adapter.py, which exist.The README contradicted itself (AC2)
PROVE and SHIP listed as pending exactly what the Web UI section listed as shipped. A reader cannot tell which half is true.
Checked each against the code before flipping it:
components/proof/GateRunPanel.tsx,RunHistoryPanel.tsx,GateEvidencePanel.tsxcomponents/proof/CaptureGlitchModal.tsxapp/proof/[req_id]/components/review/PRStatusPanel.tsx(rendersdata.ci_checks)Also
0.9.0→0.9.1to matchpyproject.toml, and theDATABASE_PATHdefault from "in-memory SQLite" to./.codeframe/state.db, which is whatget_db_for_cliactually does.CHANGELOG listed 1 of 212 commits since v0.9.1 (AC3)
SECURITY.mdsupports only the latest release, so that omission mattered most for the security work. The new Unreleased section leads with it and flags the ones that change defaults and need configuration on an existing deploy:WORKSPACE_ROOTfails closed — the server refuses to start when auth is enforced and no allowlist is set ([P0.2] Give WORKSPACE_ROOT one meaning, fail closed when unset, and delete the dead WorkspaceManager #896)/auth/registerrequires an out-of-band secret; required for any networked deploy ([P0.3] Gate bootstrap /auth/register behind an out-of-band secret #897)admingenuinely refuses a non-superuser session ([P0.4] Enforce real scopes and tenancy: JWT sessions get admin, read-only keys can revoke keys, workspace ownership is reassignable #898)llm.base_url,.env([P0.11] Close the untrusted-repo execution boundary: repo-committed hooks and agent-readable credential store #905, [P0.9] Treat a repo-supplied llm.base_url as untrusted #903, [P0.10] Stop a repository .env from overriding the operator's environment #904, [P0.1] Gitignore .env.production and check history for committed secrets #895)$HOME([P0.12] Confine plan-engine file operations to the workspace root #906, [P0.13] Run plan-engine shell steps and gate subprocesses with one allowlisted environment #907, [P0.5] Confine review_files() to the workspace — client-supplied paths escape it #899, [P0.10] Do not pass the operator's full secret environment into LLM-drivenrun_command#721, [P0.25] Delegated agent adapters inherit the operator's full environment and HOME #996)Phases 5.1–5.5, the PROOF9 merge gate, worktree isolation and the Playwright rewrite are summarized alongside, with the Changed section covering #946 and #948.
TESTING.md (AC4)
~400 lines of Sprint-1 checklist that imported
codeframe.agents.providers.anthropic_providerand told you to start the server with a long-renamed command. Replaced with the current suite: the one gate command, the directory layout, which markers change what runs and why-mreplaces rather than combines, the enforced coverage floor (and that it bites on subset runs), and how to run the lifecycle and Playwright suites.The link/import check (AC5)
tests/test_root_docs_950.py, in the default gate — 43 tests:codeframe.*module named in a fenced ```python block is importablepyproject.toml's.coveragerc'sIt carries its own guards: a non-empty-links assertion per doc (all of zero links resolve), a checkbox-syntax check (a typo'd
- [X]renders as plain text, which is how stale entries survive review), andtest_the_check_would_catch_a_deleted_module, which asserts the import check still rejects the exact module the old TESTING.md named.19 of the 43 fail against the pre-fix tree.
Known limitations
SECURITY.mdandCHANGELOG.mdare skipped by the non-empty-links guard: they legitimately link almost entirely externally. Broken relative links in them are still caught.docs/**is untouched here.