# β Close-Out — Cycle #261 (PR #263)

## Cycle summary

| | |
|---|---|
| Issue | #261 — Wire skill activation to filesystem discovery + frontmatter visibility |
| PR | #263 — squash-merged to main as `41485ad` |
| Ships in | 3.57.0 (release commit `3357409`; tag `3.57.0` push deferred to γ — HTTP 403 sandbox constraint per β step 8; branch cleanup `claude/alpha-skill-go-implementation-LJVHx` also deferred to γ for the same reason) |
| Review rounds | **3** (RC → conditional A → A) — **above ≤2 target; §9.1 trigger fires** |
| Findings total | 4 (all judgment, 0 mechanical) |
| Mechanical ratio | 0% (0/4) — below 10-finding threshold; no process issue filed |
| Diff shape | **L6–L7** at the mechanism boundary (filesystem-as-authority enforced in Go; `visibility: internal` effective at runtime for the first time; many-to-many activation model made explicit in doctor wiring; real-corpus integration tests auto-catch regression) |
| Cycle process level | **L6** (cycle cap — §9.1 review-rounds trigger fires; L5 missed cleanly because two authoring-time defects reached review) |

## Findings

### F1 (D, judgment) — `ParseFrontmatter` dropped 81% of production trigger lines

Round 1 parser only supported block-list YAML (`triggers:\n  - a`); the real corpus uses inline flow-sequence (`triggers: [a, b, c]`) in 42 of 52 SKILL.md files. The new doctor check, wired over this parser, then flagged 19 cnos.core skills as "empty triggers" on a freshly restored hub — `cn doctor` went from green (OCaml path a no-op post-ef53b939) to red. CI `kata-tier2` (job 72823211280) red.

β reproduced locally before filing: built the round-1 binary, restored a test hub, ran `cn doctor`. 19 issues surfaced with exactly the expected skill names. The OCaml masking theory (manifest_skill_ids returns `[]` post-ef53b939, so validate never touches the corpus) was confirmed by reading `src/ocaml/cmd/cn_activation.ml:144`. The fix shape proposed in the RC review was 6 lines: strip brackets, split on commas, trim each item. α implemented this at `9cfd3c9` as `parseInlineList` with whitespace tolerance + empty-list nil semantics + quoted-items-not-supported explicit scope.

β re-verified at round 2: the four required regression tests (`TestParseFrontmatter_InlineTriggersSupported`, `TestParseFrontmatter_InlineTriggersWhitespace`, `TestParseFrontmatter_InlineTriggersMalformed`, `TestValidate_RealCorpus_NoEmptyTriggers`) all land. `cn doctor` on a freshly restored hub no longer reports any `[empty]` issues.

**Disposition:** closed at `9cfd3c9`. No skill patch — application gap, not spec gap (α had access to `cn kata run --class runtime` and `cn doctor` locally; neither was exercised before round-1 push). MCA is the real-corpus integration test pattern that shipped in the same round, not a new skill rule.

### F2 (C, judgment) — non-deterministic tarball build (pre-existing main defect)

`Package dist/source sync (I3)` CI check red on this PR but reproducible on `origin/main` with no #261 changes. Root cause: `createTarGz` (`src/go/internal/pkgbuild/build.go:185-258`) uses `tar.FileInfoHeader(info, "")` which copies the live `info.ModTime()` from the working-copy file into every tar entry header, and `gzip.NewWriter(mw)` does not override `gzip.Header.ModTime` so the gzip header records the writer's creation time. Both vary by checkout time → SHA-256 varies → I3 fails intermittently.

β reproduced by `git checkout origin/main -- . && cn build` — the rebuilt checksums diverge from the committed `dist/packages/checksums.txt` on a clean main with no source changes. This is not a #261 regression.

**Disposition:** deferred by design scope per review §7.0. α filed **#264** in round 2 with:
- concrete root cause citing exact file/line
- proposed fix (zero `hdr.ModTime`/`AccessTime`/`ChangeTime`, normalize uid/gid/uname/gname, set `gw.Header.ModTime = time.Time{}`, set `gw.Header.OS = 255`)
- byte-identity regression test in the ACs
- non-goals called out (cross-toolchain reproducibility; rebuilding existing released tarballs)

β concurs with the scope discipline: fixing I3 in #263 would have conflated a mechanism port with a build-determinism fix. #264 is the committed next MCA (see assessment §7).

**Known-cycle pattern:** I3 has been red for at least two consecutive releases (3.56.x carry-over + this one). Every review body now has to explain "I3 deferred per #264". Shipping #264 as the next MCA closes this persistent reviewer-tax.

### F3 (B, judgment) — `flushList` triggers-only materialization

Round-1 `flushList` hard-coded `fm.Triggers = triggersAcc`; any other block-list-opening key silently routed items into `triggersAcc` and then discarded them at flush. Currently latent (no other block-list field exists in the parser's recognised set) but a future `aliases:` block list would silently pollute the triggers-shaped buffer.

Proposed fix (B-level note in RC review): rename `triggersAcc` → `pendingItems`, dispatch via `switch pendingListKey` inside `flushList` with the existing `triggers` case as the only arm today. Same line count, zero future footgun, aligns the data structure with the invariant rather than the accidental current state.

α implemented at `9cfd3c9` exactly to the suggested shape. β verified by re-reading `frontmatter.go:79-89`.

**Disposition:** closed at `9cfd3c9`. Recording here as an example of the lowest-severity-that-still-matters B-level finding — latent footguns with a cheap fix are worth naming even when no current caller trips them.

### F4 (D, judgment, resolved inline via γ override) — trigger-conflict corpus exposed by F1 fix

Once `ParseFrontmatter` started reading production inline-list triggers in round 2, the cnos.core corpus turned up two classes of failure the previous (blind) path had masked:

- **12 internal-parent conflicts** (e.g. `cdd/review` internal claiming `review` while public `cdd` orchestrator also claims `review`). These are not activation ambiguities — the runtime never routes a trigger to an internal skill, only the public orchestrator, which then delegates. OCaml's `manifest_skill_ids`-based validate had the same semantic (internal sub-skills never entered the conflict loop) but achieved it as a side effect of empty `manifest_skill_ids`; the Go port needed to implement it as a deliberate filter.
- **9 genuine public-public overlaps** (`alignment`, `boundary`, `coherence`, `drift`, `onboard`, `reflect`, `self-check`, `sync`, `verify`). These are real semantic overlaps across domain skills: `coherence` legitimately applies to both `agent/clp` and `agent/coherent`; `verify` to both `agent/clp` and `agent/coherence-test`; etc. Under a 1:1 keyword→skill dispatch model these are authoring bugs; under a many-to-many activation-hint model they are intentional.

β's round-2 review framed F4 as design-scope outside #261 (the resolution requires doctrine on skill/trigger precedence, doctor severity, or corpus curation) and expected α to file a follow-up issue. α instead consulted γ and, per γ's direction, landed a two-part resolution in round 3 at `7e76798`:

- **(A) Visibility filter in `ValidateSkills`.** Internal skills no longer participate as conflict claimants. Mirrors OCaml-era semantics exactly. Two new tests (`TestValidate_InternalDoesNotConflictWithPublic`, `TestValidate_TwoInternalDoNotConflict`) prove both the internal-vs-public and internal-vs-internal paths. Drops 12 spurious orchestrator+internal conflicts from the real corpus.

- **(B) Severity split in doctor wiring.** `IssueMissingSkill` (unreadable/malformed SKILL.md — genuine structural break) stays `StatusFail`. `IssueEmptyTriggers` and `IssueTriggerConflict` become `StatusInfo` — doctor prints them as `○` warnings with precise messages but does not escalate the hub. The underlying model is that cnos activation keywords are many-to-many hints, not exclusive dispatches; overlapping keywords across domain skills are a legitimate authoring pattern. `TestSkillActivationCheck_FailsOnTriggerConflict` → `_WarnsOnTriggerConflict`.

β verified locally at round 3: `cn doctor` on a hub with `cnos.core@3.57.0 + cnos.kata@0.2.0 + cnos.cdd.kata@0.3.0` exits rc=0 with `○ skill activation 9 warning(s)` (the 9 expected public-public overlaps); `cn kata run --class runtime` passes all 4 runtime katas including the `R3-doctor-broken` pre-break baseline.

**OCaml severity divergence note.** β's round-3 approval surfaced a real semantic departure: `src/ocaml/cmd/cn_doctor.ml:46-49` maps `Trigger_conflict` to `Cn_fmt.fail` and Missing/Empty to `Cn_fmt.warn`; `any_conflict` is the OCaml fatal signal. The new Go mapping inverts this (Missing fatal; Empty + Conflict warn). AC4's "equivalent to what `cn_activation.validate` does today" speaks to the validator's issue generation (still equivalent: same three `IssueKind`s), not to the doctor severity wiring, so the literal contract is preserved. But the mapping change is a real semantic departure that downstream tooling greping for `✗ skill activation` on conflicts will notice.

β did not block on the severity divergence — the mapping is defensible on the many-to-many model, γ ratified the path explicitly, and the new behavior is both coherent and operator-visible via `○` warnings. But β should have surfaced the divergence in rounds 1 or 2 rather than in the round-3 approval note. Recording as a review-skill gap below.

**Disposition:** closed at `7e76798`. Review-skill gap recorded for γ triage (review §2.2.8 consumer-corpus as authority surface; review §2.2.8 OCaml-doctor severity mapping as an authority surface alongside OCaml-activation parser). Neither patched this session — both benefit from two to three more parser-review cycles of observation before codifying.

## §9.1 Triggers

Fired:

- [x] **review rounds > 2** — actual 3 (one RC, two narrowings).
- [x] **loaded skill failed to prevent a finding** — F1's inline-list gap would have been caught by `cn kata run --class runtime` locally at authoring time (which α did on round 3). The skill (`eng/go`) already covers CI-verification-before-review; the gap is application, not spec.

Not fired:
- [ ] mechanical ratio > 20% — 0% (0/4 total findings; below 10-finding threshold regardless).
- [ ] avoidable tooling/environmental failure — I3 is a pre-existing main defect deferred per #264, not a cycle regression. HTTP 403 on tag push + branch delete is the documented sandbox constraint per β step 8 / §2.6a; release artifacts are committed to main and the non-git-push actions are deferred to γ/operator.

Cycle Iteration section lives in the post-release assessment §4b; the triggers above drive that section's mandatory presence.

## γ reports

**Two requests to γ this cycle:**

1. **Push tag `3.57.0` to origin.** The local tag exists at release commit `3357409`. `git push origin 3.57.0` returned HTTP 403 (sandbox constraint, reproduced across two retries with independent `git ls-remote` verification confirming the tag is not on the remote). β ran out of retry budget inside the sandbox. From an environment that can reach origin: `git push origin 3.57.0`. The release CI workflow is tag-triggered — binaries won't build until the tag lands.

2. **Delete merged remote branch `claude/alpha-skill-go-implementation-LJVHx`.** Same HTTP 403 constraint. From an environment that can reach origin: `git push origin --delete claude/alpha-skill-go-implementation-LJVHx`. The PR is squash-merged as `41485ad`; the branch content is in git history via the merge commit and via `7e76798` (the final PR tip) accessible until the branch is deleted.

**Three candidate MCAs recorded for γ triage, none shipped this session:**

1. **Review skill §2.2.8 — extend "authority surfaces" to include the production consumer corpus.** F1 surfaced because β's round-1 §2.2.8 audit cited OCaml as the reference authority but did not audit the parser against the real `src/packages/*/skills/**/SKILL.md` corpus — which was materially different because OCaml's parser was also blind to the corpus post-ef53b939. Candidate addendum: when reviewing a parser/validator, the authority surfaces include (a) the canonical spec, (b) the reference implementation, and (c) the production consumer corpus. Deferred to γ triage pending two to three more parser-review cycles.

2. **Review skill §2.2.8 — extend "authority surfaces" to include adjacent-wrapper severity maps when a validator is ported.** F4's OCaml severity divergence (Trigger_conflict fatal in OCaml `cn_doctor.ml`; warn in new Go `doctor.go`) surfaced only at round-3 approval. Candidate addendum: when porting a validator, the authority surfaces include (a) the validator's issue generation and (b) the adjacent doctor/CLI layer's severity mapping of those issues. Same "deferred pending observation" disposition as candidate 1 — both could collapse into one §2.2.8 sharpening.

3. **Doctrine doc for the activation model.** The many-to-many activation-hint semantic that F4's severity split endorses currently lives only in `src/go/internal/doctor/doctor.go:107-109` comments and in the `PACKAGE-ARTIFACTS.md §Activation` prose (which still reads "runtime loads **the** matching skill" in the singular). A canonical doctrine surface — either a new `docs/alpha/ACTIVATION-MODEL.md` or a sharpening of `PACKAGE-ARTIFACTS.md` — would formalise the semantic so downstream cycles don't have to re-derive it from doctor comments. Future-cycle docs task, not β-shipped.

**No pending MCA proposals from α this cycle** beyond the F2→#264 filing, which is already the next MCA.

## Next cycle

β concurs with this cycle's §7 commitment: **#264** is the next MCA. Rationale in the assessment §7 — adjacency to this cycle's build/restore chain, concrete one-function fix with shape already drafted in the issue body, closes the persistent I3 CI-trust gap that has taxed every recent cycle's review body. α owns, branch pending, first AC is byte-identical rebuild on the same clean tree, MCI freeze continues (10 growing-lag items).

---

Signed: β (`beta@cdd.cnos`) · 2026-04-24 · release commit `3357409` · merge commit `41485ad` · close-out `.cdd/releases/3.57.0/beta/261.md`
