Repository navigation
Conversation
…acuous spec makes the receipt red Refs #11873 Refs Trinity-S-AI-DNA/t27os#9 Replaces #11863, whose single commit carried only a cross-repo reference and so failed the L1 commit gate. The tree is byte-identical (labs.t27 blob 2f4f64c): t27c lab receipt runs/598483d81bcf2be22e1df320101182a661fe67b0.3fd57f76.json 9/9, 0 vacuous, 0 blocked; t27b pass per the native ratchet run 40001985581 on 598483d. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Night tick 13: lab dispatched on c43e36c (run 40003679651, specs/t27os/labs.t27, m6=false wasm=false). Receipt lands at Trinity-S-AI-DNA/t27os runs/c43e36c35104ee9e267c762924f85f21d5349d35.*.json. |
|
Lab receipt for c43e36c (run 40003679651, success): Trinity-S-AI-DNA/t27os runs/c43e36c35104ee9e267c762924f85f21d5349d35.51672ac5.json |
|
Night tick 27, t27b leg for head c43e36c (
The check is red for ledger staleness only: 0 UNEXPECTED FAILURE, 23 UNEXPECTED PASS, 54 UNLISTED. Master f308c93 is red the same way (run 40001627259), so this red comes from master, not from this PR. Both compiler legs are now on record (t27c from the T27 OS lab receipt, t27b here). Refs #11889. |
…acuous spec makes the receipt red (Refs #11873) (#12087) * spec(t27os): labs receipt_verdict -- an omitted, BLOCKED, failed or vacuous spec makes the receipt red (Refs #11873) Rebuilt on master e518fc3 from #11875 (DIRTY: master rewrote labs.t27 around the gate-command tests). Same fn and test, placed after run_verdict. Refs t27os#9. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * seal(t27os): labs.t27 seal from lab receipt 4bde0df.e4ffcc1e (Refs #11873) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…loses #11954) (#12101) Rebuilt on master as one commit: the stacked #11955 went DIRTY after its base #11875 was superseded by #12087 (receipt_verdict now on master). Same file, same tests; uses labs.t27 :: receipt_verdict, restates no rule. Refs Trinity-S-AI-DNA/t27os#18 Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* ci(dupes): drop digit_byte, lt_s, sar32 from the ledger -- this PR removes the copies (Refs #11885)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* spec(queen): the night loop's lane sweep -- claim-aware release on the reaper's proofs, and a tick commits only on its own branch (#11874)
Refs #11873
Refs Trinity-S-AI-DNA/t27os#8
Replaces #11866, whose single commit carried only a cross-repo
reference and so failed the L1 commit gate. The tree is byte-identical
(worktree_keep.t27 blob b9b97669): t27c lab receipt
runs/1aa955447fd7713f0a3be42c083275dd4a49a120.1e9401ff.json 16/16,
0 vacuous; t27b pass per the native ratchet on 1aa955447 (ledger pass,
0 unexpected failures).
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* ci(seals): ledger two seals master left stale -- worktree_keep, t27b wasm (Refs #11840) (#11929)
Master 5e30b412b is red on Spec Guards: check_seal_currency reports two
STALE generated-code hashes, both because the spec moved and no reseal
landed with it:
- queen_QueenWorktreeKeep.json -- specs/queen/worktree_keep.t27, moved by #11874
- t27b_T27bWasm.json -- specs/tri/t27b/wasm.t27, moved by 94adbb1b2
One master red turns every open PR red on spec-guards and coverage. The
real repair is a reseal from a master-built t27c. That cannot run here:
the Mac may not run t27c seal, Railway is signed out, and the lab's reseal
leg (#11903) is waiting for the lab.yml workflow scope. So the two seals
go into tools/seal_baseline.txt as kind `stale`, which is the ledger's
own word for "spec changed since sealing". split() counts them as known
only while their spec_hash still disagrees, so this exempts nothing
except these two moves. The reseal drops both lines in its own commit.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* fix(gen-zig): render parameterised const structs as Zig generic fns (Refs #11912 #11840)
DEFECT (#11912, class 1 of the wasm32 audit, epic #11840): a
parameterised const struct -- `pub const Box(T) = struct { value : T,
};` -- emitted as a PLAIN Zig struct with the parameter an undeclared
identifier:
pub const Box = struct {
value: T,
};
The module refused to compile on ANY target (native and
wasm32-freestanding alike): "use of undeclared identifier 'T'". The
parser was innocent: node.params carries the parameter (ADR-008,
verified params: [("T","")]); the emitter dropped it.
FIX: in gen_struct_decl, when node.params is non-empty, render Zig's
generic-function idiom:
pub fn Box(comptime T: type) type {
return struct {
value: T,
};
}
Multi-parameter declarations compose (Result(T,E) ->
`fn Result(comptime T: type, comptime E: type) type`, State(S,T)
likewise), keyword field names keep their escaping (@"error"), and
the plain (no-params) path keeps its exact previous render. The call
sites (`Box(u8)`) already render as calls, so they compose unchanged.
PAIRED DELETION (foreign-budget shrink rule, owner rule 2026-10-09:
glue may not grow the hand-written foreign surface): remove the dead
`from_i8`/`to_i8` impls on AsmSectionKind and AsmRelocKind plus the
two round-trip tests that exercised nothing else (39 + 36 = 76 lines;
both items are named "never used" by the compiler's own dead-code
lint and have zero callers in the repo). Test count moves 1799 ->
1797 accordingly. Net: -38 hand-written foreign lines.
M5: FROZEN_HASH re-stamped
(182a47746c3338d8df04408fd024c34dbfa8015a2d9b7e09c70e434dca1ff472).
Seals: gen_hash_zig re-stamped for all 13 corpus specs carrying a
parameterised struct decl (15 declarations; Tree, IO, Reader, Zipper,
Writer, Option, Queue, Either, Result, BTree, BTreeNode, Ring, Maybe,
State, HashSet). Codegen output of non-generic specs is unchanged.
VERIFIED:
- repro (issue #11912): zig build-obj native OK,
wasm32-freestanding OK (before: "use of undeclared identifier
'T'" on both).
- corpus users: the struct's own error is GONE on all 13 (maybe.t27
failure site moved spec.zig:22:12 struct field -> spec.zig:26:30
fn-type-alias layer). The modules remain BLOCKED pending the NEXT
generic layer (fn-level comptime params + the `= fn(T) Maybe(T)`
fn-type-alias layer) -- a follow-up slice, to be filed.
- cargo test -p t27c --bin t27c: 1797 passed, 0 failed, 2 ignored.
- foreign-budget and own-language gates: exit 0.
Label note: owner-approved-foreign (owner 2026-10-23, session
instruction repeated five times: do all three autonomously; the
emitter glue is the labeled slice per the port-train pattern -- the
decision spec lands as the follow-up).
* fix(gates): master reds repair pass 8 (Refs #11038) (#11928)
* fix(gates): master reds repair pass 8 (Refs #11038)
Three reds on master after the port-train wave that the nine-step
repair cycle alone could not clear:
1. gate-topology.yml failed to parse on every push (zero-job failed
run, workflow shown under its file path). The claw-criteria-post
note step is a flow mapping whose run: value is a plain scalar
holding a comma; in flow context the scalar ends at the comma and
the rest of the sentence becomes a bogus step key, so GitHub
rejects the whole file. #10572 fixed the jq line for this same
defect class and missed this line. The run value is now
single-quoted; the shell it names is byte-identical. actionlint
is clean, tri census pin --gate PASS.
2. Duplicate Body Ratchet: the port wave added byte-identical copies
of digit_byte (claw/text + t27f/a11y_mirror), lt_s and sar32
(fpga/wasm_interp + fpga/wasm_opcodes) and sort_asc_u32
(t27f/live_mode sort_u32 + t27f/measure_live sort_asc_u32).
Deliberate port copies -- each port target keeps its own
definitions -- so the ledger moves in the same commit:
dupe_scan --bless adds exactly those four lines, gate exit 0.
3. OpenSSF Scorecard: the gcr.io/openssf/scorecard-action:v2.4.0
image pull is denied upstream (billing on OpenSSF's own Google
project), an infrastructure outage in the action itself. v2.4.1
publishes to ghcr.io; the pin moves v2.4.0 -> v2.4.1, nothing
else in the workflow changes.
The nine-step repair cycle ran green before and after this commit:
verilog widths, types ratchet, types classified, seals drift,
seal coverage, seal currency, assertionless tests, documented
commands, specs generate -- all exit 0.
* fix(gates): master reds repair pass 8 (Refs #11038)
Re-seal the two specs master's mid-flight merges left stale:
specs/tri/t27b/wasm.t27 (#11927, wasm32 floor 3, +263 lines) and
specs/queen/worktree_keep.t27 (#11874, night-loop lane sweep).
t27c seal --save + tri seals sync-twins on both; seal coverage and
seal currency exit 0, all other cycle gates re-run green.
* ci(seals): re-stamp the two tuple seals master left stale (Refs #11912 #11840)
#11930 rendered parameterised const structs as Zig generic fns but
missed tuple.t27 in its seal re-stamp sweep: the audit grep used
[A-Za-z_]+ for the declaration name, and `Tuple2`/`Tuple3` carry a
digit, so `pub const Tuple2(A, B) = struct {` never matched. Master
inherited two stale seals (TriTuple.json, collections_TriTuple.json;
gen_hash_zig f49f77e5 -> a87c06f1).
Re-stamped with `t27c seal --save specs/tri/collections/tuple.t27`.
check_seal_currency: STALE generated-code hash 2 -> 0, exit 0.
Tuple2/Tuple3 now emit `pub fn Tuple2(comptime A: type, comptime
B: type) type { return struct { first: A, second: B, }; }` (verified:
fields carry A/B inside the generic fn); the module's own remaining
BLOCK is the fn-level generic layer (`fn pair(a: A, b: B)`), the
slice #11930 filed as follow-up -- not this seal repair.
* spec(t27os): night take rule -- stale in-progress retake, leg-only remainders, credential-blocked to requests (Refs #11892) (#11893)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* spec(t27os): lab_legs -- a receipt line is green only with both compilers (Refs #11889) (#11890)
* spec(t27os): lab_legs -- a receipt line is green only with both compilers (Refs #11889, Refs #11873)
leg_state reads one compiler's counts (absent, blocked, fail, vacuous, pass);
line_verdict needs t27c and t27b PASS, excusing only a t27c BLOCKED on an
@extern spec whose t27b leg passes; may_leave_draft gates a night PR on every
touched spec green. Executor commands named as data for the lab.yml generator.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* spec(t27os): lab_legs -- the t27b leg as an arm64 lab.yml job, text and gate (Refs #11889, Refs #11873)
t27b's JIT runs only on aarch64; the lab job runs on x86_64 ubuntu-latest. The leg is a
second job (needs: run, ubuntu-24.04-arm, the run job's resolved sha, t27b test --check)
writing runs/<sha>.t27b.txt in the receipt's key=value shape. T27B_JOB_YAML and
RUN_OUTPUTS_YAML are the text TRI CLAW copies into lab.yml; t27b_job_ok / run_outputs_ok
gate it, with negative controls for an x86 runner, a missing --check and a missing sha.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* fix(gen-zig): a t27 fn type renders as Zig's fn (A) R, arrow removed (Refs #11940 #11840)
DEFECT: a t27 fn TYPE carrying the t27 arrow -- state.t27's
run : "fn(S) -> (S, T)" -- reached the Zig output verbatim, and Zig's fn
type has no arrow: error: expected return type expression, found '->'
stopped the whole module at the first fn-typed field.
FIX: t27_fn_type_to_zig in the gen-zig type mapper: fn (S) struct { S, T }
(a multi-value return is the anonymous struct t27_tuple_type_to_zig
already builds), fn (A) void for an absent/void return, named parameters
keep only their type. The const-alias arm unifies with W729's builtin
alias arm. Budget payment (owner rule 2026-10-07 #7371): six dead fns
deleted -- retime_forward, retime_backward, emit_interface, byte_offset,
lint_count, heap_start -- each flagged never-used by rustc and referenced
nowhere else (bootstrap tests, cli/t27b, gen/ all zero refs).
VERIFY: ArrowRepro.t27 (pub const Step = fn(S) -> (S)) emits
pub const Step = fn ( S ) ( S ); and zig build-obj is silent natively and
under -target wasm32-freestanding; state.t27 and reader.t27 fields render
run: fn (S) struct { S, T } / fn (R) T; 26 specs' gen_hash_zig changed,
all 52 seal files re-stamped, seal state equals master's pre-existing
staleness (20, all non-zig drift), no spec went from compiling to failing;
cargo test -p t27c --bin t27c: 1797 passed, 0 failed.
* spec(t27os): disclosure -- no number leaves without its five fields (Refs #11944) (#11945)
Board twin: Trinity-S-AI-DNA/t27os#20. reader, judge, n, cost, repro on every
number T27 OS publishes about itself; an empty or placeholder field, n = 0, or
a CI from one run refuses the number; the checker says all-covered only when
number and footer counts match and are not zero. The 048f7f45 receipt is the
worked example: refused until its cost is recorded.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* spec(t27os): lab inputs reach the shell through env, never by expansion (Closes #11950) (#11951)
lab.yml expands inputs.sha and inputs.specs into run text before bash
parses it; lab_legs.t27 T27B_JOB_YAML carries the same pattern. The new
law refuses any run body holding an input expansion, ships the corrected
sha and test-report steps as ENV + RUN text, and keeps the live steps and
T27B_JOB_YAML as negative controls.
Refs Trinity-S-AI-DNA/t27os#3
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* spec(t27os): the t27b job reads the spec list through env, never by expansion (Closes #11952) (#11953)
lab_legs.t27 :: T27B_JOB_YAML looped `for spec in ${{ inputs.specs }}`,
the expansion #11950 removed from the t27c steps. The t27b step now sets
env SPECS, turns globbing off and loops over $SPECS. lab_inputs.t27 owns
the job-level check (job_inputs_ok), with the pre-fix loop, an assignment
expansion and a globbing-on job as negative controls.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* spec(t27os): receipt_name -- a lab receipt is named only from a full resolved sha (Refs #11840) (#11870)
* spec(t27os): receipt_name -- a lab receipt is named only from a full resolved sha (Refs #11840)
t27os#11: a scheduled lab run has no input sha and would write runs/.<c8>.json.
t27os#10 (third way): a full sha went through an API lookup that answered null.
The law: a full input skips the lookup, a non-full answer refuses the run, and
the name is runs/<40 hex>.<c8>.json or nothing.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* spec(t27os): receipt_name keys the name on the challenge DIGEST, as lab.yml does (Refs #11840)
Measured on runs/305d83ad...ff17d40b.json: c8 is sha256(challenge)[0..8];
the raw challenge is never published.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* spec(t27os): a scheduled lab run tests the core set, never nothing (Refs #11840)
The lab schedule fires (t27os runs 40005713854, 40015647905) but carries
no inputs: the spec loop read "for spec in ;", wrote no summary and died
at cat, so no receipt. receipt_name.t27 now says an empty specs input
means the default core set, and a run whose list is still empty is refused.
Board Trinity-S-AI-DNA/t27os#3, task t27os#11.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* spec(crons): night loop UI health reads publish.txt, not a closed page's Z row (Refs #11887) (#11888)
* spec(crons): night loop UI health reads publish.txt; a stale Z with the HIVE page closed is not a finding (Refs #11887)
The hive feed job runs only while the HIVE page is open (page_feed_due);
the always-on heartbeat is publish.txt. ui_health gives one verdict per
tick and ui_is_finding says which ones go to t27os#3.
Refs #11887
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* spec(crons): night loop SWEEP-STEP -- every 6th tick, own merged lanes only (Refs #11873)
The lane-hygiene protocol of Trinity-S-AI-DNA/t27os#8 becomes a tick step: sweep_due
(every 6th tick), sweep_remove (own night- lanes only, at most 8 removals per tick). The
per-worktree verdict is not restated; it is worktree_keep.t27 lane_sweep_verdict (#11874).
Refs #11887
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* spec(crons): night loop LAND-STEP -- a local Refs #N, cross-repo-only refused (Refs #11873)
l1_local_ref mirrors the L1 gate regex (Closes|Fixes|Resolves|Refs|Updates)\s*#[0-9]+;
a Trinity-S-AI-DNA/t27os#N reference alone is refused, as on #11863/#11866/#11870.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* spec(crons): the night loop's TASK-PICK step points at night_take.t27 may_retake (Refs #11956) (#11957)
The card named AUDIT, PR-GATE, UI-HEALTH, SWEEP and RETROSPECTIVE steps and no
pick step, so the retake rule of #11892 was law no card pointed at. The new
section names may_retake and pick as the law without restating a value, and
pick_may_run orders the pick after the PR gate and every red repair.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* spec(crons): the night tick's receipt comment carries the disclosure footer (Refs #11958) (#11959)
RECEIPT-COMMENT-STEP: a receipt comment is posted only when
specs/t27os/disclosure.t27 footer_verdict judges its five-field footer
DISC_OK (reader, judge, n as a count, cost from dispatched_at to the
receipt utc, repro). First publishing path wired for
Trinity-S-AI-DNA/t27os#20.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* spec(t27os): disclosure_scan -- count published numbers and footed numbers in one document (Refs #11960) (#11961)
Criterion 3 of Trinity-S-AI-DNA/t27os#20: the pure core of the checker over
runs/*.summary.txt and the README. The verdict is disclosure::coverage_verdict;
negative controls for a bare summary, a placeholder, a dropped field line, a
footer above its numbers and a half-covered document.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* spec(t27os): the README published-numbers section checked by disclosure_scan (Refs #11960) (#11962)
Criterion 2 of t27os#20 (the README worked example, t27os#21) is now a
fixture, byte-identical to the PR head, and doc_verdict says COV_ALL on it;
negative control: the same rows with the n: line dropped are a gap.
Refs #11960
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* spec(t27b): wasm.t27 floor 4 -- the constant-leaf emitter's law, ported from the working wasm32 emitter (epic #11840 M-A, port #6198, ref PR #11942) (#11964)
- FIX: f32/f64 value-type bytes were the const opcodes (0x43/0x44); the
binary format's value types are 0x7D/0x7C. The working reference emitter
(cli/t27b/src/wasm32_emitter.rs, PR #11942), whose modules Node's
WebAssembly instantiates 100/100 in the equality gate, is the evidence.
- NEW law: OP_I64_CONST/OP_F32_CONST/OP_F64_CONST, i64_const, f32_const,
f64_const (LE IEEE-754 bit patterns), section_header, export_entry,
SEC_EXPORT.
- Tests ported from the reference: the exact 43-byte the_answer module,
the sleb edge vectors, the f32/f64 LE bit patterns, a two-export
i64+f64 module composition. 22/22 t27c test-report, 0 vacuous.
- gen/rust/tri/t27b/wasm.rs is t27c gen-rust of the spec (L2, force-added
like its tracked siblings); nothing hand-written is added or modified
(Only t27).
Refs #6198 (port epic), advances #11840 (M-A); companion to reference PR #11942.
* chore(seals): shrink the stale-hold ledger -- queen_QueenWorktreeKeep and t27b_T27bWasm now hold their generated code (Refs #11038) (#11963)
* spec(tri/t27b): wasm.t27 floor 5 -- the arithmetic floor the live-closure scalar trio lowers to (i32 sub/mul/div_u, eqz, select), param-functype and stack-program composition pinned; crons: the T27F closure lab watch, the hourly full-closure lab dispatch (epic #11840 M-B; Refs #6198, #11781, #10262) (#11976)
* chore(seals): re-ledger t27b_T27bWasm -- #11964 changed wasm.t27 after #11963 dropped its stale line (Refs #11840) (#11977)
Merge race on master 63040712e: #11963 removed the t27b_T27bWasm stale-hold
line because the 00:57Z seal held; #11964 (floor 4) then changed
specs/tri/t27b/wasm.t27 without a reseal. Every open PR now fails coverage
and spec-guards with "1 seal(s) newly do not hold: t27b_T27bWasm.json [stale]".
Restores the ledger line, kind stale, naming #11964, until a master-built
t27c re-saves the seal in the #11903 batch. No spec changed.
Refs #11840
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* fix(gen-zig): nested and optional fn types render arrow-free (Refs #11940 #11840)
DEFECT: two fn-type shapes still leaked the t27 arrow into gen-zig after
15e4ba4d (sub-slice 3 v1), both measured: a NESTED fn-type argument --
fn(u8, ?fn(u8) -> void) -> ?i32 emitted 'fn (u8, ?fn([]constu8) void)->?i32'
because the mapper split at the FIRST ')' which closes the INNER fn's list,
mangling the outer return onto it (image-loader.t27's shape); and a
'?'-prefixed fn type -- '?fn(A) -> R' starts with '?', not 'fn', so it fell
past the whole fn arm with its arrow intact.
FIX: the argument list ends at the ')' MATCHING the opening one (depth scan);
arguments split on commas OUTSIDE parens (a nested fn/tuple arg carries its
own); a '?' prefix maps its inner type through the fn arm and keeps the
option; the named-parameter rule (keep only the type) applies only where no
nested type begins. M5: FROZEN_HASH re-stamped.
BUDGET (owner rule 2026-10-09, foreign code only shrinks): the 38 added
mapper lines are paid by deleting HirDiff + HirDiffEngine (69 lines) -- dead
per rustc, zero references outside their own block (bootstrap, cli/t27b, gen,
scripts, tests all empty).
VERIFY: five repro shapes (state.t27's run field, plain alias, no-fn control,
nested+optional, zero-arg) silent under zig build-obj natively and under
-target wasm32-freestanding; state.t27's remaining blocked line (36:28,
Fn(S) fn-signature class) byte-identical to v1's seal -- sub-slice 1's layer;
gen_hash_zig compared old-vs-new over ALL 2,959 sealed specs: 0 changed, no
seal re-stamp needed (measured); cargo test -p t27c --bin t27c: 1797 passed,
0 failed. Diff: +38/-69 in compiler.rs.
* spec(t27b): wasm.t27 floor 6 -- export_section, call/control, i64.add, tee, drop (Refs #11840)
The honest rebase of this branch's floor-4 commit (aa3e3a387) onto master's
floors 1-5. Master had already taken what that commit shared with it: the
export entry and section id (#11964's constant-leaf law, carrying the
f32/f64 value-type correction this branch predates), the constant
instructions, and the i32 arithmetic floor (#11976). The branch's 39-byte
one-export capstone is subsumed by master's 43-byte the_answer module, and
its 5-arg export_entry by master's corrected 4-arg law -- neither is
duplicated.
What this commit keeps is the branch's UNIQUE content, renumbered from its
"floor 4" to floor 6, tests and all:
- export_section: the in-place framing twin of code_section (vec count +
pre-joined entries under the id 7), the 12-byte and 11-byte frames pinned,
plus the 200-index entry vector (uleb past one byte) master's export test
does not pin;
- the call/control family: call 0x10, block 0x02 / loop 0x03 / if 0x04
opening the void blocktype 0x40, else 0x05, br 0x0C, br_if 0x0D, return
0x0F, each immediate pinned;
- the i64 stack floor: i64.add 0x7C, local.tee 0x22, drop 0x1A, plus the two
i64.const vectors master's floor-4 test lacks (-123456's C0 BB 78 and
2^32's six-byte 80 80 80 80 10);
- a new floor-6 capstone in place of the subsumed one: the first
TWO-function module -- an exported wrapper whose body is one call to a
callee that adds two i64 constants -- 48 bytes, every one pinned.
32/32 tests under t27c test-report, 0 vacuous; master's 27 all stay.
gen/rust/tri/t27b/wasm.rs regenerated from the spec (t27c gen-rust).
The t27b_T27bWasm seal is re-saved (t27c seal --save, master-built binary,
32/32 recorded): it HOLDS for the first time since #11964 changed the spec
unsealed, so the stale-hold line #11977 parked in tools/seal_baseline.txt is
dropped per that ledger's own rule -- the gate now holds the repair fixed.
Seal-coverage delta against pristine master measured with the same binary:
newly-broken sets identical (23 pre-existing, none from this change), the
repaired seal absent from the list.
Refs #11840
* spec(t27os): a claim stamped further ahead than SKEW_S is malformed and stale (Refs #11974) (#11975)
stale_claim read any since later than now as fresh, so a hand-typed stamp
ahead of the clock hid the entry from the two-hour retake rule (tick 59:
06:40Z written at 06:29Z). Up to SKEW_S = 300 s ahead still reads fresh
(clock skew between machines); further ahead reads stale.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* docs(analog): v0.1 release notes (final) and one-page summary for the external team (Updates #11972) (#11973)
* docs(analog): v0.1 release notes and one-page summary for the external team (Updates #10486)
Replaces the 2026-10-20 draft with the final notes: M3c-4 log tables for four
corners, M3e body effect, M4b-q comparator on PSP103, M5c-g acceptance
evaluator (9 PASS / 0 FAIL / 4 NOT MODELLED of 13 blocks), M3d inverter on the
board (1217 of 1217), M3f phase 1 and 2a, the RAW readback, the bench. Every
number carries its PR, test or receipt; the does-not-claim list is explicit
(no speed claim, one corner on the board, phase 2a does not close 100 MHz).
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
* docs(analog): summary rows carry the scope the full notes state -- fitted converter, 32 doubles, ngspice timing, comparator body effect (Updates #11972)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
* fix(gen-zig): drop tests_phase34_diff, the deleted engine's own tests (Refs #11940 #11840)
CI caught what my local reference check truncated: compiler.rs's own
#[cfg(test)] module tests_phase34_diff (3 tests, 40 lines) exercised
HirDiffEngine::diff/equivalent -- the code the budget payment deleted. The
t27-wasm-explorer crate mounts compiler.rs WITH its test module, so its
build-and-test failed to compile: cannot find type HirDiffEngine (3x, lines
43208/43215/43228). The tests referenced only the engine and each other --
dead along with it. Repo-wide HirDiff reference count is now 0 across all
.rs files (counted, not grepped-and-truncated).
VERIFY: cargo test -p t27c --bin t27c 1793 passed 0 failed (the known
a_looping flake passed isolated); cargo test --no-run --manifest-path
bindings/wasm-explorer/Cargo.toml compiles clean, no errors; nestedfn and
arrow_repro repros still silent natively and under wasm32-freestanding.
PR diff is now +38/-110 in compiler.rs -- the budget still passes.
* feat(compiler): fn-level comptime type params -- parser + Zig emitter (Refs #11940 #11840)
fn name(comptime T: type, ...) parsed as three garbage params before this
slice (comptime lexes as a plain Ident): the repro emitted
fn identity(@"comptime": T, @"type": , value: T) T. The parser now reads the
shape into (name, "type") and refuses a comptime VALUE parameter with a parse
error; gen-zig renders the generic-function idiom comptime T: type, skips the
value-scope maps for type params, and discards one only when the signature
does not already use it. Call sites pass the type explicitly (identity(u8,
42)) -- call-site inference is the recorded follow-up. A struct literal
attached to a call (Box(T){ ... }, the fn pure(comptime T: type, value: T)
Maybe(T) shape) was captured as text on the call's value and dropped by the
Zig emitter; it is now written, and the unused-parameter scan reads that text.
Debt shrinks: the two never-called dead test helpers assert_dropped and
assert_decl_dropped are deleted (39 added / 50 deleted in the one foreign
file touched). Coverage is native: NEW specs/tri/collections/box.t27 passes
test-report 3/3 (runtime asserts executed, 0 vacuous); repros in
/tmp/opencode/repros pass zig test and native + wasm32 build-obj; cargo test
-p t27c --bin t27c 1797 passed; M5 re-stamp.
* spec(t27f): live_struct_glue -- the struct-path export glue v2 contract as law, written before the emitter: the gx_-buffer shapes (33 exports: setters, actions, 10 ptr/len pairs), the GLUE_REFUSED_BASE=64 band beside live_mode's 0..5/33..35, total init, idempotent reads, and two-node + batch round-trips transcription-checked against work_graph's own law fns (6/6 tests, 3 invariants, 350,808 asserts); open questions inline as ; QUESTION. Refs #10262, #11781; the contract the struct-path emitter writes against. (#12005)
* t27b(wasm): floor 6 -- the emit() composer as per-fn descriptors (#12003)
The #9103 gap (no slice of slices) answered the macho.t27 way: a 24-byte
descriptor record per fn (name offset/length into a names blob, parameter
count, result valtype, body offset/length into a bodies blob) plus
compose_module, which assembles preamble + type + function + export + code
through the floor-1..5 law fns only (module_preamble, functype_full,
vec_prefix, func_entry, export_entry, code_entry, code_section, section),
failing closed on descriptors off the law or an empty export set, exactly
as the reference emitter refuses them by name.
Capstones pin the live-scalar closure byte for byte: the 87-byte two-fn
module (arrival_frame + latency_ms, the build Node's WebAssembly verified
on the emitter branch) and the 117-byte trio with paints_due
(Node-verified 2026-10-24). test-report 36/36, 0 vacuous; mutation check
paid (one flipped pin fails). gen-rust regenerated additively (29 -> 42
pub fns, no existing fn touched); seal re-saved and its stale ledger line
dropped.
Refs #6198 (port epic).
* spec(t27os): devices.t27 lg_rows -- the LOGS page parser for the night loop's log tail (Closes #11991; Refs Trinity-S-AI-DNA/t27os#23) (#11993)
The T27 OS window renders nothing of ~/.t27os/loop/log.txt. This adds the
pure parser the LOGS page will draw from: lg_rows turns a tail -c 6144 of
the log into at most DL_MAX=96 rows of (epoch, kind, subject start,
subject end), offsets into the tail in the dv_* style. Kinds tick-start,
tick-end, claude, G, note, BAD. A malformed line is flagged as BAD and
neither corrupts the row above nor stops the walk (negative control in the
tests); a cut tail drops its partial first line; more lines keep the last
96; CR LF endings are trimmed; lg_clock writes HH:MM:SS UTC.
Both compilers: t27c test-report 24/24, 0 vacuous; t27b test 24/24,
invariant held. Seal re-saved with a t27c that reproduces master seals
(hive_feed_acceptance, kanban byte-identical). The glass_window wiring
(page LOGS, TBO_LOG buffer, tail job) is the next unit.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* t27b(wasm): floor 8 -- the refusal walk as law: the walk order (skip, void, M-A uncarried-then-body, M-B params-then-return-then-body, expr Const/Var/Arith with op-before-operands and lhs-before-rhs, select shape facts, module-level), every EmitError construct and detail byte-stable, EmitError::message's exact line, the emitter valtype carrier rule, the ArithOp debug names; 50/50 tests, table test mutation-checked Refs #6198 (port epic). (#12007)
* tools: ledger live_struct_glue's packed LiveGlue width (1,723,167 bits -- the wasm memory image, landed unledgered by #12005) so the widths gate holds for every lane behind it; the design question stays #2566 Refs #6198 (port epic). (#12008)
* spec(t27os): the LOGS page -- the night loop's own log rendered in the window (Refs Trinity-S-AI-DNA/t27os#23)
The owner asked twice on 2026-10-24 why the swarm's work is invisible in
the window ('why can't I see how the agents work' / 'no logs'). The loop
writes ~/.t27os/loop/log.txt; nothing in the window read it. This adds the
fifth tool page: letter L (page label LAB -> LOGS in TOOL_PAGES and
petal_menu WORLD_NAMES, both, so the equality test holds; the tool keeps
its name t27l and its artifact now cites both the lab specs and the log).
- agent_parts.t27: PAGE_LOGS=5, PAGE_KINDS 5->6, PERIOD_LOGS 30 s,
page_kind(12), the page_period arm; the five-pages test, the cadence
due/not-due pair at 1029/1030.
- devices.t27: lg_rows (dv_* style, offsets not copies, DL_MAX 96) parsing
the MEASURED event lines (tick-start, claude-start, tick-end rc=N,
overlap-skip); lg_prose counting the tick reports the page does not
flatten; lg_tail_cmd -- the tail -c 6144 into tail.part + mv job, the
same dance as every feed job (tg_read cannot seek). Tests: the measured
shapes built byte-explicit, the negative control (an 11-digit epoch row
is flagged DLF_BAD, does not corrupt the row above, the walk continues),
DL_MAX bounds, the command's shape. 23/23, 0 vacuous.
- glass_window.t27: TBO_LOG=77824 (the old TB_SIZE top, append-at-top
convention), TBO_LOG_N=6144, TB_SIZE 77824->83968; TPG_LG_* words in the
verified free gap 129-134; lg_load (drops the cut first line of a byte
tail) + lg_tick (load-once, reap, page_feed_due every 30 s while open);
draw_logs_page -- the header (source, events, prose), bottom-anchored
rows (age, kind with ! for a nonzero rc and ? for a malformed line,
sanitized subject); the dispatch arm, the tick wiring beside hive_tick,
and the layout asserts extended (TBO_RC + RC_CAP == TBO_LOG,
TBO_LOG + TBO_LOG_N == TB_SIZE) in both assert sites.
Pre-existing, NOT from this PR: glass_window's runtime test-report is
BLOCKED on this machine's zig because the harness's own
@extern("CFStringCreateWithBytes") now needs two arguments -- verified by
running test-report on pristine origin/master (same BLOCKED). Typecheck
passes 0 errors; CI's zig accepts the harness as-is (master green all
night). agent_parts and devices test-reports: 23/23 each, 0 vacuous.
* spec(t27os): labs gate commands — the repair cycle as executable data (Refs #11783 #11038) (#11868)
GATE_COMMANDS [9]str pins the exact shell command per gate, in gate order --
the same invocations CI runs (corpus-ratchet, documented-commands,
emit-bitexact-gate, seal-coverage, spec-guards). gate_command(i) returns the
command or empty for out-of-range; all_gates_pass([9]bool) is the verdict
rule. The cycle proven 6x in practice (#11735, #11786 x2, #11825, #11838)
now has its commands as law, not as memory.
Tests 6 -> 8, all pass, 0 vacuous (13 + 5 new runtime asserts).
* night loop: BOARD-GUARD-STEP -- a closed permanent board reopens before the claim (Closes #11978) (#11979)
* fix(crons): BOARD-GUARD-STEP -- the permanent board reopens before the claim, keyword-close notes refused (Closes #11978)
* seal(crons): re-seal t27os-night-loop with bootstrap built from master 89f2d9917 -- gen-drift was the old dirty-tree binary, provenance now recorded (Closes #11978)
---------
Co-authored-by: Claude <claude@anthropic.com>
* chore(seals): reseal 13 collections/io/trees specs from the lab seal leg -- gen_hash_zig only (Refs #11903) (#12023)
Master's spec-guards and coverage checks are red: 21 seals "newly do not
hold", all on gen_hash_zig of specs/tri/collections, io and trees. The
seals come from the T27 OS lab seal leg (t27os#31, merged 0a50691) at
master 447e856, run 40099325826, published as
runs/447e8569691e8569c6b6c26bcc9b23f03ced5bdd.seals/ in
Trinity-S-AI-DNA/t27os: a t27c built off master in CI, no /Users/ path.
Each of the 20 hashes the master spec-guards log names as "current"
equals the hash written here; the 5 remaining files are their twins.
Specs are unchanged; only gen_hash_zig and sealed_at move.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* docs(analog): competitor delta 2026-10-24 as section 12 of competitors.md (Closes #12026) (#12029)
Reference-chain risks (OSDI 0.4 vs 0.5, IHP dev moving) go to #12027; the commercial speed bar is named, the no-speed-claim line stays.
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
* t27b: wasm32 emitter M-B -- parameter-carrying scalar exports lower to the floor-5 law (#11840) (#11983)
* t27b: wasm32 emitter M-B -- parameter-carrying scalar exports lower to the floor-5 law (epic #11840)
The emitter's second cut: a pub fn with parameters whose body is one
`return <expr>;` over + - * / on the i32 carrier lowers to a stack program of
the floor-5 law's opcodes (local_get/i32_const/i32_add/i32_sub/i32_mul/
i32_div_u), its functype composed by wasm_law::functype_full over the fn's own
parameter list. `/` and integer @divTrunc arrive as ArithOp::Div and cross as
i32.div_u. Everything else in a param'd pub fn is refused by name (expression
kind, arithmetic op, local variable, fn return type, fn parameters off the
i32 carrier). The M-A constant-leaf path is byte-identical: the 100-spec
Node-vs-native battery stays 100/100.
Verified: cargo build --release -p t27b && cargo test -p t27b -> 175 passed,
0 failed; the pinned latency/frame module instantiates in Node's WebAssembly,
latency(7,2)=96 and frame(33)=3.
Hand-written Rust by owner approval (owner-approved-foreign, session
2026-10-23, confined to cli/t27b); the spec that replaces this file is
specs/tri/t27b/wasm32.t27 under the port epic.
Refs #6198 (port epic), advances #11840 (M-B); companion to #11942, #11964.
* spec(t27f): live_scalar_closure -- the two emitable laws of live_mode as the stack expressions the M-B cut lowers, transcription-pinned to the law (415 asserts); builds the 87-byte t27f.wasm whose exports Node verifies (frames 1/1/2/3/65, latency 96/256) (Refs #6198, advances #11840 M-B, #10262)
* t27b: the select pattern -- if (<param> == 0) return <const>; return <const>; lowers to eqz+select (the law floors 0x45/0x1B); live_scalar_closure gains paints_due verbatim, transcription-pinned (66 asserts, 481 total); the trio wasm exports all three, Node verifies (Refs #6198, advances #11840 M-B, #10262)
* t27b: the trio module held by the suite -- build live_scalar_closure, Node-verify all three laws (the exact PROVENANCE numbers); suite 176/0 (Refs #6198, advances #11840 M-B, #10262)
* t27b(wasm): floors 9+10 -- the body lowering and the IR-to-descriptor glue as law (spec+gen+seal, 62/62) (#12030)
* t27b(wasm): floor 9 -- the body lowering as law: lower_stack's postfix walk (lower_expr_node: EK_VAR->local.get, EK_CONST->i32.const through the u32>=2^31 carrier crossing, EK_ARITH->the floor-5 opcode byte, Div via i32.div_u), const_insn's carrier crossing for every carried type (i64/u64 sleb image, f32/f64 LE bits through the floor-4 fns, the i32 image otherwise), sleb_value the reader half so every crossing round-trips, select_body's five instructions (true-const, false-const, local.get, eqz, select); the capstone re-derives the 117-byte trio module's three bodies byte for byte through floor 7 over floor 9 lowering; 56/56 tests, capstone mutation-checked Refs #6198 (port epic).
* t27b(wasm): floor 10 -- the IR-to-descriptor glue as law: emit()'s prog walk over a FACT TABLE (one 48-byte row per fn: flags, name, nparams, the return type name, the body shape, the body's floor-8 verdict body_r, a payload pointer into a 16-byte NODE AREA, the line) filling floor 7's three areas -- walk_refusal (first refusal wins, empty export set REF_MODULE, malformed table fails closed), walk_refusal_row (the adapter's map back to the refusing fn's name and line), walk_prog (per-fn desc_put + name append + floor-9 body lowering with a per-shape worst-case capacity reserve: 12 for a carried const, 6/node postfix, 21 select), fn_body_bytes (each shape's body with its trailing end byte), walk_names_len/walk_bodies_len; capstones re-derive floor 7's 117-byte trio (with skip rows proving tests and private fns are not exports) and floor 4's 43-byte the-answer leaf byte for byte through the walk -- the thin-adapter contract emit() delegates onto in the follow-up PR (this PR stays spec+gen+seal, 0 foreign lines); 62/62 tests, capstone mutation-checked Refs #6198 (port epic).
---------
Co-authored-by: gHashTag <gHashTag@users.noreply.github.com>
* spec(fpga): wasm board P3 -- i64.const joins as the low-32 floor (0x42, the i32 SLEB submachine)
The fleet crossing (t27os#3) refused the two i64 corpus specs: the MVP engine
had no 0x42. This adds it as the alias of the i32.const path -- the same
five-byte SLEB128 submachine, the same u32 stack word, so every i64 whose low
32 bits are what the answer contract expresses now crosses (canonical SLEB of
five bytes or fewer; a longer continuation still refuses with ERR_LEB, the
same honest boundary as i32). The 64-bit datapath stays a separate increment.
Behavioral test p3_i64_wire_programs (18/18, 0 vacuous): the fleet's exact
programs over the wire with save/restore of page 0 -- 42 B1 D1 F9 D6 03 0B
answers DE68B1 (u64 987654321's low 24) and 42 7B 0B answers FFFFFB (i64 -5),
matching the emitter's canonical bytes bit for bit.
* docs(analog): PSP103 and cornerMOSlv hashes at the IHP pin, dev and main; 3 skill traps (Refs #12027) (#12032)
Prose only. Read-only GitHub tree API comparison dated 2026-10-24: dev equals the pin on 17 of 17 files, main differs on 2. Skill traps: issue-shape outcome rules, T27 OS control client.
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
* docs: lane handoff for the P4 float floor (Refs t27os#3, stacks on #12033)
* fix(gen-zig): an arrow in a fn-header parameter list consumes into the parameter (Refs #11940) (#12037)
After a complete parameter type the only continuations of a parameter list are ',' and ')', so an arrow there can only be the return of the parameter's own fn type. It was read as a phantom name: fn modify(fn: Fn(S) -> S) parsed as [(fn, Fn(S)), (S, )] and the emitted Zig carried a parameter with an empty type plus a phantom discard line (state.t27 modify, reader.t27 asks/local, writer.t27 censor). The fn TYPE head also rides the main type-identifier arm now: 'fn' lexes as KwFn, not Ident, so a fn-typed parameter used to return an EMPTY type and the header died on Expected LBrace.
Seals for the eight touched specs regenerated with a t27c built from this rebased tree; FROZEN_HASH restamped from the merged compiler.rs. Budget: hand-written foreign lines +38/-7 in compiler.rs, paid for with dead-code deletions (host/driver.rs -10, host/irq.rs -5, runtime/mod.rs -20).
* ci(seals): re-seal three drifted twins -- t27f/petal_menu, t27os/agent_parts, t27os/devices (spec+all gen hashes moved) (Refs #11038) (#12039)
* spec(fpga): wasm board P4 -- the float consts as bit words (0x43/0x44, the raw-IEEE floor)
The fleet crossing (t27os#3) refused the float corpus specs: the engine had no
0x43 and no 0x44. This adds both as RAW-BIT words -- a real wasm f32.const
carries its four IEEE-754 bytes little-endian with no LEB at all, f64.const
its eight, and the floor pushes those bits as the u32 stack word: f32
wholesale, f64 as the low 32 (its first four bytes), the same honest floor as
P3 gave i64.const. Float arithmetic and the f64 high half stay a separate
increment.
Placement follows the lane handoff's law: grep 'scrap_op == OP_I32_EQZ' finds
exactly ONE dispatch site (the MVP code[] runner and the user uprog[] runner
share it through run_base), the float arm is a proper sibling of the i32/i64
const arm there, inserted by exact-match edits with the one new closing brace
placed by a brace-depth pass -- a pure insertion, zero existing lines touched,
brace balance 0 and t27c check at its baseline 0 errors / 0 warnings.
Behavioral test p4_f32_wire_programs (18/18 total, 0 vacuous, 20 asserts in
the new test): the fleet's exact programs over the wire with save/restore of
page 0 -- 43 00 00 20 40 0B (f32.const 2.5, word 0x40200000) answers low24
00 00 20; 44 00 00 00 00 00 00 04 40 0B (f64.const 2.5) answers its honest
zero low-32; 44 18 2D 44 54 FB 21 09 40 0B (f64.const pi, 0x400921FB54442D18)
answers 18 2D 44 -- the low24 of 0x54442D18, so the low-32 law is witnessed
on a nonzero half, not just a zero.
Refs #12033, t27os#3
* spec(t27f): live_glue_layout -- the layout plane of the struct-path export glue: the 23 CONSTANT gx_ exports (ptr/len/cap pairs of the fixed 143,692-byte layout) the wasm32 emitter's M-A cut lowers today, each returning the contract card's own constant so the plane cannot drift from live_struct_glue; pairs tile the memory in the card order (no gaps, all inside MEM_CAP), the 10 stateful names named and left to the stateful floors; 3/3 tests, 49 runtime asserts, 0 vacuous; emitted 683-byte wasm32 module, 23 exports, all values verified in a wasm runtime; the emitter gap (memory/data/globals, locals, loops, calls, u64, void, ptr params) filed on #5980. Refs #10262, #11781; companion to #12005's contract, the struct-path emitter writes against both. (#12040)
* fix(specs): generic collections speak fn-level comptime params (Refs #11940 #12000)
Convert the convertible members of #11940's 14-spec blocked table to the
fn-level comptime grammar #12000 landed, following box.t27: types bind at
each fn (fn some(comptime T: type, value: T) -> Option(T)) and call sites
pass them explicitly (some(i64, 42)). maybe's bind/map take the function
type as a second comptime param (bind(i64, MaybeBindFnI64, m, f)), which
expresses the tie to T at the call site while ADR-008 still rejects
generic fn-type aliases. Beyond the signatures, the never-compiled bodies
needed the emitter's Zig shapes: .field = value inits, &[_]T{} empty
slices, AutoHashMap, and renames forced by the target language (Result's
E collided with math::constants' Euler E in the use-resolved source; its
error field/param are Zig keywords). reader/writer/state stay untouched:
their fn-typed fields/params and closure bodies are sub-slices 2+3,
compiler-side. t27c test-report, measured with a current build (the
shared t27-build binary predates #12000 and blocks box.t27 itself):
maybe 14/14, either 15/15, result 10/10, tuple 9/9, queue 5/5, option
4/4, set 4/4 (1 pre-existing vacuous), io 2/2 -- eight green. tree now
blocks on its self-referential value field (needs indirection),
ring_buffer on the cross-module Option(T) reference and an
allocator-backed create_buffer, btree on allocator values at call
sites: each advanced to its own next defect, recorded in .trinity/seals.
21 seal files resealed (both naming copies); seal --verify MATCH on all
eleven.
* fix(specs): generic collections speak fn-level comptime params (Refs #11940 #12000) (#12045)
Convert the convertible members of #11940's 14-spec blocked table to the
fn-level comptime grammar #12000 landed, following box.t27: types bind at
each fn (fn some(comptime T: type, value: T) -> Option(T)) and call sites
pass them explicitly (some(i64, 42)). maybe's bind/map take the function
type as a second comptime param (bind(i64, MaybeBindFnI64, m, f)), which
expresses the tie to T at the call site while ADR-008 still rejects
generic fn-type aliases. Beyond the signatures, the never-compiled bodies
needed the emitter's Zig shapes: .field = value inits, &[_]T{} empty
slices, AutoHashMap, and renames forced by the target language (Result's
E collided with math::constants' Euler E in the use-resolved source; its
error field/param are Zig keywords). reader/writer/state stay untouched:
their fn-typed fields/params and closure bodies are sub-slices 2+3,
compiler-side. t27c test-report, measured with a current build (the
shared t27-build binary predates #12000 and blocks box.t27 itself):
maybe 14/14, either 15/15, result 10/10, tuple 9/9, queue 5/5, option
4/4, set 4/4 (1 pre-existing vacuous), io 2/2 -- eight green. tree now
blocks on its self-referential value field (needs indirection),
ring_buffer on the cross-module Option(T) reference and an
allocator-backed create_buffer, btree on allocator values at call
sites: each advanced to its own next defect, recorded in .trinity/seals.
21 seal files resealed (both naming copies); seal --verify MATCH on all
eleven.
* fix(gen-rust): slice out-params borrow mutably, undefined array locals zero-init (Refs #12036) (#12042)
Two defects left the wasm floors' generated Rust uncompilable
(gen/rust/tri/t27b/wasm.rs, spec fns of specs/tri/t27b/wasm.t27):
1. The call-arg wrapper for a callee-WRITTEN slice parameter wrapped the
argument wholesale, but the slice arm of expr_to_rust had already
emitted a SHARED borrow. A spec passing buf[0..5] to such a callee
reached rustc as `&mut &buf[0..5]` -- a mutable borrow OF a reference
(E0596). Strip the leading shared borrow and borrow the place itself:
`&mut buf[0..5]`.
2. A typed local declared `= undefined` (or with no initialiser) emitted
a bare `let mut v: [T; n];`. When the array is filled through a
`&mut arr[0..n]` handed to a callee, rustc cannot see that write --
it does not count as initialising the array -- so every later read
was E0381. Zero-initialise arrays of zeroable element type instead,
matching the interpreter, which reads only the written prefix. NOT
Default::default() (withdrawn in #3223: [usize; 256] has none), and
not scalars: there a bare `let x: T;` is legal Rust and a read before
a real assignment should fail loudly.
Applied at BOTH local-emission sites: gen_fn carries its own copy of
the local logic, and a fix at only one of the two changes no output.
Regenerated gen/rust/tri/t27b/wasm.rs: export_section (vtmp, htmp) and
type_body (ps, rs). Acceptance: `cargo build --release -p t27b` now
compiles (it includes the file by path from wasm32_emitter.rs); before,
6 errors (E0596 x2, E0381 x4). Full suite: cargo test -p t27c --bin t27c
1782 passed, 0 failed. FROZEN_HASH restamped via the M5 frozen-digest
ceremony (old frozen binary printed the new line).
Budget: bootstrap/src/compiler.rs +30/-1, inside the standing exception
(owner 2026-10-05) and the 40/file, 80/PR caps; paid with the dead
bootstrap/src/host/histogram.rs (-286, rustc: every item never used) and
its two host/mod.rs lines. gen/ is t27c output, not hand-written.
Refs #12036
* test(analog): a planted-fault negative control in each of the five analog specs that had none, coverage 145/150 -> 150/150 (Refs #12041) (#12046)
Four new tests that plant a fault and assert the spec's own check refuses it (swapped ROM slice, flipped ROM bit, flipped stamp word in the folded register, flipped log word in a slice copy), and one rename of a test that already planted a fault. Each new test fails under a blind or mutated check (6 mutations, all FAIL). Seals re-saved with the master-built t27c.
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
* t27b(wasm): M-C -- comparisons and the eqz fold lower; the law's floor 11 (Refs #11983, #11840, t27os#3) (#12048)
The named gap of t27os#3's probe closed on the emitter side: the cell
executes the full 0x45-0x4F family while the emitter's own refusal said
'parameters, i32 constants and + - * / only'. Now the six IR comparisons
lower on the i32 carrier:
- law floor 11 (specs/tri/t27b/wasm.t27, spec+gen+seal, 65/65): the six
opcodes (0x46 eq, 0x47 ne, 0x48 lt_s, 0x4a gt_s, 0x4c le_s, 0x4e ge_s),
their writers, cmp_opcode, and eqz_fold -- the rule that 'x == 0' folds
to one eqz, 'x != 0' to two. Floors 8 and 9 mirror the walk: EK_CMP
carries (no comparison refuses on its operator), lower_expr_node emits
the opcode byte, the refusal detail words updated in lockstep with the
emitter's own texts.
- emitter (cli/t27b/src/wasm32_emitter.rs): the ExprKind::Cmp arm -- the
fold decision comes from the law (wasm_law::eqz_fold), the operand the
emitter picks; everything else is lhs, rhs, opcode, exactly the arith
arm's postfix shape.
SIGNED for the ordered four, matching the house pattern: '/' lowered to
div_u because the die taught us the die's div is unsigned; here the die's
own law (wasm_board_ax7203.t27, lt_s32(0xFFFFFFFF, 1) == 1) numbers the
same bytes signed, and t27's ordered comparisons on i32 are Zig's signed
ones -- die and source agree, so signed is both.
Evidence: 'pub fn lt(a: i32, b: i32) -> bool { return a < b; }' compiles
to a 39-byte module whose expression is 20 00 20 01 48 0b (local.get 0,
local.get 1, i32.lt_s, end). The die fleet (AX7203, /dev/cu.usbserial-130,
P3 bitstream, cmp_fleet_mc.py from tonight's bridge): 6 ops x 6 pairs --
(7,3), (-5,2), (3,3), (-2147483648,2147483647), (0,0), (-7,-3) -- 36
exact, 0 not; every signed-sensitive cell (lt(-5,2)=1, lt(-7,-3)=1,
ge(-7,-3)=0, the full-range pair) confirms signed on silicon. The
standard-runtime twin runs the same opcodes in Node: MC OK.
Budget: 73 foreign lines added, 142 deleted (five inline tests that
duplicated tests/wasm32.rs one-for-one removed, the file split its header
already documents). wasm32 gate 11/11, equality battery 100/100; the two
lib failures (hir_roundtrip bridge/uart path lookups) are pre-existing on
the base and untouched here.
* chore(seals): reseal the 247 seals #12042 moved -- master Spec Guards green again (Refs #12036) (#12062)
#12042 changed gen-rust (slice out-params borrow mutably, undefined array
locals zero-init), so every spec with a Rust leg emits different code and
Spec Guards on master 69eef64da counts 247 STALE generated-code hashes.
These are the seals the T27 OS lab wrote with its own master-built t27c
(tri seals drift --fix, lab run 40112957744, receipt
Trinity-S-AI-DNA/t27os runs/69eef64da108d79238f6316715c38c32c35a7972.27b6b423.json,
.seals/CHANGED.txt = 247 files), copied byte for byte: 246 move only
gen_hash_rust (+ test_runner where the runner hash moved), one
(fpga_fpga_wasm_board) also catches up its spec_hash after a spec edit.
Both legs on the receipt: t27c labs 8/8, t27b labs 8/8 asserts 34.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* docs(analog): what the seal command refuses on the 16 milestone specs, one planted fault at a time (Refs #12065) (#12066)
The bare seal form refuses 0 of 16 (exit 0, hashes only); --save refuses
16 of 16 on failing tests and --verify refuses 16 of 16 on a hash mismatch;
all three pass the 16 clean specs. Four single-line faults survive the
mutate plant tool (no test pins them). The all-at-once run is disclosed as
confounded and not used. The SC-002 row of the release notes is edited in a
follow-up once #12063 lands.
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
* spec(tri/t27b): wasm.t27 reuses macho put_bytes/dec_len -- master duplicate-bodies red, rebuilt on master (#12038)
* spec(tri/t27b): wasm.t27 reuses macho put_bytes/dec_len instead of its own copy_bytes/u32_dec_len -- master duplicate-bodies red, rebuilt on master 2ccaee065 after #12030/#11983 added callers
Refs #12024
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* chore(seals): wasm seal + gen from T27 OS lab run 40115576122 after the master merge
Lab receipt runs/7a9b09f8a459092951970eb1be2fe5d4d882e3fc.9c523495.json:
t27c wasm 65/65 + macho 22/22, t27b wasm 65/65 + macho 22/22 (asserts 790).
Seal and gen/rust/tri/t27b/wasm.rs copied byte-for-byte from the receipt's
.seals/ and .gen/; nothing hand-edited.
Refs #12024, see #11840
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* spec(t27os): devices.t27 -- lg_tail_cmd runs nothing for an unsafe home (root_safe guard) (Refs #11991) (#12009)
* spec(t27os): devices.t27 logs tail job -- lg_tail_cmd copies the last LG_TAIL bytes of log.txt and renames them whole; lg_home_ok refuses a home that could break the quote (Refs #11991)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* chore(seals): devices, agent_parts, petal_menu resealed by lab run 40105075253 (receipt runs/5d58803ca...5af120b5, both legs 26/26) (Refs #11991)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* chore(seals): take master's agent_parts + devices seals before update-branch; lab reseal follows (Refs #11991)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* chore(seals): take master's petal_menu seal before update-branch (Refs #11991)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* chore(seals): devices.t27 seal from lab run 40116665819 (t27c 26/26, t27b 26/26) after update-branch onto master (Refs #11991)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* spec(t27o): install workflow quotes expression literals with apostrophes (Refs #11873) (#11904)
* spec(t27o): install workflow quotes expression literals with apostrophes (Refs #11873)
GitHub expressions accept only single-quoted string literals; the mode
line of WORKFLOW_YAML used double quotes, so the workflow the Trinity App
proposes on installation would fail the parse. The file comment that
claimed an apostrophe opens a t27 char literal is corrected (str holds
apostrophes, e.g. specs/analog/accept_sar.t27).
New gate expressions_single_quoted over all three YAML templates, with
the shipped line as the refused negative control.
Refs #11873 -- see Trinity-S-AI-DNA/t27os#10 (tick-24 side finding).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* spec(t27o): test-body comments use // -- a ; inside a body is a parse error (Refs #11873)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* chore(seals): t27o_T27oInstall resealed by the lab's master-built t27c (lab run 40100846805, receipt runs/258729db1e75cc7647c67f4ef9e763d2ffbd310b.c5a49219.json: t27c 12/12, t27b 12/12 asserts 60)
Refs #11903
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* spec(t27os): lab_publish.t27 -- a lab receipt is published on master, whatever ref was dispatched (#12012)
* spec(t27os): lab_publish.t27 -- a lab receipt is published on master, whatever ref was dispatched; the two lab.yml publish steps as text, with the run 40092668897 step and the t27b pull-rebase step as refused specimens (Refs #11889, Refs #11873)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* spec(t27os): lab_publish.t27 -- the rebase guard is a test, not an invariant: t27c lowers an invariant to a Zig comptime block and a scan of a 900-byte step text there blocked lab run 40093374520 (Refs #11889)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* tri coverage: a row whose only seal mismatch is gen_hash_rust says STALE-T27C? (Closes #12071) (#12072)
Loop tick 8 (#12070) lost an hour to 14 gen_hash_rust MISMATCH rows that were
no drift: the t27c it ran predated the last Rust emitter change (#12042), and
two seals saved with it went red in CI (#12068). Nothing in the report told
the two cases apart.
specs/tri/coverage/coverage.t27 gets rust_only_mismatch(text): true when the
spec_hash and the zig, verilog and c twins print a whole MATCH line and a line
starts with gen_hash_rust: MISMATCH. emit_row appends STALE_HINT to a row whose
seal fact is missing and whose seal text has that signature. A spec edit moves
spec_hash too, so it never has the signature. The exit code, --strict and every
other row are unchanged. No glue change, no git call, no hand-written non-t27
line: the issue's first design (compare the builder sha with the last
compiler.rs commit) needed a git call in hand Rust and was dropped.
3 new tests (21 now): the signature on the measured stale text in any line
order, its refusal for drift / a clean seal / empty text / a missing twin /
lines that only quote the words, and the row byte for byte (hint appended,
drift row unchanged, a seal that holds has no hint, a short buffer refuses the
longer row). The existing row test now plants a real spec_hash drift instead of
the Rust-only text, which is the signature.
Seal re-saved with a t27c built from master 19a89f1e39 (built_by +19a89f1e3);
--verify prints all hashes MATCH; the tracked Rust twin is regenerated.
tri coverage on this spec and the analog pair: gaps 0, 15/15.
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
* test(analog): pin the drive-mode code table and the 9999 no-edge value; two load mutants shown equivalent (Refs #12067) (#12068)
* test(analog): pin the drive-mode code table and the 9999 no-edge value; document two equivalent load mutants (Refs #12067)
Finding 4 of the 2026-10-25 survivor sweep left four lines that no test
failed on. Three are now pinned, one pair is shown to be equivalent:
- DR_UP 1 -> 7 is killed by a new sar_kick_net test that reads the dense
code table (DR_IDLE < DR_UP < DR_DOWN < DR_IDEAL < DR_MIRROR < 5) and the
two PMOS and two NMOS drivers by their code number.
- return 9999 -> 9998 at both no-edge returns of the chain error is killed
by a new sar_logic test that asks for an edge the run never made.
- SL_DC_LOAD_R +-1 and SL_TG_IN_LOAD +-1 still survive. The arc model is
integer ps with a floor, so a step of one in a 4-5 digit load moves an arc
by less than one ps and no integer output changes; the weighted probe sums
are identical to the digit for 431, 33381 and 33379. Written up as section 7
of docs/analog/seal-refusal-2026-10-25.md.
Both specs re-saved and verified (hashes MATCH); tests 24/24 and 18/18;
coverage gaps 0.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
* analog: re-save the sar_logic and sar_kick_net seals with a t27c built from master -- the tick 7 saves carried the pre-#12042 Rust hash (Refs #12067)
CI on this PR failed in coverage and spec-guards with "FAIL: 2 seal(s) newly do
not hold ... still hashes the same, but gen_hash_rust do not" for
analog_AnalogSarKickNet.json and analog_AnalogSarLogic.json (gen-drift). Cause:
the tick 7 saves used a t27c built before #12042 (55040898f9) changed the Rust
emitter, and #12062 had re-saved every other seal with the new emitter.
Re-saved both with a t27c built from master 19a89f1e39 (tests 24 and 18, both
pass). The diff is only the gen_hash_rust field and the seal metadata; the spec
hash and the zig, verilog and c hashes are unchanged. --verify prints all
hashes MATCH for both, tri coverage prints gaps 0 coverage 10/10.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
* fix(t27os): lv_copy_row copies the row's written bytes, not the dead tail (Closes #11919) (#12074)
* fix(t27os): lv_copy_row copies the row's written bytes, not the dead tail of its slot (Closes #11919)
Rebuilt on master b9d83f9ef2: #11920 conflicts only in the lanes_view seal,
which master resealed in #12062; the seal is re-made by the lab's
master-built t27c.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* chore(seals): t27os_T27osLanesView resealed by the lab's master-built t27c (receipt runs/7d83327e57ad124f3eebe6ae7c2367bac10d85ec.9f16a870.json: t27c 34/34) (Refs #11919)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* spec(crons): the night loop's SYNC-STEP points at t27os sync_gate.t27 and skips the gate's own file (Refs #11980) (#12084)
* spec(crons): the night loop's SYNC-STEP points at t27os sync_gate.t27 and skips the gate's own file -- #11981 rebuilt on master (Refs #11980)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* seal(crons): t27os-night-loop reseal from the t27os lab receipt a01bf8745c (t27c 27/27, t27b 27/27) (Refs #11980)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* test(analog): pin the two test-gap mutants of sar_dff_q and gate the rest with an accepted file (Closes #12083) (#12085)
tri mutate spec on specs/analog/sar_dff_q.t27 (master b9d83f9ef2): 56 mutants,
45 killed, 6 survived, 4 hung, 1 unviable. Two survivors were test gaps
(dq_scale loop bound at line 136, dq_solve_k sweep bound at line 174); two tests
appended after the last test now kill them. The other four survivors are
equivalent or equivalent in practice, and the four hung drop-step mutants end
only by the clock; docs/analog/mutation-accepted-sar_dff_q.txt names all eight.
After: 56 mutants, 47 killed, 4 survived, 4 hung, 1 unviable; the gate with
--accepted exits 0. The seal of analog_AnalogSarDffQ is re-saved with the
master-built t27c.
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
* spec(t27os): labs receipt_verdict -- an omitted, BLOCKED, failed or vacuous spec makes the receipt red (Refs #11873) (#12087)
* spec(t27os): labs receipt_verdict -- an omitted, BLOCKED, failed or vacuous spec makes the receipt red (Refs #11873)
Rebuilt on master e518fc3d56 from #11875 (DIRTY: master rewrote labs.t27
around the gate-command tests). Same fn and test, placed after run_verdict.
Refs t27os#9.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* seal(t27os): labs.t27 seal from lab receipt 4bde0df9a1.e4ffcc1e (Refs #11873)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* spec(crons): night-loop card measures its own prompt drift (Refs #12095) (#12100)
The night-loop card names its steps as law, but the prompt the cron runs
lives in ~/.t27os/loop/tick.sh, outside any repository. prompt_drift counts
the law steps (BOARD-GUARD-STEP first, then AUDIT, PR-GATE, UI-HEALTH, SYNC,
SWEEP, TASK-PICK, RECEIPT-COMMENT, RETROSPECTIVE) that a prompt does not
name; a prompt launches only at drift 0. Tick-80 and tick-102 prompts both
measure drift 5. Negative controls: one dropped step gives 1, dropping only
step 0 is caught, an empty prompt gives STEP_COUNT+1.
One-commit rebuild of #12047 on master 141605504e (its commits carried only
a cross-repo reference, so L1 was red). Spec blob 5315ac5c99 is byte-identical
to the one lab run 40126680581 passed (t27c 31/31, t27b 31/31, asserts 88);
the seal is the one taken from that receipt.
Refs #12095, see Trinity-S-AI-DNA/t27os#3
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* spec(t27os): receipt result section -- typed rows, one branchable ok (Closes #11954) (#12101)
Rebuilt on master as one commit: the stacked #11955 went DIRTY after its
base #11875 was superseded by #12087 (receipt_verdict now on master).
Same file, same tests; uses labs.t27 :: receipt_verdict, restates no rule.
Refs Trinity-S-AI-DNA/t27os#18
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* fix(t27f): measure_live sorts with live_mode's sort_u32 -- last sort_asc_u32 copy gone (Refs #11885) (#12104)
* fix(t27f): measure_live sorts with live_mode's sort_u32 -- last sort_asc_u32 copy gone (Refs #11885)
sort_asc_u32 in specs/t27f/measure_live.t27 was a byte copy of sort_u32 in
specs/t27f/live_mode.t27. live_mode exports sort_u32; measure_live imports it
and drops the copy; the duplicate-bodies baseline loses its sort_asc_u32 row.
Rebuilt on master as one commit (was #11916, DIRTY/stale base).
Refs #11885
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* seal(t27f): live_mode + measure_live resealed by the T27 OS lab (run 40130266778, receipt 1787d531c8.c5c5f819) (Refs #11885)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* test(analog): pin 29 survivors of sar_switch_q with 14 new tests, accept the 19 left (#12102)
* test(analog): pin 29 survivors of sar_switch_q with 14 new tests, accept the 19 left (Closes #12086)
tri mutate spec on specs/analog/sar_switch_q.t2…
Replaces #11863 (its only commit carried a cross-repo-only reference, so the L1 commit gate stayed red; same tree, labs.t27 blob 2f4f64cb; t27c lab 9/9, t27b pass in ratchet run 40001985581).
Refs #11873
Refs Trinity-S-AI-DNA/t27os#9
What
specs/t27os/labs.t27gainsreceipt_verdict(requested, reported, failed, blocked, vacuous): a lab receipt is RUN_FAILED when it drops a spec it was asked to verify, carries a BLOCKED spec, a failed test, a vacuous test, or was asked to verify nothing. Built on the existingrun_verdict, so the forced/failed rule stays in one place.The test pins the two live specimens from t27os#9: the 15:34Z receipt with
identity.t27 blocked=1, and the 15:53Z receipt that silently omitted identity.t27 (4 asked, 3 reported).Why it is only Refs
The executor (
lab.ymlin t27os) still swallows the test-report exit code. Repo law routes workflow YAML through TRI CLAW, so this PR gives that change a spec to gate on; it does not edit the YAML.Verified
runs/dbdc7ca69d12ce8d52ed8bed2fab4be95db9114c.51caa591.jsonin Trinity-S-AI-DNA/t27os ->labs.t27|tests=7|pass=7|FAIL=0|vacuous=0|blocked=0🤖 Generated with Claude Code
🤖 Generated with Claude Code