docs(remediation): charter — Builds 1-2 justified by two independent impossibility proofs; RM-60 option analysis
Per Mos. The choke-point executor and PG spine are not a design preference — they are forced. Twice during the mission's own first deliveries, work stopped against a security property that cannot exist at the layer needing it: D-19 (audited party controls the manifest certifying it — artifact integrity) and D-25 (audited party controls the code entering the sandbox — execution integrity). Both reduce to self-verification by the audited party is not verification, and both resolve only via an authority outside its control. Neither proof was sought; both arrived while shipping something else, from different directions, at different layers. An architecture forced by two independent impossibility proofs is stronger evidence than one argued for. RM-60 records Mos's sharper option analysis: A (unprivileged userns) does NOT fix the vulnerability — it grants a capability and leaves the ORDERING defect untouched, so B is required regardless; A without B is kernel exposure bought for nothing. B is the correct primitive, generalises to RM-59 and the choke-point executor, and may not need A at all. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 5
parent
2b85afe4ea
commit
9a7ab73952
@@ -109,6 +109,31 @@ gate/program; the LLM handles only genuine judgment.
|
||||
| **4. Comms service** | AUTHORITY, INBOX (+ versioning roadmap) | Envelope (comms/v1) → sole-path service → PG/Redis → pluggable adapters (tmux→Matrix/Discord/Slack/Telegram). Version the protocol, not participants. |
|
||||
| **+ Hygiene & proof** | FLEET, WORKFLOW, CONFORMANCE | One roster-owned socket/host + stale GC; allowlist auto-sync; the conformance harness that fault-injects the failure classes and proves builds 1–4 hold. |
|
||||
|
||||
## Why Builds 1–2 are necessary — two independent impossibility proofs
|
||||
|
||||
**The choke-point executor and PG spine are not a design preference. They are forced.** Twice during
|
||||
the mission's own first deliveries, work stopped against a security property that **cannot exist** at
|
||||
the layer that needed it — and both times the only resolution was an authority _outside_ the audited
|
||||
party's control, which is precisely what Builds 1–2 provide.
|
||||
|
||||
| | the audited party controls… | so what fails | found as |
|
||||
| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------- | --------------- | -------- |
|
||||
| **Artifact integrity** | the manifest that certifies its own generated tree (same-UID write ⇒ regenerate manifest _and_ marker consistently, CWE-345) | tamper-evidence | **D-19** |
|
||||
| **Execution integrity** | the code that enters the sandbox (PR-controlled config executes _before_ the boundary exists) | isolation | **D-25** |
|
||||
|
||||
Both reduce to one sentence:
|
||||
|
||||
> **Self-verification by the audited party is not verification.**
|
||||
|
||||
And to one consequence: **the anchor must live outside the audited party's authority.** A local check
|
||||
cannot defend against an actor who can rewrite the check; a repo cannot grant a capability to
|
||||
PR-controlled config and simultaneously prevent that config from using it.
|
||||
|
||||
**An architecture forced by two independent impossibility proofs is stronger evidence than one argued
|
||||
for.** Neither proof was sought — both arrived while trying to ship something else, from different
|
||||
directions (a symlink manifest; a CI sandbox), at different layers. RM-59 and RM-60 are the two tracked
|
||||
dependencies this creates, and they are the same dependency in different clothes.
|
||||
|
||||
## The finding that sets the cost
|
||||
|
||||
**Built-but-unwired disease.** `@mosaicstack/macp` is stranded (nothing calls it); `packages/coord` primitives
|
||||
|
||||
+42
-13
@@ -117,6 +117,35 @@ layer (D-25). Not deferred for cost or effort; deferred because it is **impossib
|
||||
|
||||
**Unblocked by: RM-60.** Accepted by `mos-remediation`; independently ruled by `rev-974`.
|
||||
|
||||
### RM-60 — why option B, and why option A does not work even alone (Mos, 2026-08-01)
|
||||
|
||||
Recorded because the reasoning is easy to get backwards, and getting it backwards buys standing kernel
|
||||
exposure for nothing.
|
||||
|
||||
- **A (runner enables unprivileged user namespaces / rootless sandbox) DOES NOT FIX THE VULNERABILITY.**
|
||||
It makes a sandbox _possible_; it says nothing about **when** the boundary is established relative to
|
||||
PR-controlled code. **The defect is an ORDERING defect** — PR config executes before the boundary
|
||||
exists. A grants a capability and leaves the ordering untouched, so B would still be required to close
|
||||
it. **A without B is kernel exposure bought for nothing.**
|
||||
- **B (protected default-branch pipeline config, or an immutable trusted launcher) IS the missing
|
||||
thing.** A launcher established from **protected** configuration, outside the PR author's control,
|
||||
entering isolation _before_ any PR-controlled executable is evaluated — that is the pre-execution
|
||||
trust boundary, and it is the same "authority outside the audited party" that **D-19 and D-25 both
|
||||
prove mandatory**. It may not need A at all: a protected launcher can use whatever isolation the
|
||||
runner already supports.
|
||||
- **B generalises; A does not.** The protected-launcher pattern is what **RM-59** needs, and is a small
|
||||
instance of the **choke-point executor** the spine needs. A buys one narrow capability at a standing
|
||||
kernel-exposure cost.
|
||||
|
||||
**Therefore B is not the cautious choice — it is the correct primitive.** A is a workaround that does
|
||||
not work on its own.
|
||||
|
||||
**Status:** on Jason's board for a morning decision, with this reasoning, alongside the queue-guard item
|
||||
(D-23), cross-referenced to RM-59. **Deliberately not actioned overnight:** enabling runner namespace
|
||||
exposure or changing provider protected-pipeline posture is a host security-posture change belonging to
|
||||
infrastructure authority. Nothing is blocked meanwhile — RM-02's head is unprivileged and fail-closed,
|
||||
the privileged experiment stays uncommitted and out of branch history.
|
||||
|
||||
### D-25 — self-verification by the audited party, a second time, one layer down
|
||||
|
||||
RM-02's per-commit replay needs isolation. Docker denied Bubblewrap namespace creation; the obvious fix
|
||||
@@ -1015,19 +1044,19 @@ spread is itself information, and X1 says we calibrate on real merged PRs.
|
||||
|
||||
### P5 — Retirements, hygiene, conformance
|
||||
|
||||
| id | task | src | depends_on | est (S/O) | tier |
|
||||
| ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- | -------------------------------------- | ---------------- | ------ |
|
||||
| RM-50 | One roster-owned socket/host; quarantine unmanaged; **deterministic reaper for stale sessions AND dead-session disk scratch** (D-7) | O+S+live | RM-04 | 14K / 150K | sonnet |
|
||||
| RM-51 | Auto-sync **allowlist** (never auto-stage unknown paths) + worktree/lease isolation | O+S | RM-02 | 8K / 110K | sonnet |
|
||||
| RM-52 | Retire the Python controller + duplicate MACP islands (3 → 1) | O+S | RM-26, RM-27, RM-25, RM-28 | 14K / 110K | codex |
|
||||
| RM-53 | Flat-file orchestration → DB hard cutover, with rehearsed rollback artifact | O+S | RM-27, RM-30, RM-34, RM-29 | (in S-10) / 200K | opus |
|
||||
| RM-54 | Fleet-wide inert-gate audit against the RM-02 registry | O | RM-02 | — / 120K | sonnet |
|
||||
| RM-55 | **Conformance harness:** fault-inject the live failure classes on real artifacts | O+S | RM-35, RM-41, RM-53 | 18K / 260K | opus |
|
||||
| RM-56 | Retirement proof: CI asserts all three retirements are complete **and stay complete** | O | RM-52, RM-45, RM-53 | — / 90K | codex |
|
||||
| RM-57 | Operator cutover docs + activation proof; map all 15 decisions to evidence | S | RM-04, RM-36, RM-45, RM-55 | 6K / — | codex |
|
||||
| RM-60 | **External pre-execution trust boundary for CI** — protected default-branch pipeline config or an immutable trusted launcher that enters the sandbox **before** any PR-controlled executable/config is evaluated; unblocks isolated per-commit replay (RM02-REQ-10) | mos-remediation (D-25) | infra/provider authority (Mos + Jason) | 25K | opus |
|
||||
| RM-59 | **Close the D-19 residual risk** — generated-state verification anchored **outside** the worktree's authority (executor/spine-side attestation), retiring the same-UID self-authentication gap | mos-remediation (D-19) | RM-12, RM-21, RM-25 | 20K | opus |
|
||||
| RM-58 | **Mechanical pre-dispatch context reset** — the orchestrator resets a seat out-of-band and verifies it, rather than asking the agent to reset itself | mos-remediation (D-4) | RM-31, RM-50 | 8K | sonnet |
|
||||
| id | task | src | depends_on | est (S/O) | tier |
|
||||
| ----- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- | -------------------------------------- | ---------------- | ------ |
|
||||
| RM-50 | One roster-owned socket/host; quarantine unmanaged; **deterministic reaper for stale sessions AND dead-session disk scratch** (D-7) | O+S+live | RM-04 | 14K / 150K | sonnet |
|
||||
| RM-51 | Auto-sync **allowlist** (never auto-stage unknown paths) + worktree/lease isolation | O+S | RM-02 | 8K / 110K | sonnet |
|
||||
| RM-52 | Retire the Python controller + duplicate MACP islands (3 → 1) | O+S | RM-26, RM-27, RM-25, RM-28 | 14K / 110K | codex |
|
||||
| RM-53 | Flat-file orchestration → DB hard cutover, with rehearsed rollback artifact | O+S | RM-27, RM-30, RM-34, RM-29 | (in S-10) / 200K | opus |
|
||||
| RM-54 | Fleet-wide inert-gate audit against the RM-02 registry | O | RM-02 | — / 120K | sonnet |
|
||||
| RM-55 | **Conformance harness:** fault-inject the live failure classes on real artifacts | O+S | RM-35, RM-41, RM-53 | 18K / 260K | opus |
|
||||
| RM-56 | Retirement proof: CI asserts all three retirements are complete **and stay complete** | O | RM-52, RM-45, RM-53 | — / 90K | codex |
|
||||
| RM-57 | Operator cutover docs + activation proof; map all 15 decisions to evidence | S | RM-04, RM-36, RM-45, RM-55 | 6K / — | codex |
|
||||
| RM-60 | **External pre-execution trust boundary for CI (option B — the correct primitive, not the cautious one)** — protected default-branch pipeline config or an immutable trusted launcher that enters the sandbox **before** any PR-controlled executable/config is evaluated; unblocks isolated per-commit replay (RM02-REQ-10) | mos-remediation (D-25) | infra/provider authority (Mos + Jason) | 25K | opus |
|
||||
| RM-59 | **Close the D-19 residual risk** — generated-state verification anchored **outside** the worktree's authority (executor/spine-side attestation), retiring the same-UID self-authentication gap | mos-remediation (D-19) | RM-12, RM-21, RM-25 | 20K | opus |
|
||||
| RM-58 | **Mechanical pre-dispatch context reset** — the orchestrator resets a seat out-of-band and verifies it, rather than asking the agent to reset itself | mos-remediation (D-4) | RM-31, RM-50 | 8K | sonnet |
|
||||
|
||||
**Critical path:** `RM-01 → RM-02 → RM-10 → RM-11 → RM-12 → RM-21 → RM-23 → RM-31 → RM-33 → RM-34 → RM-53 → RM-55`.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user