Repository navigation
ci: check the Markdown the demo reads, on every change - #42
Conversation
A change to docs/ or examples/decisions/ skips make check and CI, but those files are the demo's record. A renamed heading broke 6 of the 14 golden questions and 2 eval tasks, and no check saw it. scripts/corpus-check.sh seeds a scratch record as make demo-ready does. It fails when: - a golden question or an eval task names no entry in the record; - the keywords of a golden question do not find its answer in the top 8; - act 11 does not find its two lists in README.md, or a list is empty. The new CI job, corpus, runs make corpus-check on every change. Each eval task now names its answer in `answers`. Act 11 takes the binary from AMEM. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Bhj4Ck4y5iwZUsjpgQx8A2
The check now scores act 7's recall suite, which moves to golden/platform.toml, with the answer "Trust and review" in place of the old heading. golden/acts.toml names the DR-19 and DR-22 entries that acts 4, 7 and 10 ask about. The text of each eval task's entries must match its expect; for asf-pressures, the number of table rows must. Act 11 must print every item of the two README lists. The seed writes to a file, so a crash fails the check. The eval answers name parts by title, not by number. The check seeds from DEMO_FROM, keeps non-ASCII text as it is, and removes its directory on a signal. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Bhj4Ck4y5iwZUsjpgQx8A2
There was a problem hiding this comment.
🟡 Changes recommended
The table check miscounts rows based on bold formatting, and the corpus check can pass despite failed writes that leave incomplete records.
2 open issues
What changed in this PR
This PR adds a CI check for Markdown that supplies the demo record and README lists. It also includes corrections from prerequisite PR #37.
Changes:
- Add
make corpus-checkand run it in CI, including on Markdown-only changes. - Check golden answers, keyword retrieval, eval answer text, and act 11 list output.
- Correct stale demo expectations, documentation, command names, and diagnostic text.
| File | Description |
|---|---|
| scripts/seed-corpus.py | Default to the amem command. |
| scripts/fetch-wslcsdk.test.sh | Correct the executable name in a comment. |
| scripts/fetch-wslcsdk.sh | Correct the executable name in usage text and comments. |
| scripts/docs-only.sh | Explain corpus checks in comments. |
| scripts/demo/lib.sh | Allow the AMEM binary override. |
| scripts/demo/7-platform.sh | Read the recall suite from TOML. |
| scripts/demo/10-moves.sh | Clarify that the export step writes a new note. |
| scripts/corpus-check.sh | Add corpus, eval, retrieval, and README checks. |
| README.md | Clarify gateway credentials and authentication modes. |
| PLAN.md | Distinguish historical measurements from current questions. |
| Makefile | Add the corpus-check target. |
| local/README.md | Correct launcher, gateway, handoff, and evaluation guidance. |
| images/harness/README.md | Correct image contents and binary location. |
| images/harness/Dockerfile | Correct image-description comments. |
| golden/platform.toml | Extract and correct act 7’s recall suite. |
| golden/docs.toml | Update stale questions, answers, and keywords. |
| golden/acts.toml | Add entry expectations for demo act questions. |
| evals/demo.toml | Add answer references and correct grading patterns. |
| docs/reference-stack.md | Separate planned architecture from current implementation. |
| docs/harness-containers.md | Correct Dependabot status. |
| docs/demo-narrative.md | Clarify historical results and export counts. |
| crates/wslc-api/src/dll.rs | Correct the executable name in DLL guidance. |
| crates/web/tests/reader_browser.rs | Correct the command name in test documentation. |
| crates/web/src/lib.rs | Correct launcher commands in documentation. |
| crates/sandbox/src/seatbelt.rs | Correct binary names in comments. |
| crates/sandbox/src/linux.rs | Correct relay command names in documentation. |
| crates/sandbox/src/lib.rs | Update harness documentation and generated comments. |
| crates/policy/src/lib.rs | Correct the init command in documentation. |
| crates/otel/Cargo.toml | Correct the binary name in package metadata. |
| crates/memory/tests/launch.rs | Correct command names in test comments. |
| crates/memory/src/wslc.rs | Clarify gateway diagnostics and command documentation. |
| crates/memory/src/wslc_api.rs | Correct command documentation and refresh guidance. |
| crates/memory/src/taps.rs | Correct tap command documentation and error guidance. |
| crates/memory/src/savings.rs | Correct the recall command in output. |
| crates/memory/src/main.rs | Correct command names in help, errors, and comments. |
| crates/memory/src/credentials.rs | Clarify gateway credential usage text. |
| crates/egress/src/lib.rs | Correct the usage command in documentation. |
| crates/client/src/lib.rs | Correct the serve command in documentation. |
| CONTRIBUTING.md | Correct the binary name and init example. |
| AGENTS.md | Document corpus checks and Markdown validation steps. |
| .github/workflows/image.yml | Correct the build-step name and explain binary staging. |
| .github/workflows/ci.yml | Add the corpus job without the docs-only skip condition. |
Review effort: Balanced
| answers = ["What the Foundation taught the design"] | ||
| # the number is not in the text: scripts/corpus-check.sh counts the lines of the answer | ||
| # entry that match `counts`, and checks `expect` against that count | ||
| counts = "^\\| \\*\\*" |
There was a problem hiding this comment.
Fixed in 1436c8e. counts now matches each table row that follows another row and is not the separator, so bold does not matter. On the table of part 10, the old pattern counted 6, and the new pattern counts 6. With a seventh row without bold, the old pattern counted 6 and the new pattern counts 7. With one row without bold, the old pattern counted 5 and the new pattern counts 6.
Posted by Claude on behalf of @sstriker
| cd "$here" | ||
|
|
||
| "$amem" --root "$root" init --owner human:demo:check --domain dom-demo >/dev/null | ||
| python3 scripts/seed-corpus.py --root "$root" --memory "$amem" "$@" >"$work/seed.txt" |
There was a problem hiding this comment.
Fixed in 1436c8e. seed-corpus.py has a --strict option. With it, the script fails when a write fails. corpus-check.sh uses it. I ran the check with an amem that fails the write of one section that no suite names. Before the change, the check exited 0. Now it exits 1 with "1 writes failed".
Posted by Claude on behalf of @sstriker
Copilot found two gaps. The asf-pressures pattern counted only rows with bold text, so a seventh row without bold was not counted. Now it counts each row that follows another row and is not the separator. The seed went on after a failed write and exited 0, so the check could pass on a partial record. Now seed-corpus.py has --strict, and the check uses it. With one failed write, the check exited 0 before this change and exits 1 now. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Bhj4Ck4y5iwZUsjpgQx8A2
# Conflicts: # .github/workflows/ci.yml # Makefile
Brings in what landed since the last merge (#37, #38, #41, #42, #39, #48 to #52, #54 to #56). Two conflicts: - Makefile .PHONY: keep corpus-check from main, and drop reader, which this branch removes. - crates/web/static/reader/dm_reader_bg.wasm: #49 built it again on main. This branch deletes it, because crates/web/build.rs builds it from the sources, the change of #49 included. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D5DyJNQBUKom7QzrdkqRHn
Brings in what landed since the last merge (#37, #38, #41, #42, #39, #48 to #52, #54 to #56). One conflict, in crates/server/src/lib.rs: #52 adds `last_stamp`, so that a write of this service is not dated before the one before it. This branch adds `Memory::for_request()`, a view that writes for the same session. The view now shares `last_stamp` with its session, as it shares the other state that is kept per session. New test: a_request_view_dates_its_writes_after_its_session_s_last_one. With a view that starts its own `last_stamp`, the write is dated at the clock, 30 s before the last stamp of the session, and the test fails. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D5DyJNQBUKom7QzrdkqRHn

Summary
This change depends on #37. Merge #37 first. Until then, this diff also shows the commits of #37.
scripts/docs-only.shlets a change to Markdown outsidecrates/andtaps/skip the build and the tests. But the demo reads some of that Markdown:scripts/seed-corpus.pyseeds the demo record fromdocs/andexamples/decisions/.golden/docs.toml, the recall suite of act 7, andevals/demo.tomlname entries of that record as answers.README.md.A rename of a heading, or an edit to a list, can break the demo, and no check finds it. #37 corrects seven golden answers and two eval tasks that broke in this way.
This change adds
make corpus-check(scripts/corpus-check.sh), and acorpusjob in CI that runs it. The job runs on every change, and also on a change to Markdown only. The check seeds a scratch record from$(DEMO_FROM), asmake demo-readydoes. It fails when:golden/docs.toml,golden/platform.tomlorgolden/acts.tomlnames no entry of the record;answers, or has noanswers;expect. Forasf-pressures, the check counts the data rows of the table (counts), and matchesexpectagainst that number;README.md;seed-corpus.py --strict).The check does not run a harness, so it does not show what a model answers.
Other changes:
golden/platform.toml, not from text in the script. Its third answer was "Trust, review", a heading that no longer exists. Now it is "Trust and review".golden/acts.tomlholds the questions that acts 4, 7 and 10 ask about DR-19 and DR-22.evals/demo.tomlhasanswers.scripts/eval.pyreads onlyid,promptandexpect, so it does not change.scripts/demo/lib.shtakes the binary fromAMEMwhen it is set, so the check can run act 11 with the binary it built.scripts/docs-only.shand a comment inci.ymlsay that thecorpusjob runs on a change to Markdown only.Tests
The check passes on this branch. I made each change below in a copy of the branch, and ran the check of the first version of this branch and the check of this version against it.
examples/decisions/DR-22-interchange-format.mddeletedgolden/acts.tomlnames no entry for the DR-22 questionS2changed toS4in DR-19dr19-spike,expectmatches no textdr19-decision,expectmatches no textasf-pressures,expectmatches no textdocs/with a byte that is not UTF-8UnicodeDecodeErrorgolden/platform.tomlnames no entry for that questionmaingolden/platform.tomlnames no entryasf-pressuresfails. The pattern before this version counted 6Earlier, the first version of this branch failed on
main's golden suite, on a stale eval answer, on tasks with noanswers, on a renamed README heading, and on an emptied list.Checks
make corpus-checkpasses: 104 entries from 9 files.golden/docs.toml: keywords 15 of 15, question 15 of 15, stripped 14 of 15.golden/platform.toml: 3 of 3 for each strategy. Evals: 4 of 4 tasks hold their answer. Act 11: 9 and 14 items, of 9 and 14.make checkpasses: 737 tests run, 737 passed.Adversarial pass
A fresh agent attacked the first version of this branch. The second commit corrects what it found:
DEMO_FROM.ci.ymlsaid that every job below it skips on a change to Markdown only.Two findings are not changed:
answersin the same change.CARGO_TARGET_DIRset, the target runs a binary fromtarget/. The other targets of the Makefile do the same. A change to all of them is a separate change.Copilot then found that
countscounted only rows with bold text, and that the seed went on after a failed write and exited 0. The last commit corrects both. No pass ran after the second or the last commit.Posted by Claude on behalf of @sstriker