Satisfaction argument
This file is a projection over openspec/specs/, regenerated wholesale at archive time and never patched.
Its rows come only from the post-sync corpus, one per current requirement; discharge annotations for rows that predate the CAM-92 archive were carried over from the previous projection by capability and requirement title.
Discharge annotations come from the owning verification artifacts cited below, not from an agreement between configuration files.
The W ∧ S ⇒ R obligation is separate from implementation refinement and from an archive-ready behavioral verdict.
Nothing here is an end-to-end guarantee; OpenSpec structure checks are not behavioral validation.
Status
Section titled “Status”The post-sync corpus has 299 requirements across 29 capabilities: 246 requirement-side rows and 53 world-assumption rows.
152 requirement-side rows are discharged — 3 at narrow CAM-41 interface boundaries, 36 from CAM-68’s telemetry store slice, 26 from CAM-70’s fleet alerting slice, 14 from CAM-77’s shared reference tree, 31 from CAM-69’s dev-loop collection slice, 8 from CAM-71’s Linux fleet collection slice, 3 from CAM-76’s external watch of the alert path, 19 from CAM-73’s fleet dashboard, 10 from CAM-79’s browser relay delivery and 2 from CAM-72’s darwin collection slice; 94 remain undischarged, each with a follow-up reference.
Of those undischarged rows, 9 name world assumptions but no named specification-side discharge; 85 name neither.
The 53 world rows remain self-attested, not independently discharged; their monitoring/scenario truth is not re-proved by this projection.
A13 has real incident evidence, including CAM-59, but no new world-assumption audit is claimed here.
A29–A33 carry CAM-68’s first-activation and runtime monitoring evidence, A33 and A37–A42 carry CAM-70’s cutover and runtime observations, A34 and A35 carry CAM-77’s VM and post-deploy observations, A43–A49 carry CAM-69’s deployment and acceptance observations, A13, A37–A40, A42 and A50–A52 carry CAM-71’s deployment, acceptance and review observations, A33 and A53–A55 carry CAM-76’s acceptance observations, A31 and A56–A60 carry CAM-73’s container-test and deployment observations, A67 and A69 carry CAM-79’s observations on stibnite, A68 not yet observed, and A61–A66, A70 and A77 carry CAM-72’s acceptance observations on stibnite, each with its CAM-72 verify §8c status: A61 observed for its StartInterval half and not violated for its calendar half, whose coalescing at wake is not exercised, A62, A63, A65, A66 and A77 observed, A64 observed with daily counts that restated its range, and A70 observed and not violated; all are cited per row; that evidence monitors them and does not discharge them.
CAM-63 qualifications are load-bearing: GNOME reachability is amended to exclude live-niri display-manager restart (CAM-66, unrepaired); 8.2 no-history is a source-read-only method limitation, not discharged by evaluation; 8.3/8.4/8.5 are evaluation, not observation; 8.6 is declined under CAM-59; 8.7 is physical testing with same-boot positive/negative controls and whole-boot totals 1 requested / 1 entry. Task 8.1 would have caught the strand; the post-deploy checklist ordering itself caused the lockout inside niri. These behavioral dispositions do not manufacture named specification-side discharges.
Evidence and follow-up conventions
Section titled “Evidence and follow-up conventions”- CAM-41 evidence:
openspec/changes/archive/2026-09-02-integrate-mergify-stacked-landing/verify.md:105–111,185–191; qualifications W1–W6 at:31–50. - CAM-62 evidence/follow-ups:
openspec/changes/archive/2026-09-09-pyrite-never-sleep/verify.md§§7–8 andretrospective.md§6. - CAM-63 evidence/follow-ups:
openspec/changes/archive/2026-09-10-pyrite-niri-second-session/verify.md§§8,9.12 andretrospective.md§6. - CAM-68 evidence/follow-ups:
openspec/changes/archive/2026-10-18-stand-up-greptimedb-on-magnetite/verify.md§§8b,9.4,9.5,10,11,tasks.md§10 andretrospective.md§6. - CAM-70 evidence/follow-ups:
openspec/changes/archive/2026-10-21-stand-up-fleet-alerting/verify.md§§8b,9,10,11,tasks.md§10,review.mdandretrospective.md§6. - CAM-69 evidence/follow-ups:
openspec/changes/archive/2026-10-28-stand-up-devloop-collection/verify.md§§8b,9,10,11,tasks.md§10,review.mdandretrospective.md§6. - CAM-71 evidence/follow-ups:
openspec/changes/archive/2026-11-02-stand-up-linux-fleet-collection/verify.md§§8a,8b,8d,9,tasks.md§12,review.mdandretrospective.md§6. - CAM-76 evidence/follow-ups:
openspec/changes/archive/2026-11-05-watch-the-alert-path-externally/verify.md§§8a,8b,8d,9,10 andtasks.md§§4,6. - CAM-73 evidence/follow-ups:
openspec/changes/archive/2026-11-05-serve-the-fleet-dashboard/verify.md§§8a,8b,8d,9,10 andtasks.md§§4,6,7. - CAM-77 evidence/follow-ups:
openspec/changes/archive/2026-10-20-share-ghq-reference-tree/verify.md§§5,5a–5e,8b,tasks.md9.4 andretrospective.md§6. - CAM-79 evidence/follow-ups:
openspec/changes/archive/2026-11-05-deliver-omp-browser-relay/verify.md§§8a,8b,8d,9 and Addendum,tasks.md5.4 andretrospective.md§6; follow-up CAM-80. - CAM-72 evidence/follow-ups:
openspec/changes/archive/2026-11-08-stand-up-darwin-collection/verify.md§§8a,8b,8c,8d,9,10,tasks.md§11,review.mdandretrospective.md§6; follow-ups CAM-88 and the two new issues ofreview.mdF11 and F15, not yet filed. - CAM-92 evidence/follow-ups:
openspec/changes/archive/2026-11-08-resolve-a-restarted-kept-alive-jobs-failure/verify.md§§1,7,8a,8b,9 andtasks.md§§2,4,6; follow-up CAM-93, the nix daemon’s move to a release carrying NixOS/nix#16517 (design D4). evidence annotation follow-upmeans OpenSpec changeannotate-discharge-evidence(active or subsequently archived), not implicit acceptance.V-interfacemeans the CAM-63 retrospective §6 architecture decision: introduce named interface properties or explicitly decide the corpus discharge convention.V-vocabularymeans the next sole designation-table owner grounds world/shared terms and relocates machine predicates; CAM-63 verify §8 is agent-executed/non-blocking and NEVER validation.- Older capability strata remain inferred and not re-audited; CAM-41 declares its three additions interface, CAM-62/CAM-63 declare graphical-desktop-session behavioral; CAM-68 declares telemetry-store and host-metrics-collection behavioral and telemetry-store-interface interface; CAM-70 declares fleet-alerting behavioral and fleet-alerting-interface interface; CAM-77 declares shared-reference-tree behavioral and shared-reference-tree-interface interface; CAM-69 declares devloop-collection behavioral and devloop-collection-interface interface; CAM-71 declares fleet-ingress-interface interface; CAM-76 declares fleet-alerting behavioral and fleet-alerting-interface interface again; CAM-73 declares fleet-dashboard behavioral and fleet-dashboard-interface interface, and telemetry-store behavioral and telemetry-store-interface interface again; CAM-79 declares browser-relay-delivery behavioral and browser-relay-delivery-interface interface; CAM-72 declares devloop-collection, fleet-alerting and host-metrics-collection behavioral and devloop-collection-interface, fleet-alerting-interface, fleet-ingress-interface and telemetry-store-interface interface.
- Every capability section cites the authoritative main-spec path; row order and titles are derived from that file.
agentic-workflow-routing
Section titled “agentic-workflow-routing”Source: openspec/specs/agentic-workflow-routing/spec.md.
| Requirement | Stratum | Discharged by (S) | Under (W) | Status |
|---|---|---|---|---|
| Unified seven-state Linear-canonical board | interface | — | — | undischarged — evidence annotation follow-up |
| In Review decomposes into two ordered human-steered sub-gates | interface | — | — | undischarged — evidence annotation follow-up |
| Shared re-queue with bounded-retries termination guarantee | interface | — | — | undischarged — evidence annotation follow-up |
| AFK, HIL, and Manual execution-mode fork at the Todo to In Progress boundary | interface | — | — | undischarged — evidence annotation follow-up |
| Compose by delegation, never re-implement | interface | — | — | undischarged — evidence annotation follow-up |
| HIL apply-phase jj and worktree isolation guidance | interface | — | — | undischarged — evidence annotation follow-up |
apple-laptop-hardware-support
Section titled “apple-laptop-hardware-support”Source: openspec/specs/apple-laptop-hardware-support/spec.md.
| Requirement | Stratum | Discharged by (S) | Under (W) | Status |
|---|---|---|---|---|
| The pyrite host module imports the upstream model profile with its unwanted firmware pulls disabled | behavioral | — | — | undischarged — evidence annotation follow-up |
| The machine module states its firmware affirmations rather than inheriting them | behavioral | — | — | undischarged — evidence annotation follow-up |
| The stage-1 initrd force-loads the four SPI/SMC modules that make the unlock prompt answerable | behavioral | — | — | undischarged — evidence annotation follow-up |
| boot.initrd.kernelModules is never overridden with mkForce | behavioral | — | — | undischarged — evidence annotation follow-up |
| A USB-C keyboard and the clan-vars passphrase are prerequisites of the first boot, not recoveries improvised afterward | behavioral | — | — | undischarged — evidence annotation follow-up |
| The machine’s configuration is never seeded from nixos-generate-config | behavioral | — | — | undischarged — evidence annotation follow-up |
| The sleep path is gated by three units the machine module defines itself | behavioral | — | — | undischarged — evidence annotation follow-up |
| Suspend is entered through the systemd-sleep path and resumes with the pool intact | behavioral | — | — | undischarged — evidence annotation follow-up; contradicted in part by CAM-59, see CAM-62 qualifications |
| A panic that outlives the disk is recorded through EFI pstore, because every other channel is unavailable on this machine | behavioral | — | — | undischarged — evidence annotation follow-up |
bare-metal-install-path
Section titled “bare-metal-install-path”Source: openspec/specs/bare-metal-install-path/spec.md.
| Requirement | Stratum | Discharged by (S) | Under (W) | Status |
|---|---|---|---|---|
| The install path is recorded in the repository, and is written to be re-runnable without being shown to be | behavioral | — | — | undischarged — evidence annotation follow-up |
| An install is accepted as evidence only if it exercised the create path | behavioral | — | — | undischarged — evidence annotation follow-up |
| The hardware report is committed as static data and never regenerated on the target | behavioral | — | — | undischarged — evidence annotation follow-up |
| The machine is registered across every hand-maintained list a new machine touches | behavioral | — | — | undischarged — evidence annotation follow-up |
| Network association is declarative, and the credentials are sops-encrypted clan vars | behavioral | — | — | undischarged — evidence annotation follow-up |
| ZeroTier admission requires redeploying the controller | behavioral | — | — | undischarged — evidence annotation follow-up |
| A FIDO2 token is verified present before each enrollment, and disko’s own guard is never that verification | behavioral | — | — | undischarged — evidence annotation follow-up |
browser-relay-delivery-interface
Section titled “browser-relay-delivery-interface”Source: openspec/specs/browser-relay-delivery-interface/spec.md.
| Requirement | Stratum | Discharged by (S) | Under (W) | Status |
|---|---|---|---|---|
| The extension package is omp’s own install output for the deployed omp release | interface | package-omp-browser-relay-extension with its build-time stamp check and the 0.0.0 stamp mutant; nix build --rebuild and an empty diff -r against upstream’s v18.16.0 zip (tasks 1.1, 1.2, 4.1) | — | discharged at package-check interface; CAM-79 verify §8b, §9.1 |
| Activation leaves a real, account-writable extension folder holding exactly the package | interface | the symlinked-folder refusal in a test activation; the post-activation inspection on stibnite: test -L fails, realpath is the folder’s own path, diff -r against the package is empty, every file u+w (tasks 2.1, 5.1) | — | discharged at observed interface; the drop-a-file scenario was not exercised on stibnite; CAM-79 verify §8b, §9.1, §9.2 |
| The extension folder is delivered by default on darwin only | interface | evaluation of the option and the activation step for crs58@aarch64-darwin and every x86_64-linux home in the checks (tasks 2.1, 6.2) | — | discharged at evaluation; CAM-79 verify §8b, §9.1 |
| omp’s managed configuration leaves the relay off by default | interface | programs.omp.settings evaluates .browser.relay to null (task 2.2) | — | discharged at evaluation; CAM-79 verify §8b |
| The fleet sets no Helium extension or debugger policy | interface | stibnite’s net.imput.helium defaults carry none of the listed keys and no configuration profile is declared (task 2.3) | — | discharged at evaluation; CAM-79 verify §8b |
| Trust boundary of the delivery interface | interface | the requirement’s own statement | world-assumptions A67, A68, A69 | discharged by statement; browser-side claims are cited as runtime observation; CAM-79 verify §8b, §8d |
browser-relay-delivery
Section titled “browser-relay-delivery”Source: openspec/specs/browser-relay-delivery/spec.md.
| Requirement | Stratum | Discharged by (S) | Under (W) | Status |
|---|---|---|---|---|
| The relay extension is present for every account that runs the agent on a macOS host | behavioral | Activation leaves a real, account-writable extension folder holding exactly the package; The extension folder is delivered by default on darwin only | world-assumptions A69 | discharged — CAM-79 verify §8b; observed for crs58 on stibnite after the 2026-11-05 activation (tasks 5.1, 6.2); no other darwin host activated |
| Each browser profile loads the relay extension once | behavioral | Activation leaves a real, account-writable extension folder holding exactly the package | world-assumptions A67 | discharged — CAM-79 verify §8b; one load in the one profile in scope, sciexp, under the extension ID predicted from the folder’s path (tasks 5.2, 6.1, rescoped by the person’s decision); identity across a later release not yet observed (CAM-80) |
| The loaded relay extension follows the agent release without being reloaded by hand | behavioral | — | world-assumptions A67, A68, A69 | undischarged — task 5.4 stays open until the first llm-agents omp bump deployed to stibnite; archived undischarged by the person’s decision; follow-up CAM-80 |
| An agent drives the person’s browser only when a request asks for it | behavioral | omp's managed configuration leaves the relay off by default | — (rests on omp) | discharged — CAM-79 verify §8b; observed once each way on 2026-11-05: app.relay: true drove a Helium tab, a request without it opened on omp’s headless browser (task 5.3) |
| The fleet leaves every browser profile’s extensions to the person | behavioral | The fleet sets no Helium extension or debugger policy | — | discharged — CAM-79 verify §8b; at evaluation (task 2.3) |
devloop-collection-interface
Section titled “devloop-collection-interface”Source: openspec/specs/devloop-collection-interface/spec.md.
| Requirement | Stratum | Discharged by (S) | Under (W) | Status |
|---|---|---|---|---|
| The collector reads nixbot’s builds and attributes through two cursor queries | interface | delivered queries equal to the evaluated ones; EXPLAIN ANALYZE with the live cursor; backfill to nixbot’s counts (tasks 2.6, 3.2, 7.4) | world-assumptions A43, A47 | discharged — CAM-69 verify §8b, §9.6 |
| Each nixbot query re-reads a five-minute overlap in pages of 10,000 rows | interface | overlap fixtures and devloop-ingest case; widest finished_at tie of 106 rows; a restart re-sent no backfill (tasks 2.5, 2.6, 7.4) | — | discharged — CAM-69 verify §8b, §9.6 |
| Each nixbot query returns only allow-listed columns as text | interface | devloop-queries error-cell clause rejecting selectError and errorUnderAlias (tasks 2.5, 2.6, 10.3) | — | discharged — CAM-69 verify §8b, §11.1 |
| The attribute query derives abandoned from the shared marker | interface | marker fixtures and clause; abandoned only for the marker in devloop-ingest (tasks 2.5, 2.6) | — | discharged — CAM-69 verify §8b |
| The nixbot readers authenticate by peer and hold column grants only | interface | devloop-queries reduced-grant mutant; both roles read by peer on magnetite (tasks 2.6, 3.1, 4.1) | world-assumptions A45 | discharged — CAM-69 verify §8b, §9.6 |
| Column grants are applied once nixbot’s columns exist | interface | devloop-pg-grants ordered after nixbot.service and active on magnetite; its drvPath unchanged by the F2 wording fix (tasks 3.1, 7.4, 10.1) | — | discharged — CAM-69 verify §8b, §9.6, §11.1; amended by #3564 |
| gitea-mq’s five batch messages are parsed from its journal | interface | parser mutant rejected; per-msg counts equal on magnetite after #3560 (tasks 3.3, 4.6, 7.4) | world-assumptions A44 | discharged — CAM-69 verify §8b, §9.6; the first observation failed (282 of 772 lines) and #3560 fixed it, §12.1 |
| The collector’s journal read is asserted | interface | journalGroupCleared override fails with the assertion’s message (task 3.7) | — | discharged — CAM-69 verify §8b |
| Each activation appends one deploy record | interface | script cases; devloop-ingest switch case; D1’s one line with the replaced closure; the boot line (tasks 1.3, 3.9, 7.1, 7.2) | world-assumptions A49 | discharged — CAM-69 verify §8b, §9.3, §9.4 |
| Each agent host’s collector ships its own deploy records | interface | deployRecordOtherPath rejected by C6 and C7; deploy_record sent 3, stored 3; C6 and C7 ok daily (tasks 3.4, 4.6); CAM-71: fleet-ingress delivery case; deploy-record lines equal rows on magnetite, cinnabar and pyrite (tasks 2.7, 3.4, 4.6, 5.4, 11.1); CAM-72: the darwin agent’s logs/devloop-deploy_record pipeline from file_log/deploy-record to otlp_http/ingress-logs with ok: validate agent; stibnite’s 14 rows for its file’s 14 lines (tasks 2.7, 5.3) | world-assumptions A65 | discharged — CAM-69 verify §8b, §9.6, §10.4; amended and renamed by CAM-71 verify §8b, §9.3; amended by CAM-72 verify §8b (configured, and observed on stibnite at 2026-11-06T05:20Z) |
| The devloop tables are pre-created with keys, a time index and deduplication | interface | pre-D2 compile check on GreptimeDB 1.2.1; SHOW CREATE TABLE of the four tables; count(*) equal to distinct keys (tasks 2.2, 2.4, 2.7, 3.9, 7.3) | world-assumptions A46 | discharged — CAM-69 verify §8b, §9.5, §9.6 |
| Each devloop table has an ingest pipeline that keeps only its allow-listed fields | interface | tableShape and pipelineWithoutFlaky rejected by C5; the four pipelines on magnetite (tasks 2.2, 2.7, 3.9) | — | discharged — CAM-69 verify §8b, §9.5 |
| One devloop allow-list decides every stored column | interface | evaluated allow-list; DESC TABLE against the list (tasks 2.1, 3.9) | — | discharged — CAM-69 verify §8b |
| Dev-loop sources are stamped and routed to their table | interface | R3.1 mutants logsToFleet, logsToMetricsExporter, otlpInLogsPipeline and logsQueueNotPersistent; every exporter at send_failed=0 (tasks 3.5, 3.6); CAM-71: R3.1 with otlpInLogsPipeline rejected; an agent’s logs/devloop-deploy_record exporting to otlp_http/ingress-logs (tasks 2.5, 2.7) | — | discharged — CAM-69 verify §8b, §9.6; amended by CAM-71 verify §8b |
| devloop-reconcile runs daily as its own reader | interface | R8.2 fourthRegulatorHolder override rejected; notified units; memory peaks of 11.5–20 MB against 128M; OOMScoreAdjust=0 after REVC (tasks 4.3, 4.4, 7.5, 10.6) | — | discharged — CAM-69 verify §8b, §9.7, §11.1; amended by #3564 |
| devloop-reconcile compares CI rows with nixbot every day | interface | C1 and C2 mutants and the restarted-build leg, red then green (tasks 4.2, 4.6, 10.2) | — | discharged — CAM-69 verify §8b, §11.1; amended by #3564 |
| devloop-reconcile compares batch events with the journal every day | interface | C3, C4 and C5 mutants rejected (tasks 4.2, 4.6) | world-assumptions A48 | discharged — CAM-69 verify §8b, §10.4 |
| devloop-reconcile compares deploy records with the file and the current system | interface | deployRecordOtherPath and snippetSwapsClosures rejected (tasks 4.2, 4.6) | — | discharged — CAM-69 verify §8b, §10.4 |
| devloop-queries binds the export queries to nixbot’s migrations | interface | lexically applied migrations equal to magnetite’s schema dump; PostgreSQL-major assertion failing under a PostgreSQL 17 override; reconcile queries run as devloop-reconcile (tasks 2.6, 4.1) | — | discharged — CAM-69 verify §8b, §9.2 |
| devloop-queries binds the abandonment marker to the patch’s production code | interface | the one marker clause; its evaluation cost (tasks 2.6, 10.4) | — | discharged — CAM-69 verify §8b, §9.1, §11.1; amended by #3564 |
| The x86_64-linux NixOS machine checks carry the deploy-record snippet | interface | the obligation failing for an emptied entry and another host’s script on magnetite and for an emptied postActivation on stibnite; each configuration’s activation running its own script (tasks 1.4, 1.5) | — | discharged — CAM-69 verify §8b; held by CI on the five x86_64-linux NixOS machine checks only; the four darwin machines and scheelite shown once by evaluation |
| devloop-ingest shows the collection path and the reconcile able to fail | interface | the devloop-ingest runs of tasks 3.9, 4.6, 5.6 and 10.7 | — | discharged — CAM-69 verify §8b, §11.1; the switch case takes its recorded fallback in the container |
| This capability states its own trust boundary | interface | the requirement’s own statement; no regulator applies; CAM-71: the amended statement (task 10.1); CAM-72: the amended statement (task 9.1) | — | discharged by statement — CAM-69 verify §8b; amended by CAM-71 verify §8b, §8d; amended by CAM-72 verify §8b, §8d |
devloop-collection
Section titled “devloop-collection”Source: openspec/specs/devloop-collection/spec.md.
| Requirement | Stratum | Discharged by (S) | Under (W) | Status |
|---|---|---|---|---|
| Every dev-loop event is recorded once and kept for a year | behavioral | The collector reads nixbot's builds and attributes through two cursor queries; gitea-mq's five batch messages are parsed from its journal; Each activation appends one deploy record; Each agent host's collector ships its own deploy records; The devloop tables are pre-created with keys, a time index and deduplication; Dev-loop sources are stamped and routed to their table | world-assumptions A43, A44, A46, A47, A65 | discharged — CAM-69 verify §8b, §9.6, §9.9, §10.4; the year’s retention is shown by the devloop TTL, not by a year of data; amended by CAM-71 verify §8b, §9.3 (deploy-record rows equal lines on magnetite, cinnabar and pyrite, task 11.1); amended by CAM-72 verify §8b (stibnite’s deploy_record rows equal its file’s 14 lines at 2026-11-06T05:20Z, task 5.3) |
| A gap in the dev-loop history reaches a person within a day | behavioral | devloop-reconcile runs daily as its own reader; devloop-reconcile compares CI rows with nixbot every day; devloop-reconcile compares batch events with the journal every day; devloop-reconcile compares deploy records with the file and the current system; Failure notices are posted to one topic | world-assumptions A33, A43, A48 | discharged — CAM-69 verify §8b, §9.7, §10.4; amended by CAM-71 verify §8b (the scheduled reconcile passing after the receiver moved, task 4.6) |
| No error text, message body or other free text enters the dev-loop history | behavioral | One devloop allow-list decides every stored column; The devloop tables are pre-created with keys, a time index and deduplication; Ingest is OTLP over HTTP with a database header | — | discharged — CAM-69 verify §8b, §9.5 |
| The past week of the dev loop can be asked about | behavioral | The devloop tables are pre-created with keys, a time index and deduplication; The collector reads nixbot's builds and attributes through two cursor queries | world-assumptions A43, A44 | discharged — CAM-69 verify §8b, §9.9 |
| A deploy can be attributed to the commits that built it | behavioral | Each activation appends one deploy record; The x86_64-linux NixOS machine checks carry the deploy-record snippet | world-assumptions A49 | discharged — CAM-69 verify §8b, §9.3, §9.9, §10.3; on magnetite only, the other nine machines carry the snippet and are not collected in S2 |
| The build service’s records are read without being changed and without a stored credential | behavioral | The nixbot readers authenticate by peer and hold column grants only | world-assumptions A45 | discharged — CAM-69 verify §8b, §9.6 |
encrypted-zfs-root
Section titled “encrypted-zfs-root”Source: openspec/specs/encrypted-zfs-root/spec.md.
| Requirement | Stratum | Discharged by (S) | Under (W) | Status |
|---|---|---|---|---|
| The root is a ZFS pool created with an explicit ashift matching the disk’s 4096-byte sectors | behavioral | — | — | undischarged — evidence annotation follow-up |
| The ESP is typed EF00 and sized 1G | behavioral | — | — | undischarged — evidence annotation follow-up |
| A sibling partition carries the ZFS content that becomes the pool’s vdev | behavioral | — | — | undischarged — evidence annotation follow-up |
| The pool device is named by a namespace-explicit by-id path | behavioral | — | — | undischarged — evidence annotation follow-up |
| The pool sits inside a LUKS2 container holding the clan-vars passphrase in slot 0 and a FIDO2 token in each of slots 1 and 2 | behavioral | — | — | undischarged — evidence annotation follow-up |
| The costs and the gains of the LUKS layer are both recorded rather than discovered later | behavioral | — | — | undischarged — evidence annotation follow-up |
| The LUKS header and the keyslot inventory are maintained artifacts, not install-time byproducts | behavioral | — | — | undischarged — evidence annotation follow-up |
first-party-skill-distribution
Section titled “first-party-skill-distribution”Source: openspec/specs/first-party-skill-distribution/spec.md.
| Requirement | Stratum | Discharged by (S) | Under (W) | Status |
|---|---|---|---|---|
| Build-time apm composition of first-party skills | interface | — | — | undischarged — CAM-41 verify W1/W2 canonical reconciliation follow-up |
| Immutable delivery and always-succeeds activation | interface | — | — | undischarged — evidence annotation follow-up |
| Flat skill name preservation | interface | — | — | undischarged — CAM-41 verify W3 canonical reconciliation follow-up |
| Distinct first-party policy and upstream mechanism skills | interface | .#apm-skills-compose; pinned-source byte comparison; first-party policy, ownership and VCS sections | — | discharged at two-target Nix composition interface; CAM-41 verify §9b |
fleet-alerting-interface
Section titled “fleet-alerting-interface”Source: openspec/specs/fleet-alerting-interface/spec.md.
| Requirement | Stratum | Discharged by (S) | Under (W) | Status |
|---|---|---|---|---|
| The evaluator queries each rule’s database as the regulators’ store account | interface | R8.2 holder assertion with its mutant; fixture-server refusal leg; first run on magnetite (tasks 4.3, 4.8); CAM-69: R8.2 admitting devloop-reconcile; two-database leg with its fleet-only mutant; 15 PromQL and 1 SQL query per run on magnetite (tasks 4.4, 5.3, 5.4, 5.5, 7.6); CAM-71: first run after the rules change; a fifth regulator-password holder rejected (tasks 6.6, 7.3); CAM-72: 31 queries a run, 16 presence selectors, 14 PromQL and 1 SQL, as regulator, with no StoreQueryFailing and a run of 3.3 s (task 6.5) | — | discharged at regulator and runtime interfaces; CAM-70 verify §8b, §9.3; amended and renamed by CAM-69 verify §8b, §9.8; amended by CAM-71 verify §8b; amended by CAM-72 verify §8b (observed from 2026-11-06T15:48:26Z) |
| Alert rules are rendered from one Nix source to the evaluator and to promtool | interface | promtool pass with the malformedExpression mutant; fixture legs on the rendered rules; a forced condition for each shipped rule (tasks 4.1, 4.5, 7.6, 10.10); CAM-69: PullRequestQueueWaitBurn rendered to the evaluator only, SUCCESS: 7 rules found (task 5.2); CAM-71: fleetAlertRules red without notifiedUnits, then green; SUCCESS: 11 rules found (tasks 2.8, 6.3); CAM-72: promtool 15 rules; keptAliveUnloaded red, then green, with notRunningBothArms rejected (tasks 6.3, 8.3, 8.3a); CAM-92: keptAliveRestarted red, then green with keptAliveCrashed and notKeptAliveHeld, failedIgnoresLaunch rejected, and the delivered two-arm expression equal to the one measured on the store (tasks 1.1, 2.1, 2.2, 6.1) | — | discharged at regulator and runtime interfaces; CAM-70 verify §8b, §9.7; amended by CAM-69 verify §8b; amended by CAM-71 verify §8b; amended by CAM-72 verify §8b (configured, and observed at 8.3a’s rerun); amended by CAM-92 verify §8b (configured and observed) |
| Alert instance state is kept in one state file and posted once per transition | interface | fixture sequence with noStateWrite and forZero; property test against model.py (tasks 4.2, 4.6) | — | discharged at regulator interface; CAM-70 verify §8b |
| Store errors and silent hosts freeze instance state | interface | store-error and silent-host legs with noStoreFreeze and noAbsenceFreeze; thaw legs and property (tasks 4.2, 10.1); CAM-69: per-database freeze legs with allDatabasesFreeze (tasks 5.1, 5.4, 10.5); CAM-72: pendingAcrossFreeze and pendingAfterWake red, then green, with the property test passing; no post naming stibnite across 8.6’s sleep (tasks 3.5, 3.6, 8.6) | world-assumptions A61, A64 | discharged at regulator interface; CAM-70 verify §8b, §11.1; amended by CAM-69 verify §8b, §11.1; amended by CAM-72 verify §8b (observed across 8.6’s sleep) |
| Each rule’s presence selector is watched | interface | both signal-gap legs; misspelt-selector control on magnetite (tasks 4.1, 7.2); CAM-71: legs red before the rules change; the unfiltered-selector mutants; the stored signals read on magnetite (tasks 6.2, 6.3, 6.7); CAM-72: linuxSelectorDarwinOnly red with seven posts, then green; stibniteNotCollecting, darwinSignalMissing and nvmeExpectsStibnite (tasks 3.7, 6.2, 6.3) | — | discharged at regulator and runtime interfaces; CAM-70 verify §8b, §9.3; amended by CAM-71 verify §8b; amended by CAM-72 verify §8b (configured, and no RuleSignalMissing from 2026-11-06T15:48Z to 21:27Z) |
| An always-on host’s silence is reported | interface | always-on-host leg with the noHostsUpdate mutant (task 10.2); CAM-71: cinnabarSilentLeg and laptopSilentLeg; [FIRING] and [RESOLVED] RuleSignalMissing cinnabar on magnetite’s evaluator; pyrite offline without an alert (tasks 5.6, 6.2, 6.3, 9.2) | — | discharged at regulator interface by check only; CAM-70 verify §8b, §11.2; added by #3516; amended by CAM-71 verify §8b; observed at runtime on cinnabar and pyrite (§9.2) |
| Alerts are posted to fleet-alerts with a title and a severity priority | interface | fixture server’s recorded posts, including the host-less titles; runtime titles and priorities (tasks 4.3, 10.7, 10.9); CAM-69: [FIRING] StoreQueryFailing <database> fixture titles; runtime PullRequestQueueWaitBurn posts (tasks 5.4, 7.7) | — | discharged at regulator and runtime interfaces; CAM-70 verify §8b, §9.7; amended by CAM-69 verify §8b, §9.9 |
| Each completed evaluator run posts a heartbeat | interface | heartbeat on the normal and store-error legs; heartbeats counted after C2 (tasks 4.3, 7.2) | — | discharged at regulator and runtime interfaces; CAM-70 verify §8b, §9.3 |
| The dead-man on cinnabar polls the heartbeat topic after an anonymous-publish probe | interface | dead-man legs with the probe mutant; R9.3; R9.4; cinnabar’s dead-man assertions with their overrides (tasks 5.1, 7.3, 7.5, 10.8); CAM-71: each run’s probe refused with 403 before its poll under ntfy 2.31.0 (#3666) | world-assumptions A42 | discharged at regulator, assertion and runtime interfaces; CAM-70 verify §8b, §9.4, §9.6, §11.3; amended by CAM-71 verify §8b |
| ntfy grants the fleet topics to alerter through declarative provisioning | interface | ntfy-provisioning with four mutants; R9.4; an anonymous host-topic publish accepted beside a refused fleet-alerts publish (tasks 3.3, 3.4, 5.2) | world-assumptions A37, A38 | discharged at regulator and runtime interfaces; CAM-70 verify §8b, §9.2, §9.4 |
| ntfy counts each mesh client as its own visitor | interface | pre-C1 negative control; separate visitor counters after C1 (tasks 3.3, 7.1) | world-assumptions A40, A41 | discharged at runtime interface; CAM-70 verify §8b, §9.2; stibnite is counted by its IPv4 address (§9.9) |
| The alerter token travels only as a file | interface | package-ntfy-send-test-token-transport with its argv mutant; unitsWithoutToken assertion; an unknown token refused 401 at C1 (tasks 1.1, 1.2, 3.2, 4.7, 10.9); CAM-72: stibnite’s token _otelcol 0400; the token’s hashes unchanged with seven readers; an anonymous POST from stibnite refused with 403 and the wrapper’s posts with NTFY_TOKEN_FILE accepted (tasks 2.2, 2.3, 8.8) | world-assumptions A39, A66 | discharged at package-test, assertion and runtime interfaces; CAM-70 verify §8b, §9.2, §11.3; amended by CAM-72 verify §8b, §9.2 (configured, and observed at 2026-11-07T08:31:42Z) |
| The alert budget is counted over the evaluator’s state and the notifier’s FAILED log | interface | budget and unreadable-log legs; failed.log rehearsal with the drop-append and drop-mode mutants; R9.1 at runtime (tasks 2.3, 4.2, 9.1, 10.5) | — | discharged at regulator and runtime interfaces; CAM-70 verify §8b, §10.2 |
| The rule check runs promtool, fixture mutants and a property test | interface | each mutant rejected (tasks 4.5, 4.6); CAM-76: the nine ping legs and the five ping mutants rejected at their named legs; fleet-alert at 351,808,048 B against the 536,870,912 B budget (tasks 2.1, 2.4, 2.8) | — | discharged at regulator interface; CAM-70 verify §8b; evaluation cost §9.1; amended by CAM-76 verify §8b, §9.1 (the budget moved from the statement to its existing scenario at archive) |
| The evaluator’s memory ceiling and start timeout are asserted | interface | R9.5 mutant and control; the timing relation failing at postDeadlineSec = 40 (tasks 4.4, 10.4) | — | discharged at evaluation-time assertion interface; CAM-70 verify §8b, §11.2; amended by #3516 |
| The weekly test rule is evaluated in one window each Monday | interface | window leg across the daylight-saving change; forced window on magnetite; the scheduled post on 2026-10-19 (tasks 4.1, 7.6, 7.7) | — | discharged at regulator and runtime interfaces; CAM-70 verify §8b, §9.8 |
| This capability states its own trust boundary | interface | the requirement’s own statement; no regulator applies; CAM-76: the amended statement and the runbook’s section “The external watch” (tasks 5.1, 6.1); CAM-72: the amended statement and the runbook’s darwin section (tasks 7.2, 9.1) | — | discharged by statement; CAM-70 verify §8b; amended by CAM-69 verify §8b; amended by CAM-76 verify §8b, §8d; amended by CAM-72 verify §8b, §8d |
| The pull-request queue-wait rule reads devloop through SQL | interface | rendered rule; one SQL query on devloop per run (tasks 5.1, 5.2, 5.6) | — | discharged — CAM-69 verify §8b, §9.8 |
| The dead-man pings the watch service only after a passing run | interface | the ping legs red, then nine ok: legs and five mutants rejected; 6 of 6 runs pinged after the deploy; the ntfy stop’s five failing runs and the evaluator stop’s four empty-window runs sent no ping; 260 of 260 runs pinged over the quiet window (tasks 2.1, 2.4, 3.2, 4.2, 4.3, 4.4) | world-assumptions A53 | discharged at regulator and runtime interfaces — CAM-76 verify §8b, §9.2; the OK (not found) and closed-port scenarios at build only |
| The ping URL travels only as a credential read on stdin | interface | the transport test red, then the URL on stdin and its argv mutant rejected; the store-path assertion failing an extendModules override; the generator’s script rejecting a malformed URL; the deployed unit’s LoadCredential and no hc-ping in its environment or journal (tasks 2.2, 2.3, 2.5, 2.7, 3.2) | — | discharged at package-test, assertion and runtime interfaces — CAM-76 verify §8b; the prompt’s rejection shown by the generator’s script, not at the gated prompt (§10) |
fleet-alerting
Section titled “fleet-alerting”Source: openspec/specs/fleet-alerting/spec.md.
| Requirement | Stratum | Discharged by (S) | Under (W) | Status |
|---|---|---|---|---|
| Each known failure class on a host reaches a person as an alert | behavioral | The evaluator queries each rule's database as the regulators' store account; Alert rules are rendered from one Nix source to the evaluator and to promtool; Alerts are posted to fleet-alerts with a title and a severity priority; ntfy counts each mesh client as its own visitor; The darwin probe reports each allow-listed launchd job and the host's disk health in a textfile; A laptop's disk health is read on the host and served on loopback | world-assumptions A33, A40, A41, A51, A62, A63 | discharged — CAM-70 verify §8b; every shipped rule fired and resolved §9.7; arrival on the phone composed in §10.1; amended by CAM-69 verify §8b (two-database leg, task 5.5); amended by CAM-71 verify §8b, §9.3 (file-system and NVMe rules over magnetite, cinnabar and pyrite; pyrite’s replays made after the rules shipped); amended by CAM-72 verify §8b, §9.3 (LaunchdJobNotRunning and LaunchdJobFailed fired and resolved once each on stibnite, tasks 8.3a, 8.4; the replay over nix-cleanup-gcroots’ run, task 6.1a, taken over a run kickstarted at 2026-11-08T00:12:53Z by operator decision O2, so launchd’s calendar trigger is not exercised); amended by CAM-92 verify §8b (a kept-alive job’s abnormal exit counted only within 30 min of its relaunch: the org.nixos.nix-daemon instance resolved at 2026-11-08T16:59:03Z after magnetite’s deploy without a restart, tasks 4.2, 6.1; a new crash’s firing shown by the legs and the replay over stibnite’s history only, tasks 2.2, 2.3) |
| An alert instance reaches a person once when it fires and at most once when it resolves | behavioral | Alert instance state is kept in one state file and posted once per transition; Alerts are posted to fleet-alerts with a title and a severity priority | — | discharged — CAM-70 verify §8b, §9.7 |
| An unreachable telemetry store or a silent host freezes alerts | behavioral | Store errors and silent hosts freeze instance state | world-assumptions A61, A64 | discharged — CAM-70 verify §8b after #3510; first runtime observation failed and was re-observed, verify §11.1; amended by CAM-69 verify §8b (per-database freeze, tasks 5.1, 10.5), §11.1; amended by CAM-72 verify §8b (no post naming stibnite across an induced sleep with 13 dark wakes and a natural sleep with 26, tasks 8.6, 8.7) |
| A missing signal is itself reported | behavioral | Each rule's presence selector is watched; An always-on host's silence is reported; One host table declares the agent hosts and what each reports | world-assumptions A13, A50 | discharged — CAM-70 verify §8b; always-on-host clause by check only at CAM-70 (tasks 10.2, verify §11.2); amended by CAM-71 verify §8b, §9.2: cinnabar’s silence fired and resolved live, pyrite’s offline run raised nothing and its missing disk health was reported (tasks 5.6, 6.7, 9.2) |
| A silent evaluator is reported from another host | behavioral | Each completed evaluator run posts a heartbeat; The dead-man on cinnabar polls the heartbeat topic after an anonymous-publish probe | world-assumptions A33, A42 | discharged — CAM-70 verify §8b; R9.3 verify §9.6; amended by CAM-71 verify §8b (#3666; the live silence test re-run on the current code, §9.3) |
| Only the alerting credential publishes alerts and heartbeats | behavioral | ntfy grants the fleet topics to alerter through declarative provisioning; The alerter token travels only as a file | world-assumptions A37, A38 | discharged — CAM-70 verify §8b; R9.4 verify §9.4 |
| Alert volume stays within the alert budget | behavioral | The alert budget is counted over the evaluator's state and the notifier's FAILED log | — | discharged — CAM-70 verify §8b; R9.1 against the captured messages verify §10.2 |
| The evaluator stays inside its envelope on magnetite | behavioral | The evaluator's memory ceiling and start timeout are asserted | world-assumptions A31 | discharged — CAM-70 verify §8b; tasks 10.4 |
| A weekly test alert proves the path to a person | behavioral | The weekly test rule is evaluated in one window each Monday | world-assumptions A33 | discharged — CAM-70 verify §8b; the first Monday message reached no phone, receipt shown by a later test post (verify §9.8) |
| Pull-request builds that wait too long to start reach a person as a warning | behavioral | The pull-request queue-wait rule reads devloop through SQL; The evaluator queries each rule's database as the regulators' store account; Alert instance state is kept in one state file and posted once per transition; Every dev-loop event is recorded once and kept for a year | world-assumptions A33 | discharged — CAM-69 verify §8b, §9.8, §9.9, §10.5; every firing so far is a flake-updater burst, kept by operator decision O3 (§11.2) |
| An outage of the alert path reaches the operator by email from outside the fleet | behavioral | The dead-man pings the watch service only after a passing run; The ping URL travels only as a credential read on stdin; The rule check runs promtool, fixture mutants and a property test | world-assumptions A53, A54, A55 | discharged — CAM-76 verify §8b, §9.2: the ntfy stop and the evaluator stop of 2026-11-04 each emailed 15 min after the last accepted ping and again after the first ping; no email over the quiet window of 2026-11-04T16:40:03Z to 2026-11-05T14:16:43Z, shortened from 24 h by operator decision (§10); a failure during an ntfy outage posts no FAILED, an observed gap not discharged (§10) |
fleet-dashboard-interface
Section titled “fleet-dashboard-interface”Source: openspec/specs/fleet-dashboard-interface/spec.md.
| Requirement | Stratum | Discharged by (S) | Under (W) | Status |
|---|---|---|---|---|
| The dashboard service runs the vendor’s release with its pinned plugins | interface | package-perses-bin install and version checks with the Prometheus 0.59.0 mutant; the serving predicate’s plugin clause with 11-pluginsOnTmpfs (tasks 2.2, 3.2) | — | discharged at package-check and regulator interfaces; CAM-73 verify §8b |
| The dashboard service listens on loopback behind one vhost | interface | the listener and vhost clauses with their mutants; the strip override failing magnetite’s evaluation; container header, bypass and metrics cases; 127.0.0.1:8095 the only Perses listener on magnetite (tasks 3.2, 3.4, 3.7, 4.2) | — | discharged at regulator, container runtime-test and observed interfaces; CAM-73 verify §8b |
| The identity provider admits only the dashboard group | interface | the client and authentication clauses with their mutants; scope maps ["perses_users"] and the stub without members; the refusal and the admission at deployment (tasks 3.2, 3.5, 4.3, 4.4) | world-assumptions A56, A57 | discharged at regulator interface; refusal and admission observed once on 2026-11-05; CAM-73 verify §8b |
| Readers hold only read permission on a read-only server | interface | the permission clauses with their mutants; container write cases; an anonymous PUT answered 405 on magnetite (tasks 3.2, 3.7, 7.1) | world-assumptions A58 | discharged at regulator and container runtime-test interfaces; CAM-73 verify §8b |
| The telemetry store is read only through two global datasources | interface | lint over both datasources; the datasource clauses with their mutants; container query, refusal, database-header and header cases (tasks 3.2, 3.3, 3.7) | world-assumptions A58, A59 | discharged at regulator and container runtime-test interfaces; CAM-73 verify §8b |
| Committed files are the only source of views and datasources | interface | the provisioning clause with its mutant; container planted-view case (tasks 3.2, 3.7) | world-assumptions A58 | discharged at regulator and container runtime-test interfaces; CAM-73 verify §8b |
| The dashboard service’s secrets arrive only as credentials | interface | the credential clause with its mutants; the holder override; restartUnits; the generated vars and clan vars check (tasks 3.2, 3.5, 3.8, 3.9) | — | discharged at evaluation-time regulator interface; CAM-73 verify §8b |
| The dashboard service runs inside a memory envelope and hands its failures to the notifier | interface | 11-bigMemory and 11-highAtMax; the kill-order override; the kill on magnetite with its notice and restart (tasks 3.2, 3.5, 4.5) | — | discharged at regulator and observed interfaces; CAM-73 verify §8b |
| The view files lint clean at the shipped plugins | interface | perses-lint red, then the seven mutants rejected with their messages and bare lint accepting extra-field.json (tasks 2.1, 2.4, 3.3) | — | discharged at regulator interface; CAM-73 verify §8b; evaluation cost §9.1 |
| The serving configuration is judged by one predicate | interface | perses-config red, then 47 mutants each rejected by its clause (tasks 3.1, 3.2) | — | discharged at regulator interface; CAM-73 verify §8b; evaluation cost §9.1 |
| The container runtime test exercises the read path | interface | vmTests.x86_64-linux.perses-greptimedb with every case and the bypass control (task 3.7) | — | discharged when run on 2026-11-05; it does not gate; CAM-73 verify §8b |
| The dashboard hostname resolves to magnetite | interface | the obs record created by just terraform; the certificate issued and served at deployment (tasks 3.6, 4.1, 4.2) | world-assumptions A60 | discharged at observed interface; no dig output logged, CAM-73 verify §8b, §10 |
| This capability states its own trust boundary | interface | the requirement’s own statement; the runbook’s “Reaching the dashboard” (tasks 5.1, 6.1) | — | discharged by statement; CAM-73 verify §8b, §8d |
fleet-dashboard
Section titled “fleet-dashboard”Source: openspec/specs/fleet-dashboard/spec.md.
| Requirement | Stratum | Discharged by (S) | Under (W) | Status |
|---|---|---|---|---|
| An admitted person views the fleet’s signals and the dev-loop history by host | behavioral | The dashboard service runs the vendor's release with its pinned plugins; The dashboard service listens on loopback behind one vhost; The telemetry store is read only through two global datasources; Committed files are the only source of views and datasources; The view files lint clean at the shipped plugins | world-assumptions A58 | discharged — CAM-73 verify §8b; both views with data at admission; per-host reading in the view not recorded (tasks 4.4, 7.1) |
| A person outside the dashboard group is refused | behavioral | The identity provider admits only the dashboard group; The dashboard service listens on loopback behind one vhost | world-assumptions A56, A57 | discharged — CAM-73 verify §8b; refusal observed once (task 4.3) |
| A person removed from the dashboard group loses access within an hour | behavioral | The identity provider admits only the dashboard group | world-assumptions A57, A58 | discharged — CAM-73 verify §8b; configured, no removal performed |
| Nobody changes the views except by a committed change | behavioral | Readers hold only read permission on a read-only server; Committed files are the only source of views and datasources | world-assumptions A58 | discharged — CAM-73 verify §8b; a save by an admitted person in the UI not observed |
| No store credential reaches a person, and the dashboard service only reads | behavioral | The telemetry store is read only through two global datasources; The dashboard service listens on loopback behind one vhost; The dashboard service's secrets arrive only as credentials; Credentials exist only as activation-resolved files owned by non-worker users | world-assumptions A58, A59 | discharged — CAM-73 verify §8b; the browser’s storage not observed |
| The dashboard service stays inside its memory envelope and its failures reach a person | behavioral | The dashboard service runs inside a memory envelope and hands its failures to the notifier | world-assumptions A31 | discharged — CAM-73 verify §8b; kill, notice and restart observed (task 4.5); peak 56 MiB after the restart |
fleet-ingress-interface
Section titled “fleet-ingress-interface”Source: openspec/specs/fleet-ingress-interface/spec.md.
| Requirement | Stratum | Discharged by (S) | Under (W) | Status |
|---|---|---|---|---|
| One host table declares the agent hosts and what each reports | interface | the evaluated flake.lib.observabilityHosts; the three assertion overrides failing evaluation (task 2.2); CAM-72: the platform assertion naming six rows with "platform":null, then seven rows, and the scratch edit’s failure (task 2.1) | — | discharged — CAM-71 verify §8b; amended by CAM-72 verify §8b (configured) |
| The collection CA issues each agent host one certificate | interface | otel-ca and each otel-cert generated with every token hash unchanged; fleet-ingress certificate cases (tasks 2.3, 3.4); CAM-72: CN=stibnite with client authentication, verified against otel-ca; the key _otelcol 0400, restartUnits = [ ] and OTEL_CERT_SHA256 equal to the certificate’s hash (tasks 2.2, 2.3) | — | discharged — CAM-71 verify §8b; amended by CAM-72 verify §8b, §9.2 (configured) |
| The ingress receiver accepts only certificate holders on magnetite’s ZeroTier address | interface | R3.1 mesh-receiver clause red, then green; absentClientCa in fleet-ingress; stibnite refused without a certificate (tasks 2.1, 2.5, 3.4, 4.5) | — | discharged — CAM-71 verify §8b, §9.2 |
| Each agent exports by its role | interface | queue assertion red on electrum, then its overrides; cinnabar’s queue growing before magnetite’s receiver and draining after it (tasks 2.4, 3.4, 4.3, 4.5); CAM-72: exporterAddressOther rejected; queue64 and queues600 failing evaluation; stibnite’s sends growing from 725 to 971 points in 60 s (tasks 2.4, 2.6, 5.3) | world-assumptions A65 | discharged — CAM-71 verify §8b, §9.2; amended by CAM-72 verify §8b (configured, and observed at 2026-11-06T05:20Z) |
| otel-envelope regulates each agent from its own collector | interface | otel-envelope cases with five mutants; fleet-ingress; no unattributed FAIL over 24 h on each host; FAILED otel-envelope.service on cinnabar and its RESOLVED (tasks 3.1, 3.2, 3.4, 9.1, 9.2, 9.3); CAM-72: the darwin cases with c5WrongPid, c5ReadsRss and c5UnreadablePasses rejected; the daemon’s interval, account and calendar control; C5 live as _otelcol; 8.2’s stopped-collector control posting one FAILED and one RESOLVED (tasks 3.3, 3.4, 5.3a, 8.1, 8.2) | world-assumptions A70 | discharged — CAM-71 verify §8b, §9.3; pyrite over its observed window by operator decision; amended by CAM-72 verify §8b, §9.3; stibnite’s run without a failure judged over 2026-11-07T08:24Z to 2026-11-08T00:30Z, about 16 h, by operator decision O2 |
| otel-envelope on the ingress host regulates the fleet budget | interface | budget case red, then green with each fixture failing its clause; budgetOnlyHourly; B1–B6 on magnetite; the drop-in control’s FAILED and RESOLVED (tasks 7.1, 7.2, 7.6) | — | discharged — CAM-71 verify §8b |
| A laptop’s disk health is read on the host and served on loopback | interface | scrape render; the device ACL, critical warning and percentage used stored from pyrite (tasks 2.6, 5.3); CAM-72: the smartctl fixture and its expected smartctl.prom; eight smartctl_device_* series stored for stibnite (tasks 2.5, 5.3) | world-assumptions A51, A63 | discharged — CAM-71 verify §8b, after #3668 and #3669; amended and renamed by CAM-72 verify §8b (configured, and observed at 2026-11-06T05:20Z; pyrite’s NVMe path unchanged) |
| This capability states its own trust boundary | interface | the requirement’s own statement; the runbook’s certificate, rotation and refusal sections (tasks 8.2, 10.1); CAM-72: the amended statement and the runbook’s darwin section (tasks 7.2, 9.1) | — | discharged by statement — CAM-71 verify §8b, §8d; amended by CAM-72 verify §8b, §8d |
| The darwin probe reports each allow-listed launchd job and the host’s disk health in a textfile | interface | eight probe cases and four mutants rejected; the signal-killed fixture replaced by the recorded reply, nonIdleNoExitCode passing and missingExitCodeAsZero rejected (tasks 2.5, 8.4) | world-assumptions A62 | discharged — CAM-72 verify §8b; observed at 2026-11-07T05:42:20Z |
| No darwin collection job runs on a calendar schedule | interface | probeCalendar and envelopeCalendar failing evaluation; after 8.6’s wake the probe ran once within 60 s and the envelope once within 300 s, with no burst (tasks 2.6, 8.6) | world-assumptions A61 | discharged — CAM-72 verify §8b; configured, and observed across 8.6’s sleep |
graphical-desktop-session
Section titled “graphical-desktop-session”Source: openspec/specs/graphical-desktop-session/spec.md.
| Requirement | Stratum | Discharged by (S) | Under (W) | Status |
|---|---|---|---|---|
| The pyrite host provides a local GNOME desktop under GDM | behavioral | — | — | undischarged — V-interface / evidence annotation follow-up; no named S despite retained runtime evidence |
| The laptop does not suspend itself when nobody is using it | behavioral | — | world-assumptions A13 | undischarged — no named S; CAM-62 verify §8b / retrospective §6; see CAM-62 qualifications |
| A person at the panel can choose between two desktops, and the established one is what they get if they do not choose | behavioral | — | — | undischarged — V-interface; amended GNOME reachability excludes live-niri display-manager restart (CAM-66, unrepaired); 8.2 no-history METHOD LIMITATION, source-read only |
| A newly offered desktop does not suspend the host when nobody is using it | behavioral | — | world-assumptions A13 | undischarged — V-interface; 8.3/8.4/8.5 evaluation, 8.6 declined CAM-59, 8.7 physical controls; see CAM-63 qualifications |
| A desktop is not offered until the settings it will start with have been checked by the program that will start it | behavioral | — | — | undischarged — V-interface; actual positive/negative builds and binary equality do not name S; includes vacuous |
host-metrics-collection
Section titled “host-metrics-collection”Source: openspec/specs/host-metrics-collection/spec.md.
| Requirement | Stratum | Discharged by (S) | Under (W) | Status |
|---|---|---|---|---|
| Each agent host contributes its own signals to the telemetry store | behavioral | Ingest is OTLP over HTTP with a database header; Scrape targets are reached on loopback; The collector's configuration bounds what it gathers; The ingress receiver accepts only certificate holders on magnetite's ZeroTier address; Each agent exports by its role; A laptop's disk health is read on the host and served on loopback; The darwin probe reports each allow-listed launchd job and the host's disk health in a textfile | world-assumptions A50, A51, A62, A63, A65 | discharged — CAM-68 verify §8b; amended by CAM-69 verify §8b, §9.6 (fleet holds no log table); amended and renamed by CAM-71 verify §8b, §9.3 (magnetite, cinnabar and pyrite, pyrite from 2026-11-01T05:55:54Z by operator decision); amended by CAM-72 verify §8b (stibnite’s system_*, process_*, three launchd_job_* and eight smartctl_device_* series stored from 2026-11-06T05:20Z, task 5.3) |
| Each stored series names its host | behavioral | Ingest is OTLP over HTTP with a database header; Reads are PromQL and SQL over HTTP with a database header; Prometheus remote storage stays enabled for the PromQL query API | — | discharged — CAM-68 verify §8b; amended by CAM-72 verify §8b (PromQL and SQL each return stibnite’s rows at 2026-11-06T05:20Z, task 5.3) |
| Series cardinality stays bounded | behavioral | The collector's configuration bounds what it gathers; otel-envelope on the ingress host regulates the fleet budget; The darwin probe reports each allow-listed launchd job and the host's disk health in a textfile | world-assumptions A77 | discharged — CAM-68 verify §8b; §8c alphabet finding repaired in #3501; amended by CAM-71 verify §8b, §9.3 (per-host bounds held, pyrite over its observed window); amended by CAM-72 verify §8b (the darwin floor of 384 MiB with the fleet executables kept below it, fleetKeptBelowFloor with keepListIgnored rejected, B3 ok per hour after 6.6a, tasks 6.6a, 11.2; the bound of 30 judged by operator decision O2, launchd_label over 2026-11-07T08:24Z to 2026-11-08T00:30Z and process_executable_name over the 24 h ending 2026-11-08T00:30Z, task 8.1) |
| Collection survives a telemetry store restart without losing the queued interval | behavioral | The collector's queue persists across a telemetry store restart; Each agent exports by its role | world-assumptions A52 | discharged — CAM-68 verify §8b; verify §10.3; amended by CAM-71 verify §8b (agent queue assertion; fleet-ingress back-pressure and restart cases); amended by CAM-72 verify §8b (configured on stibnite: queue64 and queues600 fail evaluation and both queues were 0 at 8.6’s wake and after; the restart path not run on darwin) |
| Stored unit names carry no owner’s name | behavioral | Omnigent unit names are stored under aliases; The darwin probe reports each allow-listed launchd job and the host's disk health in a textfile | — | discharged — CAM-68 verify §8b; amended by CAM-71 verify §8b (the agent alias assertion with its override); amended by CAM-72 verify §8b (aliasDropped rejected, omnigentNobody failing evaluation, and org.nixos.omnigent-host-owner-1 stored with no owner’s name, tasks 2.5, 2.6) |
| A failed collection or store job notifies a person | behavioral | Failure notices are posted to one topic; A failure episode ends at the unit's next successful start or exit; One host table declares the agent hosts and what each reports; otel-envelope regulates each agent from its own collector; Each known failure class on a host reaches a person as an alert | world-assumptions A33, A37, A66 | discharged — CAM-68 verify §8b; verify §9.5, §11.1; CAM-70 verify §8b (posting with the credential); amended by CAM-71 verify §8b (notified units per host; FAILED otel-envelope.service on cinnabar delivered); amended by CAM-72 verify §8b (8.2’s FAILED otel-envelope on stibnite and RESOLVED through the notifier wrapper; 8.4’s LaunchdJobFailed for otelcol-process, tasks 3.2, 8.2, 8.4) |
openspec-linear-sync
Section titled “openspec-linear-sync”Source: openspec/specs/openspec-linear-sync/spec.md.
| Requirement | Stratum | Discharged by (S) | Under (W) | Status |
|---|---|---|---|---|
| Drive Linear exclusively through linear-cli | interface | — | — | undischarged — evidence annotation follow-up |
| Bind four forward transitions plus re-queue with invariants | interface | — | — | undischarged — evidence annotation follow-up |
| Local sync ledger as authoritative current-phase signal | interface | — | — | undischarged — evidence annotation follow-up |
| Single-location frontmatter binding that resolves against the registry | interface | — | — | undischarged — evidence annotation follow-up |
| Mirror the Linear issue description from proposal.md business content | interface | — | — | undischarged — evidence annotation follow-up |
| Archive-time document UPSERT with mirroring | interface | — | — | undischarged — evidence annotation follow-up |
| One-question setup, never-auto-select, best-effort non-blocking | interface | — | — | undischarged — evidence annotation follow-up |
pi-agent-environment
Section titled “pi-agent-environment”Source: openspec/specs/pi-agent-environment/spec.md.
| Requirement | Stratum | Discharged by (S) | Under (W) | Status |
|---|---|---|---|---|
| Nix-owned Pi resources | behavioral | — | — | undischarged — evidence annotation follow-up |
| Mutable settings seed | behavioral | — | — | undischarged — evidence annotation follow-up |
| Runtime state boundary | behavioral | — | — | undischarged — evidence annotation follow-up |
| Source-only extension package | behavioral | — | — | undischarged — evidence annotation follow-up |
| Selected extensions | behavioral | — | — | undischarged — evidence annotation follow-up |
| Nix-owned runtime executables | behavioral | — | — | undischarged — evidence annotation follow-up |
| Excluded extension resources | behavioral | — | — | undischarged — evidence annotation follow-up |
| Retained compaction extension | behavioral | — | — | undischarged — evidence annotation follow-up |
| Canonical skill sink | behavioral | — | — | undischarged — evidence annotation follow-up |
| Catppuccin source provenance | behavioral | — | — | undischarged — evidence annotation follow-up |
| Catppuccin theme delivery | behavioral | — | — | undischarged — evidence annotation follow-up |
| Permission-gate reuse | behavioral | — | world-assumptions A1 | undischarged — evidence annotation follow-up |
| Additional shell policy | behavioral | — | world-assumptions A2 | undischarged — evidence annotation follow-up |
| Non-Bash edit and write policy | behavioral | — | world-assumptions A1, A2, A3, A4, A5, A6, A7 | undischarged — evidence annotation follow-up |
| Git default-branch boundary | behavioral | — | world-assumptions A3, A5, A7, A8 | undischarged — evidence annotation follow-up |
| Jj diamond boundary | behavioral | — | world-assumptions A3, A5, A7, A8 | undischarged — evidence annotation follow-up |
| Fail-open policy | behavioral | — | world-assumptions A1, A2, A3, A4 | undischarged — evidence annotation follow-up |
| Secret-safe direnv | behavioral | — | — | undischarged — evidence annotation follow-up |
| Opt-in slow mode | behavioral | — | — | undischarged — evidence annotation follow-up |
| Consolidated custom regulators | behavioral | — | — | undischarged — evidence annotation follow-up |
| Offline aggregate smoke | behavioral | — | — | undischarged — evidence annotation follow-up |
| Rollback preservation | behavioral | — | — | undischarged — evidence annotation follow-up |
| Activation requires explicit permission | behavioral | — | — | undischarged — evidence annotation follow-up |
| Post-activation confirmation gate | behavioral | — | — | undischarged — evidence annotation follow-up |
project-management-hub
Section titled “project-management-hub”Source: openspec/specs/project-management-hub/spec.md.
| Requirement | Stratum | Discharged by (S) | Under (W) | Status |
|---|---|---|---|---|
| Linear Method ontology spine | interface | — | — | undischarged — evidence annotation follow-up |
| Four flat one-level reference areas | interface | — | — | undischarged — evidence annotation follow-up |
| Linear workspace safety gate keyed on confirmed credentials | interface | — | — | undischarged — evidence annotation follow-up |
requirements-stratification
Section titled “requirements-stratification”Source: openspec/specs/requirements-stratification/spec.md.
| Requirement | Stratum | Discharged by (S) | Under (W) | Status |
|---|---|---|---|---|
| Stratum assignment for any requirement-like statement | behavioral | — | — | undischarged — evidence annotation follow-up |
| Grounding of terms used in requirements | behavioral | — | — | undischarged — evidence annotation follow-up / V-vocabulary; CAM-62 and CAM-63 unresolved nouns |
| Separation of what is assumed from what is wanted | behavioral | — | — | undischarged — evidence annotation follow-up |
| Discharge of a requirement is stated, not implied | behavioral | — | — | undischarged — evidence annotation follow-up |
| Obstacle analysis produces the boundary and open questions | behavioral | — | — | undischarged — evidence annotation follow-up |
satisfaction-argument-audit
Section titled “satisfaction-argument-audit”Source: openspec/specs/satisfaction-argument-audit/spec.md.
| Requirement | Stratum | Discharged by (S) | Under (W) | Status |
|---|---|---|---|---|
| Specification is checked against intent independently | behavioral | — | — | undischarged — evidence annotation follow-up |
| Everything the argument depends on unverified is enumerated | behavioral | — | — | undischarged — evidence annotation follow-up |
| Agreement between two artifacts is not treated as confirmation | behavioral | — | — | undischarged — evidence annotation follow-up |
| External claims are bounded by what was actually established | behavioral | — | — | undischarged — evidence annotation follow-up |
| The audit runs at a boundary, not continuously | behavioral | — | — | undischarged — evidence annotation follow-up |
shared-reference-tree-interface
Section titled “shared-reference-tree-interface”Source: openspec/specs/shared-reference-tree-interface/spec.md.
| Requirement | Stratum | Discharged by (S) | Under (W) | Status |
|---|---|---|---|---|
| Sharing hosts are declared, and only they change | interface | NixOS and darwin module assertions on the three machine checks, each failing under a mutation; non-sharing projection unchanged against main (task 10.2) | — | discharged at evaluation interface; CAM-77 verify §5 |
| The shared root is owned by the writer and closed to everyone else | interface | tmpfiles and darwin provisioning assertions; VM test with group-writable mutation; post-deploy ownership audit with no orphaned owner | — | discharged at evaluation, VM and runtime interfaces; CAM-77 verify §5 |
| Each participating account resolves the shared root | interface | participant programs.ghq-shared.root assertion; VM ghq root per reader; post-deploy ghq root per account | world-assumptions A35 | discharged at evaluation, VM and runtime interfaces; CAM-77 verify §5 |
| Readers trust the writer’s tree and nothing broader | interface | safe.directory exactness and enclosing-entry assertions and safe.bareRepository assertions, each failing under mutations; VM ownership and bare-repository refusals; post-deploy settings per account | world-assumptions A34 | discharged at evaluation, VM and runtime interfaces; CAM-77 verify §5, §5a, §5b |
| Acquisition is delegated to the writer through a socket-activated entry point | interface | VM delegation, deepen, promote, update and tags subtests; handler and wrapper package tests; post-deploy ghq-sync -u . and tags per account | — | discharged at package-test, VM and runtime interfaces; CAM-77 verify §5 |
| The writer accepts only constrained requests | interface | handler package test refusal classes; VM malformed requests refused through the client | — | discharged at package-test and VM interfaces; CAM-77 verify §5a |
| Migration moves only administrators’ trees in place, sets other trees aside, and can be rolled back | interface | VM migration subtest (administrator move and rollback, refusals, set-aside with reacquisition, mid-apply probe, resumed rollback, earlier-format records), failing with each earlier tool; ACL and writer-stop package test | — | discharged at VM and package-test interfaces; CAM-77 verify §5, §5c–5e; darwin refusal through its probe only |
| Each property is backed by evidence that can fail | interface | VM group-writable and broken-control mutations fail at their subtests; assertion mutations fail evaluation | — | discharged — CAM-77 verify §5 |
| This capability states its own trust boundary | interface | — | — | undischarged — boundary statement, not a property; follow-up: CAM-77 qualifications |
shared-reference-tree
Section titled “shared-reference-tree”Source: openspec/specs/shared-reference-tree/spec.md.
| Requirement | Stratum | Discharged by (S) | Under (W) | Status |
|---|---|---|---|---|
| Every participating account reads one reference tree per host | behavioral | Sharing hosts are declared, and only they change; Each participating account resolves the shared root | world-assumptions A35 | discharged — CAM-77 verify §8b; post-deploy §5 |
| Only the writer changes the reference tree | behavioral | The shared root is owned by the writer and closed to everyone else; Readers trust the writer's tree and nothing broader; Acquisition is delegated to the writer through a socket-activated entry point | world-assumptions A34 | discharged — CAM-77 verify §8b; VM threat demonstration and post-deploy refusals §5 |
| A missing reference repository can be requested without a person | behavioral | Acquisition is delegated to the writer through a socket-activated entry point; The writer accepts only constrained requests | — | discharged — CAM-77 verify §8b |
| Only participating accounts can read the reference tree | behavioral | The shared root is owned by the writer and closed to everyone else | — | discharged — CAM-77 verify §8b; nobody refused at root and socket §5 |
| Sharing the reference tree leaves every private home private | behavioral | Sharing hosts are declared, and only they change; existing Omnigent worker obligations (private 0700 homes, admitted groups) | — | discharged — CAM-77 verify §8b |
| Moving per-account copies into the reference tree loses nothing and is reversible | behavioral | Migration moves only administrators' trees in place, sets other trees aside, and can be rolled back | world-assumptions A36 | discharged — CAM-77 verify §8b, §5c–5e; stibnite migrated by the earlier tool, whose records still roll back |
skill-corpus-interface
Section titled “skill-corpus-interface”Source: openspec/specs/skill-corpus-interface/spec.md.
| Requirement | Stratum | Discharged by (S) | Under (W) | Status |
|---|---|---|---|---|
| A named skill is resolvable in the delivered corpus | interface | — | — | undischarged — evidence annotation follow-up |
| A skill’s trigger surface admits the situations it must fire on | interface | — | — | undischarged — evidence annotation follow-up |
| Stated ownership boundaries hold across the corpus | interface | — | — | undischarged — evidence annotation follow-up |
| Stacked landing guidance is conditioned by role and repository mode | interface | first-party role/requirement-map/routing sections; evaluated user-context text; integrated-main stack-land predicate/tests | — | discharged at composed/rendered guidance interface; CAM-41 verify §9b |
stratified-change-authoring
Section titled “stratified-change-authoring”Source: openspec/specs/stratified-change-authoring/spec.md.
| Requirement | Stratum | Discharged by (S) | Under (W) | Status |
|---|---|---|---|---|
| Proposal artifact records a stratum tag per capability | interface | — | — | undischarged — evidence annotation follow-up |
| Specs artifact applies stratum-conditional vocabulary rules | interface | — | — | undischarged — evidence annotation follow-up |
| Verify artifact runs non-blocking stratum checks | interface | — | — | undischarged — evidence annotation follow-up |
| Archive step regenerates the satisfaction projection | interface | — | — | undischarged — evidence annotation follow-up |
| Tasks artifact records per-task verification | interface | — | — | undischarged — evidence annotation follow-up |
| The stratum layer states its own trust boundary | interface | — | — | undischarged — evidence annotation follow-up |
telemetry-store-interface
Section titled “telemetry-store-interface”Source: openspec/specs/telemetry-store-interface/spec.md.
| Requirement | Stratum | Discharged by (S) | Under (W) | Status |
|---|---|---|---|---|
| Listeners are bound to loopback only | interface | R7.1 in the greptimedb-envelope check; CAM-71: R3.1’s loopback clause with the mesh-receiver exception; ss -tlnH on magnetite (tasks 2.1, 4.5) | — | discharged at evaluation-time regulator interface; CAM-68 verify §8b; amended by CAM-71 verify §8b |
| Prometheus remote storage stays enabled for the PromQL query API | interface | pipeline container test PromQL cases (task 2.1) | — | discharged at container runtime-test interface; CAM-68 verify §8b |
| Scrape targets are reached on loopback | interface | R3.1 (tasks 3.3, 3.7, 4.4); CAM-71: agent scrape render; LocalExporterDown cinnabar fired and resolved (tasks 2.6, 9.3); CAM-72: the darwin loopback clause with nodeListenEmpty and exporterAddressOther rejected; nodeWildcard failing evaluation (tasks 2.4, 2.6) | — | discharged at evaluation-time regulator interface; CAM-68 verify §8b; amended by CAM-71 verify §8b; amended by CAM-72 verify §8b (configured) |
| Store accounts carry fixed permission modes | interface | users-file check; R8.2; container auth matrix (task 6.1) | — | discharged at regulator and runtime-test interfaces; CAM-68 verify §8b |
| Ingest is OTLP over HTTP with a database header | interface | R3.1, R1.2; container ingest case (task 6.1); CAM-69: R3.1 logs-routing mutants; per-table log exporters on magnetite (tasks 3.5, 3.6); CAM-71: R3.1 otlpInLogsPipeline; fleet-ingress delivery (tasks 2.5, 3.4) | — | discharged at regulator and runtime-test interfaces; CAM-68 verify §8b; amended by CAM-69 verify §8b, §9.6; amended by CAM-71 verify §8b |
| Reads are PromQL and SQL over HTTP with a database header | interface | container read-back case (task 6.1) | — | discharged at container runtime-test interface; CAM-68 verify §8b |
| Databases and their retention are set at the telemetry store | interface | schema oneshot (task 2.6); container retention cases (task 6.1); CAM-69: schema-job script probe; devloop at 365d with its four tables and no table ttl (tasks 2.3, 2.4, 7.3) | — | discharged at runtime-test interface; CAM-68 verify §8b; amended by CAM-69 verify §8b, §9.5 |
| Tables allowed a retention of their own are declared | interface | flake.lib.greptimedbEnvelopeTables table-TTL clause over services.greptimedb.tableTtls; container undeclared-ttl negative control (tasks 10.5, 10.10) | — | discharged at regulator and runtime-test interfaces; CAM-68 verify §11.2; added after §8b |
| The store and the collector name the same databases | interface | ingress-module assertion that the store’s database names equal flake.lib.otelCollectorSchema.databases (task 10.4) | — | discharged at evaluation-time assertion interface; CAM-68 tasks 10.4, verify §11; added after §8b |
| Object data lives under one prefix of one bucket | interface | R6.4 storage clause; R6.3; container sst_format negative control (tasks 2.1, 2.5, 4.3, 5.1, 10.10) | world-assumptions A29 | discharged at regulator interface; CAM-68 verify §8b; verify §11.2 |
| Credentials exist only as activation-resolved files owned by non-worker users | interface | R8.2 with its mutants (CAM-68 tasks 2.4, 4.3); R8.2 admitting fleet-alert and rejecting a third holder (CAM-70 task 4.8); R8.2 admitting devloop-reconcile and rejecting a fourth holder (CAM-69 task 4.4); CAM-71: R8.2 workerOwnsOtelKey rejected; a fifth regulator-password holder rejected (tasks 2.3, 2.9, 7.3); CAM-73: R8.2 admitting perses as the only perses-password holder and its fleet-alert override rejected; perses-password restarting perses.service (task 3.5); CAM-72: stibnite’s key and token _otelcol 0400 in evaluation and on stibnite (task 2.2) | — | discharged at evaluation-time regulator interface; CAM-68 verify §8b; CAM-70 verify §8b; amended by CAM-69 verify §8b; amended by CAM-71 verify §8b; amended by CAM-73 verify §8b; amended by CAM-72 verify §8b (configured, and observed at 2026-11-06T03:18Z) |
| The account file the telemetry store loaded is recorded | interface | ExecStartPre hash (task 2.2); R7.4 (task 5.1) | — | discharged at regulator interface; CAM-68 verify §8b; no Discharges: clause names it by title |
| The telemetry store and the collector run inside a declared envelope | interface | R7.1 with seven mutants; R7.2, R7.3; pyrite VM kill-order test (tasks 2.2, 4.1, 5.1, 6.2); CAM-71: the agent’s MemoryMax 256M and its limiter override (task 2.4); CAM-72: the darwin limiters and queue assertions; C5’s cases and mutants; 105 consecutive passing C5 runs; limitersAsDeclared and c5LimitsAsDeclared over stibnite’s evaluated fragment with four mutants rejected (tasks 2.6, 3.3, 5.3a, 8.1, 11.3) | world-assumptions A31, A32, A70 | discharged at regulator and runtime-test interfaces; CAM-68 verify §8b; amended by CAM-71 verify §8b; amended by CAM-72 verify §8b; 8.1’s footprint criterion judged over 2026-11-07T08:24Z to 2026-11-08T00:30Z by operator decision O2 |
| Runtime regulators treat absent evidence as failure | interface | renamed-table mutant (tasks 5.1, 5.2) | — | discharged at runtime regulator interface; CAM-68 verify §8b |
| The telemetry store’s release and usage reporting are fixed at evaluation | interface | R1.1 amended; R1.4 with mutants (task 4.2) | world-assumptions A30 | discharged at evaluation-time regulator interface; CAM-68 verify §8b |
| The collector’s configuration bounds what it gathers | interface | R3.1 process and systemd clauses (tasks 3.2, 4.4); CAM-71: the agent role’s assertions; scrape render; the budget clauses (tasks 2.2, 2.6, 7.2); CAM-72: the darwin clauses ok with seventhIdentityAttribute, processEndpoint and diskIncludeAll rejected; the darwin floor of 384 MiB and the fleet-executables keep-list with keepListIgnored rejected (tasks 2.4, 6.6a, 11.2) | world-assumptions A77 | discharged at evaluation-time regulator interface; CAM-68 verify §8b; amended by CAM-71 verify §8b; amended by CAM-72 verify §8b (configured) |
| Omnigent unit names are stored under aliases | interface | R3.1 alias clause (task 4.4); container alias read-back (task 6.1); CAM-71: the agent alias assertion with the omnigent-host-nobody override (task 2.2); CAM-72: aliasDropped rejected and omnigentNobody failing evaluation; the alias stored for stibnite (tasks 2.5, 2.6) | — | discharged at regulator and runtime-test interfaces; CAM-68 verify §8b; amended by CAM-71 verify §8b; amended by CAM-72 verify §8b (configured, and observed at 2026-11-06T14:45Z) |
| The collector’s queue persists across a telemetry store restart | interface | R3.1 queue clause (tasks 3.2, 4.4); container restart case (task 6.1); CAM-69: logsQueueNotPersistent mutant (tasks 3.5, 3.6) | — | discharged at regulator and runtime-test interfaces; CAM-68 verify §8b; verify §10.3; amended by CAM-69 verify §8b |
| Failure notices are posted to one topic | interface | R3.1 failure-wiring clause and notifier rehearsal with their mutants; package-ntfy-send-test-token-transport; resolve-hook assertion; forced failure (CAM-68 tasks 3.4, 3.5, 4.4, 8.6; CAM-70 tasks 1.2, 2.2, 2.3, 4.7, 10.9); CAM-69: R3.1 mutant dropping devloop-reconcile; forced reconcile failure and resolve delivered (tasks 4.5, 7.5); CAM-71: notified units per host with envelopeNotNotified; FAILED otel-envelope.service on cinnabar and its RESOLVED (tasks 2.8, 3.3, 9.2); CAM-72: the notifier wrapper’s cases and the envelope daemon; both 8.2 posts read back from fleet-alerts (tasks 3.2, 3.4, 8.2) | world-assumptions A66 | discharged at regulator interface; CAM-68 verify §8b; CAM-70 verify §8b; delivery with alerter §9.4; amended by CAM-69 verify §8b, §9.7; two notices were lost in the 2026-10-25 deploy window, §12.3; amended by CAM-71 verify §8b; amended by CAM-72 verify §8b (observed at 2026-11-07T04:57:32Z and 05:02:34Z) |
| A failure episode ends at the unit’s next successful start or exit | interface | R3.1 failure-wiring clause with its start-hook mutant and notifier crash-loop rehearsal (task 10.1); CAM-72: the wrapper’s pass, fail, fail, pass case; RESOLVED from the first run after the bootstrap (tasks 3.2, 8.2) | — | discharged at regulator interface; CAM-68 tasks 10.1, live notifier verify §11.1; added after §8b; amended by CAM-72 verify §8b (observed at 2026-11-07T05:02:34Z) |
| This capability states its own trust boundary | interface | the requirement’s own statement; no regulator applies; CAM-72: the amended statement (task 9.1, named by tasks.md 11.5) | — | discharged by statement; CAM-68 verify §8b; CAM-70 verify §8b; Purpose sentence edited at archive (CAM-70 task 8.4); amended by CAM-72 verify §8b, §8d |
telemetry-store
Section titled “telemetry-store”Source: openspec/specs/telemetry-store/spec.md.
| Requirement | Stratum | Discharged by (S) | Under (W) | Status |
|---|---|---|---|---|
| A database keeps its series for its retention and no longer | behavioral | Databases and their retention are set at the telemetry store; Object data lives under one prefix of one bucket | world-assumptions A29 | discharged — CAM-68 verify §8b |
| Part of a database keeps the database’s retention unless another is declared | behavioral | Tables allowed a retention of their own are declared | — | discharged — CAM-68 tasks 10.5, 10.10; verify §11.2; added after §8b, see CAM-68 qualifications |
| Only the collector writes and only named readers read | behavioral | Store accounts carry fixed permission modes; Listeners are bound to loopback only; Credentials exist only as activation-resolved files owned by non-worker users | — | discharged — CAM-68 verify §8b |
| A replaced store credential takes effect on the running telemetry store | behavioral | Credentials exist only as activation-resolved files owned by non-worker users; The account file the telemetry store loaded is recorded | — | discharged — CAM-68 verify §8b |
| The telemetry store stays inside a memory envelope that leaves build capacity to the build service | behavioral | The telemetry store and the collector run inside a declared envelope | world-assumptions A31, A32 | discharged — CAM-68 verify §8b; kill order by pyrite VM test (task 6.2) |
| The telemetry store stays inside a disk envelope of its own | behavioral | The telemetry store and the collector run inside a declared envelope | — | discharged — CAM-68 verify §8b |
| The telemetry store sends no usage report to its vendor | behavioral | The telemetry store's release and usage reporting are fixed at evaluation | — | discharged — CAM-68 verify §8b |
| The telemetry store runs a stable vendor release that serves its dashboard | behavioral | The telemetry store's release and usage reporting are fixed at evaluation; Listeners are bound to loopback only; The dashboard service listens on loopback behind one vhost | world-assumptions A30 | discharged — CAM-68 verify §8b; authenticated dashboard check verify §9.4; amended by CAM-73 verify §8b (the embedded dashboard kept to loopback as the operator’s fallback; the vhost clause’s otherUpstream mutant) |
| The telemetry store’s own failures reach a person | behavioral | Failure notices are posted to one topic | world-assumptions A33, A37 | discharged — CAM-68 verify §8b; verify §9.5, §11.1; CAM-70 verify §8b, §9.4 (delivery with the credential) |
third-party-plugin-dependency
Section titled “third-party-plugin-dependency”Source: openspec/specs/third-party-plugin-dependency/spec.md.
| Requirement | Stratum | Discharged by (S) | Under (W) | Status |
|---|---|---|---|---|
| First-party packages declare nix-pinned apm dependencies on upstream plugins | interface | — | — | undischarged — evidence annotation follow-up |
| Upstream plugins consumed without forking and extended additively | interface | — | — | undischarged — evidence annotation follow-up |
| Release-aligned offline Mergify skill dependency | interface | equal package-version evaluations; normal/negative structure builds; offline composition; generated-lock revision/hashes; byte comparison | Mergify tag 2026.8.31.1 → 727ce50b8fb3be8a9a24025807e159d644dbba80, dated CAM-41 inspection | discharged at Nix build interface; repository-local frozen delivery pending CAM-41 W4 |
world-assumptions
Section titled “world-assumptions”Source: openspec/specs/world-assumptions/spec.md.
| Requirement | Stratum | Discharges (R) | Status |
|---|---|---|---|
| A1 — No native permission system | world | Permission-gate reuse; Non-Bash edit and write policy; Fail-open policy | self-attested; monitoring follow-up: evidence annotation follow-up |
| A2 — Unanswerable dialog stalls a session with UI but no human present | world | Additional shell policy; Non-Bash edit and write policy; Fail-open policy | self-attested; monitoring follow-up: evidence annotation follow-up |
| A3 — Policy failure carries no safety evidence | world | Non-Bash edit and write policy; Git default-branch boundary; Jj diamond boundary; Fail-open policy | self-attested; monitoring follow-up: evidence annotation follow-up |
| A4 — Refusing on ambiguity has a real cost and prevents nothing | world | Non-Bash edit and write policy; Fail-open policy | self-attested; monitoring follow-up: evidence annotation follow-up |
| A5 — A tracked target is recoverable from repository history | world | Non-Bash edit and write policy; Git default-branch boundary; Jj diamond boundary | self-attested; monitoring follow-up: evidence annotation follow-up |
| A6 — Atomic inherits Pi’s configuration root unconditionally | world | Non-Bash edit and write policy | self-attested; monitoring follow-up: evidence annotation follow-up |
| A7 — Pi’s enumerated path forms are exhaustive | world | Non-Bash edit and write policy; Git default-branch boundary; Jj diamond boundary | self-attested; monitoring follow-up: evidence annotation follow-up |
| A8 — Jj’s outside-repository diagnostic is stable | world | Git default-branch boundary; Jj diamond boundary | self-attested; monitoring follow-up: evidence annotation follow-up |
| Grounded vocabulary for behavioral requirements | world | Grounds behavioral vocabulary; not requirement-scoped | self-attested; monitoring follow-up: evidence annotation follow-up; CAM-68 verify §8a nouns grounded in #3501; CAM-70 verify §8a nouns open, retrospective §6; CAM-69 verify §8a disposition; CAM-71 verify §8a disposition (seven nouns resolved by tasks.md 12.8; collected host rewritten, §8a.3); CAM-76 verify §8a (watch service, ping and email added; the title noun outage has no row); CAM-73 verify §8a (seven rows added; datasource, access and member have no row); CAM-79 verify §8a (thirteen rows added, browser split into dashboard and relay, release given the agent sense; session is used in a wider sense than its autonomous row, and settings and permissions have no row of their own); CAM-72 verify §8a (seven rows added, watched launchd jobs among them by tasks.md 11.7, collected host rewritten to name stibnite and probe given a third sense, darwin host; HMC’s “supervisor” reworded to “launchd”, so every content noun of its nine statements resolves to a row; the row check prints only collected host, §8a.3) |
| A13 — Resuming this laptop from a suspended state is unreliable, and recovering a failed resume requires a person at the machine | world | The laptop does not suspend itself when nobody is using it; A newly offered desktop does not suspend the host when nobody is using it; A missing signal is itself reported | self-attested; monitoring follow-up: evidence annotation follow-up; CAM-59 incident evidence, CAM-62 added eighth failure; observed once by CAM-71: one suspend and clean resume of pyrite while collecting, and its silence raising nothing (CAM-71 verify §8b, §9.3) |
| A29 — Cloudflare R2 behaves as S3-compatible object storage for the telemetry store’s client | world | A database keeps its series for its retention and no longer; Object data lives under one prefix of one bucket | self-attested; monitored by first activation (CAM-68 verify §9.4) and the R6.4 readiness probe |
| A30 — nixpkgs channels lag the telemetry store’s vendor releases and omit its dashboard | world | The telemetry store runs a stable vendor release that serves its dashboard; The telemetry store’s release and usage reporting are fixed at evaluation | self-attested; monitored by R1.1 accepting the channel’s package once it declares the dashboard (CAM-68 verify §8b) |
| A31 — magnetite’s memory is finite and shared with the build service’s evaluation work | world | The telemetry store stays inside a memory envelope that leaves build capacity to the build service; The telemetry store and the collector run inside a declared envelope; The evaluator stays inside its envelope on magnetite; The dashboard service stays inside its memory envelope and its failures reach a person | self-attested; monitored hourly by R7.2 (CAM-68 verify §8b); CAM-73: Perses’ peak of 56 MiB after its restart, inside its 256 MiB ceiling (CAM-73 verify §8b) |
| A32 — magnetite has no /dev/kvm, and the kernel’s kill order does not depend on the host it runs on | world | The telemetry store stays inside a memory envelope that leaves build capacity to the build service; The telemetry store and the collector run inside a declared envelope | self-attested; exercised by the pyrite kill-order VM test (CAM-68 task 6.2); kernel-equivalence not independently re-proved |
| A33 — The fleet’s notification service on cinnabar is reachable over ZeroTier and is the single delivery path | world | The telemetry store’s own failures reach a person; A failed collection or store job notifies a person; Each known failure class on a host reaches a person as an alert; A silent evaluator is reported from another host; A weekly test alert proves the path to a person | self-attested; monitored by forced-failure delivery (CAM-68 verify §9.5, §11.1) and the access matrix after C3 (CAM-70 verify §9.4); revised by CAM-76: healthchecks.io’s email reports that the dead-man’s pings stopped and carries no alert, so cinnabar stays the single delivery path for alerts (CAM-76 verify §8b) |
| A37 — ntfy provisions users, access entries and tokens from its declaration, and refuses to start on an undeclared user | world | Only the alerting credential publishes alerts and heartbeats; ntfy grants the fleet topics to alerter through declarative provisioning; A failed collection or store job notifies a person; The telemetry store’s own failures reach a person | self-attested; observed by alerter and its token coming from server config at C1 (CAM-70 verify §9.2); ntfy-provisioning cites the pinned source; re-read at ntfy 2.31.0, which cinnabar runs (CAM-71 verify §8b, tasks.md 12.4) |
| A38 — One ntfy access entry decides a request, a named user’s before the anonymous one’s | world | Only the alerting credential publishes alerts and heartbeats; ntfy grants the fleet topics to alerter through declarative provisioning | self-attested; observed by alerter accepted beside an anonymous fleet-alerts publish refused 403 (CAM-70 verify §9.4); re-read at ntfy 2.31.0, which cinnabar runs (CAM-71 verify §8b, tasks.md 12.4) |
| A39 — ntfy refuses a request whose token it does not know, even where anonymous access is allowed | world | The alerter token travels only as a file | self-attested; observed by an unknown token refused 401 on an open topic at C1 (CAM-70 verify §9.2); re-read at ntfy 2.31.0, which cinnabar runs (CAM-71 verify §8b, tasks.md 12.4) |
| A40 — ntfy rate-limits a client by its address masked to a prefix, taken from a trusted proxy’s forwarding header | world | Each known failure class on a host reaches a person as an alert; ntfy counts each mesh client as its own visitor | self-attested; observed by separate visitor counters after C1 (CAM-70 verify §9.2); the IPv4 prefix stays at its default (§9.9); re-read at ntfy 2.31.0, which cinnabar runs (CAM-71 verify §8b, tasks.md 12.4) |
| A41 — caddy reaches ntfy from ::1 and forwards the mesh client’s address | world | Each known failure class on a host reaches a person as an alert; ntfy counts each mesh client as its own visitor | self-attested; observed by the journal showing each client’s own mesh address, never ::1 (CAM-70 verify §9.2) |
| A42 — ntfy keeps a topic’s messages for a week and returns a recent window to a poll | world | A silent evaluator is reported from another host; The dead-man on cinnabar polls the heartbeat topic after an anonymous-publish probe | self-attested; observed by the dead-man’s heartbeat counts and R9.3 (CAM-70 verify §9.4, §9.6); renamed by #3666 for the 168 h cache, configured and observed to 12.05 h (CAM-71 verify §8b); a poll after 2026-11-08T06:04Z observes the week |
| A34 — Git runs repository-local programs as the invoking account, and refuses foreign-owned repositories unless trusted | world | Only the writer changes the reference tree; Readers trust the writer’s tree and nothing broader | self-attested; observed by the VM threat demonstration (a writer-planted core.fsmonitor runs as a reader) and stibnite’s dubious-ownership negative control (CAM-77 verify §5) |
| A35 — ghq resolves its root from the environment, then git configuration, then the home directory, through symlinks | world | Every participating account reads one reference tree per host; Each participating account resolves the shared root | self-attested; observed by ghq root resolving the shared root for every account on all three hosts (CAM-77 verify §5) |
| A36 — A host’s administrator can act as any account on that host | world | Moving per-account copies into the reference tree loses nothing and is reversible | self-attested; monitoring follow-up: evidence annotation follow-up; administrator membership read with getgrouplist on each host (CAM-77 verify §5) |
| A43 — nixbot’s migrations create the build and attribute columns the dev-loop copy reads, and finish times are transaction start times | world | Every dev-loop event is recorded once and kept for a year; A gap in the dev-loop history reaches a person within a day; The past week of the dev loop can be asked about; The collector reads nixbot’s builds and attributes through two cursor queries | self-attested; observed by magnetite’s schema dump equal to the lexically applied migrations (CAM-69 verify §9.2) |
| A44 — gitea-mq announces each batch transition in one of five exact journal messages | world | Every dev-loop event is recorded once and kept for a year; The past week of the dev loop can be asked about; gitea-mq’s five batch messages are parsed from its journal | self-attested; observed by per-msg journal counts equal to batch_event’s after #3560 (CAM-69 verify §9.6) |
| A45 — PostgreSQL on magnetite admits a local role named after the connecting system user without a password | world | The build service’s records are read without being changed and without a stored credential; The nixbot readers authenticate by peer and hold column grants only | self-attested; observed by both readers connecting by peer without a password on magnetite (CAM-69 verify §9.6) |
| A46 — GreptimeDB 1.2.1 keeps one row per key and time in a pre-created non-append table | world | Every dev-loop event is recorded once and kept for a year; The devloop tables are pre-created with keys, a time index and deduplication | self-attested; observed by count(*) equal to distinct keys after the overlap re-reads and the cursor reset (CAM-69 verify §9.6) |
| A47 — The collector’s sqlquery receiver resumes logs queries from the last row’s tracking value | world | Every dev-loop event is recorded once and kept for a year; The collector reads nixbot’s builds and attributes through two cursor queries | self-attested; observed by a collector restart re-reading only the overlap (CAM-69 verify §9.6) |
| A48 — magnetite’s journal keeps gitea-mq’s lines for longer than the reconcile’s window | world | A gap in the dev-loop history reaches a person within a day; devloop-reconcile compares batch events with the journal every day | self-attested; observed by the oldest gitea-mq.service entries 34 and 32 days old, with no journal size or age limit (CAM-69 verify §9.7) |
| A49 — NixOS and nix-darwin run activation snippets before the current system is relinked | world | A deploy can be attributed to the commits that built it; Each activation appends one deploy record | self-attested; observed by D1’s record naming the replaced closure (CAM-69 verify §9.3) |
| A50 — electrum, galena and scheelite exist only while provisioned on demand | world | A missing signal is itself reported; Each agent host contributes its own signals to the telemetry store | self-attested; observed by the evaluated host table and no stored series from electrum, galena or scheelite (CAM-71 verify §8b) |
| A51 — pyrite’s NVMe controller answers the SMART health log at the pinned smartmontools | world | Each known failure class on a host reaches a person as an alert; A laptop’s disk health is read on the host and served on loopback; Each agent host contributes its own signals to the telemetry store | self-attested; observed for the health log by pyrite’s SMART samples stored every minute after #3668; the error-information log is not answered and not read (CAM-71 verify §8b) |
| A52 — The collector answers back-pressure with a retryable refusal and keeps its persistent queue across an outage and a restart | world | Collection survives a telemetry store restart without losing the queued interval | self-attested; observed by the fleet-ingress back-pressure and restart cases (CAM-71 verify §8b) |
| A53 — healthchecks.io counts a ping by its URL and emails when pings stop for longer than a check’s period and grace | world | An outage of the alert path reaches the operator by email from outside the fleet; The dead-man pings the watch service only after a passing run | self-attested; observed twice on 2026-11-04, each down email 15 min after the last accepted ping and each up email after the first ping (CAM-76 verify §8b, §9.2) |
| A54 — healthchecks.io runs outside the fleet, on Hetzner in Germany | world | An outage of the alert path reaches the operator by email from outside the fleet | self-attested; read from the service’s pages on 2026-11-01; not violated, no outage of the service seen from 2026-11-04T14:30Z to 2026-11-05T14:16:43Z (CAM-76 verify §8b) |
| A55 — The operator’s mailbox is reached without the fleet | world | An outage of the alert path reaches the operator by email from outside the fleet | self-attested; observed by the down email arriving at a gmail.com address while ntfy on cinnabar was stopped, 2026-11-04 15:25:06Z to 15:50:06Z; an outage of cinnabar itself not exercised (CAM-76 verify §8b) |
| A56 — Kanidm refuses an authorization whose scopes no group of the person maps | world | A person outside the dashboard group is refused; The identity provider admits only the dashboard group | self-attested; observed by cameron’s Access Denied before he joined perses_users, 2026-11-05 about 14:02Z (CAM-73 verify §8b) |
| A57 — Dashboard-group membership is kept in the running identity provider | world | A person outside the dashboard group is refused; A person removed from the dashboard group loses access within an hour; The identity provider admits only the dashboard group | self-attested; observed by the empty group after the deploy and the member added by kanidm group add-members, 2026-11-05 (CAM-73 verify §8b) |
| A58 — Perses 0.55.1 removes its write routes in read-only mode, proxies with the stored credential and fixed headers, and refreshes a session without depending on the identity provider’s answer | world | An admitted person views the fleet’s signals and the dev-loop history by host; A person removed from the dashboard group loses access within an hour; Nobody changes the views except by a committed change; No store credential reaches a person, and the dashboard service only reads; Readers hold only read permission on a read-only server; The telemetry store is read only through two global datasources; Committed files are the only source of views and datasources | self-attested; observed by the probe at 0.55.1, the container runtime test and an anonymous PUT answered 405 on magnetite; the refresh clause rests on its source read (CAM-73 verify §8b) |
| A59 — GreptimeDB 1.2.1 reads x-greptime-auth before Authorization | world | No store credential reaches a person, and the dashboard service only reads; The telemetry store is read only through two global datasources | self-attested; observed by the container runtime test’s bypass control reaching the store as admin (CAM-73 verify §8b) |
| A60 — magnetite is reachable on public TCP port 80 for HTTP-01 | world | The dashboard hostname resolves to magnetite | self-attested; observed by the certificate for obs. issued at deployment, 2026-11-05 (CAM-73 verify §8b) |
| A67 — Helium identifies an unpacked extension by the resolved path of its folder | world | Each browser profile loads the relay extension once; The loaded relay extension follows the agent release without being reloaded by hand; Trust boundary of the delivery interface | self-attested; observed once: the recorded path and extension ID in sciexp match the prediction on Helium 0.20.3.1 (CAM-79 verify §8b, §9.3) |
| A68 — omp’s relay refreshes only its own extension folder, only toward a newer release, and then reloads the extension | world | The loaded relay extension follows the agent release without being reloaded by hand; Trust boundary of the delivery interface | self-attested; not observed: relay and extension both reported 18.16.0, so no refresh was due (CAM-79 verify §8b); observation carried by CAM-80 |
A69 — omp’s default relay extension folder is ~/.omp/browser-relay/extension while no XDG data folder or profile for omp exists | world | The relay extension is present for every account that runs the agent on a macOS host; The loaded relay extension follows the agent release without being reloaded by hand; Trust boundary of the delivery interface | self-attested; configured and not violated for crs58 on stibnite on 2026-11-05: $XDG_DATA_HOME/omp absent and ~/.omp a real directory (CAM-79 verify §8b) |
| A61 — launchd misses a StartInterval firing during sleep and coalesces missed StartCalendarInterval firings into one run at wake | world | An unreachable telemetry store or a silent host freezes alerts; Store errors and silent hosts freeze instance state; No darwin collection job runs on a calendar schedule | self-attested; the StartInterval half observed over 8.6’s sleep from 2026-11-07T07:13:58Z to 07:53:52Z, the probe running once within 60 s of wake and the envelope once within 300 s; the calendar half not violated from 2026-11-06T05:12Z, no darwin collection job using StartCalendarInterval, and its coalescing at wake not exercised, because org.nixos.nix-cleanup-gcroots was kickstarted at 2026-11-08T00:12:53Z by operator decision O2 instead of waiting for its calendar run (CAM-72 verify §8c) |
| A62 — launchctl print reports a system job’s state, runs and last exit code as unversioned text, and omits the exit code for some killed jobs | world | The darwin probe reports each allow-listed launchd job and the host’s disk health in a textfile; Each known failure class on a host reaches a person as an alert; Each agent host contributes its own signals to the telemetry store | self-attested; observed after a SIGKILL of otelcol-process at 2026-11-07T05:42:20Z: no last exit code or last exit reason line, last terminating signal = Killed: 9, and launchd.prom -1 (CAM-72 verify §8c) |
| A63 — stibnite’s internal SSD answers the SMART health read without privilege at the pinned smartmontools | world | Each known failure class on a host reaches a person as an alert; A laptop’s disk health is read on the host and served on loopback; Each agent host contributes its own signals to the telemetry store | self-attested; observed by eight smartctl_device_* series stored for stibnite, read by _prometheus-node-exporter, at 2026-11-06T05:20Z, and not violated from 15:48Z to 21:27Z (CAM-72 verify §8c) |
| A64 — stibnite sleeps and wakes in the dark many times a day | world | An unreachable telemetry store or a silent host freezes alerts; Store errors and silent hosts freeze instance state | self-attested; observed by 13 dark wakes in 8.6’s 40 min sleep and 26 in 8.7’s natural sleep; pmset -g log held 22 to 132 Sleep entries a day from 2026-10-31 to 2026-11-06, below the first-stated 90 to 140 on five of seven days, so tasks.md 11.8 restated the range as 20 to 140 with agent sessions’ power assertions keeping stibnite awake (CAM-72 verify §8c, review.md F8) |
| A65 — A store-built binary on stibnite reaches the ingress over ZeroTier | world | Every dev-loop event is recorded once and kept for a year; Each agent host’s collector ships its own deploy records; Each agent exports by its role; Each agent host contributes its own signals to the telemetry store; A failed collection or store job notifies a person | self-attested; observed by the store-built collector’s sends growing from 725 to 971 points in 60 s at 2026-11-06T05:20Z, and not violated since (CAM-72 verify §8c) |
| A66 — ntfy refuses an anonymous post to a fleet topic from stibnite | world | The alerter token travels only as a file; A failed collection or store job notifies a person | self-attested; observed by an anonymous post from stibnite refused with 403 at 2026-11-07T08:31:42Z (CAM-72 verify §8c) |
| A70 — macOS top prints a process’s physical footprint as unversioned text to an unprivileged account | world | otel-envelope regulates each agent from its own collector; The telemetry store and the collector run inside a declared envelope | self-attested; observed at 2026-11-06T05:26Z and not violated from 06:28Z, every C5 run passing but 8.2’s control; 8.1’s window judged over 2026-11-07T08:24Z to 2026-11-08T00:30Z by operator decision O2 (CAM-72 verify §8c) |
| A77 — macOS resident size counts each process’s mapped share of the shared cache, so ordinary processes read tens to hundreds of MiB | world | Series cardinality stays bounded; The collector’s configuration bounds what it gathers | self-attested; observed by stibnite’s stored resident sizes from 2026-11-06T05:17Z to 21:14Z, 82 names above 64 MiB (CAM-72 verify §8c) |
A9–A12, A14–A28 and A71–A76 remain absent from the current main corpus: active deltas carry them (stand-up-nixbot-on-magnetite A9–A12, k3s-nixos-vm-tests A14–A16, capi-hetzner-cluster A17–A21, stand-up-gitea-mq-on-magnetite A22–A28, bind-mesh-writes-to-their-host A71–A76), not this archive; path-scope-plugin-releases (A9, A10), filter-check-sources-for-substitution (A22, A23) and k3s-nixos-vm-tests (A13) reuse numbers already taken, unresolved here.
CAM-64 tracks full-content MODIFIED sync loss; CAM-68’s MODIFIED Grounded vocabulary for behavioral requirements was synced as a whole-block replacement carrying its fourteen double-sense terms.
CAM-70’s MODIFIED block was synced the same way, carrying fifteen double-sense terms (evaluator added) and every pre-sync row, with credential (notification service) rewritten under the same term and sense (CAM-70 verify §10.3).
CAM-77’s MODIFIED block was rebuilt on CAM-70’s synced block before it archived and synced the same way: every pre-sync row is kept, person and writer are each split into two senses (the earlier text kept under service and database), eleven rows are added, and eighteen double-sense terms are named (CAM-77 verify §3).
CAM-69’s MODIFIED block was synced the same way as a whole-block replacement: all 136 pre-sync term rows are kept and its 35 rows are added, 171 in all (CAM-69 verify §10.6).
CAM-71’s MODIFIED block was synced the same way as a whole-block replacement: every pre-sync row is kept but collected host, rewritten under the same term to name magnetite, cinnabar and pyrite (CAM-71 verify §8a.3), and its 16 rows are added, 192 in all, with twenty-two double-sense terms named; its three new assumptions A50–A52 were added beside it.
CAM-76’s MODIFIED block was synced the same way as a whole-block replacement on CAM-71’s synced main, unchanged since: every pre-sync row is kept and its 3 rows, watch service, ping and email, are added, 195 in all; its MODIFIED A33 and its three new assumptions A53–A55 were added beside it (CAM-76 verify §8a.3).
CAM-73’s MODIFIED block was rebased on CAM-76’s synced main before it archived and synced the same way as a whole-block replacement: every pre-sync row is kept and its 7 rows, dashboard service, view, chart, dashboard group, admitted person, identity provider and browser, are added, 202 in all; its five new assumptions A56–A60 were added beside it (CAM-73 verify §8a.3).
CAM-79’s MODIFIED block was synced the same way as a whole-block replacement on CAM-73’s synced main, unchanged since: every pre-sync row is kept but browser, split into the senses dashboard, carrying the pre-sync text, and relay, and its 13 rows are added, 215 in all, with twenty-four double-sense terms named; its three new assumptions were added beside it as A67–A69, renumbered from A61–A63 at archive because the active stand-up-darwin-collection holds A61–A66 (CAM-79 verify §8a.3 and Addendum).
CAM-72’s MODIFIED block was retaken from main after CAM-79’s archive by tasks.md 11.1 and synced the same way as a whole-block replacement: every pre-sync row is kept but collected host, rewritten under the same term to name stibnite, and its 7 rows are added, 222 in all, with probe given a third sense and twenty-four double-sense terms named; its eight new assumptions A61–A66, A70 and A77 were added beside it (CAM-72 verify §8a.3).
stand-up-gitea-mq-on-magnetite and stand-up-nixbot-on-magnetite still MODIFY the block from copies that lack main rows, now including CAM-79’s and CAM-72’s; by the operator’s decision of 2026-10-28, CAM-69 archived first, each of them rebuilds its block on CAM-69’s synced main before its own archive, and stand-up-gitea-mq-on-magnetite’s batch, merge queue and pull request rows are reconciled with CAM-69’s then (CAM-69 verify §10.6, retrospective §6).
CAM-41 qualifications
Section titled “CAM-41 qualifications”- W1/W2/W3: canonical four-direct-target provenance, build-only APM statement and absolute-autoload census conflict with the observed two-target/later-fan-out, producer installer and single-force-load arrangement; separate canonical reconciliation remains open.
- W4: the archived verification could not establish repository-local ignored
.agents/delivery; post-main generated relock is required before that frozen-delivery claim. This projection does not assert current root-lock or ignored-tree contents. - W5/W6: archived repository evidence did not establish absence of external activation/landing or publication; those historical boundaries are not new queries of present forge state.
- S1: placeholder Purpose maintenance remains separate from these discharges; no repo-wide structural success is claimed here.
CAM-62 qualifications
Section titled “CAM-62 qualifications”- Battery inactivity and panel blank/lock were discharged by evaluation, not behavioral observation. Each residual costs an elapsed idle window and no redeploy; no new window is claimed by CAM-63.
- The inactivity requirement has no named S: the greeter/user dconf properties occur only in design/tasks. Its world A13 annotation alone does not discharge it; the table retains the undischarged row and retrospective §6 follow-up.
laptop,person, andnetworkdesignation gaps were recorded, not silently repaired; CAM-63 adds its own recorded vocabulary/interface gaps.- CAM-59 remains an unexplained resume defect, historical cohort 8 failures against 30 successes across 14 boots after CAM-62 verification. The latest failure broke the prior first-suspend-of-boot success regularity; idle harm reduction is not a repair.
- No plan.md was authored in CAM-62; tasks carried the manual-check role. Publication and full behavioral coverage were not inferred from archive.
CAM-63 qualifications
Section titled “CAM-63 qualifications”Primary disposition record: openspec/changes/archive/2026-09-10-pyrite-niri-second-session/verify.md §9.12; incident: known-limitations.md; follow-ups: retrospective.md §6.
- Requirement amended after counterexample: only unconditional GNOME reachability and recovery WHEN narrow for live-niri display-manager restart; GNOME registration/selectability/default-for-no-history, per-user persistence/no host overwrite and recovery THEN/AND remain outside that exception. Niri v26.04 lacks the leader-death bridge GNOME 50.1 has; no configuration of ours supplies that upstream behavior. This is not a fixable configuration defect hidden by bar-lowering. CAM-66 remains the excluded, unrepaired upstream follow-up, not a discharge or a claimed upstream submission.
- 8.2 split: remembered choice discharged by persisted Session=niri at operator login and subsequent logins; no-history GNOME remains a METHOD LIMITATION, source-read only, grounded in GDM 50.1 hardcoded fallback and explicit defaultSession=null/no rewrite, not observation and not discharged-by-evaluation. The operator declined destroying their real saved preference; a second disposable user with no session history is the safe future check.
- 6.6 runtime observation: niri session 238 / compositor PID 158454, gsettings through its own environment: idle-delay uint32 1800, gsd power schema absent from XDG_DATA_DIRS. GNOME power settings are structurally inapplicable in that niri session, not merely unread by an absent daemon. Four delay-mode sleep inhibitors, no block handle-power-key inhibitor, independently corroborate niri 8.7; GNOME gsd-media-keys holds that block-mode inhibitor and bypasses logind.
- 8.3/8.4/8.5 evaluation, not observation. 8.6 declined under CAM-59 physical-recovery risk. No untouched niri AC/battery or repeated GNOME/greeter interval, no deliberate niri suspend/guard/wake pass.
- 8.7 physical tests: GNOME 176 press at 02:02:54.328864 UTC; niri 209 presses at 02:03:39.311662 and 02:03:41.429194, all on 2026-09-10. Same-boot pre-fix positive control: September 9 21:16:36.327747 press → media-keys request 21:16:36.392292 → PM entry 21:16:37.863260. Protected logged presses with no suspend/shutdown are negative controls. Whole-boot totals 1 requested / 1 entry, not zero or two; the extra grep hit was sudo audit text.
- Task 8.1 was the test that would have caught the strand. The checklist ordering itself caused the lockout inside niri. Correct order quits niri and verifies the affected user service inactive before any separately authorized display-manager restart; SSH/greeter location alone is insufficient.
- Formal obligations remain undischarged: no named S for any of the four CAM-63 delta requirements. V-interface/V-vocabulary are agent-executed/non-blocking findings, NEVER validation; a clean designation lint without grounding is vacuous.
- Slice B residuals: xwayland-satellite absent, xcursor-theme default warning, GNOME GlobalShortcutsProvider InvalidArgs warning, portal functional transactions untested, 8.2 no-history half, empty logind Desktop despite niri environment/desktop-entry metadata. Empty Desktop propagation remains unresolved rather than guessed.
- Other follow-ups unchanged: CAM-59 resume, CAM-60 unattended boot, CAM-61 Bluetooth/wlp2s0, CAM-64 MODIFIED content loss. The local C sd-login monitor was deliberately not carried; prototype preserved in logs/niri-session-strand-defect.md, not verified end-to-end.
CAM-68 qualifications
Section titled “CAM-68 qualifications”Primary disposition record: openspec/changes/archive/2026-10-18-stand-up-greptimedb-on-magnetite/verify.md §8b; deployment evidence §§9–10; review follow-ups §11 and review.md; follow-ups: retrospective.md §6.
- Verdict PASS WITH WARNINGS: the warnings were §8a (content nouns without a designation row) and §8c (two non-world phenomena in behavioral requirements); both were addressed in #3501 before archive, and the synced designation table and
Series cardinality stays boundedcarry those fixes. - Four requirements postdate §8b:
Part of a database keeps the database's retention unless another is declared,Tables allowed a retention of their own are declared,The store and the collector name the same databasesandA failure episode ends at the unit's next successful start or exitcame from review findings F1, F3 and F4 (#3497, #3498); their rows citetasks.md10.1, 10.4, 10.5 and 10.10 and verify §11, not the §8b table. - Interface discharges are regulator and runtime-test evidence: evaluation-time checks with mutants, the hourly envelope regulator, the pipeline container test and the on-demand pyrite VM kill-order test, plus first-activation observations on magnetite.
The account file the telemetry store loaded is recordedis named by noDischarges:clause by title; task 5.1 names it as R7.4. - Trust boundary is stated, not discharged: R2 durability and token scope belong to Cloudflare (A29), any root process on magnetite can reach the loopback listener, ntfy access was ZeroTier membership until CAM-70 replaced it with ntfy’s access entries, and cinnabar is the single delivery path (A33); nothing here guarantees a series reaches the store end to end.
- The roborev sub-gate was replaced at the operator’s direction by the holistic review in
review.md(twelve findings, all applied); verify §11 records the redeployments after #3497 and #3499.
CAM-70 qualifications
Section titled “CAM-70 qualifications”Primary disposition record: openspec/changes/archive/2026-10-21-stand-up-fleet-alerting/verify.md §8b; deployment evidence §§9–10; review follow-ups §11 and review.md; follow-ups: retrospective.md §6.
- Verdict PASS WITH WARNINGS: the
LocalExporterDownpair that tasks.md 9.1 asks to see on the phone was not observed there, because no phone was subscribed until 2026-10-20; its last link is composed from pyrite’s capture offleet-alertsand the 7.7 test post received on the phone over the same topic and server (verify §10.1); the §8a designation nouns remain open as a retrospective §6 promote item. - Review follow-ups changed requirements:
An always-on host's silence is reportedwas added, andA missing signal is itself reported,The evaluator's memory ceiling and start timeout are assertedand the title requirement were amended, by #3516; the always-on-host clause is discharged by check only, with no runtime observation. - Interface discharges are regulator, package-test, assertion and runtime evidence: evaluation-time checks with mutants (
fleet-alert,ntfy-provisioning,otel-collector-config,package-ntfy-send-test-token-transport), host assertions shown able to fail by overrides, and cutover observations on magnetite and cinnabar, some made by an agent and marked so in verify §8b. - Trust boundary is stated, not discharged: ntfy enforces the access entries and rate limits (A37–A41); any root process on magnetite or cinnabar can read the
alertertoken; cinnabar is the single delivery path (A33), and nothing reported an ntfy outage before CAM-76 added healthchecks.io’s email, a gap that blocked CAM-72 (review F4); nothing here guarantees that an alert reaches a person. - The roborev sub-gate was replaced at the operator’s direction by the holistic review in
review.md(twelve findings, none critical): F1–F3, F5–F9, F11 and F12 were applied in #3516 and #3519, F4 is documented, and F10 is deferred to S2; verify §11 records the redeployment after #3516, and #3519 was not deployed because it changed no alerting unit.
CAM-69 qualifications
Section titled “CAM-69 qualifications”Primary disposition record: openspec/changes/archive/2026-10-28-stand-up-devloop-collection/verify.md §8b; deployment evidence §§9–10; review follow-ups §11 and review.md; follow-ups: retrospective.md §6.
- Verdict PASS WITH WARNINGS: tasks.md 9.1’s arrival and batch legs were measured on a substitute build and batch, not on pull request 5 (verify §10.1, §10.2); the reconcile window is six scheduled runs by operator decision, not seven (§10.4); and 10.5’s store-failure count is 4, not 0, from the two evaluator failures of 2026-10-25 inside magnetite’s deploy windows, which posted no
StoreQueryFailing(§10.5, §12.3). - Review follow-ups changed requirements: #3564 amended
Column grants are applied once nixbot's columns exist(F2),devloop-reconcile compares CI rows with nixbot every day(F3),devloop-queries binds the abandonment marker to the patch's production code(F5) anddevloop-reconcile runs daily as its own reader(F7) and was deployed as REVC; F1, the burn rule firing on flake-updater batches, was kept as is by operator decision O3 (#3591, tasks.md 10.10). - Interface discharges are regulator, container-test and observed evidence: evaluation-time checks with mutants (
devloop-queries, R3.1, R8.2, the deploy-record obligation, the collector’s journal assertion), thedevloop-ingestcontainer test with its mutant legs, and observations on magnetite after D1–D5, D3B and REVC; the deploy-record obligation is held by CI on the five x86_64-linux NixOS machine checks only, and the four darwin machines and scheelite were shown once by evaluation (retrospective §6 carries the follow-up for S5). - Trust boundary is stated, not discharged: nixbot and gitea-mq produce the source rows and lines and magnetite only reads them, trusting their schema and messages at the pinned revisions; any root process on magnetite can read the
regulatorpassword and the deploy-record file, which is world-readable on every host; deploy records on other hosts are not shipped until S4 and S5; nothing here guarantees that a given dev-loop event reaches the store. - The roborev sub-gate was replaced at the operator’s direction by the holistic review in
review.md(ten findings, none critical): F2–F10 were applied in #3564 and F1 was decided by the operator in #3591 (verify §11). - At archive, the bodies of eight requirements this change MODIFIED in
fleet-alerting-interface,host-metrics-collectionandtelemetry-store-interfacewere shortened to 500 characters or fewer by moving their enumerations into scenarios of the same requirement, with titles and obligations unchanged, so that every capability this change touches other thanworld-assumptionspassesopenspec validate --specs --strict.
CAM-71 qualifications
Section titled “CAM-71 qualifications”Primary disposition record: openspec/changes/archive/2026-11-02-stand-up-linux-fleet-collection/verify.md §8b; trust boundaries §8d; deployment evidence and observations §9; review follow-ups tasks.md §12 and review.md; follow-ups: retrospective.md §6.
- Verdict: every
tasks.mditem is done; pyrite’s acceptance (tasks 5.8, 9.1’s pyrite part, 11.1) was taken over its observed window from 2026-11-01T05:55:54Z to 2026-11-02T00:57:15Z by the operator’s decision of 2026-11-02 (verify §9.3), and pyrite’s suspend and resume was observed once, not repeatedly (A13). - Review follow-ups changed requirements: the holistic review in
review.md(thirteen findings, none critical) was applied astasks.md§12; F9 restated FAA missing signal is itself reportedwith a 15-minute bound, the store’s 5-minute lookback followed by the evaluator’s 10 minutes, and F4 re-read A37–A40 at ntfy 2.31.0, whose version guard is CAM-78; #3666 broughtA silent evaluator is reported from another host, the dead-man requirement and the renamed A42 into the deltas. - Interface discharges are regulator, container-test and observed evidence: evaluation-time checks with mutants (
otel-collector-config,otel-envelope,fleet-alert, R8.2 and the agent role’s assertions shown failing by overrides), thefleet-ingresscontainer test, and observations on magnetite, cinnabar and pyrite after each deploy; stibnite’s refusal at the ingress is observed, and electrum, galena and scheelite are shown only by evaluation. - Trust boundary is stated, not discharged: any holder of an
otel-cacertificate is trusted to write, and a certificate’s CN is not bound to thehost.nameits agent stamps; certificates have no revocation, so a lost key stays valid untilotel-cais rotated; ZeroTier carries packets and does not authenticate the writer; nothing here guarantees that a given series or dev-loop event reaches the store. - At archive, the statement of FA
A missing signal is itself reportedwas shortened to 500 characters or fewer by moving the account of its 15 minutes into a new scenario of the same requirement,The 15 minutes are counted, with its title and obligations unchanged, so that no spec newly failsopenspec validate --all --strict.
CAM-76 qualifications
Section titled “CAM-76 qualifications”Primary disposition record: openspec/changes/archive/2026-11-05-watch-the-alert-path-externally/verify.md §8b; trust boundary §8d; acceptance times §9.2; deviations and the observed gap §10.
- Verdict: every
tasks.mditem is done; 4.2 and 4.3 ran from one-shot timers with the operator confirming the received times afterwards (4.1), and 4.4’s quiet window ran 21 h 37 min rather than 24 h by the operator’s decision. - Observed gap, not discharged: a dead-man failure during an ntfy outage posts no
FAILED fleet-deadman, because the notifier posts to the stopped ntfy and does not retry; the healthchecks.io email reported the outage (verify §10). - Interface discharges are regulator, package-test, assertion and observed evidence: the
fleet-alertping legs with five mutants, the ping transport test with its argv mutant, the store-path assertion shown failing by an override, and observations on cinnabar and magnetite from 2026-11-04T14:28:53Z to 2026-11-05T14:16:43Z. - Trust boundary is stated, not discharged: healthchecks.io evaluates the check’s period and grace and sends the email, the operator’s mail provider delivers it, and this machine only pings; the check’s period, grace and integration are set in healthchecks.io’s interface; the ping URL is a bearer credential any root process on cinnabar can read; nothing reports an outage that takes down healthchecks.io together with cinnabar.
- At archive, the statement of FAI
The rule check runs promtool, fixture mutants and a property testwas shortened to 500 characters or fewer by dropping its closing clause on the 0.5 GiB budget, which its scenarioThe check's evaluation cost is measuredalready states, so that no spec newly failsopenspec validate --all --strict.
CAM-73 qualifications
Section titled “CAM-73 qualifications”Primary disposition record: openspec/changes/archive/2026-11-05-serve-the-fleet-dashboard/verify.md §8b; trust boundary §8d; evaluation cost and acceptance times §9; deviations and observed gaps §10.
- Verdict: every
tasks.mditem is done; 7.1 stands on the operator’s statement at admission that both views showed collected data, by the orchestrator’s decision, with the store’s per-host memory samples, Perses’ memory after its restart, an anonymous write refused and the Kanidm client’s tile fields read by command afterwards (verify §10). - Observed gaps, not discharged: the browser’s storage on
obs., a save attempted by an admitted person in the UI, the tile as the apps portal draws it, and each host’s latest point in the view were not observed; no removal fromperses_userswas performed, so the one-hour loss of access is configured, not observed (verify §8b, §10). - Interface discharges are regulator, package-check, container-test and observed evidence:
perses-lintandperses-configwith their mutants,package-perses-bin’s install check with its mutant, magnetite’s assertions shown failing by overrides, the on-demand container runtime test with its bypass control, and observations on magnetite on 2026-11-05. - Trust boundary is stated, not discharged: Kanidm authenticates people and refuses non-members, and membership is set in the running Kanidm outside the repository; Perses enforces read-only mode, guest permissions, endpoint patterns and header allow-lists, and the store refuses writes from
perses:ro; a removed member keeps access for at most 1 h; any root process on magnetite can read the credentials; nothing compares a rendered chart with the stored series. - At archive, the statements of TS
The telemetry store runs a stable vendor release that serves its dashboardand TSICredentials exist only as activation-resolved files owned by non-worker userswere shortened to 500 characters or fewer by dropping a closing clause that adds no obligation, and the Purposes offleet-dashboardandfleet-dashboard-interfacewere written after the sync, so that no spec newly failsopenspec validate --all --strict.
CAM-77 qualifications
Section titled “CAM-77 qualifications”Primary disposition record: openspec/changes/archive/2026-10-20-share-ghq-reference-tree/verify.md §8b; runtime and deploy evidence §5; review rounds §5a–5e; follow-ups: retrospective.md §6 and task 9.4.
- Verdict PASS WITH WARNINGS: task 9.4, deleting stibnite’s empty
~/ghq.pre-shared-20261017and the migration records, waits for the operator; a deploy of main before the merge removed the writer from magnetite, recovered by redeploying with the same uid (verify §5). - Trust boundary decided by the user (2026-10-17): only an administrator’s tree moves in place, under A36, and only when no entry could have been written by another account; every other account’s tree is set aside and reacquired through the writer; nothing a non-administrator wrote is in any shared tree.
- Interface discharges are evaluation, package-test, VM and post-deploy evidence: module assertions shown able to fail by mutations, the NixOS test with the
group-writableandbroken-controlmutations, and post-deploy checks on pyrite, magnetite and stibnite; darwin runtime behaviour is observed by inspection on stibnite only, and the darwin migration refusal is tested through its probe, not an end-to-end apply. - Trust boundary is stated, not discharged: the properties hold at the hosts’ declared configuration and Unix permissions; they do not cover an account overriding its own git or ghq configuration, root or the writer acting against the tree, or upstream content.
CAM-79 qualifications
Section titled “CAM-79 qualifications”Primary disposition record: openspec/changes/archive/2026-11-05-deliver-omp-browser-relay/verify.md §8b; trust boundary §8d; evidence §9; the person’s decisions and the renumbering in its Addendum; follow-up CAM-80.
- Verdict PASS WITH WARNINGS: tasks 5.2 and 6.1 were rescoped by the person’s decision to the one Helium profile in which the relay is loaded,
sciexp, because loading it hands omp control of that profile; the badge reading “on” was not recorded by the verifier and rests on the person’s report (verify Addendum). - Undischarged at archive, by the person’s decision: BRD
The loaded relay extension follows the agent release without being reloaded by handand task 5.4 wait for the firstllm-agentsomp bump deployed to stibnite, and A68 is not yet observed; follow-up CAM-80. - Interface discharges are package-check, evaluation and observed evidence: the package check with its stamp mutant and an empty
diff -ragainst upstream’s zip, the symlinked-folder refusal in a test activation, evaluations of the option, the managed settings and the Helium defaults, and the post-activation inspection on stibnite; the drop-a-file scenario was not exercised on stibnite. - Trust boundary is stated, not discharged: Helium derives the extension identity (A67), omp’s relay writes the folder between activations and reloads the extension (A68), omp chooses the folder (A69) and honours a per-request relay choice; nothing here confers isolation between an agent and the person’s browser once the extension is loaded.
- At archive, world assumptions A61–A63 of this change were renumbered A67–A69, because the active
stand-up-darwin-collectionalready holds A61–A66; no other change was edited.
CAM-72 qualifications
Section titled “CAM-72 qualifications”Primary disposition record: openspec/changes/archive/2026-11-08-stand-up-darwin-collection/verify.md §8b; designation lint §8a; world assumptions §8c; trust boundaries §8d; evaluation cost, deploy and acceptance records §9; migration flags §10; review follow-ups tasks.md §11 and review.md; follow-ups: retrospective.md §6.
- Verdict: every
tasks.mditem is done; 8.1 was judged by the operator’s decision O2 of 2026-11-07 over 2026-11-07T08:24Z to 2026-11-08T00:30Z, about 16 h instead of 24 h, with the distinct-process-name criterion read over the full 24 h ending 00:30Z; for 6.1a,org.nixos.nix-cleanup-gcrootswas kickstarted at 2026-11-08T00:12:53Z instead of waiting for its calendar run, so launchd’s calendar trigger, A61’s calendar half, is not exercised. - Discharged by operator decision O2: the rows resting on 8.1 or 6.1a, FA
Each known failure class on a host reaches a person as an alert, FIIotel-envelope regulates each agent from its own collector, HMCSeries cardinality stays boundedand TSIThe telemetry store and the collector run inside a declared envelope, are discharged with that qualification, and A61 and A70 carry it in their status. - Review follow-ups changed requirements: the holistic review in
review.md(nineteen findings, four significant, none critical) was applied astasks.md§11; F1 retook the vocabulary block from main, F2 stated each platform’s process floor and the darwin keep-list in TSI and named A77 in HMC, F3 added clauses reading stibnite’s evaluated limiters and C5’s limits, F7 addedwatched launchd jobs, and F8 restated A64’s range; F17 was rejected. - Interface discharges are regulator, assertion, container-test and observed evidence: evaluation-time checks with mutants (
otel-collector-darwin,otel-envelope,fleet-alert), the darwin fragment’s assertions shown failing by overrides, thefleet-ingresscontainer test at #3736’s head, and observations on stibnite and magnetite from 2026-11-06 to 2026-11-08, among them the stopped-collector, stopped-job, signal-kill, plist-reload, induced-sleep and anonymous-post controls of tasks 8.2 to 8.8. - Trust boundary is stated, not discharged: any holder of an
otel-cacertificate is trusted to write, and a certificate’s CN is not bound to thehost.nameits agent stamps; stibnite’s key and its copy of thealertertoken travel on a laptop and stay valid untilotel-cais rotated or the token replaced;org.nixos.otelcol-processruns as root, and any root process on stibnite can read the_otelcolkey and inject points on loopback; the probe trustslaunchctl print’s unversioned text (A62); adeploy_recordrow’shostdoes not prove which host sent it; nothing here guarantees that a series, a dev-loop event or an alert reaches its end. - At archive, seventeen requirement statements in
fleet-alerting,fleet-alerting-interface,fleet-ingress-interface,host-metrics-collectionandtelemetry-store-interfacewere shortened to 500 characters or fewer by moving twenty whole sentences verbatim into new scenarios of the same requirements, with titles and obligations unchanged, so that no spec newly failsopenspec validate --specs --strict(record:logs/s5-evidence/9.6-shortening-20261108T002103Z.md). - Left open: F11’s per-host derivation of the kept-alive labels and F15’s narrowing of D10’s restart to host silence are new issues not yet filed, whose texts are in
logs/s5-evidence/new-issues.md; F16 is deferred to CAM-88, with F18’s per-executable sum; F13’s summary change reaches magnetite at its next deploy.
Known limits
Section titled “Known limits”This projection contains no formal proof and no claim of end-to-end implementation verification.
The three inherited CAM-41 interface discharges establish machine-visible artifacts only: no harness selection, human compliance, authorization, forge correctness, activation or landing guarantee.
The 36 CAM-68 discharges establish configuration, regulator and tested-pipeline behavior on magnetite only; they assert neither R2 durability, ntfy delivery when cinnabar is down, nor end-to-end arrival of every series.
The 26 CAM-70 discharges establish configuration, regulator and observed cutover behavior on magnetite and cinnabar only; they assert neither delivery while cinnabar or its notification service is down, nor that a person reads an alert.
The 31 CAM-69 discharges establish configuration, regulator, container-test and observed behavior on magnetite only; the deploy-record obligation is held by CI on the five x86_64-linux NixOS machine checks only, the four darwin machines and scheelite having been shown once by evaluation; they assert nothing about deploys on the other nine machines reaching devloop, nor about events nixbot or gitea-mq never record.
The 8 CAM-71 discharges establish configuration, regulator, container-test and observed behavior on magnetite, cinnabar and pyrite only, pyrite over its observed window; they assert nothing about stibnite, collected from CAM-72, or the other darwin machines, nor that a host’s series are written only under its own name, since a certificate’s CN is not bound to host.name.
The 14 CAM-77 discharges establish configuration, VM-test and post-deploy behavior on pyrite, magnetite and stibnite only; they assert nothing about upstream content or an account that overrides its own git or ghq configuration.
The 3 CAM-76 discharges establish regulator, package-test, assertion and observed behavior on cinnabar and magnetite only; they assert nothing about an outage that takes down healthchecks.io together with cinnabar, nor that an email reaches a person.
The 19 CAM-73 discharges establish configuration, regulator, container-test and observed behavior on magnetite only; they assert nothing about who a person in perses_users is, about a chart’s values against the stored series, or about stibnite, whose series arrived with CAM-72.
The 10 CAM-79 discharges establish package-check, evaluation and observed behavior on stibnite for crs58 in the Helium profile sciexp only; they assert nothing about other darwin hosts or profiles, about the relay extension following an omp upgrade (CAM-80), or about what an agent does in the person’s browser once a request asks for the relay.
The 2 CAM-72 discharges and its amendments of 31 discharged rows establish configuration, regulator, container-test and observed behavior on stibnite and magnetite only, stibnite’s acceptance judged over the window of operator decision O2; they assert nothing about other darwin hosts, which have no collector of their own, nor about launchd’s calendar trigger at wake, nor that a host’s series are written only under its own name, since a certificate’s CN is not bound to host.name, nor that a deploy_record row’s host names the host that sent it.
Pyrite file-db contents and runtime adoption are different evidence; user dconf overrides deliberately remain possible.
An archive-ready PASS WITH WARNINGS and an undischarged formal row are compatible claims at different boundaries, not a silent acceptance of missing evidence.