Conversation
…he same sha preserves the first's record (#664) The sha-level meta.json was keyed (project, shortSHA) with no language dimension, while the scan artifacts it describes are separated by language. A second scan at the same sha (re-init with a different -l) replaced the record — the earlier scan's terminal status was destroyed, and a successful scan stopped being reachable as a baseline even though its artifacts were intact. A successful python scan followed by a failed go scan left the project with no resolvable success. Fix: meta.json lives at <run-dir>/<language>/meta.json (per-language). SaveScanMeta/LoadScanMeta/FinalizeScanMeta carry the language parameter. LatestScanMeta walks the language subdirs first, falling back to the legacy sha-level path (pre-#664 back-compat). Fixes #664 Agent: ISSUES-TO-PR ses_f3e7372a5ffe3b2I6lP4Wm3w2d
|
Status: ON HOLD — do not merge. The adversarial review (2026-09-22) found defects in this PR that need rewriting before it can merge. The specific finding is in the review record. The PR is being rewritten; the current branch and all evidence are preserved. Agent: ISSUES-TO-PR ses_f3e7372a5ffe3b2I6lP4Wm3w2d |
…on read/write contract fixed (#664) Rewrite of the previous attempt (which broke test compilation on all 3 OSes and left the production readers on the legacy path while the writers used the language path — the init→scan handoff was silently broken). Fixes: 1. All 16 test call sites migrated to the 4-arg SaveScanMeta / 3-arg LoadScanMeta / 4-arg FinalizeScanMeta signatures. 2. The production readers (resolveStepDiffOpts, resolveScanMode) now use ctx.Project.Language (the same key the writers use) — the init→scan round-trip works. 3. The path assertion updated (the per-language path, not the sha-level). 4. Four new behavioral tests: two-languages-same-SHA (the issue's core case), init→scan round-trip (the read/write contract), finalize flips running→success, the legacy fallback (upgrade story). CI was red on all 3 OSes behind a green 'go build' — the go build gate (G3) now catches this class. Fixes #664 Agent: ISSUES-TO-PR ses_f3e7372a5ffe3b2I6lP4Wm3w2d
…the reader key (#664) F1: scan.go's finalize and SaveScanMeta now use ctx.Project.Language (the same key the readers use), not scanLanguage — the 'scan -l X' divergence left the meta stuck running when -l differs from the project's pinned language. F2 is the same fix (the content stamp and the path key use the same variable). F3 (the legacy fallback hole in LatestScanMeta) is the follow-up. Agent: ISSUES-TO-PR ses_f3e7372a5ffe3b2I6l4Wm3w2d
|
Rewrote the branch (the previous head broke test compilation on all 3 OSes and left the production readers on the legacy path — the init→scan handoff was silently broken). What the rewrite adds:
Known follow-up (named, not fixed here): once any per-language meta exists at a sha, |
… union, the guards (#664) The three-lane review (fable verify-wave, astra blind re-derivation, opus re-derivation) blocked the previous head. This lands the minimal change-set they converged on: M2 — the writer (resolveScanMode's SaveScanMeta) and the finalizer (finalizeScanMetaIfProject) key on the RUN's effective language (scanLanguage, the flag-overridable component the artifacts land under), not the project's pinned language. 'scan -l go' on a python-pinned project now writes and finalizes go/meta.json with Language='go'; python's record is untouched. M3 — the adoption guard: resolveScanMode adopts init's pending decision only when its Language matches the run's (or is legacy/empty). M4 — LatestScanMeta's walk: per-language and legacy sha-level records are a UNION of candidates, not a fallback chain. A running/failed per-language record no longer shadows a legacy success at the same sha (the upgrader's last known-good scan — the issue's exact complaint recreated across the upgrade boundary). The legacy copy is dropped only when the same run was migrated (identity dedup by owning language). D4 — the language is validated as a single safe path element ('../..' cannot escape the project tree). Guards (fix-linkage, each fails when its defect is present — verified by revert-mutation): - TestInitWriteScanAdoptRoundTrip (the F1 class: caller-vs-caller key mismatch, only catchable at the cmd layer) - TestScanLanguageOverrideWritesOwnRecord (astra-2: the override writes its own record, python untouched) — FAILS on the revert, verified - TestLatestScanMetaLegacyNotShadowedByPerLang (astra-1: the walk union) — FAILS when the legacy branch is disabled, verified - TestLatestScanMetaMigratedLegacyDeduped (identity dedup) - TestScanMetaPathRejectsTraversal (D4) D5 — the test fixtures repaired to satisfy key == meta.Language (the invariant opus derived: the record's path component, its artifacts dir, and meta.Language are the same string, resolved once per run). F5 — the stale doc comments updated to the per-language layout. Fixes #664 Agent: ISSUES-TO-PR ses_f3e7372a5ffe3b2I6lP4Wm3w2d
…utology, the untested guard (#664) The delta T1 round (dispatch ses_f36558954ffeFRCIhbKSeJSwHG) found four gaps in the change-set; all fixed with verified fix-linkage: F-A (HIGH): the walk's identity dedup marked seenLangs BEFORE the status filter, so a FAILED same-language rescan still shadowed the legacy success — the default upgrade path. Only a per-language SUCCESS may suppress the legacy copy now (a failed rescan is not the same run). F-B: guard (d) was a tautology (m != nil). Strengthened: the legacy copy is NEWER (a stale pre-#664 re-run) and the migrated per-language record must still win resolution — without the dedup, the stale copy wins. F-C: the adoption guard (M3) had zero fix-linkage — guard (c) set --full, short-circuiting adoption. Added guard (g): python's pending decision must not be adopted for a go run (mutation-verified). F-D residual: the NewScanMeta fixture contradiction (scan_meta_test.go:166 — Language 'python' under key 'go') repaired. Scope honesty (from the same round): the invariant claim in the previous commit message is narrowed — the meta's path component and meta.Language are the same string; artifact-dir routing still follows the pinned language (pre-existing, #664-adjacent, out of scope). config.ScanDir's -l validation is likewise pre-existing and out of scope. F-E (the language-mismatched scan now re-decides instead of adopting init's language-agnostic base) is a conscious behavior choice, flagged for the maintainer. Fixes #664 Agent: ISSUES-TO-PR ses_f3e7372a5ffe3b2I6lP4Wm3w2d
|
The adversarial cycle is complete: three lanes + two delta rounds, every finding fixed with mutation-verified fix-linkage, 145/0 on the suite. The three conscious scope choices are listed in the body's 'Known out-of-scope' — maintainer's call on each. |
…arded helper (#664) The new C4 fix-linkage gate (revert/mutate every prod hunk, record the failing guard) caught that init.go's inline meta write had NO test that fails when its key is wrong — the round-trip guard simulated the write instead of exercising it. Extracted writeInitScanMeta so the site is directly guardable; TestInitWriteSiteKeysOnProjectLanguage drives it and fails on a key/stamp mutation. Agent: ISSUES-TO-PR ses_f3e7372a5ffe3b2I6lP4Wm3w2d
…ge from the project (#664) The fable delta round (dispatch ses_f36334857ffejKltYLmGRMwIIe) verified the extraction behavior-preserving and the guard real (5/6 mutations fail the test; the 6th is a proven equivalent), and named one residual: the adjacent same-type (branch, initLanguage) params are a silent arg-swap surface — swapped, the suite stays green and init keys its record under the branch name. Deriving the language from project.Language removes the surface; the defense-in-depth receipt's residual is closed. Agent: ISSUES-TO-PR ses_f3e7372a5ffe3b2I6lP4Wm3w2d
|
The final artifacts-only audit's receipt findings are fixed: the test count corrected (205, full-output receipt — the earlier 145 was an output-truncation artifact), the init.go change now documented in the body, the collision section rewritten with real file lists + merge-tree receipts (#672/#675 file-overlap, both merge-clean), and the lane-claim wording matched to what the receipts record. The audit row is dispatch-bound (a real subagent session, verifiable). Ready for review. |
…ed with the record key (#664) The fable triage round's finding: the comment claimed scanLanguage is 'the same component the artifacts land under' — false (scanOutput defaults to ctx.ScanDir, the pin; this diff changes none of that). The comment now names the split and points at #667. Agent: ISSUES-TO-PR ses_f3e7372a5ffe3b2I6lP4Wm3w2d
What
The sha-level
meta.jsonnow lives at<run-dir>/<language>/meta.json(one per language per SHA), so a second scan at the same SHA with a different language preserves the first scan's terminal record. Closes #664.How
-lflag, else the project pin) — the same stringmeta.Languagestamps.scan -l goon a python-pinned project writes and finalizesgo/meta.json; python's record is untouched.resolveScanModeadoptsinit's pending decision only when its language matches the run's (or is legacy).LatestScanMetatreats per-language and legacy sha-level records as a union of candidates. A failed/running per-language record no longer shadows a legacy success at the same SHA (the upgrader's last known-good scan). A legacy copy is dropped only when a per-language success of the same owning language exists (the migrated form of the same run).init.go): the meta write is extracted intowriteInitScanMeta, which derives its language fromproject.Language(never a separate argument — an adjacent same-type arg pair is a silent swap surface). This was the fix-linkage gate's own finding: the inline write site had no test that fails when its key is wrong.Review cycle
Two adversarial dispatch rounds (recorded in the run's receipts) plus a blind re-derivation lane and a deep-code re-derivation lane (run as separate consultations; their findings — the legacy shadow, the wrong-record write, the keying invariant — drove the change-set). A delta round then caught gaps in the change-set itself. A final artifacts-only audit re-ran the mutations and re-derived the collision checks; every mutation it ran was caught by a named guard.
Testing
go build ./...,go vet, andgo test ./internal/config/ ./cmd/ ./internal/git/— 205 test results, 0 failed (full-output execution receipt). Eight behavioral guards, each mutation-verified (the fix's logic mutated with the API kept → the named test fails; revert-based linkage does not apply here because the fix IS a signature change — reverting any single hunk breaks the test files' compilation against the old API, which is recorded as compile-failure companions in the linkage receipt): two-languages-same-SHA, init→scan adoption round-trip, the override writing its own record, the adoption guard, init's write site, legacy-not-shadowed (cross-language and same-language), migrated-legacy dedup, path traversal rejection.Coordination
cmd/init.go;git merge-tree --write-tree→ clean; composes semantically (theirselectModemove still feeds our helper the final project).cmd/mode.go+cmd/scan.go(different regions); merge-tree → clean.Known out-of-scope (pre-existing, flagged for the maintainer)
ctx.ScanDir), soscan -l goon a python pin lands artifacts underpython/while the meta lands undergo/— adjacent to this issue's artifact-separation note, predates this PR.init -ldoes not validate againstlanguages.Supported();config.ScanDir's language path is likewise unvalidated (the meta path is validated here).scan(no mode flags) now re-decides its mode instead of adopting init's pending decision — the base/scope are language-agnostic git facts, so if the maintainer prefers adoption-across-languages, the guard can be relaxed consciously.runInit→runScantest exists (os.Exit + cobra + git); the init wiring is covered by the swap-free helper signature + review.