commit 09b40057d2d3fce78900e7f8d428556a3aa716cd (tree)
parent b652754164c13882558602c4c6a37a58f7039389
Author: Motiejus Jakštys <motiejus@jakstys.lt>
Date: Sun, 15 Feb 2026 08:13:07 +0000
update skill
Diffstat:
2 files changed, 159 insertions(+), 93 deletions(-)
diff --git a/stage0/.claude/skills/port-astgen/SKILL.md b/stage0/.claude/skills/port-astgen/SKILL.md
@@ -5,127 +5,86 @@ allowed-tools: Read, Write, Edit, Bash, Grep, Glob, Task
disable-model-invocation: true
---
-# Port AstGen — Iterative Corpus Test Loop
+# Port AstGen — Orchestrator
-You are porting `AstGen.zig` to `astgen.c`. This is a **mechanical
-translation** — no creativity, no invention. When the C code differs
-from Zig, copy the Zig structure into C.
+You manage the iterative porting loop. For each iteration you enable a
+skipped test, dispatch a worker agent, then verify and commit.
-## Key files
-
-- `stage0/astgen.c` — C implementation (modify this)
-- `stage0/astgen_test.zig` — corpus tests (enable/skip tests here)
-- `lib/std/zig/AstGen.zig` — upstream reference (~14k lines)
-- `lib/std/zig/Ast.zig` — AST node accessors
-- `lib/std/zig/Zir.zig` — ZIR instruction definitions
+**You do NOT**: analyze test output in detail, compare Zig/C code, or
+edit `astgen.c`. The worker handles all of that.
## Loop
-Repeat the following steps until all corpus tests pass or you've made
-3 consecutive iterations with zero progress.
+Repeat until no `SkipZigTest` lines remain in `astgen_test.zig`.
-### Step 1: Find the first skipped corpus test
+### Step 1: Find the first skipped test
-Search `astgen_test.zig` for lines matching:
+Search `stage0/astgen_test.zig` for lines matching:
```
if (true) return error.SkipZigTest
```
Pick the first one. If none found, all corpus tests pass — stop.
-### Step 2: Enable it
+Note the test name (the `test "..."` header above the skip line) and
+the line number.
+
+### Step 2: Comment it out
-Remove or comment out the `if (true) return error.SkipZigTest` line.
+Comment out the `if (true) return error.SkipZigTest;` line to enable
+the test.
-### Step 3: Run tests
+### Step 3: Quick smoke test
+Run:
```sh
-zig build test-zig0 2>&1
+zig build test-zig0 2>&1 | head -10
```
+Capture only the first ~10 lines. This tells you pass/fail at a glance
+without bloating your context. The worker will run the full test itself.
-Record the output. If tests pass, go to Step 7.
-
-### Step 4: Analyze the failure
-
-From the test output, determine the failure type:
-
-- **`has_compile_errors`**: Temporarily add `#include <stdio.h>` and
- `fprintf(stderr, ...)` to `setCompileError()` in `astgen.c` to find
- which `SET_ERROR` fires. Run the test again and note the function and
- line.
-- **`zir mismatch`**: Note `inst_len`, `extra_len`, `string_bytes_len`
- diffs and the first tag mismatch position.
-- **`unhandled tag N`**: Add the missing ZIR tag to the `expectEqualData`
- and `dataMatches` switch statements in `astgen_test.zig`.
-
-### Step 5: Compare implementations
-
-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 (operand_src_node)
-
-Do NOT guess. Read both implementations completely and compare
-mechanically.
+### Step 4: Dispatch worker
-### Step 6: Port the fix
-
-Apply the minimal mechanical change to `astgen.c` to match the upstream.
-Run `zig build test-zig0` after each change to check for progress.
+1. Read the file `.claude/skills/port-astgen/worker-prompt.md`.
+2. Replace the placeholder `{{TEST_CONTEXT}}` with the actual context:
+ - Test name and line number from Step 1
+ - The first ~10 lines of test output from Step 3
+3. Launch via the Task tool:
+ ```
+ subagent_type=general-purpose
+ prompt=<the worker prompt with context filled in>
+ ```
-**Progress** means any of:
-- `inst_len` diff decreased
-- `extra_len` diff decreased
-- `string_bytes_len` diff decreased
-- First tag mismatch position moved later
+### Step 5: Parse worker response
-If after porting a fix the test still fails but progress was made,
-continue to Step 7 (commit progress, re-skip).
+The worker returns a structured result. Extract:
+- `STATUS`: one of `pass`, `progress`, or `no-progress`
+- `COMMIT_MSG`: a descriptive commit message
-### Step 7: Clean up and commit
+### Step 6: Verify build
-If progress was made (see Step 6), we need to checkpoint it by committing.
+Launch a sub-agent to run:
-1. If the corpus test still fails: re-add the `SkipZigTest` line with
- a TODO comment describing the remaining diff.
-2. Remove ALL `fprintf`/`printf` debug statements from `astgen.c`.
-3. Remove `#include <stdio.h>` if it was added for debugging.
+```sh
+zig build fmt-zig0 && zig build all-zig0 -Dvalgrind |& grep -v Warning
+```
+This must exit 0 with no unexpected output. The agent must investigate:
-4. Verify this exits 0 with no unexpected output:
+1. Any valgrind errors.
+2. Any debug output (should comment out printf statements).
+3. Any formatting or staticcheck issues.
+3. Any failing tests -- should not happen as agent verifies before returning,
+ but if it does, the sub-agent should fix them.
- zig build fmt-zig0 && zig build all-zig0 -Dvalgrind |& grep -v Warning
+### Step 7: Commit
-5. Commit:
- ```sh
- git add astgen.c astgen_test.zig
- git commit -m "<descriptive message>
+```sh
+git add stage0/astgen.c stage0/astgen_test.zig
+git commit -m "<COMMIT_MSG from worker>
- Co-Authored-By: <whatever model is running this>"
- ```
+Co-Authored-By: <whatever model is running this>"
+```
### Step 8: Repeat
-Go back to Step 1.
-
-## 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.
-- **Functions must appear in the same order as in the upstream Zig file.**
-- **Commit after every iteration**, even partial positive progress.
-- **Prefer finding systematic differences for catching bugs** instead of
- debugging and hunting for them. Zig code is bug-free for the purposes of
- porting. When test cases fail, it means the C implementation differs from the
- Zig one, which is the source of the bug. So standard "bug hunting" methods no
- longer apply -- making implementations consistent is a much better approach
- in all ways.
-- From `zig build` commands, use *only* `zig build *-zig0`. Other `zig build`
- commands may start building/testing zig itself, which takes ages and is
- wholly unnecessary.
+Go back to Step 1. **Never stop early** — continue until all
+`SkipZigTest` lines are gone and all tests pass.
diff --git a/stage0/.claude/skills/port-astgen/worker-prompt.md b/stage0/.claude/skills/port-astgen/worker-prompt.md
@@ -0,0 +1,107 @@
+# Port AstGen — Worker (single iteration)
+
+You are a worker agent porting `AstGen.zig` to `astgen.c`. This is a
+**mechanical translation** — no creativity, no invention. When the C
+code differs from Zig, copy the Zig structure into C.
+
+The orchestrator has already enabled a corpus test for you. Your job:
+diagnose the failure, port the fix, clean up, and return a result.
+
+## Context from orchestrator
+
+{{TEST_CONTEXT}}
+
+## Key files
+
+- `stage0/astgen.c` — C implementation (modify this)
+- `stage0/astgen_test.zig` — corpus tests (enable/skip tests here)
+- `lib/std/zig/AstGen.zig` — upstream reference (~14k lines)
+- `lib/std/zig/Ast.zig` — AST node accessors
+- `lib/std/zig/Zir.zig` — ZIR instruction definitions
+
+## Workflow
+
+### Step 1: Run the full test
+
+```sh
+zig build test-zig0 2>&1
+```
+
+Record the full output. If tests pass, skip to Step 5.
+
+### Step 2: Analyze the failure
+
+From the test output, determine the failure type:
+
+- **`has_compile_errors`**: Temporarily add `#include <stdio.h>` and
+ `fprintf(stderr, ...)` to `setCompileError()` in `astgen.c` to find
+ which `SET_ERROR` fires. Run the test again and note the function and
+ line.
+- **`zir mismatch`**: Note `inst_len`, `extra_len`, `string_bytes_len`
+ diffs and the first tag mismatch position.
+- **`unhandled tag N`**: Add the missing ZIR tag to the `expectEqualData`
+ and `dataMatches` switch statements in `astgen_test.zig`.
+
+### Step 3: Compare implementations
+
+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 (operand_src_node)
+
+Do NOT guess. Read both implementations completely and compare
+mechanically.
+
+### Step 4: Port the fix
+
+Apply the minimal mechanical change to `astgen.c` to match the upstream. Run
+`zig build test-zig0 -Dcc=tcc` after each change to check for progress.
+
+**Progress** means any of:
+- `inst_len` diff decreased
+- `extra_len` diff decreased
+- `string_bytes_len` diff decreased
+- First tag mismatch position moved later
+
+### Step 5: Clean up
+
+1. Remove ALL `fprintf`/`printf` debug statements from `astgen.c`.
+2. Remove `#include <stdio.h>` if it was added for debugging.
+3. If the test still fails: re-add the `if (true) return error.SkipZigTest;`
+ line with a TODO comment describing the remaining diff.
+
+### Step 6: Return result
+
+You MUST end your response with exactly this format:
+
+```
+STATUS: pass | progress | no-progress
+COMMIT_MSG: <one-line descriptive message about what was ported/fixed>
+```
+
+- `pass` — the enabled test now passes (SkipZigTest was NOT re-added)
+- `progress` — partial progress was made (SkipZigTest was re-added with TODO)
+- `no-progress` — no measurable improvement (SkipZigTest was re-added)
+
+## 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.
+- **Functions must appear in the same order as in the upstream Zig file.**
+- **Prefer finding systematic differences for catching bugs** instead of
+ debugging and hunting for them. Zig code is bug-free for the purposes of
+ porting. When test cases fail, it means the C implementation differs from the
+ Zig one, which is the source of the bug. So standard "bug hunting" methods no
+ longer apply — making implementations consistent is a much better approach
+ in all ways.
+- From `zig build` commands, use *only* `zig build *-zig0`. Other `zig build`
+ commands may start building/testing zig itself, which takes ages and is
+ wholly unnecessary.