cycle(54): self-coherence cleanup + β APPROVED#59
Conversation
…tch contract γ creates cycle/54 from origin/main @ 3efde94 (post-S1+S2+S3+S4 merge). Scaffold names scope, AC mapping (8 ACs), α/β/operator/δ dispatch contract, known constraints. α and β are dispatched as separate subagent sessions per CDD §1.4 Triadic rule — no γ+α collapse this cycle. Wave-1 carry-over disclosed to α/β briefs: session-bound git proxy 403 recovery pattern; OCaml toolchain absent in dispatch sandbox (B-severity ci-status finding is γ-authorized).
…tric c_sigma_num) Each kata gains a [baseline] block capturing: - baseline_engine_commit/version/command/mode/config_hash/input_file_hashes - per-axis α, β, γ (recorded triples where available; inferred where not) - c_sigma_math and c_sigma_num (geometric (α·β·γ)^(1/3)) - zero_component_present, numeric_floor_applied - rationale_category (aggregate-correction or frontier-tightening) Kata-04 and kata-05 carry frontier-tightening rationale to retain documented 'moving frontier' margins. Kata-01/02/03 inherit aggregate-correction with conservative range retention (per-axis triples on those katas were inferred from README signal narrative, not explicitly recorded; exact c_sigma_num CI re-baseline pending).
THESIS, QUICKSTART, ARCHITECTURE, OPERATOR-MANUAL, katas/README, and all five per-kata READMEs now: - describe geometric C_sigma_math and C_sigma_num (canonical v3.2, v0.10.0) - reference provenance.aggregate_math.C_sigma_math and provenance.aggregate_numeric.C_sigma_num in JSON examples and score-range references - remove the flat top-level c_sigma example - remove the arithmetic-mean (alpha+beta+gamma)/3 language Per-kata READMEs additionally record both the pre-cutover arithmetic reading (preserved as historical calibration) and the post-cutover geometric C_sigma_num value, plus a pointer to kata.toml [baseline] for the v0.10.0 provenance block.
…ing CI rule, RELEASE.md v0.10.0 AC5: CHANGELOG.md gets a 0.10.0 ledger row + detail section with a prominent migration note stating that pre-v0.10.0 frozen reports quote arithmetic aggregates and are not directly comparable to post-cutover output. References #49 master + four predecessor cycles (#50, #51, #52, #53). AC7: scripts/check-forbidden-wording.sh — bash script (no external deps; uses git-diff -U0 hunk parsing) that compares HEAD to a base ref (default origin/main) and rejects newly-added 'Operational acceptance', 'Operationally accepted', 'self-coherence ACCEPT', 'release criteria satisfied' outside docs/{tier}/{bundle}/{X.Y.Z}/, docs/archive/, .git/, _build/, .cdd/, CHANGELOG.md, RELEASE.md, and this script itself. Wired into .github/workflows/ci.yml as a new forbidden-wording job that runs on push + pull_request. Existing historical occurrences in excluded paths pass — the check is strictly forward-only. AC8: RELEASE.md rewritten as the v0.10.0 release notes describing the canonical-v3.2-cutover wave end-to-end (engine cutover via sub-cycles #50-#53, cleanup pass via #54). References #49 master.
engine/ocaml/test/test_target_registry.ml: 4 hermetic assertions
covering AC6's 5 bullet points:
AC6.1 parse_registry returns Ok for targets/registry.tsc and
asserts registry_format = "tsc-target-registry/0.1"
AC6.2 exactly the three names {spec, engine, repo} are registered
AC6.3 resolve_target_path returns Ok for each name -> the canonical
targets/{spec,engine,repo}.tsc manifest path
AC6.4 parse_manifest returns Ok with a non-empty manifest_include
(or manifest_include_targets) for each target
AC6.5 file-expansion produces > 0 files for each target via the
same root/path semantics main.ml uses (the expand_glob helper
is reproduced verbatim in the test so the runtime semantics
are exercised end-to-end)
The test walks up from cwd to find repo root (VERSION + targets/
registry.tsc co-located) which matches the dune runtime convention.
Wired into engine/ocaml/test/dune as test_target_registry. Existing
tests (test_response_schema, test_ood, test_cross_target,
test_mechanical, test_coherence, test_kata) coexist unchanged.
…review-readiness All eight ACs addressed and mapped to commit SHAs: AC1 katas re-baselined commit 1fa777e AC2 active docs canonical commit 2f45da8 AC3 project.tsc removed commit d6e8453 AC4 frozen-snapshot verified clean (no edits — banner absent) AC5 CHANGELOG migration note commit a274923 AC6 target-registry smoke tests commit 2242680 AC7 forbidden-wording CI rule commit a274923 AC8 release artifacts at 0.10.0 commit d6e8453 + a274923 Known debt (B-severity, explicit): - OCaml toolchain absent; dune build/runtest deferred to CI - Session-bound git proxy 403; cycle/54 stuck at 0981855 on origin, work pushed to cycle/54-fix as operator mirror - Kata-01/02/03 baseline triples inferred (cycle-34 recorded only the arithmetic-mean aggregate); pending CI re-baseline - Kata-04/05 retain frontier-tightening rationale (intentional) - Historical-report migration explicitly out of scope per #54 Ready for β.
…wording check The workflow that invokes scripts/check-forbidden-wording.sh names the phrases it checks for in its job-comment header (lines 102-108). That self-reference is documentation, not a new occurrence of the retired wording — analogous to how the script itself is on the exclusion list. Without this exclusion, running the script against the cycle/54 head finds 4 'forbidden' phrases in the ci.yml comment block, which would fail the very job that runs the script. Self-application now passes: $ bash scripts/check-forbidden-wording.sh main check-forbidden-wording: pass (base ref: main)
Contract integrity: all 11 rows yes/n/a. AC1–AC8 verified at HEAD 4d293ff. Honest-claim sub-checks (13) all pass — AC4 banner absence structural (empty diff), kata baseline geometric c_sigma_math reproduced to 4dp, AC7 self-application defect fixed at 431293f and re-run exit 0, AC8 version-consistency PASSED. CI gate (rule 3.10) deferred per γ-authorization — no OCaml toolchain in dispatch sandbox; classified B-severity `ci-status: defer to CI run`, operator verifies on the PR. γ-scaffold present (rule 3.11b satisfied). No D / C / B / A findings. Merge instruction: open PR cycle/54-closeout → main with `Closes #54`.
The new test_target_registry.ml (commit 2242680) used unwrapped nested match expressions and the `fail (...) ; []` sequence pattern. Under dune's default :standard flags on the CI OCaml 5.2 toolchain, this emits build-breaking warnings: - Inner `match ... with | ... | ...` without parens/begin..end risks fragile pattern-arm attribution to the outer match. - `fail (Printf.sprintf ...) ; []` sequences fail (which returns 'a via exit 1) with a list literal; warning 21 'this statement never returns' / warning 10 'this expression should have type unit' may be promoted to errors. This fix: - Wrap every nested `match` in `(match ... with | ... | ...)` parens, matching the convention used in engine/ocaml/test/test_cross_target.ml (which has been green on main throughout this wave). - Drop trailing `; []` after `fail` calls; since `fail : string -> 'a`, the empty list is unreachable and `'a` already unifies to the expected list type. No behavior change: every test still calls Target_registry.parse_registry / resolve_target_path / parse_manifest with the same arguments and checks the same invariants. AC6 oracle preserved. Addresses PR #59 build job failure (no other OCaml file changed in this cycle vs origin/main; test_target_registry.ml is the only diff). Refs: #54 Co-authored-by: alpha <alpha@tsc.cdd.cnos>
Documents the post-CI drift diagnosis and fix: - δ-at-gate symptoms triaged (c_sigma rename, comparison_to_json arity, w21) — none present in this cycle's diff. - Actual drift located in test_target_registry.ml: unwrapped nested match expressions and fail; [] sequence pattern, both triggering build-breaking warnings on OCaml 5.2 with dune's default :standard flags. - Fix applied at 7a23890; AC6 oracle unchanged. - Toolchain still absent; verification via convention parity with test_cross_target.ml which has been green on main throughout the wave. Refs: #54 fix-r1 Co-authored-by: alpha <alpha@tsc.cdd.cnos>
α fix-round R1 — pushedFix SHA: Drift diagnosisPR #59's only OCaml change vs
Actual drift — OCaml grammar in
|
…ggregate The v0.10.0 canonical-v3.2 cutover (cycle/50, commit 93c662c) replaced the flat [c_sigma : float] field on [Mechanical_scoring.result] with an [aggregate : Mechanical_scoring.aggregate] sub-record carrying [c_sigma_math], [c_sigma_num], [epsilon], [zero_component_present], [numeric_floor_applied]. The synthetic test fixture [mk_result] in test_cross_target.ml still used the pre-cutover [c_sigma = ...] form and would not compile against the current type. This fix constructs the aggregate via [Coherence.aggregate] (the same path [Cross_target.row_of_mechanical] uses internally) and assigns it to the [aggregate] field. The synthetic value carries: - [c_sigma_math]: strict geometric mean (collapses to 0 on zero α/β/γ) - [c_sigma_num]: ε-floored geometric mean (well-defined under degeneracy) - [epsilon]: from [Coherence.epsilon_default] - [zero_component_present] / [numeric_floor_applied]: as computed No behavior change to the test oracle: the test still calls [Cross_target.row_of_mechanical] / [report_from_results] with the same synthetic (α, β, γ) triples, and Cross_target re-derives the aggregate from r.alpha/beta/gamma.score regardless of r.aggregate, so AC2/AC3/AC4 oracles are preserved bit-for-bit. R1 disclosure: this is one of the three failures R1 mis-diagnosed as "not present in this cycle's diff." It was present on cycle/54-closeout HEAD d6a48b2 (and on origin/main itself); R1's grep was too narrow. Refs: #54 Co-authored-by: alpha <alpha@tsc.cdd.cnos>
… arg [Mechanical_scoring.compare] is declared as: val compare : ?config:config -> old_:Bundle.t -> new_:Bundle.t -> comparison With an optional argument followed only by labeled arguments (no unit or positional terminator), OCaml cannot decide when application is "complete" — the call [compare ~old_:bundle_a ~new_:bundle_b] returns a curried function value (still expecting either ?config or another positional), not a [comparison]. Passing that function value to [comparison_to_json] produces a type error: function-typed value where [Yojson.Safe.t] is expected. The fix passes [~config:Mechanical_scoring.default_config] explicitly at the call site so the optional is bound and [compare] resolves to a fully-applied [comparison]. Behavior is unchanged because [default_config] is the same value the optional would default to internally; the AC3 oracle (form-suffixed delta field names + value parity) is preserved bit-for-bit. This is failure #2 of the three the operator's δ-at-gate observed on cycle/54-closeout HEAD d6a48b2 — R1's grep missed it because the symptom is whole-call-site shape, not a single literal token. The brief's hint ("Pass ~config:Mechanical_scoring.default_config explicitly, OR terminate the partial application with ()") was acted on via the first alternative since the current .mli has no unit terminator. Refs: #54 Co-authored-by: alpha <alpha@tsc.cdd.cnos>
Records the three failures the δ-at-gate operator named on PR #59 build log at HEAD d6a48b2, the R2 fixes applied (commits 09842e5 + 2ab45c2), honest acknowledgment of R1's mis-diagnosis, and CI-green verdict on 2ab45c2. R1 had dismissed the operator-named symptoms as "not present in this cycle's diff" — F1 (c_sigma in test_cross_target.ml) and F2 (compare partial application in test_mechanical.ml) were in fact literal compile errors on the branch. F3 (warning 21 in test_target_registry.ml) was already resolved by R1 commit 7a23890; R2 re-verified. The lesson recorded plainly: audit by interface contract (does the literal call/access type-check against the current .mli?), not by file-diff (the failing site may be in a file untouched this cycle). CI verification on 2ab45c2: - build (job 75944432772): success at 07:11:05Z - run-katas (auto-discovered) (job 75944432816): success at 07:10:43Z Refs: #54 Co-authored-by: alpha <alpha@tsc.cdd.cnos>
α fix-round R2 — CI greenFinal SHA:
Three fixes
R1 vs R2 — honest disclosureR1's drift section in The lesson, recorded in §Fix-round-2 of self-coherence: audit by interface contract (does the literal call/access type-check against the current What's on the branch now
Toolchain still unavailable in dispatch sandbox; both fixes derived by Ready for β R2. Generated by Claude Code |
Appends Round 2 section to .cdd/unreleased/54/beta-review.md covering the focused re-review after α fix-round R2. Round 2 verdict: APPROVED, zero findings. V1 — fix-round addresses the three named failures: ✅ F1 (09842e5): test_cross_target.ml c_sigma → aggregate sub-record F2 (2ab45c2): test_mechanical.ml compare ~config explicit binding F3: already resolved by α R1 commit 7a23890; re-verified clean V2 — rule 3.10 CI-green gate satisfied: ✅ build + run-katas success on fix-bearing commit 2ab45c2. HEAD 2c8dee7 is doc-only OCaml-identical; non-OCaml jobs already green. Reclassifies R1's deferred B-severity ci-status finding to satisfied. V3 — α R1 mis-diagnosis disclosed honestly: ✅ Self-coherence §Fix-round-2 + PR #59 comment both name the wrong inference and record the lesson (audit by interface contract, not by file-diff). V4 — frozen snapshots untouched in fix-round: ✅ git diff 4d293ff..HEAD on frozen dirs = 0 lines. V5 — release artifacts consistent at 0.10.0: ✅ VERSION, dune-project, opam all stable at 0.10.0. Scope discipline: git diff 4d293ff..HEAD -- engine/ocaml/lib/ is empty. No production code modified in fix-round. α stayed inside test-alignment authority. Merge instruction: merge PR #59 (cycle/54-closeout → main) via UI with Closes #54 in the merge commit. main is branch-protected; β does not direct-push. Refs: #54 Co-authored-by: beta <beta@tsc.cdd.cnos>
β R2 review — APPROVEDVerdict: APPROVED, zero findings. Fix-round verification
Scope discipline
Findings (R2)None. Zero R2 findings; R1's sole B-severity Merge instruction (rule 3.11)Merge PR #59 ( Notes for cdd-iteration
— β R2 Generated by Claude Code |
Closes #54
Cherry-picks β review artifact (67dd306) onto closeout branch.