Repository navigation
docs: the compile and instance-lifecycle programs become state of record (#1707 #2193 #2550 #2802) - #3015
Conversation
…ord (#1707 #2193 #2550 #2802) Four maintainer-directed programs lived as issue threads. An audit measured each directive against the code rather than against the issue text, and the result is committed as two Architecture pages so the remaining work is pickable-up cold instead of re-derived. Several of the issues' own premises had gone stale and the corrections are recorded rather than dropped — notably that MeshWeaver.Cli is `memex`, a REST/docker CLI with no Roslyn in it, and is NOT the compiler tool; the compiler tool is packed from tools/MeshWeaver.PluginTester, and no CI lane consumes it. The findings worth acting on, all measured: * `Modules:RequirePrebuilt` — the adopt-only gate — is real and load-bearing and appears in ZERO config files, so "never fall back to compiling" is provided for and enforced nowhere. * The batch driver is reached only on a readiness-gated pod; a serving pod still compiles per-node, and the runtime DB-edit compile never reaches it. * A Store update does not rebuild its dependents: the mesh-wide closure exists and the package installer is not one of its two callers. That is the mechanism behind the 2026-08-25 Store outage. * The awaiting-setup flag is set and read by nothing, so an empty image now boots successfully into a portal that can do nothing and says nothing. Carried out here, because each is small, safe and self-contained: * Delete CompilationLock — a file lock with no caller, which could only ever have covered one shared filesystem and is async/Task.Delay-based, which the house rules forbid. It was not the #1706 work-lease and reading it as one sends you down a dead end. * The operator gate learns the direction that rots. It asked only "does every command the plan names exist?", which can fail only when a script is deleted; it was structurally blind to a script that SHIPS while no plan entry names it. hosting-kv-rotate had shipped, had zero tests and was absent from the list, so nothing in CI knew it existed. Every shipped hosting-* must now be claimed by the plan or declared not-yet-wired. * The tracked-file floor was stale at 19 (16 commands); 17 commands ship. * hosting-kv-rotate gets behaviour tests, including the one property whose failure is unrecoverable: it must never print the minted key. Asserted by mutation — making the script echo the key turns the test red. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SD7aiLSo59xng2TzU32xEa
There was a problem hiding this comment.
🟡 Changes recommended
The new hosting-kv-rotate dry-run test currently allows a false pass by accepting any output containing “would” instead of requiring the ::hosting:: key_hash= marker.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR converts several “program” issue threads into committed, measured state-of-record documentation pages, while also tightening the hosting-operator CI gate and adding behavioral tests around the new hosting-kv-rotate operator script.
Changes:
- Add two new Architecture documentation pages capturing the measured “state of record” for compile and instance-lifecycle programs.
- Remove an unused, async-based
CompilationLockimplementation from the compiler pipeline. - Strengthen the hosting-operator workflow and tests (including new
hosting-kv-rotatecoverage and a reverse-direction “unclaimed shipped scripts” gate).
File summaries
| File | Description |
|---|---|
| src/MeshWeaver.Documentation/Data/Architecture/InstanceLifecycleStateOfRecord.md | New state-of-record doc for instance setup + registry-key rotation program ownership/scope. |
| src/MeshWeaver.Documentation/Data/Architecture/CompileProgramStateOfRecord.md | New state-of-record doc for compile cleanup + baked-DLL program directives vs measured implementation. |
| src/MeshWeaver.Compiler.Pipeline/CompilationLock.cs | Deletes unused file-based async lock implementation. |
| deploy/aks/operator/test/run-tests.sh | Adds behavioral tests for hosting-kv-rotate, including leak-prevention checks. |
| .github/workflows/hosting-operator.yml | Enhances operator CI gate: updated tracked-file floor and detects shipped-but-unplanned commands. |
Review details
- Files reviewed: 5/5 changed files
- Comments generated: 1
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Test Results (shard 4)1 719 tests 1 719 ✅ 2m 3s ⏱️ Results for commit 4ef589a. ♻️ This comment has been updated with latest results. |
Test Results (shard 1)420 tests 420 ✅ 1m 27s ⏱️ Results for commit 4ef589a. ♻️ This comment has been updated with latest results. |
Test Results (shard 5) 3 files 3 suites 1m 21s ⏱️ Results for commit 4ef589a. ♻️ This comment has been updated with latest results. |
Test Results (shard 0)216 tests 216 ✅ 2m 21s ⏱️ Results for commit 4ef589a. ♻️ This comment has been updated with latest results. |
Test Results (shard 2)531 tests 529 ✅ 1m 33s ⏱️ Results for commit 4ef589a. ♻️ This comment has been updated with latest results. |
Test Results (shard 3)586 tests 586 ✅ 56s ⏱️ Results for commit 4ef589a. ♻️ This comment has been updated with latest results. |
Test Results 14 files 14 suites 9m 43s ⏱️ Results for commit 4ef589a. ♻️ This comment has been updated with latest results. |
From the automatic review on #3015, and it was right — the arm accepted the word "would", which a dry run prints unconditionally from its first step. So that assertion passed on every input, including a script that had stopped emitting `::hosting:: key_hash=` entirely. The control plane adopts that hash on the registry BEFORE the restart lands the new value in the pods, so losing it means the pods come up against a registry expecting the old key — exactly the regression the arm existed to catch. Now asserts the marker and nothing else. `hosting::say key_hash` sits outside the dry-run branch precisely so a rehearsal still reports it. Mutation-proven: replacing the emission with a no-op turns it red. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SD7aiLSo59xng2TzU32xEa
Closes #1707, #2193, #2550 and #2802 by converting them to committed state-of-record pages, per the maintainer's disposition for the programs bucket: document what is actually built, carry out the gaps that are genuinely carryable, close the issue.
A program that exists only as an issue thread is invisible to the next session and does not ship with the platform. These four were exactly that.
Method — measured, not read
Every row was measured against the code on 2026-09-01. Several of the issues' own premises had gone stale, and the corrections are recorded rather than silently dropped. The sharpest one:
What the audit found
Modules:RequirePrebuiltis real and load-bearing — it throws on the install lane, parks on the compile lane with a named reason and attempt count zero, and the execute-time gate refuses to arm a refused build. It appears in zero.json/.yaml/.yml/.shunderdeploy/ormemex/. So "never fall back to compiling" is architecturally provided for and enforced nowhere.ispattern-match on anobjectpayload — a trap-door that would silently select nothing, reaching the same outage more quietly.Carried out here
Each is small, safe and self-contained; anything larger is recorded instead.
1. Deleted
CompilationLock— a file lock with no caller anywhere. It could only ever have covered one shared filesystem, and it isasync/Task.Delay-based, which AGENTS.md forbids. It was not the #1706 work-lease, and reading it as one sends you down a dead end.internal sealed, so no in-mesh caller can reach it.2. The operator gate learns the direction that rots. It asked only "does every command the plan names exist?" — which can fail only when someone deletes a script. It was structurally blind to the opposite drift: a script that ships while no plan entry names it. Measured:
hosting-kv-rotatehad shipped, had zero behaviour tests, and was absent from the list, so nothing in CI knew it existed. Every shippedhosting-*must now be either claimed by the plan or declared not-yet-wired with a reason.Mutation-proven rather than asserted:
3. The tracked-file floor was stale at 19 files / "16 commands". 17 commands ship.
4.
hosting-kv-rotategets behaviour tests matching the existing idiom — required-flag refusals and two injection guards — plus the one property whose failure is unrecoverable: it must never print the minted key. A key that reaches a job log has been disclosed to everyone who can read Actions, and rotating again does not un-disclose it. The script's banner promises this; promises in comments are what this repo keeps discovering were never true.Mutation-proven — making the script echo the key turns it red:
The paired assertion matters too: a script that leaked nothing because it did nothing would pass the leak check, so the dry run must still report its work.
Verification
deploy/aks/operator/test/run-tests.sh: 72 passed, 0 failed, with all six newkv-rotatecases confirmed present in the output (not silently skipped).yaml.safe_load,bash -n).dotnet build -c Release -warnaserror:MeshWeaver.Compiler.PipelineandMeshWeaver.Documentation.Test— 0 Warning(s), 0 Error(s) each.MeshWeaver.Documentation.Test168 passed, 0 failed, includingDocumentationLinkIntegrityTest; every../Siblinglink in both new pages verified to resolve to a real file.Deliberately NOT done
The setup wizard GUI, the helm-chart relocation, a runner pool, and removing source from the mesh DB — all multi-repo or multi-week, and recorded precisely instead. One ordering hazard is called out so it is not discovered the hard way: verification compares a bundle's fingerprint against the live mesh source nodes, so removing source demotes every adoption from verified to unverified, which the execution gate permits — doing it before the adopt-only gate is enforced loses verification silently, with nothing red.
The Store-dependents cascade is a real bug rather than a program, and is not fixed here — it needs its own change with tests. It is written up with the fix shape and the payload-cast hazard so it can be picked up directly.
🤖 Generated with Claude Code
https://claude.ai/code/session_01SD7aiLSo59xng2TzU32xEa