Repository navigation
fix(gitignore): anchor .Codex/ to repo root, report outside worktrees (ADR-1078) - #602
Conversation
|
ZETETIC-REVIEW: APPROVE Reviewed final head 5447cbb. Whole PR inspected at 7fcb1cb against origin/main, including delta since 6714ed9, then all six changed paths through final head. No blocking findings. Remote CI at this exact head remains required and is owned by the coordinator. Independently verified: clean exact head; diff whitespace check; both backend check lists; optional warning exit behavior; main-checkout anchoring; resolved ancestry and both host roots; NUL parser preserving newline and trailing space; real-Git regression coverage; ADR-1079 manifest and exact mirror agreement; no stale ADR-1078 pointers in changed code or documentation; timeout precedent; function size split. The proposed PR body identifies the behavior, validation versions, targeted mutation limits and Windows filename-test limitation. Its 19-test count described the earlier head and should be refreshed before publication with the final validation result. Reported validation for the earlier head: 19 doctor tests, pinned Ruff 0.16.6 check and format, craftsmanship, wiki gate, and two killed mutants. These executions belong to the implementer/coordinator; reviewer did not rerun them or assert that count for final head. Final delta inspection verifies that unavailable Git results now produce an honest optional warning with possible causes and a retry command. Empty successful output remains distinct. New tests assert parser markers, Unicode, empty/None results, orphan markers, both registries, CLI warning and exit status, repair text, and MCP readiness/check payload. A separate consumer test covers unavailable Git without blocking CLI or MCP readiness. ADR and changelog document this behavior; the final mirror exactly matches the canonical ADR. The wording observation about the parser docstring has been corrected to inspection unavailable. Final HEAD and clean status independently checked; final whitespace check passed. Repository remained read-only. No GitHub comment or merge performed. |
|
ZETETIC-REVIEW: REQUEST_CHANGES Reviewed 5447cbb in a detached worktree at that sha, gates run with the repository's Measured on the head: Blocking finding, measured by running the PR's
Non-blocking: The rest of the delta since 6714ed9 holds up: the |
The doctor check for worktree locations is PR #602, not merged. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01Cz7A6goxVzfKL9NT7k4zDH
…and Codex (#603) * docs(readme): predictions and calibration, one store for Claude Code and Codex The README described what Cortex remembers and never that it can record what it expected (#597, ADR-1076): a section under "Keep context useful" shows predict, resolve_prediction and calibration with their real return shapes and says what the Brier score means against the 0.25 of a constant 0.5 forecast. The host table gains the row, and the Codex paragraph says the plugin reads the same saved backend selection as the Claude launcher (#600). The unreleased changelog had two "### Added" headings; one now. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01Cz7A6goxVzfKL9NT7k4zDH * docs(readme): one column per host in the capability table Codex was folded into "local stdio hosts" although its plugin starts the server with --profile lean (ten named tools, no hooks) while a direct codex mcp add gets the full surface. The table now has a column for each, says which tools lean lacks (predictions, wiki writes, ingestion), where the shared backend selection lives (#600), and which worktree directory doctor checks per host. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01Cz7A6goxVzfKL9NT7k4zDH * docs(readme): the calibration band the code can return, and the release hedge for Codex BAND_EDGES steps by 0.2, so the illustrative reliability row shows [0.6, 0.8]. The Codex paragraph names CORTEX_BACKEND between the two variables it already named and says the shared backend selection reaches the plugin with the release after 4.22.0, since the plugin launches the published package. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01Cz7A6goxVzfKL9NT7k4zDH * docs(readme): the worktree row states the convention, not a doctor check The doctor check for worktree locations is PR #602, not merged. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01Cz7A6goxVzfKL9NT7k4zDH * docs(readme): the lean profile's real reason, and each worktree cell sourced to what names it ADR-0693 records why the Codex plugin starts lean: the full surface is the largest fixed token cost a session pays, not a startup-time limit. The worktree row cites docs/agent-guidance.md for the Claude Code directory only; the Codex directory is observed behaviour that #601 gitignored. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01Cz7A6goxVzfKL9NT7k4zDH --------- Co-authored-by: Claude Fable 5.1 <[email protected]>
… (ADR-1078) .gitignore's .Codex/ rule (#601) was unanchored, matching a .Codex directory at any depth instead of just the repo root. Anchor to /.Codex/. The condition that rule hid: a git worktree living outside .claude/worktrees/, the only location docs/agent-guidance.md:160-166 names, stays where the owner decided it stays, but is now reported rather than silenced. mcp_server/doctor.py gains an optional, non-blocking "worktree locations" check (surfaced through python -m mcp_server.doctor, check_setup, and /preflight) that lists any git worktree list --porcelain entry outside <main-worktree>/.claude/worktrees/. The allowed root is derived from the main worktree's own listing (always first, per git-worktree(1) section list) rather than git rev-parse --show-toplevel, which resolves to a linked worktree's own path and would false-positive on every sibling worktree run from inside one. Decision recorded as ADR-1078. Co-Authored-By: Claude Sonnet 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Cz7A6goxVzfKL9NT7k4zDH
…hod-size gate CI's craftsmanship gate job was red on 217ec1f: _worktree_locations spanned 51 lines (end_lineno - lineno), over the 40-line method cap (scripts/craftsmanship_rules.py METHOD_LINE_LIMIT). Split the classification logic into _worktree_classification(entries) -> (ok, detail), leaving _worktree_locations as a short orchestrator that turns the tuple into a Check. Same behavior, same tests. python scripts/check_craftsmanship.py --base origin/main -> Craftsmanship gate: OK Co-Authored-By: Claude Sonnet 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Cz7A6goxVzfKL9NT7k4zDH
_worktree_locations() treated every failure mode of `git worktree list` (no repository, git missing, timeout) as the same "inspection unavailable" WARN. Cortex is an MCP server whose cwd is whatever project the host opened; a project with no Git repository is ordinary, not a failure to inspect, so every such session's preflight showed a WARN whose fix command (`git worktree list --porcelain -z`) can never succeed there. `run_with_hard_timeout` collapses every subprocess failure mode to `None`, so the two cases can't be told apart after the call. A new `_is_git_checkout()` stdlib probe runs first instead — the same upward walk for a `.git` entry that Git itself performs to discover a repository, no subprocess involved. No `.git` anywhere up the tree now reports `ok True, detail "not a git checkout"`; a `.git` present but Git missing from PATH or the listing timing out keeps the optional WARN. Renamed test_not_a_git_checkout_warns to test_not_a_git_checkout_passes (now asserts the ok True case) and added test_git_unavailable_in_a_checkout_warns for the WARN case with a real .git present. Updated the parametrised None case in test_unavailable_or_empty_listing_contract, whose message no longer claims "not a Git checkout" as a possible cause since that case now short-circuits before the subprocess call. ADR-1079's Consequences section records the distinction. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01Cz7A6goxVzfKL9NT7k4zDH
5447cbb to
28aea2a
Compare
|
ZETETIC-REVIEW: APPROVE This supersedes the REQUEST_CHANGES of round two (#602 (comment)). Both findings from that round are fixed and verified at head Base and scopeThe round-two blocker: a project without gitFixed. From a directory with no From the checkout root, the check names both allowed roots: And in a real checkout where git cannot answer, with a stub No
|
Promotes the Unreleased section to 4.23.0 and moves the seventeen version surfaces (pyproject, manifest, plugin and marketplace manifests, Codex and Gemini manifests, package.json and lock, server.json, badge, uv.lock). Since 4.22.0: session hooks inject only the session's project and global memories (#604), one saved backend for Claude Code and Codex (#600), prediction records and calibration (#597), the wiki draft tools over MCP (#579), procedural skills on SQLite (#596) with a transcript-fed tool sequence (#591), the console entry point and Codex event adapter for the lifecycle hooks (#605, #608), the doctor worktree check (#602), and the launcher fixes (#573, #575, #582). The marketplace pin for zetetic-team-subagents moves to its released 2.42.0. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01Cz7A6goxVzfKL9NT7k4zDH
* release: 4.23.0 Promotes the Unreleased section to 4.23.0 and moves the seventeen version surfaces (pyproject, manifest, plugin and marketplace manifests, Codex and Gemini manifests, package.json and lock, server.json, badge, uv.lock). Since 4.22.0: session hooks inject only the session's project and global memories (#604), one saved backend for Claude Code and Codex (#600), prediction records and calibration (#597), the wiki draft tools over MCP (#579), procedural skills on SQLite (#596) with a transcript-fed tool sequence (#591), the console entry point and Codex event adapter for the lifecycle hooks (#605, #608), the doctor worktree check (#602), and the launcher fixes (#573, #575, #582). The marketplace pin for zetetic-team-subagents moves to its released 2.42.0. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01Cz7A6goxVzfKL9NT7k4zDH * release: the zetetic-team-subagents pin fetches the 2.42.0 tree it advertises The review of this cut found version 2.42.0 beside ref v2.41.0 and the 2.41.0 sha; installs would have checked out 77b4f785 under a 2.42.0 label. ref and sha now name the v2.42.0 tag commit 96454db1, as the earlier deliveries (#553, #554) moved all three fields together. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01Cz7A6goxVzfKL9NT7k4zDH * docs(changelog): name the consolidation launcher that shipped The ADR-1082 entry cited a consolidate_launch module the craftsmanship gate refused; the shipped design relaunches session_lifecycle with --consolidate <mode>, as ADR-1082 and the code say. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01Cz7A6goxVzfKL9NT7k4zDH --------- Co-authored-by: Claude Fable 5.1 <[email protected]>
PR #602 accepts both repository host worktree roots, preserves Git paths with NUL framing, and reports unavailable inspection as an optional WARN. ADR1079 avoids the allocation used by PR600.
Final author SHA: 28aea2a (rebased onto origin/main 4bd7e7f, plus one added commit fixing the not-a-git-checkout WARN a review round found).
Validation: 51 passed in 8.83s across test_doctor, test_doctor_worktrees, handlers/test_check_setup and shared/test_subprocess_safe (macOS, Python3.13; the added test is test_git_unavailable_in_a_checkout_warns). Full pytest -q: 8829 passed, 8 skipped, 459 subtests passed, 2 failed — both in tests_py/hooks/test_entry.py, unrelated to this PR's files (console-entry-point parity from #605), pre-existing on origin/main. Ruff0.16.6 check and format passed; pyright mcp_server/doctor.py clean; craftsmanship --base origin/main passed; check_doc_claims and check_project_wiki passed. Ignore probe ignored only root .Codex/probe, not nested/.Codex/probe. Newline regression failed before fix; two targeted mutants killed (reject Codex, trim path). No exhaustive mutation score claimed.
Review round two (ZETETIC-REVIEW: REQUEST_CHANGES) found that a project with no Git repository at all produced the same optional WARN as Git being unavailable or timing out, with a fix command that cannot succeed there. Fixed by probing for a
.gitentry via stdlib walk before ever shelling out; "not a git checkout" is nowok True, the WARN is reserved for Git itself failing to answer. ADR-1079 records the distinction.Completion ledger. All remote checks completed without failure on final head
5447cbb837649ef26e967b763121d16ec65003c1. Independent final code review: APPROVE; report held locally.Path ledger prefixes: D = tests_py/test_doctor.py::TestWorktreeLocations; W = tests_py/test_doctor_worktrees.py; S = tests_py/shared/test_subprocess_safe.py.
.gitin the ancestor walk)No remote publication of this draft by author. CI-dependent rows require final-SHA verification before merge.