From 0cefdfbb1f1377b3be14476ec87d2eefa824429e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Motiejus=20Jak=C5=A1tys?= Date: Mon, 16 Feb 2026 21:28:50 +0000 Subject: [PATCH] add skill --- stage0/.claude/skills/fix-stages/SKILL.md | 150 ++++++++++++++++++ .../skills/fix-stages/worker-prompt.md | 135 ++++++++++++++++ 2 files changed, 285 insertions(+) create mode 100644 stage0/.claude/skills/fix-stages/SKILL.md create mode 100644 stage0/.claude/skills/fix-stages/worker-prompt.md diff --git a/stage0/.claude/skills/fix-stages/SKILL.md b/stage0/.claude/skills/fix-stages/SKILL.md new file mode 100644 index 0000000000..b1f067e18c --- /dev/null +++ b/stage0/.claude/skills/fix-stages/SKILL.md @@ -0,0 +1,150 @@ +--- +name: fix-stages +description: Iteratively enable commented-out corpus entries in stages_test.zig, fix parser/AstGen divergences, and commit. +allowed-tools: Read, Write, Edit, Bash, Grep, Glob, Task +disable-model-invocation: true +--- + +# Fix Stages — Orchestrator + +You manage the iterative loop of enabling corpus entries in `stages_test.zig`. +For each iteration you uncomment entries, test them, and either batch-commit +passing files or dispatch a worker to fix failures. + +**You do NOT**: analyze test output in detail, compare Zig/C code, or +edit `astgen.c`/`parser.c`. The worker handles all of that. + +**CRITICAL RULES:** +1. **NEVER stop early.** Do not pause to ask the user if you should continue. + Do not summarize remaining work and wait. Keep looping until every corpus + entry is uncommented and passing. +2. **ALWAYS run the test command yourself before committing.** Never trust + the worker's claim that tests pass — verify it. +3. **Batch passing files.** When multiple consecutive files pass without code + changes, commit them together in one commit. + +## Phase 0: Verify baseline is green + +Run the full test suite: + +```sh +cd ~/code/zig +./zig3 build test-zig0 -Dzig0-cc=tcc 2>&1 | tail -5 +``` + +If non-zero exit or failures: dispatch a worker (Step 4) with the failure +context. After the worker returns, follow Steps 5–7. Re-run Phase 0 until +clean. + +If clean: proceed to the main loop. + +## Main Loop + +Repeat until no commented-out entries (`//"..`) remain in `stages_test.zig` +`corpus_files`. + +### Step 1: Uncomment the next entry + +Search `stage0/stages_test.zig` for lines matching `//"..` inside the +`corpus_files` tuple. Pick the first one. Uncomment it (remove `//` prefix). + +### Step 2: Smoke test + +```sh +./zig3 build test-zig0 -Dzig0-cc=tcc 2>&1 | tail -10 +``` + +### Step 3: Evaluate result + +**If it passes** — go back to Step 1 and uncomment the next entry. Accumulate +passing files without committing yet. + +**If it fails** — proceed to Step 4 for the failing file. + +### Step 4: Dispatch worker + +1. Read `.claude/skills/fix-stages/worker-prompt.md`. +2. Replace `{{TEST_CONTEXT}}` with: + - File path that failed + - First ~20 lines of test output from Step 2 +3. Launch via the Task tool: + ``` + subagent_type=general-purpose + prompt= + ``` + +### Step 5: Parse worker response + +Extract: +- `STATUS`: one of `pass`, `progress`, or `no-progress` +- `COMMIT_MSG`: a descriptive commit message + +### Step 6: Handle by status + +**If STATUS is `pass` or `progress`:** + +Verify before committing: + +```sh +./zig3 build all-zig0 -Dvalgrind |& grep -v Warning | head -10 ; echo "EXIT: $?" +``` + +Check: (1) EXIT is 0, (2) no unexpected errors. If either fails, dispatch +another worker to fix. + +Only if clean, commit all accumulated changes: + +```sh +git add stage0/astgen.c stage0/parser.c stage0/stages_test.zig +git commit -m " + +Co-Authored-By: " +``` + +If `progress` (not `pass`), the worker re-commented the failing entry. Commit +anyway — the passing files + partial fix are still valuable. + +**If STATUS is `no-progress`:** + +Worker should have re-commented the entry. Verify: + +```sh +git diff stage0/stages_test.zig +``` + +If there are accumulated passing files (from previous Step 3a iterations), +commit those: + +```sh +git add stage0/stages_test.zig +git commit -m "stages_test: enable + +Co-Authored-By: " +``` + +If nothing to commit, revert and continue: + +```sh +git checkout -- stage0/astgen.c stage0/parser.c stage0/stages_test.zig +``` + +### Step 7: Repeat + +Go back to Step 1. **Never stop early** — continue until all corpus entries +are uncommented. + +## Commit message conventions + +- Batch of passing files: `"stages_test: enable , , ..."` +- Worker fix + passing files: use the worker's COMMIT_MSG +- If the list of files is too long, use `"stages_test: enable N files from /"` + +## Final Check + +When no commented-out entries remain, run: + +```sh +./zig3 build all-zig0 -Dvalgrind |& grep -v Warning | head -10 ; echo "EXIT: $?" +``` + +Must exit 0 with no output. diff --git a/stage0/.claude/skills/fix-stages/worker-prompt.md b/stage0/.claude/skills/fix-stages/worker-prompt.md new file mode 100644 index 0000000000..cc74164923 --- /dev/null +++ b/stage0/.claude/skills/fix-stages/worker-prompt.md @@ -0,0 +1,135 @@ +# Fix Stages — Worker (single iteration) + +You are a worker agent fixing a corpus test failure in `stages_test.zig`. +The file fails either at the **parser stage** (C parser vs Zig parser) or the +**AstGen stage** (C AstGen vs Zig AstGen). Your job: diagnose the failure, +port the fix from upstream Zig to C, clean up, and return a result. + +This is a **mechanical translation** — no creativity, no invention. When the +C code differs from Zig, copy the Zig structure into C. + +## Context from orchestrator + +{{TEST_CONTEXT}} + +## Key files + +- `stage0/astgen.c` — C AstGen implementation (modify if AstGen failure) +- `stage0/parser.c` — C parser implementation (modify if parser failure) +- `stage0/stages_test.zig` — corpus test (re-comment entry if can't fix) +- `stage0/parser_test.zig` — parser test infrastructure (comparators) +- `stage0/astgen_test.zig` — AstGen test infrastructure (comparators) +- `lib/std/zig/AstGen.zig` — upstream AstGen reference (~14k lines) +- `lib/std/zig/Parse.zig` — upstream parser reference +- `lib/std/zig/Ast.zig` — AST node accessors +- `lib/std/zig/Zir.zig` — ZIR instruction definitions + +## Workflow + +### Step 1: Run the full test + +```sh +cd ~/code/zig +./zig3 build test-zig0 -Dzig0-cc=tcc 2>&1 +``` + +Record the full output. If tests pass, skip to Step 5. + +### Step 2: Determine failure stage + +From the stack trace, identify which stage failed: + +- **Parser failure**: stack trace goes through `parser_test.corpusCheck` + - `expectAstConsistent` — AST node/token mismatch between C and Zig parsers + - `expectEqualStrings` — rendered output doesn't match source (canonical form) + +- **AstGen failure**: stack trace goes through `astgen_test.corpusCheck` + - `has_compile_errors` — C AstGen emitted compile errors + - `expectEqualZir` — ZIR instruction/extra/string mismatch + - `expectEqualData` — specific data field mismatch + +### Step 3: Analyze the failure + +**For AstGen `has_compile_errors`:** Temporarily add `#include ` and +`fprintf(stderr, ...)` to `setCompileError()` in `astgen.c` to find which +`SET_ERROR` fires. Run the test again and note the function and line. + +**For AstGen `zir mismatch`:** Note `inst_len`, `extra_len`, +`string_bytes_len` diffs and the first tag mismatch position. + +**For parser failures:** Note the AST node index, expected vs actual tag/token, +and surrounding source context. + +### Step 4: Compare and port + +Find the upstream Zig function that corresponds to the failing code path. +Use the Task tool with `subagent_type=general-purpose` to read both +implementations and enumerate **every difference**. + +Focus on differences that affect output: +- Extra data written (field order, conditional fields, body lengths) +- Instruction tags emitted +- String table entries +- Break payload values +- AST node tags and token associations + +Apply the minimal mechanical change to match the upstream. Make ONE change at +a time. After each change, run: + +```sh +./zig3 build test-zig0 -Dzig0-cc=tcc 2>&1 | head -20 +``` + +Check that no previously-passing tests broke. + +**Progress** means any of: +- `inst_len` diff decreased +- `extra_len` diff decreased +- `string_bytes_len` diff decreased +- First tag mismatch position moved later +- Compile errors resolved (even if ZIR mismatch remains) +- AST mismatch moved to a later node + +### Step 5: Clean up + +1. Remove ALL `fprintf`/`printf` debug statements from `astgen.c`/`parser.c`. +2. Remove `#include ` if it was added for debugging. +3. If the test still fails: + - Re-comment the entry in `stages_test.zig` (add `//` prefix back). + - Add a TODO comment above it describing the remaining diff. +4. Final verification — this must exit 0: + +```sh +./zig3 build test-zig0 -Dzig0-cc=tcc 2>&1 | tail -5 +``` + +### Step 6: Return result + +You MUST end your response with exactly this format: + +``` +STATUS: pass | progress | no-progress +COMMIT_MSG: +``` + +- `pass` — the enabled test now passes (entry remains uncommented) +- `progress` — partial progress was made (entry was re-commented with TODO) +- `no-progress` — no measurable improvement (entry was re-commented) + +## Rules + +- **Mechanical copy only.** Do not invent new approaches. If the upstream does + X, do X in C. +- **Never remove zig-cache.** +- **NEVER print to stdout/stderr in committed code.** Debug prints are + temporary only. Before returning, grep for `fprintf\|printf` in + `astgen.c`/`parser.c` and remove any you find. +- **Do NOT commit.** The orchestrator handles all commits. +- **Functions must appear in the same order as in the upstream Zig file.** +- **Prefer finding systematic differences** instead of debugging and hunting + for bugs. Zig code is bug-free for the purposes of porting. When test cases + fail, it means the C implementation differs from the Zig one. Making + implementations consistent is the correct approach. +- From `./zig3 build` commands, use *only* `./zig3 build *-zig0`. Other + `./zig3 build` commands may start building/testing zig itself, which takes + ages and is wholly unnecessary.