Skip to content

Memory lowering, usage accounting, durable volumes, and a fail-closed daimon-bridge gate - #7

Merged
apresmoi merged 34 commits into
mainfrom
feat/operational-ecosystem
Aug 30, 2026
Merged

Memory lowering, usage accounting, durable volumes, and a fail-closed daimon-bridge gate#7
apresmoi merged 34 commits into
mainfrom
feat/operational-ecosystem

Conversation

@apresmoi

Copy link
Copy Markdown
Collaborator

What

Declared skills reach engines for the first time. They were written to workspace/skills/, which no CLI engine reads. Moltnet installs its own skill into .agents/skills/ and .codex/skills/; Spawnfile now matches for the daimon and pi runtimes. OpenClaw and PicoClaw were already correct — the bug was narrower than recorded. The daimon test derives its expectation from Moltnet's own layout function, so the two cannot drift.

Memory declarations are lowered into the Daimon runtime config, completing the wiring Daimon gained in noopolis/daimon#3. memoryOutcome is supported for a durably-mounted file-backed bank and honestly degraded otherwise — postgres, in-process stores, ephemeral persistence, or a second declared bank each degrade with a message naming the bank and the reason.

Emitter and mounter now share one durability authority, so the compile report cannot claim a transport the compiler never emitted.

A compile-time guard against colliding banks. Mneme derives its paths from the runtime home and discards the declared filename, so two banks in one directory silently become one physical store. This caught a real bug in examples/mixed-runtime-org: an agent's private sqlite bank and the team's shared json floor resolved to the same directory, so the agent's private memory was the team floor.

Usage accounting, end to end. spawnfile usage aggregates the Daimon ledger by agent and by provider, reading either a live container or — with --exported <dir> — a sealed run. Both rotation generations are read and exported.

Zero is distinguishable from unknown throughout: a maxBuffer overrun, timeout, or daemon failure surfaces as UNREADABLE and forces PARTIAL coverage rather than reading as empty. An exported run with no ledger renders , never $0 — a codex-only org legitimately writes nothing, and that is not evidence it cost nothing.

Durable volumes now survive redeploys. Memory and usage volume names folded in a fresh run id on every spawnfile up, so a redeployed organization silently started with an empty bank. Both are now exclusive-reattach. The tradeoff is deliberate: two concurrent runs of one project now fail with an occupancy error instead of silently getting separate empty banks, and durable-memory orgs cannot use the concurrent blue/green canary. The isolation being given up was isolation between two writers of a store that must not have two writers — Mneme's ledger is append-only single-writer and the usage ledger rotates by size.

A fail-closed daimon-bridge gate. specs/SURFACES.md promised "A release without daimon-bridge is rejected"; nothing implemented it. A daimon organization on a team network compiled clean, deployed, and died at container boot on a strict JSON decode. It now fails at compile with the missing capability named. Requires noopolis/moltnet#12 to be released before daimon orgs can compile at all.

The local Moltnet build works on macOS. The validator compared architecture only, never process.platform, and passed the build target as the host — making them identical by construction, so a GOOS=linux binary was exec'd on darwin and rejected as unprobeable.

Verification

3339 tests passing. The two remaining failures are Docker-dependent and reproduce identically at the baseline commit in a clean worktree.

Every change carries a failing-before test and a mutation check. The contract manifest is re-vendored with agents[].memory registered as consumed, and a new test verifies the vendored bytes against the pin — that check did not exist, which is why the digest had drifted silently.

@apresmoi
apresmoi merged commit 39f03a1 into main Aug 30, 2026
3 checks passed
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.

1 participant