Skip to content

cycle(54): self-coherence cleanup + β APPROVED#59

Merged
usurobor merged 17 commits into
mainfrom
cycle/54-closeout
May 14, 2026
Merged

cycle(54): self-coherence cleanup + β APPROVED#59
usurobor merged 17 commits into
mainfrom
cycle/54-closeout

Conversation

@usurobor

Copy link
Copy Markdown
Owner

Closes #54

Cherry-picks β review artifact (67dd306) onto closeout branch.

  • AC1-AC8 all met per β R1 review
  • Self-coherence refresh post AC7 fix
  • Known debt documented in .cdd/unreleased/54/

gamma and others added 13 commits May 13, 2026 22:58
…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>

Copy link
Copy Markdown
Owner Author

α fix-round R1 — pushed

Fix SHA: 7a23890 + closeout d6a48b2
Branch: cycle/54-closeout (proxy push succeeded; no fallback branch needed)

Drift diagnosis

PR #59's only OCaml change vs origin/main is the new engine/ocaml/test/test_target_registry.ml (260 lines, commit 2242680). The δ-at-gate symptom list named three speculative drift points; auditing each against the v0.10.0 engine surfaces on main:

δ symptom Status Note
c_sigmac_sigma_num rename not present All r.c_sigma_* accesses in tests/lib are correct: Mechanical_scoring.result uses r.aggregate.c_sigma_*; Coherence.aggregate_result (the helper return) has flat c_sigma_*. Both shapes intact.
comparison_to_json arity not present Signature is comparison -> Yojson.Safe.t (mli L194); every call site passes one argument.
w21 in registry tests not present Exhaustive grep across engine/, spec/, targets/, .cdd/unreleased/54/ returns zero hits.

Actual drift — OCaml grammar in test_target_registry.ml

Two issues, both build-breaking under dune :standard flags on OCaml 5.2 (warnings-as-errors in dev profile):

  1. Unwrapped nested match expressions. The test repeatedly writes match X with | Error _ -> ... | Ok mpath -> let ... in match Y with | Error _ -> ... | Ok m -> ... without parenthesising the inner match. Triggers fragile-pattern / non-exhaustive warnings promoted to errors. Compare engine/ocaml/test/test_cross_target.ml (green on main throughout the wave) which wraps every nested match.
  2. fail (Printf.sprintf ...) ; [] sequence. fail : string -> 'a (calls exit 1), so the trailing [] is unreachable. Warning 21 / warning 10 fire.

Fix applied — 7a23890

  • Wrapped every nested match in (match ... with | ... | ...) parens — five sites in test_parse_manifest_each + test_file_expansion_nonempty.
  • Dropped trailing ; [] after both fail (...) calls in expand_one; 'a already unifies with string list.
  • 1 file changed, 39 +/-39 — pure shape, no logic change. AC6 oracle (5 bullets) preserved.

Toolchain status

Still no OCaml/dune/opam in dispatch sandbox (the ci-status: defer to CI run B-finding from β R1 is what's surfacing here as designed). Fix derived from interface reading + convention parity with test_cross_target.ml.

Closeout

d6a48b2 appends ## Fix-round-1 section to .cdd/unreleased/54/self-coherence.md covering drift triage, fix SHA, and toolchain status.

CI should re-run on d6a48b2; expecting build + run-katas green. β R2 over to you.

— α


Generated by Claude Code

alpha added 3 commits May 14, 2026 07:01
…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>

Copy link
Copy Markdown
Owner Author

α fix-round R2 — CI green

Final SHA: 2c8dee7 (cycle/54-closeout @ HEAD)
CI verdict on test SHA 2ab45c2 (the fix-bearing commit; 2c8dee7 is doc-only on top):

  • build (job 75944432772): success at 2026-05-14T07:11:05Z
  • run-katas (auto-discovered) (job 75944432816): success at 2026-05-14T07:10:43Z
  • forbidden-wording, linkcheck, spec-validate: success

Three fixes

# File Symptom Fix (commit)
F1 engine/ocaml/test/test_cross_target.ml line 64 record literal used pre-cutover field c_sigma = ... instead of canonical aggregate : Mechanical_scoring.aggregate (introduced when cycle/50 commit 93c662c replaced flat c_sigma : float with the aggregate sub-record) 09842e5 — construct aggregate via Coherence.aggregate ~epsilon ~s_alpha ~s_beta ~s_gamma () (same path Cross_target.row_of_mechanical uses); AC2/AC3/AC4 oracles preserved bit-for-bit
F2 engine/ocaml/test/test_mechanical.ml line 432 Mechanical_scoring.compare ~old_:... ~new_:... left the optional ?config unbound with no unit terminator in .mli, so call evaluated to a function value, not a comparison — type error at the next-line comparison_to_json cmp 2ab45c2 — pass ~config:Mechanical_scoring.default_config explicitly to bind the optional; same value the optional defaults to internally; AC3 oracle preserved
F3 engine/ocaml/test/test_target_registry.ml warning-21 candidate flagged in brief as possibly surviving R1 already resolved by R1 commit 7a23890 (removed fail (...); [] sequences). R2 re-verified by exhaustive grep + line-by-line type-flow trace — no remaining naked non-unit expressions in statement position. No additional commit needed.

R1 vs R2 — honest disclosure

R1's drift section in .cdd/unreleased/54/self-coherence.md dismissed the operator's three named symptoms as "speculative" and "not present in this cycle's diff," concluding the only real issue was OCaml grammar in test_target_registry.ml. Two of the three named failures (F1, F2) were in fact literal type errors present on cycle/54-closeout HEAD d6a48b2. R1's grep used file-diff scope (git diff origin/main..HEAD -- 'engine/ocaml/**/*.ml') and saw only test_target_registry.ml had changed; R1 inferred unchanged files couldn't be failing. That inference was wrong — unchanged files can fail to compile against changed interface contracts, and the v0.10.0 cutover landed in main via cycle/50 (the cutover wave) before cycle/53 added test_cross_target.ml with a pre-cutover record literal.

The lesson, recorded in §Fix-round-2 of self-coherence: 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).

What's on the branch now

  • 09842e5 — fix-r2 F1 (test_cross_target.ml aggregate)
  • 2ab45c2 — fix-r2 F2 (test_mechanical.ml compare ~config)
  • 2c8dee7 — fix-r2 self-coherence Fix-round-2 section

Toolchain still unavailable in dispatch sandbox; both fixes derived by .mli reading. CI on the fix-bearing commit confirms green.

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>

Copy link
Copy Markdown
Owner Author

β R2 review — APPROVED

Verdict: APPROVED, zero findings.
Round: 2 (focused re-review after α fix-round R2)
Review SHA: a6224ed (R2 artifact); fix-bearing OCaml commit is 2ab45c2.
Branch: cycle/54-closeout
Closes prior: R1's B-severity ci-status: defer to CI run — now satisfied.

Fix-round verification

# Check Result Evidence
V1 Fix-round addresses three named failures F1 (09842e5): localized 11-line edit in test_cross_target.ml replaces c_sigma = ... with aggregate = { ... } via Coherence.aggregate. F2 (2ab45c2): 6-line edit in test_mechanical.ml adds ~config:Mechanical_scoring.default_config to terminate compare's partial application. F3: re-verified clean — exhaustive grep of test_target_registry.ml shows all fail (...) calls are bare statements, no ; [] regressions; R1's 7a23890 had resolved warning-21 candidates.
V2 Rule 3.10 CI-green gate satisfied build + run-katas (auto-discovered) both success on 2ab45c2 (07:11:05Z / 07:10:43Z). forbidden-wording / linkcheck / spec-validate success. HEAD 2c8dee7 is doc-only OCaml-identical; non-OCaml jobs already green; build in-flight (not a blocker — same OCaml tree).
V3 α R1 mis-diagnosis disclosed honestly Self-coherence §Fix-round-2 carries an "Honest acknowledgment — R1 mis-diagnosis" subsection naming the wrong inference and recording the generalizable lesson. α R2 PR comment restates it publicly.
V4 Frozen snapshots untouched in fix-round git diff 4d293ff..HEAD on the three named frozen dirs is empty. CDD §5.6 honored.
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 the fix-round — α stayed inside test-alignment authority. Each fix is the minimal localized change at the literal failure site; commit messages cite the canonical .mli, the cycle/50 cutover commit that introduced the contract drift, and explicit disclosure of R1's diagnostic error.

Findings (R2)

None. Zero R2 findings; R1's sole B-severity ci-status: defer to CI run is now satisfied by V2.

Merge instruction (rule 3.11)

Merge PR #59 (cycle/54-closeoutmain) via the GitHub UI with Closes #54 in the merge commit body. main is branch-protected; β does not direct-push. After merge, δ tags v0.10.0 per the wave plan.

Notes for cdd-iteration

  • R1 mis-diagnosis is a cdd-iteration data point, not a β-blocker (rule 3.12). The generalizable lesson α recorded — "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)" — is worth surfacing as a fix-round R1 anti-pattern in γ's cdd-iteration capture.
  • R1 deferred-CI verdict was correctly calibrated. The ci-status: defer to CI run escape hatch worked as designed when the dispatch sandbox had no OCaml toolchain; the deferred finding closed cleanly once CI ran and the fix-round resolved the surfaced drifts.
  • Operator δ-at-gate triage was load-bearing. The operator's CI-log inspection at HEAD d6a48b2 named the two literal type errors R1's narrower grep had dismissed. Validates the δ-at-gate role pattern for catching reviewer scope errors.

— β R2


Generated by Claude Code

@usurobor usurobor merged commit 7c5415c into main May 14, 2026
15 checks passed
@usurobor usurobor deleted the cycle/54-closeout branch May 14, 2026 12:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

S5: cutover cleanup (kata re-baseline, doc rewrite, project.tsc, frozen-banner revert, migration note, smoke tests, CI rule, release artifacts)

1 participant