Skip to content

release: t27o standalone binary, cosign keyless signing, and the reusable golden-spec Action (Refs #8996) - #9147

Merged
gHashTag merged 2 commits into
masterfrom
release/8996-signed-binary
Oct 11, 2026
Merged

gHashTag merged 2 commits into
masterfrom
release/8996-signed-binary

Conversation

@gHashTag

Copy link
Copy Markdown
Owner

Part of epic #8998. A foreign repository consumes t27o entirely inside its own GitHub Actions: we run no untrusted code, spend no LLM tokens, run no servers, hold no secrets.

What ships

.github/workflows/t27o-release.yml -- on tag t27o-v*: build tri + t27c, write checksums with bare filenames, sign every artifact cosign keyless (sign-blob --bundle, GitHub OIDC id-token, no owner secret), attest build provenance, upload all assets to the GitHub Release. It signs in-workflow on purpose: a release created with GITHUB_TOKEN never fires on: release workflows (GitHub anti-recursion), so the repo-wide sign-release.yml cannot cover this path.

.github/workflows/t27o-golden.yml -- reusable (workflow_call) workflow the foreign repo calls:

jobs:
  t27o:
    uses: gHashTag/t27/.github/workflows/t27o-golden.yml@master
    permissions: {contents: write, pull-requests: write}

It downloads tri, t27c, checksums from the release; verifies each blob's sigstore bundle against the exact certificate identity https://github.com/gHashTag/t27/.github/workflows/t27o-release.yml@refs/tags/<version>; then runs tri t27o <file> --check --t27c ./t27c over the caller's Rust files (default pathspec *.rs; rustc + zig 0.16.0 installed on the caller's runner). Modes: golden (default) opens a PR containing only specs/t27o_check/ -- each spec carries the coverage line and every refusal inline, never summarized away; scan reports in place; check fails on drift between committed specs and regeneration.

specs/tools/t27o/service.t27 -- the LOGIC the plumbing carries: modes, defaults, tag family, OIDC issuer + certificate identity, report shape, and the honest limit (equivalent on the recorded oracle vectors and translated tests, not a proof for all inputs). What counts as golden stays #8997's lane; this spec points at it. 4/4 green on the lab.

specs/port/scripts/gen_w374.t27 -- scripts/gen_w374.py ported to the blessed gen_w392 shape, one step further: invariant-line end, last-block selection and the splice are real, and the chain run proves the port reproduces the Python script's exact result. The w375/w376 replacement tables are documented in its header. 8/8 green on the lab. scripts/gen_w374.py, gen_w375.py, gen_w376.py deleted.

Validation (no secrets spent)

  • Both specs pass t27c test-report on the Railway lab: 4/4 and 8/8, exit 0.
  • tri t27o --check end-to-end on the lab, both directions: a converting sample (3/3 oracle vectors, coverage 100%, exit 0) and a refusing sample (async + generics: spec still written with // t27o: refused ... inline, exit 0 -- refusals surface in the PR, they do not fail the job).
  • Both workflow YAMLs parsed and structurally checked (jobs, inputs, defaults, permissions, PR body). actionlint is not available on the lab; schema review only.
  • Foreign budget: the foreign-budget hook passes locally -- +65 yml (40 + 25, each under the 40/file cap, total under 80), -123 py, net -58.

Untested until the first real release run

cosign keyless signing against live OIDC, release asset upload, the download-verify chain from a foreign runner, and create-pull-request in a caller's repository. The first needs the owner to push tag t27o-v0.1.0 (checklist on the issue).

Known red: own-language

The own-language gate (pre-commit, pre-push, CI) denies the two new .yml paths -- exactly the state of open PR #9117: red on CI until the owner lists them in tools/policy/foreign-exceptions.txt (owner-only file, checklist on #8996). Nothing is silenced: the same gate runs on this PR.

Refs #8996

🤖 Generated with Claude Code

…spec Action

Ship the t27o-as-a-service surface (#8996, epic #8998): a foreign repo
consumes t27o entirely inside its own GitHub Actions, with zero LLM
tokens and zero secrets of ours.

- t27o-release.yml: on tag t27o-v*, build tri + t27c, checksum, sign
  every artifact cosign keyless (OIDC id-token, no owner secret),
  attest build provenance, upload to the GitHub Release. Signs
  in-workflow because a GITHUB_TOKEN release never fires on:release
  workflows (GitHub anti-recursion), so sign-release.yml cannot cover it.
- t27o-golden.yml: reusable workflow_call. Downloads the signed
  artifacts, verifies each blob's sigstore bundle against the exact
  workflow+tag identity, runs tri t27o --check over the caller's Rust.
  golden opens a PR with specs/t27o_check (refusals inline in each
  spec); scan reports in place; check fails on drift.
- specs/tools/t27o/service.t27: the logic the plumbing carries (modes,
  defaults, tag family, OIDC issuer + identity, report shape, honest
  limit); golden criteria remain #8997's lane. 4/4 tests green (lab).
- specs/port/scripts/gen_w374.t27: scripts/gen_w374.py ported to the
  gen_w392 shape with the invariant-end, last-block and splice made
  real; chain test proves the Python result. w375/w376 tables kept in
  its header. 8/8 tests green (lab). gen_w37[456].py deleted.

Foreign lines: +65 yml, -123 py, net -58 (foreign-budget hook: pass).
str .len counts the $ sentinel (lab probe). own-language hook denies
the two new .yml paths -- same state as open PR #9117: red on CI until
the owner lists them in tools/policy/foreign-exceptions.txt (checklist
on the issue). Untested until first release run: live cosign keyless,
upload, download-verify chain, caller-side PR creation.

Refs #8996

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

PR Dashboard

Generated at: 2026-10-11 17:51:35 UTC

Summary

Status Count
Total Open PRs 50
PRs with Failing Checks 50
PRs with All Checks Green 0
READY 0
FAILING 50
PENDING 0
NO CHECKS YET 0

Seal Status

  • ⚠️ STALE -- sha256(compiler.rs)=6fc1fc5cb363 != manifest seal=87e5cbd3ad94.
    The committed NMSE numbers were certified against an older compiler.rs.
    Run scripts/reseal-check.sh locally for the two-step reseal command (advisory; not a merge gate).

This was referenced Oct 11, 2026
This was referenced Oct 11, 2026
@github-actions

Copy link
Copy Markdown
Contributor

PR Dashboard

Generated at: 2026-10-11 19:51:03 UTC

Summary

Status Count
Total Open PRs 50
PRs with Failing Checks 48
PRs with All Checks Green 2
READY 0
FAILING 48
PENDING 0
NO CHECKS YET 0

These columns do not partition: 0 + 48 + 0 + 0 = 48, and there are 50 open PRs. A PR is being counted twice or not at all.

Seal Status

  • ⚠️ STALE -- sha256(compiler.rs)=6fc1fc5cb363 != manifest seal=87e5cbd3ad94.
    The committed NMSE numbers were certified against an older compiler.rs.
    Run scripts/reseal-check.sh locally for the two-step reseal command (advisory; not a merge gate).

@gHashTag
gHashTag merged commit b54ad9a into master Oct 11, 2026
24 of 30 checks passed
gHashTag added a commit that referenced this pull request Oct 11, 2026
…(Refs #8996) (#9173)

#9147 added t27o-release.yml (tag-push release) and t27o-golden.yml
(reusable golden-spec job); neither name was in either list, so the
unclassified count rose 24 -> 25 past its ceiling and gate-topology
went red on master. Both are recorded NOT_MERGE_CRITICAL with their
reasons: a tag is not a merge, and a reusable job's caller carries the
check. Local run: CLEAN, exit 0. Net foreign lines zero -- the two new
dict lines are paid for by dropping the founding-incident sentence
that duplicated the module docstring.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
gHashTag added a commit that referenced this pull request Oct 12, 2026
…+ recipes AF4 round 2 (attest-input-rename) (#9297)

Matrix-regen fired for the first time on real drift: gates.t27 was 3 rows off
master (.github/workflows gained t27o-golden and t27o-release from #9147, and
#9117 deleted brain-seal-refresh). Regen per docs/claw/README.md: census
61 blocking + 3 soft + 2 reporting, pins re-indexed (oracle-nightly 30->29,
queen-publish 42->41, new rows pinned at 57/58 with their events).

recipes.t27 AF4 round 2 (#9285): +1 verified row -- t27o-release /
attest-input-rename (#9164: attest-build-provenance v4 renamed the input
path -> subject-path; one-word workflow edit, then delete and re-push the tag).
Table 21 -> 22 rows, census C_AUTO 16 / C_REVIEW 3 / C_OWNER 3. The fallback
row's COND now carries the compare-vs-master discipline every night tick ran
(a red on a PR describes the branch; its cause may be master; a stale failed
run describes an old SHA).

Two bound defects fixed in the same commit:
- recipes all_kinds_unique kept 19-row while bounds through the 21-row table
  (rows 19-20 were never compared); it takes the row count as a parameter now,
  tied to COUNT by the test.
- gates all_names_unique inner bound stayed 65 when the outer grew to 66: the
  computed range (i+1)..65 at i=65 inverts (66..65) and the lowering does not
  clamp it to empty -- the walk went wrong and no_duplicate_names_pairwise
  failed. Both bounds are 66 now, with a comment naming the trap; the unclamped
  inverted range is recorded for the compiler lane.

Lab (fresh t27c from master tip): typecheck OK both files; gates 10/10 tests,
recipes 11/11, 0 FAIL, 0 vacuous. ASCII clean, no new duplicate groups.

Refs #9285, #9281. Part of #9271.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
gHashTag added a commit that referenced this pull request Oct 12, 2026
…o 140 (Refs #9271)

The own-language shrink rule (owner rule 2026-10-09) holds the claw-drift
workflow step to net-negative foreign lines; #9147 set the pattern: port the
python to a spec, delete the python in the same diff. #7053 ported
scripts/gen_w388.py (66 lines) into specs/port/scripts/gen_w388.t27 but the
python deletion never happened. This diff retires it: the decisions are fully
ported, the file globbing and I/O stay with the caller per the port rule
(gen_w374.t27 documents the same split).

Documented Commands: dead `tri` mentions fell 141 -> 140 because the v3 rework
dropped the dead `tri claw` mentions from docs/claw -- lower the ceiling in
the same commit, as the gate's own message directs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
gHashTag added a commit that referenced this pull request Oct 12, 2026
… (#9277)

* claw: the drift audit law is claw_status in gates.t27, lowered by gen-c -- no hand-written reader (Refs #9271)

Owner rule 2026-10-13: no hand-written python; the v2 reader (claw.py,
claw.yml, app-manifest.yml, APP-SETUP.md) is gone. What replaces it:

- specs/claw/gates.t27: 66-gate inventory + claw_status(dir_text, dir_len,
  out, out_cap) -> i32 in the explicit-length idiom (gen-c lowers str to
  const char* and carries no .len); 15 tests, 0 vacuous.
- specs/claw/gates_pins.t27: .len pins over the hand-counted tables plus
  the call-site .len pin that catches truncated unknown-name literals (a
  truncated name is still unknown, so the in-module assert cannot);
  zig-only companion, never passed to gen-c.
- gen/c/claw/gates.c: t27c gen-c output, force-added per gen/c/policy/*.
- .github/workflows/gate-topology.yml: the claw-drift step compiles the
  four-line harness around gates.c and feeds it `ls .github/workflows`;
  exit 0 is clean, 1+ is DRIFT. Negatives proven: planted extra workflow
  -> DIR-ONLY + RC=1; dropped row -> SPEC-ONLY + RC=1.
- scripts/tri_loop/gate_sweep.py: front door only; its docstring points
  at tools/check_gate_preconditions.py (one home, not two copies).
- README/RELEASE/service/engine carry the v3 shape; the App manifest is
  v0.2 and ships nothing it cannot back.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* claw: complete port #7053 -- delete gen_w388.py; lower MAX_DEAD_TRI to 140 (Refs #9271)

The own-language shrink rule (owner rule 2026-10-09) holds the claw-drift
workflow step to net-negative foreign lines; #9147 set the pattern: port the
python to a spec, delete the python in the same diff. #7053 ported
scripts/gen_w388.py (66 lines) into specs/port/scripts/gen_w388.t27 but the
python deletion never happened. This diff retires it: the decisions are fully
ported, the file globbing and I/O stay with the caller per the port rule
(gen_w374.t27 documents the same split).

Documented Commands: dead `tri` mentions fell 141 -> 140 because the v3 rework
dropped the dead `tri claw` mentions from docs/claw -- lower the ceiling in
the same commit, as the gate's own message directs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
gHashTag added a commit that referenced this pull request Oct 12, 2026
…rt (Refs #9271) (#9302)

The claw-drift step feeds the COMMITTED gen/c/claw/gates.c, so an edit to
specs/claw/gates.t27 without a regen would drift silently -- the committed C
would keep answering for a spec it no longer lowers. spec-guards already has
the compiler every check is measured against; regen + `git diff --exit-code`
there, the same shape as t27o-golden's check mode (#8996). Verified fresh on
the lab before this diff: regenerating master's spec reproduces b95634df
byte for byte.

Offset for the +12 workflow lines, per the shrink rule (#8236) and #9147's
pattern: complete another port that landed unfinished. gen_w392.t27 is the
blessed port shape (gen_w374.t27 names it so) and scripts/gen_w392.py
(54 lines, a spent one-shot wave generator referenced by nothing at runtime)
outlived it. The Python files are deleted; the spec is the rule.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
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.

1 participant