07 · update-cursor-node
What this scenario proves
Updating Archon from one tagged version to the next must not overwrite runtime ledgers (drift.md, debt.md, memos.md, run/state files) and must update only the canonical files whose sha256 has changed.
Specifically:
- The agent fetches a new
manifest.jsonfromaaep.site(or a pinned?version=query for reproducibility). - It diffs the local files against the new sha256 list.
- It writes only changed files, keeping a
.bakfor any non-trivial overwrite. runtime_ledger_pathsfrom the manifest are read-only the entire time.- The
.archon/VERSIONfile moves to the new version exactly once, at the end, with original line endings preserved.
Test environment
| Fixture | output of scenario 01 + scenario 05 (i.e. has 1 real drift row) |
| IDE | Cursor |
| Manifest "from" version | v0.1.0 |
| Manifest "to" version | v0.1.1 (or any newer tag at run time) |
| OS | same as scenario 01 |
Pre-conditions
- Scenarios 01 + 05 both ✅.
git statusis clean — pending changes would obscure the diff.- A newer tagged manifest exists at
aaep.site/manifest.json?version=v0.1.1(or skip if not yet tagged — re-run when one ships).
Steps
text
1. In Cursor, paste exactly:
hi archon, update yourself
(URL-less; the wake rule routes this to the update protocol.)
2. The agent should:
- fetch the new manifest
- print a planned-changes table (file, old-sha, new-sha, action)
- ask for confirmation
3. Confirm.
4. Watch it write changed files + create .bak siblings for any
overwrite that isn't byte-identical to the prior canonical bytes.
5. Inspect `.archon/VERSION` — should match the new version.
6. Inspect `git diff` — only the planned files should appear changed.
7. Run `npm run validate` — should still be 0.Expected outcome
| Check | Expected |
|---|---|
| Agent prints a planned-changes table before writing | yes |
.archon/drift.md row count | unchanged (preserved) |
.archon/debt.md content | unchanged |
.archon/memos.md content | unchanged |
.archon/VERSION | matches the "to" manifest version |
python3 scripts/archon-check.py --root . exit code | 0 |
| Any Cursor commands / rules / skills file changed only when its sha256 differs from the new manifest | yes |
npm run validate exit code | 0 |
For each non-trivially overwritten file, a <file>.bak exists | yes (or all bak files cleaned per protocol — match whichever the protocol page specifies) |
Demo recordings
Recording coming soon
update-cursor-node.mp4IDE chat-panel walkthroughdocs/public/videos/update-cursor-node.mp4 once recorded. See videos/README for upload conventions. $ archon doctor .
[L1 Structural] OK
[L2 Contract] OK
[L3 Hints] OK
✔ Recording coming soon — placeholderdocs/public/asciinema/update-cursor-node.cast embedded via the asciinema-player web component. See asciinema/README for the recording command. Run records
The table below is rendered live from JSON written by the sandbox runner (scripts/sandbox-run.mjs) under docs/testing/sandbox/runs/update-cursor-node/. To add a new row, run
bash
node scripts/sandbox-run.mjs --only=update-cursor-node| Started (UTC) | Manifest | Runner | Result | Duration | Notes | Record |
|---|---|---|---|---|---|---|
2026-06-08 08:17:14 UTC | v0.1.0 | cli | ✅ passing | 351 ms | — | JSON |
2026-06-07 07:10:19 UTC | v0.1.0 | cli | ✅ passing | 347 ms | — | JSON |
2026-06-06 06:34:43 UTC | v0.1.0 | cli | ✅ passing | 367 ms | — | JSON |
2026-06-05 07:14:10 UTC | v0.1.0 | cli | ✅ passing | 356 ms | — | JSON |
2026-06-04 07:56:47 UTC | v0.1.0 | cli | ✅ passing | 358 ms | — | JSON |
2026-06-03 08:24:21 UTC | v0.1.0 | cli | ✅ passing | 364 ms | — | JSON |
2026-06-02 08:00:55 UTC | v0.1.0 | cli | ✅ passing | 356 ms | — | JSON |
2026-06-01 08:40:49 UTC | v0.1.0 | cli | ✅ passing | 360 ms | — | JSON |
2026-05-31 07:02:27 UTC | v0.1.0 | cli | ✅ passing | 348 ms | — | JSON |
2026-05-30 06:27:56 UTC | v0.1.0 | cli | ✅ passing | 348 ms | — | JSON |
2026-05-29 06:59:43 UTC | v0.1.0 | cli | ✅ passing | 353 ms | — | JSON |
2026-05-28 06:59:36 UTC | v0.1.0 | cli | ✅ passing | 356 ms | — | JSON |
2026-05-27 07:09:45 UTC | v0.1.0 | cli | ✅ passing | 367 ms | — | JSON |
2026-05-26 06:52:11 UTC | v0.1.0 | cli | ✅ passing | 316 ms | — | JSON |
2026-05-25 07:20:25 UTC | v0.1.0 | cli | ✅ passing | 346 ms | — | JSON |
2026-05-24 06:41:55 UTC | v0.1.0 | cli | ✅ passing | 361 ms | — | JSON |
2026-05-23 06:16:53 UTC | v0.1.0 | cli | ✅ passing | 340 ms | — | JSON |
2026-05-22 06:54:21 UTC | v0.1.0 | cli | ✅ passing | 353 ms | — | JSON |
2026-05-21 06:58:07 UTC | v0.1.0 | cli | ✅ passing | 346 ms | — | JSON |
2026-05-20 06:53:40 UTC | v0.1.0 | cli | ✅ passing | 345 ms | — | JSON |
2026-05-19 06:53:21 UTC | v0.1.0 | cli | ✅ passing | 345 ms | — | JSON |
2026-05-18 07:01:50 UTC | v0.1.0 | cli | ✅ passing | 374 ms | — | JSON |
2026-05-17 06:27:39 UTC | v0.1.0 | cli | ✅ passing | 354 ms | — | JSON |
2026-05-16 06:04:43 UTC | v0.1.0 | cli | ✅ passing | 347 ms | — | JSON |
2026-05-15 06:38:02 UTC | v0.1.0 | cli | ✅ passing | 352 ms | — | JSON |
2026-05-14 06:28:59 UTC | v0.1.0 | cli | ✅ passing | 352 ms | — | JSON |
2026-05-13 06:30:27 UTC | v0.1.0 | cli | ✅ passing | 332 ms | — | JSON |
2026-05-12 06:19:03 UTC | v0.1.0 | cli | ✅ passing | 347 ms | — | JSON |
2026-05-11 06:45:38 UTC | v0.1.0 | cli | ✅ passing | 319 ms | — | JSON |
2026-05-10 06:16:48 UTC | v0.1.0 | cli | ✅ passing | 368 ms | — | JSON |
2026-05-09 05:52:42 UTC | v0.1.0 | cli | ✅ passing | 331 ms | — | JSON |
2026-05-08 05:33:39 UTC | v0.1.0 | cli | ✅ passing | 381 ms | — | JSON |
2026-05-07 11:01:06 UTC | v0.1.0 | cli | ✅ passing | 330 ms | — | JSON |
2026-05-07 09:54:56 UTC | v0.1.0 | cli | ✅ passing | 345 ms | — | JSON |
2026-05-07 09:45:16 UTC | v0.1.0 | cli | ✅ passing | 394 ms | — | JSON |
2026-05-07 06:15:47 UTC | v0.1.0 | cli | ✅ passing | 348 ms | — | JSON |
2026-05-06 13:05:55 UTC | v0.1.0 | cli | ✅ passing | 387 ms | — | JSON |
2026-05-06 10:24:37 UTC | v0.1.0 | cli | ✅ passing | 353 ms | — | JSON |
2026-05-06 06:10:27 UTC | v0.1.0 | cli | ✅ passing | 366 ms | — | JSON |
2026-05-06 00:55:45 UTC | v0.1.0 | cli | ✅ passing | 351 ms | — | JSON |
2026-05-06 00:40:11 UTC | v0.1.0 | cli | ✅ passing | 373 ms | — | JSON |
2026-05-05 15:00:36 UTC | v0.1.0 | cli | ✅ passing | 314 ms | — | JSON |
2026-05-05 14:55:21 UTC | v0.1.0 | cli | ✅ passing | 374 ms | — | JSON |
2026-05-05 14:22:55 UTC | v0.1.0 | cli | ✅ passing | 366 ms | — | JSON |
2026-05-05 14:04:55 UTC | v0.1.0 | cli | ✅ passing | 363 ms | — | JSON |
2026-05-05 14:00:02 UTC | v0.1.0 | cli | ✅ passing | 375 ms | — | JSON |
2026-05-05 13:55:07 UTC | v0.1.0 | cli | ✅ passing | 369 ms | — | JSON |
Known limitations
- This scenario cannot be executed until at least two consecutive tagged manifest versions exist on
aaep.site. Until then the status stays ⏳ and the run record carries the "awaiting tag" note. - Does not test rollback. A separate
update-rollbackscenario can be added if/when rollback is part of the protocol.
Cross-references
- Protocol page:
/setup/update - Agent file:
https://aaep.site/update.md - Pre-requisite: 01 + 05
- Sibling: 08 update-cli-without-cli
json
{
"runnable": "cli",
"fixture": "fixtures/sandbox-node-ts",
"ide_platform": "cursor",
"prerequisites": [
{
"name": "archon install",
"cli": "install",
"flags": [
"--with=cli"
]
}
],
"steps": [
{
"name": "archon update (self-update)",
"cli": "update",
"flags": []
}
],
"assertions": [
{
"file_exists": ".archon/VERSION"
},
{
"file_exists": ".archon/soul.md"
},
{
"dir_exists": "tools/archon-cli"
}
],
"notes": "Same-version self-update (manifest only ships v0.1.0). Proves the update path is non-destructive. Extend when v0.2.0 ships to install a pinned older version first."
}