Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions .claude/skills/t27o/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,12 @@ For a `.zig` file there is no rustc oracle: the converted spec carries the file'

1. Read the ledger comment on #10522; `CronList` (delete duplicates after a restart); list running subagents. A lane a row calls running is not started again. The analog loop keeps its own ledger on #10486 and owns #10509 and `specs/analog/`: never start work there.
2. Anomalies before new work: open PRs of the epic that are red, conflicting or stale; a lane that reported done with no PR (`git ls-remote origin | grep t27o`); a seal that no longer verifies.
3. Opus plans and reviews, Sonnet implements (`specs/claw/model_route.t27`). Two lanes at most from this loop while the analog loop runs on the same 8 GB Mac; one lane at a time edits `rust_convert.t27`.
4. Review before auto-merge, on the PR head: `t27b test` and once `t27c test-report` (vacuous 0) on every touched spec; `t27c seal --verify`; regenerate each gen file and compare byte for byte; `python3 -I tools/dupe_scan.py` and `--like <spec>` (bodies -- `t27c dupes --name` only finds names; #10801 passed the name check with 13 copied bodies); the own-language budget compiled from the merge base (below); `python3 -I tools/check_devhome_paths.py` (#10646 brought nine `/Users/...` test literals); `cargo check -p tri`. A spec that `use`s `rust_convert.t27` (spice, zig) carries it in its seal closure: re-seal it when rust_convert changes.
5. Merge only green, then auto-merge (GraphQL `enablePullRequestAutoMerge`). Turning auto-merge off does not hold a PR -- any actor with the token can re-arm it (#10801 merged five minutes after it was switched off). To hold a PR, convert it to a draft (`convertPullRequestToDraft`); `markPullRequestReadyForReview` when it may go.
3. Sonnet 5.5 plans, implements and reviews (`specs/claw/model_route.t27`, #10929, owner 2026-10-19); Opus only after two failed attempts or on the owner's word. Two lanes at most from this loop while the analog loop runs on the same 8 GB Mac; one lane at a time edits `rust_convert.t27`.
4. Review before auto-merge, on the PR head: `t27b test` and once `t27c test-report` (vacuous 0) on every touched spec; `t27c seal --verify`; regenerate each gen file and compare byte for byte; `python3 -I tools/dupe_scan.py` and `--like <spec>` (bodies -- `t27c dupes --name` only finds names; #10801 passed the name check with 13 copied bodies); the own-language budget compiled from the merge base (below); `python3 -I tools/check_devhome_paths.py` (#10646 brought nine `/Users/...` test literals); `tri types ratchet` when the diff declares a struct or enum (a fixture type named `Gate` clashed with crm-sellers' `Gate`: the types ratchet counts a second definition of a name as a conflict, so name fixture types uniquely); `cargo check -p tri`. A red is inherited only if the PR's failures are a subset of master's: run `dupe_scan` on the PR head AND on its merge base and `comm -23` the findings (against current master the base drift shows up as false extras). A spec that `use`s `rust_convert.t27` (spice, zig) carries it in its seal closure: re-seal it when rust_convert changes.
5. Merge only green, then auto-merge (GraphQL `enablePullRequestAutoMerge`). It refuses with "in unstable status" while a NON-required check is red; when the four required checks (validate, check-linked-issue, parse-ratchet, own-language) are green and every red is master's, merge with `PUT /repos/gHashTag/t27/pulls/N/merge` and `{"merge_method":"squash","sha":"<the head you reviewed>"}` (the sha makes a late push fail the merge instead of slipping in). Turning auto-merge off does not hold a PR -- any actor with the token can re-arm it (#10801 merged five minutes after it was switched off). To hold a PR, convert it to a draft (`convertPullRequestToDraft`); `markPullRequestReadyForReview` when it may go.
6. Stacked PRs and squash merges: after the base merges, `git rebase --onto origin/master <old base tip>`, check `git diff <reviewed head> HEAD -- <converter files>` is empty, push with `--force-with-lease=<branch>:<old sha>`; auto-merge survives a force push.
7. Edit the ledger row last; add a trap here when it cost more than one try.
7. A t27b change that makes ledger-blocked specs pass, or moves a blocker, edits `docs/reports/t27b_expectations.json` in the same PR (the rows and `max_not_pass` recounted; precedents #10862, #10999). The steward applies UNEXPECTED PASS and UNLISTED from a master run itself but refuses MOVED; a new spec's UNLISTED row is the steward's.
8. Edit the epic ledger row last; add a trap here when it cost more than one try.

## Hand-written glue must net to zero

Expand All @@ -91,4 +92,7 @@ PR #10538 failed it with +9 / -0 at 1e20cfb34.
- Building `tri` on master: when `Cargo.lock` pins a crate the sandbox cannot write into `~/.cargo`, clone the registry (`cp -c -R ~/.cargo/registry $TMPDIR/cargo-home/registry`, an APFS clone that costs no space), `CARGO_HOME=$TMPDIR/cargo-home cargo fetch`, and build with that `CARGO_HOME`. Give each lane its own `ZIG_LOCAL_CACHE_DIR`: two lanes sharing one get `BLOCKED ... FileNotFound`.
- zsh: `echo "$json"` expands `\n` inside JSON strings, so write API responses to a file and parse the file; `echo =====` runs `=` expansion; text with backticks goes through a quoted heredoc, never into a double-quoted argument (it runs the command).
- gen-rust's `use` splice matches words inside string literals and can pull a whole module into the generated file (#10824): after regenerating, look at the gen file's size.
- A trailing `&` inside a `run_in_background` Bash call dies at once (`nice(5) failed`): run the command itself in the background. `rc=$?` after `| tail` is tail's exit code, not the tool's.
- The sandbox cannot delete `.git/worktrees/<name>` (`git worktree remove` and `prune` fail on the admin entry, the directory itself goes): remove only your own entry through the Terminal tab, `rm -rf "$(git rev-parse --git-common-dir)/worktrees/<name>"`. It cannot write `~/.claude/projects` from Bash either (use the Edit tool for memory files).
- The issue-shape gate (`.github/workflows/needs-boundary.yml`) closed 185 issues on 2026-10-18/19, 128 of them wrongly (it judged a queued run's event payload; fixed by #11008). An issue "closed as not planned" with the label `shape-refused` proves nothing: compile `gen/c/policy/issue_shape.c` as the workflow does and run the issue's current body through it before accepting the close (#11007).
- Each lane worktree costs about 320 MB; remove finished ones (`git worktree remove --force`) and keep 8 GB free.
Loading