AGENT SKILL

release

Ship a version as a measured coherence delta with matching code, changelog, tag, release notes, deployment, and validation.

License 许可
Apache-2.0
所属仓库
usurobor/cnos
最近更新
2026-11-07
Stars
★ 9
Forks
0

01 前言 Front Matter

name
release
calls
[]
scope
task-local
inputs
[ "approved branch", "version decision", "release context" ]
parent
cdd
outputs
[ "release artifact set", "beta close-out" ]
requires
[ "approval and release readiness" ]
triggers
[ "release", "ship", "tag", "version", "deploy", "changelog" ]
visibility
internal
description
Ship a version as a measured coherence delta with matching code, changelog, tag, release notes, deployment, and validation.
kata_surface
embedded
artifact_class
skill
governing_question
How does β turn a converged branch into a released version with a complete and auditable coherence delta?

02 资源文件 9

03 SKILL.md 正文

Release

Core Principle

Coherent release: every version bump is a measured coherence delta with a complete audit trail.

β owns: review approval outcome, git merge into main, and β close-out. δ owns tag/release/deploy (the release boundary — scripts/release.sh, binary publication, deployment). γ owns RELEASE.md authoring, cycle-directory movement, and the post-release assessment. β does not tag, push tags, bump versions for release, or cut the disconnect release. See cnos.cds/skills/cds/CDS.md §"Development lifecycle" → §"Step table" (Step 8 β review/merge; Steps 9–13 γ-and-δ release sequence), operator/SKILL.md §3.4 (doctrinal frame), and release-effector/SKILL.md (mechanics).

Canonical artifact locations (β close-out path, RELEASE.md, snapshot dirs, tag policy) are defined in cnos.cds/skills/cds/CDS.md §"Artifact contract" → §"Location matrix". All tags are bare X.Y.Z; v-prefixed tags are legacy and warn-only.

A release has parts: readiness check, version decision, changelog, release notes, tag, binaries, deployment, validation. Coherence = each part completed and each artifact matches the others (version in code = tag = changelog = binary = deployed agent). The released system is validated, not merely published.

Failure mode: version drift — tag says X, binary says Y, agent reports Z. Or: releasing without validation, so breakage ships silently. Or: incomplete deploy where artifacts ship but assessment never lands.

1. Define

1.1. Identify the parts

  • Readiness: CI green, branches merged or returned, main clean
  • Version: semver bump decided from commit content
  • Artifacts: cn.json, VERSION, package manifests, CHANGELOG, RELEASE.md, tag, GitHub release, binaries
  • Deployment: binary on target hosts, cn deps restore, validation
  • ❌ Push tag, hope it works
  • ✅ Every artifact checked, deployed, validated end-to-end

1.2. Articulate how they fit

  • Version flows: VERSION → stamp-versions.sh → cn.json + package manifests → CHANGELOG → commit → tag → CI → binaries → deploy → validate
  • Each step depends on the prior; skip one and the chain breaks
  • ❌ Tag pushed before version bumped in code (binary reports old version)
  • ✅ Version string updated everywhere before commit, tag matches code

1.3. Name the failure mode

  • Version drift: any two artifacts disagree on the version
  • Silent breakage: release ships but CI failed or validation skipped
  • Incomplete deploy: binary updated but packages stale (cn deps restore not run)
  • ❌ "cn update worked" (but agent still reports old version)
  • ✅ cn --version matches tag, cn deps restore run, agent can execute ops

2. Unfold

2.1. Readiness check

  • CI passing on main (unit tests + integration tests + kata suite)
  • No unmerged branches that should be in this release
  • git branch -r --no-merged origin/main — review each, merge or defer
  • Non-destructive merge-test on the merge tree before merge. Build the merge tree in a throwaway worktree (git worktree add /tmp/cnos-merge-test/wt origin/main && cd /tmp/cnos-merge-test/wt && git merge --no-ff --no-commit origin/cycle/{N}); run any contract validators the cycle ships (e.g. ./tools/validate-skill-frontmatter.sh if the cycle adds or modifies SKILL.md frontmatter; cn-cdd-verify for .cdd/ artifacts; scripts/check-version-consistency.sh for version stamping); confirm zero unmerged paths and zero new validator findings. Tear down the worktree. Set any worktree-local git config with the explicit --worktree flag (git config --worktree user.name X) to avoid leaking identity to the shared repo .git/config (cycle #301 O8). This pattern is also referenced from beta/SKILL.md § pre-merge gate row 3 — it is the same step, named here so the release-flow doc is authoritative.
  • ❌ Release with failing CI ("it's just a flaky test")
  • ❌ Merge without running the cycle's own validators on the merge tree ("the cycle branch passes; the merge tree will too")
  • ✅ CI green, or known failure documented and accepted (e.g. Coherence workflow on #22)
  • ✅ Merge-tree validation green (especially when the cycle ships a new contract surface like #301's I5 frontmatter validator)

2.2. Version decision

  • Review commits since last tag: git log --oneline $(git describe --tags --abbrev=0)..HEAD
  • Major: breaking changes, paradigm shift
  • Minor: new features, backwards compatible (new ops, new skills, new specs)
  • Patch: bug fixes only
  • ❌ Patch for a new runtime feature (undersells the change)
  • ✅ Minor for new Cn_shell.execute entry point; patch for CI fix

2.3. Version bump — VERSION-first flow

  • VERSION file at repo root is the single source of truth
  • Edit VERSION to the new version string (bare, no v prefix)
  • Run scripts/stamp-versions.sh — derives all manifests (cn.json, package cn.package.json files) from VERSION
  • Run scripts/check-version-consistency.sh — validates all version-stamped files agree
  • Binary embeds version from VERSION at build time — no manual edit needed
  • Tests and katas read version dynamically — no manual edit needed
  • ❌ Edit cn.json or package manifests by hand (bypasses single source of truth)
  • ❌ Skip stamp-versions.sh ("I'll update the manifests manually")
  • ✅ echo "X.Y.Z" > VERSION && scripts/stamp-versions.sh && scripts/check-version-consistency.sh

2.4. CHANGELOG

  • Add a ledger row matching the format defined in CHANGELOG.md § Release Coherence Ledger. That format is canonical — do not reinvent the row shape here.
  • The ledger row includes: Version, C_Σ, α, β, γ, Level, Rounds, and a coherence note. The Rounds column records the review-round count for the release's cycle (e.g. 1, 2, 3); for releases bundling multiple cycles, sum or list (1+2). This is a learning-curve indicator — a rising trend signals process drift, a falling trend signals accumulated context.
  • Provisional vs. final scoring rule: β writes the CHANGELOG TSC row at release commit with provisional, pending γ PRA in the level cell (or in a parenthetical next to the level). γ updates the cell to the final value in the same commit as the PRA. This ensures one writer per fact while preserving the release-time ledger entry.
  • Add a detailed section below the ledger: Added / Changed / Fixed, with each commit's impact named and linked to issues.
  • ❌ "Various improvements" (no detail)
  • ❌ Ledger row without engineering level (Level column is required)
  • ✅ Each commit's impact named, linked to issues
  • ✅ Honest TSC grades — not everything is A+
  • RELEASE.md must restate the ledger row as the Outcome section in prose. The ledger row remains canonical; the release body explains it.
  • If release notes or CHANGELOG wording are being authored, load the write skill and record it in the CDD Trace.

2.5. Release notes — RELEASE.md

  • Write RELEASE.md at repo root before tagging. This is the GitHub release body.
  • A release is a measured coherence delta. The release body must foreground what got more coherent and why, then detail the changes.
  • The release CI workflow uses RELEASE.md as the release body if present; otherwise it auto-generates from commit titles (sparse and unstructured — not acceptable).
  • RELEASE.md is committed in the release commit and consumed by CI. It stays in the repo until the next release overwrites it.
  • ❌ Let CI auto-generate release notes (just commit titles, no detail)
  • ❌ Jump straight into Fixed/Added/Changed (change-loggy, not coherence-framed)
  • ❌ Manually create the GitHub release after CI (race condition with workflow)
  • ✅ Outcome first, then changes, then proof
  • ✅ Write RELEASE.md → commit in release commit → CI uses it as release body
# RELEASE.md format

## Outcome

Coherence delta: C_Σ {grade} (`α {grade}`, `β {grade}`, `γ {grade}`) · **Level:** `L{level}`

One short paragraph:
- what became more coherent
- what surface is now more truthful / portable / durable / explicit

## Why it matters

One short paragraph:
- what incoherence this cycle targeted
- why it mattered operationally or structurally
- what changed in the system's behavior or authority model

## Fixed

- **Short description** (#issue): what changed and why it matters.

## Added

- **Short description** (#issue): what was added and what new capability or clarity it provides.

## Changed

- **Short description** (#issue): what changed in behavior, authority, or shape.

## Removed

- **Short description** (#issue): what was removed and what incoherence it eliminated.

## Validation

- Deployed to [target], validated [specific check].
- State what was proven coherent by the validation, not only that deployment succeeded.

## Known Issues

- #N — description (if any found during validation)

2.5a. Move cycle directories to release directory (tagged release)

  • Move every per-cycle directory from .cdd/unreleased/{N}/ to .cdd/releases/{X.Y.Z}/{N}/:
    mkdir -p .cdd/releases/X.Y.Z
    for dir in .cdd/unreleased/*/; do
      [ -d "$dir" ] || continue
      mv "$dir" .cdd/releases/X.Y.Z/
    done
    
  • Each .cdd/releases/{X.Y.Z}/{N}/ directory carries the same role-prefixed files that lived in .cdd/unreleased/{N}/ during the cycle (self-coherence.md, beta-review.md, alpha-closeout.md, beta-closeout.md, gamma-closeout.md, plus any cycle-specific extras) per cnos.cds/skills/cds/CDS.md §"Coordination surfaces" + §"Artifact contract" → §"Location matrix".
  • Include the moves in the release commit
  • .cdd/unreleased/ should be empty after the release commit
  • ❌ Leave cycle directories in unreleased/ after tagging (lose the version association)
  • ❌ Move after the release commit (they should be part of the release snapshot)
  • ✅ Move before commit, include in the release commit

2.5b. Docs-only disconnect (no tag)

A cycle that ships only documentation, protocol artifacts, or assessments — with no code change and no version bump — still requires a disconnect, but the disconnect is the merge commit on main, not a tag.

Cases this covers:

  • Retroactive close-out for a previously-released version (no new code, only frozen artifacts and CHANGELOG row backfill — the cycle for usurobor/tsc#27 is the canonical example)
  • Self-coherence reports and post-release assessments produced as their own cycle, not bundled with a code release
  • Skill patches that ship only as protocol changes
  • Doc-cleanup cycles (e.g. retiring stale references after a paradigm shift)

For docs-only cycles:

  • .cdd/unreleased/{N}/ moves to .cdd/releases/docs/{ISO-date}/{N}/ where {ISO-date} is the merge commit's date in YYYY-MM-DD form (e.g. .cdd/releases/docs/2026-05-08/27/).
  • No CHANGELOG ledger row. The Release Coherence Ledger tracks tagged releases. γ records the cycle in docs/gamma/cdd/docs/{ISO-date}/POST-RELEASE-ASSESSMENT.md instead — same PRA structure as a tagged release, just keyed by date.
  • The merge commit hash IS the disconnect signal. No scripts/release.sh invocation. No version bump. VERSION is unchanged.
  • scripts/check-version-consistency.sh is not required to run (nothing version-stamped changed).
# Docs-only disconnect at merge time (run as part of γ closure):
ISO_DATE="$(date -u +%Y-%m-%d)"
mkdir -p ".cdd/releases/docs/${ISO_DATE}"
for dir in .cdd/unreleased/*/; do
  [ -d "$dir" ] || continue
  mv "$dir" ".cdd/releases/docs/${ISO_DATE}/"
done
  • ❌ Leave docs-only cycle directories in .cdd/unreleased/{N}/ after merge ("there's no release to move them to")
  • ❌ Force a synthetic version bump on a docs-only cycle just to fit the tagged-release flow
  • ❌ Skip the PRA because no tag was pushed
  • ✅ Move to .cdd/releases/docs/{ISO-date}/{N}/ in the merge commit
  • ✅ γ writes docs/gamma/cdd/docs/{ISO-date}/POST-RELEASE-ASSESSMENT.md

γ declares docs-only in the issue mode header (per issue/SKILL.md §Mode declaration); the disconnect path is selected at issue-creation time, not retrofitted at merge.

2.6. Commit and signal readiness for δ tag

  • Tag naming convention: use bare version numbers without v prefix: 3.15.1, not v3.15.1. This matches VERSION file content, branch naming (claude/3.15.0-22-...), and snapshot directory names (docs/gamma/cdd/3.15.0/). Consistency across all version surfaces.
  • Tag message generation: δ creates annotated tags (not lightweight tags) with structured messages that include issue metadata, wave context when present, and CDD review artifacts when available. The tag message is automatically generated by scripts/generate-release-tag-message.sh and includes issue titles, labels, review rounds, and deterministic fallback when metadata is unavailable.
  • Commit: git commit -m "release: X.Y.Z — summary" (includes VERSION, manifests, CHANGELOG, RELEASE.md)
  • Before any push that follows a rebase, run the eng/ship rebase-integrity gate (see eng/ship § Rebase-Collision Integrity)
  • Push: git push origin main
  • β signals "release ready for δ tag" in beta-closeout.md — β does not execute git tag or push tags; δ creates the single annotated tag X.Y.Z with generated message as part of the disconnect release flow (cnos.cds/skills/cds/CDS.md §"Development lifecycle" → §"Step table" Step 10 — δ release). RELEASE.md remains the GitHub release body authority; generated tag messages are additive.
  • ❌ β pushes tag directly (conflicts with δ tag authority)
  • ❌ Mix v prefix and bare versions across tags (v3.14.6 then 3.14.7)
  • ❌ Commit without RELEASE.md (CI auto-generates sparse notes)
  • ✅ Commit (with RELEASE.md), push, signal readiness in close-out; δ handles tagging

2.6a. Delete merged branches

  • After push, delete remote branches that were merged into this release
  • git branch -r --merged origin/main | grep -v main | grep -v HEAD | sed 's/origin\///' | xargs -I{} git push origin --delete {}
  • This is mechanical cleanup, not judgment — if it's merged, it's dead
  • ❌ Leave merged branches accumulating ("someone might need them")
  • ✅ Clean up immediately after release push; history is in main

2.7. Wait for release CI

  • Release workflow builds binaries (linux-x64, macos-x64, macos-arm64)
  • Wait for completion before deploying
  • δ owns release CI polling per release-effector/SKILL.md §3 — after tag push, δ monitors release workflow completion via gh run list --branch <tag>. β waits for δ confirmation.
  • ❌ Deploy while CI still running (stale binary from previous release)
  • ✅ gh run watch {id} --exit-status then verify assets attached

2.8. Deploy to target hosts

  • Stop daemon, download binary, replace, start daemon
  • cn deps restore to sync cognitive substrate
  • Validate: cn --version, test an op that exercises the fix
  • ❌ Replace binary while daemon running (Text file busy)
  • ✅ systemctl stop → cp → chmod → systemctl start → cn --version

2.9. Validate

  • Version matches everywhere: binary, cn.json, tag
  • The specific fix or feature works end-to-end
  • Check telemetry for errors on first cycle
  • Validation must confirm the targeted coherence delta, not only binary/version correctness.
  • ❌ "It deployed" (no functional validation)
  • ✅ Trace telemetry, confirm receipts/artifacts exist, agent responds correctly

2.10. CDD Trace update

  • Update the primary branch artifact's CDD Trace with the release row:
    • artifact: tag / CHANGELOG / release artifact
    • skills loaded: release, plus write if used
    • decision: released version X.Y.Z
  • If the triadic protocol is active, β also writes:
    • release evidence in .cdd/unreleased/{N}/beta-closeout.md
    • β close-out narrative in .cdd/unreleased/{N}/beta-closeout.md for γ to read (separate from beta-review.md, which carries the round-by-round verdicts; see cnos.cds/skills/cds/CDS.md §"Coordination surfaces" → §"Cycle-state evidence")
  • γ writes the post-release assessment after β's release and close-out are complete
  • For triadic cycles, the primary branch artifact is .cdd/unreleased/{N}/self-coherence.md — it carries the trace through step 7a; β records the review verdict in .cdd/unreleased/{N}/beta-review.md (steps 8–9) and the close-out + release evidence in .cdd/unreleased/{N}/beta-closeout.md (step 10).

3. Rules

3.1. All version strings must agree

  • VERSION, cn.json, package manifests, tag, binary output, CHANGELOG
  • scripts/check-version-consistency.sh validates this mechanically
  • ❌ Tag is 3.15.1 but VERSION says 3.15.2 (forgot to commit before tagging)
  • ✅ scripts/check-version-consistency.sh passes before commit

3.2. CI must pass before tag

  • If CI fails after tag, fix and force-push tag (amend release commit)
  • ❌ Ship with known test failure ("we'll fix it next patch")
  • ✅ Fix the test, amend, force-push tag, wait for green

3.3. Never deploy stale binaries

  • Release CI builds from the tag; wait for it to complete
  • Clear cached downloads (--clobber or rm old artifacts)
  • ❌ cn update downloads cached v3.5.1 binary from /tmp
  • ✅ Fresh download after CI completes, verify binary version after install

3.4. Deploy includes deps restore

  • Binary update alone leaves cognitive substrate stale
  • cn deps restore syncs doctrine, mindsets, skills from packages
  • ❌ Binary is v3.9.1 but skills are from v3.8.0 (package drift)
  • ✅ cn deps restore immediately after binary update

3.5. Validate with the specific fix

  • Don't just check version — exercise the feature or fix
  • ❌ "Version looks right, ship it"
  • ✅ For #46: send a message, check telemetry for receipts, confirm artifacts exist

3.6. If CI fails post-tag, amend don't re-tag

  • git commit --amend --no-edit && git tag -d X.Y.Z && git tag X.Y.Z && git push --force origin main X.Y.Z
  • Tags are bare (X.Y.Z, never vX.Y.Z) — see §2.6 and cnos.cds/skills/cds/CDS.md §"Artifact contract" → §"Location matrix"
  • Keeps a clean single tag, single release commit
  • ❌ git tag -d vX.Y.Z && git tag -a vX.Y.Z && git push --force --tags (mixes legacy v-prefix; force-pushes all tags)
  • ❌ 3.9.1, 3.9.1-fix, 3.9.1-fix2 (proliferating tags)
  • ✅ One bare tag, amended until CI green

3.7. RELEASE.md must exist before tag

  • The release commit must include RELEASE.md at repo root
  • If RELEASE.md is missing, the tag must not be pushed (CI will auto-generate sparse notes)
  • ❌ Tag without RELEASE.md ("I'll update the release body manually later")
  • ✅ Write RELEASE.md → include in release commit → tag → push

3.8. TSC scoring in CHANGELOG — honest-grading rubric

Rate α (pattern), β (relation), γ (process) for each release. Honest grades — not everything is A+. The rubric below makes the grading reproducible across releases and reviewers.

Per-axis rubric:

Grade Numeric Meaning
A 4.0 met all ACs, no protocol skips, zero binding findings of the wiring or honest-claim class
A- 3.7 met all ACs, ≤1 binding finding, all findings non-blocking
B+ 3.3 met all ACs, ≥2 binding findings or one round of RC
B 3.0 met core ACs; partial-protocol release (e.g. missing RELEASE.md at tag time) or 2+ rounds of RC
C+ 2.3 shipped but missing one of: ledger row, PRA, provenance attachment
C 2.0 partial-protocol release with multiple drift items
< C < 2 re-open and remediate; do not close

Closure-gate override (fires before geometric-mean computation). If any artifact required by gamma/SKILL.md §2.10 closure gate (per cnos.cds/skills/cds/CDS.md §"Artifact contract" → §"Ownership matrix") is absent from the cycle's .cdd/unreleased/{N}/ directory at merge time — specifically any of alpha-closeout.md, beta-closeout.md, or gamma-closeout.md for a triadic cycle — then C_Σ is forced to <C regardless of per-axis math. Cycle disposition is "open and remediate"; the geometric mean is not computed. This override is verified mechanically by scripts/validate-release-gate.sh --mode pre-merge (see AC1, issue #339). The math below applies only after the closure gate passes.

Letter normalization (<C and C−). The rubric table uses <C as the grade label. Prior CHANGELOG, PRA, and alpha-closeout artifacts for cycles #331, #333, and #334 used C− for the same disposition. These are the same grade: C− is the operator-visible projection of <C. Both mean "open and remediate; do not close." Authors may use either form; the CHANGELOG column uses <C for rubric fidelity and C− is accepted as equivalent in prose artifacts.

C_Σ is the geometric mean of the three numeric grades; report the closest letter grade (e.g. (3.7 · 3.3 · 4.0)^(1/3) ≈ 3.66 ⟹ A-).

Score the release, not the intent. A retroactive partial-protocol close-out earns C+ honestly (e.g. usurobor/tsc cycle 27: v0.4.0 retroactive close-out scored α B / β C+ / γ C / C_Σ C+ — the grade reflects what shipped, not the goodwill of fixing it later).

Configuration-floor clause. Cycles run under operator/SKILL.md §5.2 (single-session δ-as-γ via Agent tool) cap the γ axis at A− regardless of execution quality, because γ/δ separation is structurally absent. The A− γ floor applies from the cycle's merge forward; it is not retroactive. The configuration must be recorded explicitly in gamma-closeout.md (see AC6 of any cycle introducing or running under §5.2). Applying the A− cap is operator-honest discipline: if gamma-closeout.md does not declare §5.2, the rubric treats the cycle as §5.1 and the cap does not apply.

CI-red cap clause. Cycles with red CI on the merge commit cap the γ axis at C (one band below current floor). Cycles that proceed to close-out without verifying CI cap the γ axis at B−. CI is a mechanical gate; failing or skipping it reflects structural γ-axis failure in cycle coordination, not judgment calls.

False-gap peer-enumeration clause. Cycles that ship on a false-gap premise (where the §Gap assertion is contradicted by existing surfaces that basic peer-enumeration would have discovered) cap the γ axis at B regardless of whether β caught and corrected the false claim. A cycle requiring fix-rounds to reconcile γ's unverified gap framing reflects failure of the peer-enumeration discipline per gamma/SKILL.md §2.2a, not implementation or review failure.

  • ❌ Every release is A+ (grade inflation, no signal)
  • ❌ Score the intent rather than what shipped
  • ❌ Round up because "the team worked hard"
  • ❌ Rate a §5.2 cycle's γ axis above A− (grade inflation, structural absence of γ/δ separation unaccounted)
  • ✅ "β: A- — DUR skills synced but README.md still references old framing"
  • ✅ "γ: C — partial-protocol release; retroactive close-out planned"
  • ✅ "γ: A− — §5.2 cycle; γ/δ separation absent; A− γ floor applied per §3.8 configuration-floor clause"

4. Kata

Scenario: A bugfix is ready on main. Execute the release.

  1. Readiness check — CI green, no unmerged branches
  2. Version decision — patch, minor, or major
  3. VERSION bump + stamp-versions.sh + check-version-consistency.sh
  4. CHANGELOG ledger row with honest TSC grades
  5. RELEASE.md with Outcome mirroring the ledger row
  6. Commit, tag (bare version), push
  7. Wait for release CI, deploy, validate with the specific fix
  8. β close-out (γ writes PRA separately)

Verify: Does scripts/check-version-consistency.sh pass? Does RELEASE.md start with the coherence delta? Does validation confirm the targeted incoherence is closed?

04 同仓库更多 Skills

usurobor
usurobor/cnos

issues/triage

Issue triage doctrine pointer. Use when classifying a new issue, deciding dispatch eligibility, or deciding whether to close/supersede/defer.

★ 9
usurobor
usurobor/cnos

issues/taxonomy

Issue label taxonomy pointer. Use when classifying an issue's kind/area/priority/effort/status/protocol/dispatch labels, or when the board needs to interpret them.

★ 9
usurobor
usurobor/cnos

issues/map

Issue-board (Issue Pivot) generation domain. Use when reasoning about `cn issues map`'s fetch, taxonomy-parse, effort-computation, and render pipeline, or about the board's JSON/HTML output contract.

律师与法务前端开发
★ 9
usurobor
usurobor/cnos

issues

cnos.issues package entrypoint. Use when reasoning about issue taxonomy, the Issue Pivot / issue-board (`cn issues map`), the read-only CDS issue-state evaluator (`cn issues fsm evaluate`), or the current command-dispatch disposition of issue tooling.

★ 9
usurobor
usurobor/cnos

receipt-stream

Cross-cycle receipt-stream doctrine for protocol-iteration. Use when γ closes a cycle and writes the per-cycle iteration artifact (`cdd-iteration.md`), when γ updates the cross-cycle aggregator at `.cdd/iterations/INDEX.md`, when ε reads the receipt stream across cycles to surface protocol-gap patterns, when a finding's disposition lands a cross-repo patch and the cross-repo trace bundle attaches, or when a courtesy empty-findings stub is written for a `protocol_gap_count == 0` cycle.

★ 9
usurobor
usurobor/cnos

mid-flight

Mid-flight γ→in-flight-α rescue channel. Use when γ needs to change a load-bearing fact (pinned axis, scope, AC, blocker) after α has begun coding, when γ edits the cycle's GitHub issue body mid-cycle, or when a spec change lands on origin/main while α/β polling sessions are in-flight.

★ 9