Skip to content

docs: the compile and instance-lifecycle programs become state of record (#1707 #2193 #2550 #2802) - #3015

Merged
rbuergi merged 2 commits into
mainfrom
docs/program-state-of-record
Sep 1, 2026
Merged

rbuergi merged 2 commits into
mainfrom
docs/program-state-of-record

Conversation

@rbuergi

@rbuergi rbuergi commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

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:

🚨 src/MeshWeaver.Cli is NOT the compiler tool. Its ToolCommandName is memex, it operates the mesh over the REST API, and it contains no Roslyn — its build verbs docker run the tester image. The compiler tool (mw-compiler) is packed from tools/MeshWeaver.PluginTester, and no CI lane consumes it. Reasoning from the project name gets you the wrong answer; one audit of this program did exactly that.

What the audit found

  • The adopt-only gate is switched on nowhere. Modules:RequirePrebuilt is 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/.sh under deploy/ or memex/. So "never fall back to compiling" is architecturally provided for and enforced nowhere.
  • The batch driver is not the universal fallback. It is selected only when the pre-warmer gates readiness, so a serving pod keeps the activation-driven sweep, and the runtime DB-edit compile never reaches it at all.
  • 🚨 A Store update does not rebuild its dependents. The correct mesh-wide closure exists and has exactly two callers — neither is the package installer, which releases only the paths it wrote that are NodeType definitions, i.e. types inside the installed package. That is the mechanism behind the 2026-08-25 Store outage, where every Store NodeType recompiled green and the page still went down. The doc also flags that the installer selects those targets with an is pattern-match on an object payload — a trap-door that would silently select nothing, reaching the same outage more quietly.
  • The awaiting-setup flag is read by nothing. An empty image no longer throws — it marks the mesh awaiting setup and returns early with none of persistence, graph or the catalog wired, and nothing serves anything in its place. The boot now succeeds into a portal that can do nothing and says nothing about why, which is strictly worse than the exception it replaced.
  • The dangerous half of key rotation is done and correct — the script mints, stores with output suppressed, unsets, reports only the SHA-256, and waits on hashes rather than values. It deliberately does not restart or verify; that sequencing lives in a plan this repo does not contain, so core cannot prove the ordering. Stated rather than papered over.

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 is async/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-rotate had shipped, had zero behaviour tests, and was absent from the list, so nothing in CI knew it existed. Every shipped hosting-* must now be either claimed by the plan or declared not-yet-wired with a reason.

Mutation-proven rather than asserted:

-- with kv-rotate declared (expect <none>) --
unclaimed: <none>
-- mutation: declaration removed (expect hosting-kv-rotate) --
unclaimed: hosting-kv-rotate

3. The tracked-file floor was stale at 19 files / "16 commands". 17 commands ship.

4. hosting-kv-rotate gets 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:

=== MUTATION: make the script leak the key, the check must FAIL ===
  FAIL  kv-rotate never prints the minted key
--- restored ---
  ok    kv-rotate never prints the minted key

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 new kv-rotate cases confirmed present in the output (not silently skipped).
  • Both workflow and test scripts parse (yaml.safe_load, bash -n).
  • dotnet build -c Release -warnaserror: MeshWeaver.Compiler.Pipeline and MeshWeaver.Documentation.Test — 0 Warning(s), 0 Error(s) each.
  • Full project, not a filter: MeshWeaver.Documentation.Test 168 passed, 0 failed, including DocumentationLinkIntegrityTest; every ../Sibling link 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

…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
Copilot AI lite review requested due to automatic review settings September 1, 2026 19:58

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 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 CompilationLock implementation from the compiler pipeline.
  • Strengthen the hosting-operator workflow and tests (including new hosting-kv-rotate coverage 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.

Comment thread deploy/aks/operator/test/run-tests.sh
@github-actions

github-actions Bot commented Sep 1, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 4)

1 719 tests   1 719 ✅  2m 3s ⏱️
    3 suites      0 💤
    3 files        0 ❌

Results for commit 4ef589a.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Sep 1, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 1)

420 tests   420 ✅  1m 27s ⏱️
  1 suites    0 💤
  1 files      0 ❌

Results for commit 4ef589a.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Sep 1, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 5)

    3 files      3 suites   1m 21s ⏱️
1 220 tests 1 028 ✅ 192 💤 0 ❌
1 221 runs  1 029 ✅ 192 💤 0 ❌

Results for commit 4ef589a.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Sep 1, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 0)

216 tests   216 ✅  2m 21s ⏱️
  1 suites    0 💤
  1 files      0 ❌

Results for commit 4ef589a.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Sep 1, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 2)

531 tests   529 ✅  1m 33s ⏱️
  4 suites    2 💤
  4 files      0 ❌

Results for commit 4ef589a.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Sep 1, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 3)

586 tests   586 ✅  56s ⏱️
  2 suites    0 💤
  2 files      0 ❌

Results for commit 4ef589a.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Sep 1, 2026 •

Copy link
Copy Markdown
Contributor

Test Results

   14 files     14 suites   9m 43s ⏱️
4 692 tests 4 498 ✅ 194 💤 0 ❌
4 693 runs  4 499 ✅ 194 💤 0 ❌

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Compile cleanup: MeshWeaver.Compiler, dependency-scoped rebuilds, consume-prebuilt-everywhere (maintainer-directed)

2 participants