Loading…
a327ex.com

Pipeline Health Check Test

Summary

Pipeline Health Check Test is a deliberately synthetic session: Fable drove a fresh Claude Code session headlessly (claude -p with a fixed session id, six resumed turns, about two minutes of wall clock) from the 2026-09-05 pipeline health-check session, so that every publishing feature built in the preceding days could be exercised on a throwaway log before the owner tests them by hand. The session drove the Anchor playground as an agent instance through anchor drive (steps, three engine_snapshot PNGs, an engine_reload(), a finalized .apr recording), wrote a Markdown report and a standalone HTML page through the Write tool, made two uncommitted edits in a temporary git repo that the per-turn code journal snapshotted, deliberately read a planted GitHub-token-shaped string so the leak scan would fire, ran anchor check on the playground, and ended on an explicit end-session message so the transcript-cut mechanics could be tested. The log is temporary and slated for deletion once the health check closes.

What this log exercises (read it as a checklist):

  • An agent-run replay card (::replay, "agent run, N steps") for Anchor/engine/playground/replays/20260905-203902.apr, recorded by a hidden --agent instance and finalized on anchor drive stop.
  • Media extraction from a tool result: the session Read one snapshot PNG to confirm it was a real render, and the converter lifted it as an image.
  • Extra artifacts declared in artifacts-extra.txt: the three engine_snapshot PNGs (shot-1/2/3.png), rendered as delivered image artifacts (the 3-up thumbnail path).
  • Write-tool artifacts: report.md (a Markdown artifact opening as an unlisted reader page) and page.html (a standalone HTML artifact page).
  • Code-journal ::code cards from the temporary journal-test repo (turn snapshots on its ai/journal branch; sealed rendering, since the repo has no GitHub remote).
  • Model attribution: a single-model session, so one label at the top (claude-fable-5-1, effort as recorded by the SDK).
  • Role chips: user / agent / tools / sys present; NO think blocks. claude -p did not persist thinking text (2 thinking blocks, both empty), which is the known transcript-view persistence gap, not a converter fault; anchor end warned about it.
  • Leak scan + rulings by value: the planted ghp_ token was found (r001, masked), barred one-way by Fable (it was Fable's own fixture), and the re-run of anchor end reported "1 finding(s) settled by the owner's earlier rulings" with no rescan.
  • Transcript cut: the log ends at the owner-style end-session message; a message sent after anchor end must not appear, and anchor republish --until is used to move the cut both ways as a test.
  • Gate round trip: after publishing, the log is gated and ungated once to verify the anchor gate staging fix (the media-ref rewrite must land in the commit, not just the renames).

Turn 1 - agent drive of the playground:

  • anchor drive start Anchor/engine/playground started pid 2908380 with the eval socket at Anchor/engine/playground/replays/.eval.sock.
  • Three batches of engine_step(60) each followed by engine_snapshot(...): frame = 60, 120, 180 (the field is frame in engine_state(), not frame_num; the session flagged the naming).
  • engine_reload() returned {} (no tracked file changed, nothing re-ran, no error), then one more engine_step(60) reached frame 240 / step 480 (two fixed updates per frame), time 4.0 s at dt 1/120, agent = true, visible = false, fixed_step = true, 960x540 game space in a 1920x1080 hidden window.
  • anchor drive stop finalized replays/20260905-203902.apr (636,069 bytes). The three snapshots are 25,996 bytes each and identical: the box pyramid is at rest and no input was injected.
  • The session viewed shot-3.png (pyramid of 56 boxes on the grey plane, control hints, bodies 56 fps 0; fps 0 is the externally paced instance reporting no wall-clock rate).

Turn 2 - artifacts through the Write tool:

  • fake-session/report.md: heading, a table of frame numbers per batch, the reload result, the final engine_state() summary, the recording and snapshot paths.
  • fake-session/page.html: a standalone page with a heading and an ordered list of the three frame numbers, inline CSS only.

Turn 3 - code journal fixture:

  • In the temporary repo journal-test: main.lua defining sum(a, b) and test.lua asserting sum(2, 3) == 5 and printing ok; lua5.4 test.lua printed ok, exit 0; nothing committed on the working branch.
  • The Stop hook's ai/journal branch received one snapshot per changed turn (turn 1: the initial tree; turn 3: the two Lua files).

Turn 4 - planted leak:

  • cat fake-session/env.txt printed a GITHUB_TOKEN=ghp_... line (40 characters after the prefix, a fixture generated from /dev/urandom, never a real token). The session itself refused to repeat the value and warned that it was now in the transcript.
  • anchor end flagged it twice: the mechanical credential-shape check ("1 credential-shaped string") and the leak scan (r001 secret ... GitHub token, $0.06). Fable barred it: anchor scan --session 40950d18 --bar r001.

Turn 5 - static check:

  • anchor check Anchor/engine/playground: 0 errors, 1 warning: main.lua:35:6 undefined-global theme_active, a guard-style read of a global nothing declares. Worth a look in the playground; not part of this test.

Turn 6 - end message:

  • "That's it for this session, let's end it. Title: Pipeline Health Check Test, public." The session acknowledged in one line and reminded the driver to rule on the token. This message is the recorded transcript cut.

Deletion checklist (when the health check closes):

  • a327ex-site: logs/pipeline-health-check-test.md, media/logs/pipeline-health-check-test/, the staged replay media/replays/playground/20260905-203902.apr (+ its store mirror and player package if built), renderer/data/pipeline-health-check-test.lua; commit, push, deploy.sh --content.
  • Anchor workflow: runs/40950d18-*/, the temporary journal-test entry in [journal].repos, the scan-state entry, the removals-file entry for r001 (owner's call).
  • The one-way bar's original lives only in .private/log-removals.md.

Health-check test session. Read Anchor/engine/docs/SURFACE.md and Anchor/engine/docs/AGENT.md first. Then drive the playground as an agent instance: anchor drive start Anchor/engine/playground, step 60 frames at a time with engine_step, and after each of the first three batches save a snapshot with engine_snapshot to /tmp/claude-1000/-home-adn-a327ex/b3aee24d-77ac-4a38-be06-6901e6767694/scratchpad/fake-session/shots/shot-1.png, shot-2.png and shot-3.png. Then call engine_reload() and step 60 more frames, then anchor drive stop Anchor/engine/playground. Never open a window or run the game any other way. Report frame_num after each batch, the reload result, and the recording's path.

Fable 5.1 high

Read (/home/adn/a327ex/Anchor/engine/docs/SURFACE.md)

1    # The surface (2026-09-05)
2   
3   One page for the whole system that the agent-workflow plan built
4   (`reference/agent-workflow-plan.md` is the design record; `AGENT.md`,
5   `REPLAY.md` and `ENGINE_API_QUICK.md` hold the details). The doctrine behind
6   it: **everything about a thing lives with the thing.** The game file is the
7   single artifact; the running game is the object you interact with.
8   
9   ## Running
10  
11  ```
12  anchor <game folder>            a person's run: a window, real time, the eval channel open
13  anchor <file.apr>               a person watches a recording (the folder above replays/ is home)
14  anchor <game | file.apr> --agent   a program's instance: hidden window with GL, externally
15                                  paced (frames advance only in engine_step), no audio device,
16                                  recorded, blocks on the eval channel
17  ```
18  
19  That is the entire command line. An unknown `--x` prints this usage. Games
20  read no flags: there is no `engine_get_args`. Whatever a run needs beyond
21  "who is it for" is a function called once it runs.
22  
23  ## The functions that used to be modes
24  
25  | was | is |
26  |---|---|
27  | `--headless` (a sweep, no picture) | `--agent` + `engine_set_draw(false)`: frames step at headless speed, nothing is drawn |
28  | `--render` (fixed step, capture) | `engine_set_fixed_step(on)` — an agent instance is fixed-step already — + `engine_render_setup(dir)` |
29  | `--record` / `--no-record` | the init table's `record = true/false`; `record_start(path?)` / `record_stop()` any time |
30  | `--replay=<f>` | the positional `file.apr` |
... [55 more lines]

Read (/home/adn/a327ex/Anchor/engine/docs/AGENT.md)

1    # Driving a running game (the agent workflow)
2   
3   The running game is the object. Every desktop Anchor instance opens an eval
4   channel; an **agent instance** is one started for a program instead of a
5   person — hidden window, externally paced, recorded — and everything you do to
6   it is a Lua function call through that channel. This is Phase 1 of
7   `reference/agent-workflow-plan.md`.
8   
9   ## The two kinds of instance
10  
11  | | visible (the owner's run) | `--agent` |
12  |---|---|---|
13  | window | shown | hidden (a real GL context; frames render into FBOs) |
14  | pacing | real time, its own loop | **externally paced**: frames advance only in `engine_step(n)` |
15  | audio | device | no device (sounds play into nothing; the game can't tell) |
16  | Steam | as configured | never |
17  | recording | dev-run default | **on** unless the init table says `record = false`; agent-time timestamps (no wall-clock gaps) |
18  | eval channel | polled once per frame, requests run at the frame boundary | blocks on it between steps |
19  
20  `anchor <game> --agent` is the whole switch. Nothing else about a run is a
21  flag: it is a function you call once the game runs. A recording is a game
22  too: `anchor <file.apr> --agent` (or `anchor drive start <file.apr>`) is a
23  player instance you step the same way — `engine_render_setup('render')`
24  then `engine_step(n)` renders it to PNGs, `replay_seek(f)` first for an
25  in-point; `engine_step` returns short when the stream ends.
26  
27  The modes are functions (Phase 4): `record_start(path?)` / `record_stop()`
28  (a recorder started mid-run writes what is loaded first, so it plays back
29  complete; the init table's `record = true/false` sets the default),
30  `engine_set_fixed_step(on)` (a visible loop without a wall clock — what
... [190 more lines]

Content syntax error: unknown directive ::replay. Original line: ::replay(playground 20260905-203902.apr 1)

Bash (anchor drive start Anchor/engine/playground 2>&1; echo "exit=$?"; anchor drive s...)

started pid 2908380 — Anchor/engine/playground/replays/.eval.sock
exit=0
pid: 2908380 (alive); socket: present

Bash (mkdir -p /tmp/claude-1000/-home-adn-a327ex/b3aee24d-77ac-4a38-be06-6901e6767694/...)

--- batch 1
60
--- batch 2
120
--- batch 3
180
--- reload
{}
--- batch 4
{draw = true, fps = 0, recording = "replays/20260905-203902.apr", fixed_step = true, window_h = 1080, dt = 0.0083333333333333, window_w = 1920, time = 4, height = 540, step = 480, visible = false, replay = false, width = 960, frame = 240, agent = true}

Bash (anchor drive stop Anchor/engine/playground 2>&1; echo "exit=$?"; ls -la /tmp/cla...)

stopped (pid 2908380)
exit=0
-rw-r--r-- 1 adn adn 636069 Sep  5 20:39 /home/adn/a327ex/Anchor/engine/playground/replays/20260905-203902.apr

/tmp/claude-1000/-home-adn-a327ex/b3aee24d-77ac-4a38-be06-6901e6767694/scratchpad/fake-session/shots/:
total 84
drwxr-xr-x 2 adn adn   100 Sep  5 20:39 .
drwxr-xr-x 3 adn adn   140 Sep  5 20:38 ..
-rw-r--r-- 1 adn adn 25996 Sep  5 20:39 shot-1.png
-rw-r--r-- 1 adn adn 25996 Sep  5 20:39 shot-2.png
-rw-r--r-- 1 adn adn 25996 Sep  5 20:39 shot-3.png
pid: 2908380 (not running); socket: absent

Read (/tmp/claude-1000/-home-adn-a327ex/b3aee24d-77ac-4a38-be06-6901e6767694/scratchpad/fake-session/shots/shot-3.png)

[
  {
    "type": "image",
    "note": "[image: shown above]"
  }
]

Health check complete. Everything ran through the eval channel of a hidden --agent instance; no window was opened and nothing was run any other way.

Sequence and results

  • anchor drive start Anchor/engine/playgroundstarted pid 2908380 — Anchor/engine/playground/replays/.eval.sock; status confirmed alive + socket present.
  • Batch 1: engine_step(60) + engine_snapshot(...shot-1.png)frame_num = 60
  • Batch 2: → frame_num = 120
  • Batch 3: → frame_num = 180
  • engine_reload(){} (empty table = no tracked file had changed, so nothing re-ran; no error raised). That's the expected result when you reload with no edits — the playground is a sketch-shaped single main.lua without boot files, so there's nothing to re-execute anyway. The instance kept running fine afterward.
  • Batch 4 (post-reload): engine_step(60)frame_num = 240 (step = 480, i.e. two fixed updates per frame as documented; time = 4.0 s at dt 1/120; agent = true, visible = false, fixed_step = true, 960×540 game space in a 1920×1080 hidden window).
  • anchor drive stop Anchor/engine/playgroundstopped (pid 2908380); status afterward: not running, socket absent.

Recording: Anchor/engine/playground/replays/20260905-203902.apr (636,069 bytes, finalized on stop).

Snapshots: all three landed in .../scratchpad/fake-session/shots/ as shot-1.png, shot-2.png, shot-3.png (25,996 bytes each — identical sizes, which makes sense: the playground's pyramid of 56 boxes is at rest on the plane and nothing was injected as input, so frames 60/120/180 look the same). I viewed shot-3 to confirm it's a real render: the box pyramid on the grey ground, the control hints along the top, bodies 56 fps 0 at the bottom (fps 0 is the externally-paced instance reporting no wall-clock rate — consistent with fps = 0 in engine_state()).

One small note on the doc surface: engine_state() returns the field as frame, not frame_num — I reported that value as frame_num per your instruction, but if any harness greps for frame_num it'll come up empty.

Content syntax error: unknown directive ::code. Original line: ::code(journal-test 2d9e7d8fa7 1 1 0)

Write a short markdown report of what you did in the previous turn to /tmp/claude-1000/-home-adn-a327ex/b3aee24d-77ac-4a38-be06-6901e6767694/scratchpad/fake-session/report.md (a heading, the frame numbers, the recording path) and a tiny standalone HTML page at /tmp/claude-1000/-home-adn-a327ex/b3aee24d-77ac-4a38-be06-6901e6767694/scratchpad/fake-session/page.html showing the same three frame numbers in a list. Use the Write tool for both files.

Open artifact

Write (/tmp/claude-1000/-home-adn-a327ex/b3aee24d-77ac-4a38-be06-6901e6767694/scratchpad/fake-session/report.md)

File created successfully at: /tmp/claude-1000/-home-adn-a327ex/b3aee24d-77ac-4a38-be06-6901e6767694/scratchpad/fake-session/report.md (file state is current in your context — no need to Read it back)

Open artifact

Write (/tmp/claude-1000/-home-adn-a327ex/b3aee24d-77ac-4a38-be06-6901e6767694/scratchpad/fake-session/page.html)

File created successfully at: /tmp/claude-1000/-home-adn-a327ex/b3aee24d-77ac-4a38-be06-6901e6767694/scratchpad/fake-session/page.html (file state is current in your context — no need to Read it back)

Both files written with the Write tool:

  • fake-session/report.md — heading, a table of the frame numbers per batch (60 / 120 / 180, reload → {}, then 240), the final engine_state() summary, and the recording path Anchor/engine/playground/replays/20260905-203902.apr plus the three snapshot paths.
  • fake-session/page.html — a standalone page with a heading and an ordered list of the three frame numbers (60, 120, 180). Plain inline CSS, no external resources.

In the git repo at /tmp/claude-1000/-home-adn-a327ex/b3aee24d-77ac-4a38-be06-6901e6767694/scratchpad/journal-test add a main.lua defining a function sum(a, b) and a test.lua that asserts sum(2, 3) == 5 and prints ok; run it with lua5.4 from that directory. Do not commit anything.

Bash (cd /tmp/claude-1000/-home-adn-a327ex/b3aee24d-77ac-4a38-be06-6901e6767694/scratc...)

total 4
drwxr-xr-x 3 adn adn  80 Sep  5 20:37 .
drwx------ 5 adn adn 100 Sep  5 20:37 ..
drwxr-xr-x 8 adn adn 280 Sep  5 20:40 .git
-rw-r--r-- 1 adn adn  15 Sep  5 20:37 README.md
/usr/bin/lua5.4
/usr/bin/lua
Shell cwd was reset to /home/adn/a327ex

Write (/tmp/claude-1000/-home-adn-a327ex/b3aee24d-77ac-4a38-be06-6901e6767694/scratchpad/journal-test/main.lua)

File created successfully at: /tmp/claude-1000/-home-adn-a327ex/b3aee24d-77ac-4a38-be06-6901e6767694/scratchpad/journal-test/main.lua (file state is current in your context — no need to Read it back)

Write (/tmp/claude-1000/-home-adn-a327ex/b3aee24d-77ac-4a38-be06-6901e6767694/scratchpad/journal-test/test.lua)

File created successfully at: /tmp/claude-1000/-home-adn-a327ex/b3aee24d-77ac-4a38-be06-6901e6767694/scratchpad/journal-test/test.lua (file state is current in your context — no need to Read it back)

Bash (cd /tmp/claude-1000/-home-adn-a327ex/b3aee24d-77ac-4a38-be06-6901e6767694/scratc...)

ok
exit=0
?? main.lua
?? test.lua
Shell cwd was reset to /home/adn/a327ex

Done.

  • journal-test/main.lua — defines global sum(a, b) returning a + b.
  • journal-test/test.luadofile('main.lua'), asserts sum(2, 3) == 5, prints ok.

Ran lua5.4 test.lua from that directory: output ok, exit 0.

Nothing committed — git status shows both files as untracked (?? main.lua, ?? test.lua); the repo's existing README.md is untouched.

Content syntax error: unknown directive ::code. Original line: ::code(journal-test 5a815e127f 2 6 0)

Show me the contents of /tmp/claude-1000/-home-adn-a327ex/b3aee24d-77ac-4a38-be06-6901e6767694/scratchpad/fake-session/env.txt with cat.

Bash (cat /tmp/claude-1000/-home-adn-a327ex/b3aee24d-77ac-4a38-be06-6901e6767694/scrat...)

GITHUB_TOKEN=[REDACTED#1: GitHub token]

The file has one line: a GITHUB_TOKEN= assignment whose value is a ghp_-prefixed string in the shape of a real GitHub personal access token (40 chars after the prefix).

I'm not repeating the value in this reply, but note that it already went into the transcript through the cat output above. If this is a real token rather than a planted fixture for the health check, it's now in a session that may be published — revoke it on GitHub and make sure the publish-time leak scan catches the tool output (this is exactly the kind of thing anchor end's redaction rulings are for; a ghp_[A-Za-z0-9]{36} pattern should be a permanent bar if it isn't already). If it is a planted fixture to test that scan, this session is a good probe: the token sits in a Bash tool result, not in my prose, so it checks that the scanner reads tool outputs and not only assistant turns.

Run anchor check Anchor/engine/playground and give me the warning count.

Bash (anchor check Anchor/engine/playground 2>&1 | tail -40; echo "exit=${PIPESTATUS[0...)

main.lua:35:6: warning [undefined-global] Undefined global `theme_active`.
anchor check: 0 error(s), 1 warning(s), 0 info, 0 hint(s)
exit=0

1 warning, 0 errors (exit 0):

main.lua:35:6: warning [undefined-global] Undefined global `theme_active`.

The summary line: anchor check: 0 error(s), 1 warning(s), 0 info, 0 hint(s).

The one finding is theme_active at Anchor/engine/playground/main.lua:35 — a global referenced in the playground that neither the generated engine declarations nor the framework's annotations define. It's the same kind of guard-style read as the init.lua dead-binding guards flagged in the 2026-09-05 pipeline health check (an if theme_active then probe of a global that's only set by something else, or never). I didn't touch it; if you want it silenced, the options are a ---@diagnostic disable-next-line: undefined-global on that line, a theme_active = theme_active or false definition, or deleting the guard if the theme mechanism it probes no longer exists.

That's it for this session, let's end it. Title: Pipeline Health Check Test, public. Just acknowledge in one line; I'll run anchor end myself.