Knowledge base evolution log
Knowledge base evolution log
Structural history of this bundle: pages added, deprecated, moved, merged, or split, and corrections of fact. This is not a software changelog — releases, features, and bug fixes belong to the project's release notes, not here.
Newest first.
2026-10-15
- Added: Landing site — building
site/distwith podman or with the toolchainsite/toolchain.shinstalls for a CI build image, and the Cloudflare build settings that publish it. The build script gains a standalone-renderer path so a host without a container runtime can still render this bundle. - Correction of fact: the site publishes as a Worker with static assets, not a Pages
project.
wrangler deployreadssite/wrangler.toml, which now declares[assets] directory = "./dist"instead ofpages_build_output_dir; a Pages config is rejected by the deploy command with no entry point and no assets directory.
2026-10-15
- Added: CI and release automation land with the org move.
.github/workflows/gates every PR and push: the fast lane (fmt,vet,tidy,lint,test -short,build, pre-commit hygiene) runs in parallel on every change; the-racemerge gate (invariant 12) is sharded across four runners and runs on Go changes plus every main push; image+budgets andokfbundle gates are path-filtered; and a separatee2eworkflow runs the lima-backed acceptance gates on a schedule or manual dispatch, self-skipping when tools are absent.release-please-config.json+.release-please-manifest.jsonstart the pre-1.0 release line atv0.1.0(Decision 0022) and release-please, authenticated as the org's agync-bot GitHub App, owns the changelog and tags. Per Decision 0022 the app mirrorsCHANGELOG.mdtodocs/operations/CHANGELOG.mdas part of the release setup, so the two stay byte-identical.
2026-10-15
- Added: Decision 0022 withdraws the
v1.0 release label. The release line is pre-1.0 and begins at
v0.1.0; release-please owns later versions. The acceptance bar stays met and gate-tested —test/e2e/v1-acceptance-gate.shis the evidence — so only the label moved. The table in decisions/index.md gains its row. - Removed: the development-process pages, pruned as material that served the
build rather than the operator. Gone from design/:
delivery.md(milestones with effort),v1.1-roadmap.md(the ranked backlog),v1-acceptance.md(the acceptance bar — its gate,test/e2e/v1-acceptance-gate.sh, stays as the evidence),ui-brief.mdandtui-brief.md(superseded byweb-system.mdandtui-system.md),web-ui-renders.md,first-run-walkthrough.html,personas.md,bootstrap-first.md(the shipped half is operations/ansible-first-bootstrap.md),amendments.mdandrequirements.md(their substance is the operations pages that implement it). Thedesign/reference/tui/handoff inputs go with them;tui-system.mdis the distilled page. Every reference in code, decisions, and operations was retargeted rather than left dangling. - Removed: 30 screenshots under
design/assets/(5.3 MB of the section's 8.3 MB) that no page, README, or code referenced. - Correction of fact:
okf validatereports image links asokf/links/brokenbecause it resolves every link target as a concept id, and an asset is not a concept. The 21 findings are design/gallery.md plus the guide pages' asset references; the renderer resolves both link forms to the same correct path, so no link is actually broken. The count fell from 29 to 21 only becauseweb-ui-renders.mdwas pruned with the pages above.
2026-10-14
- Added: Decision 0021 keeps the
hostscope write-only and makes the request response the polling surface. The table in decisions/index.md gains its row; the host request's parameters and response are now documented in operations/api.md. - Correction of fact: the secret-management vocabulary now follows a secret's
source.
exocomp secrets replaceis the canonical verb (rotatestays an alias), the guide's commands and list-example column use it (CHANGEDfor a mixed list), and the TUI header isCHANGED. exocomp rotates only a secret it minted; for an operator-supplied credential it replaces the sealed copy while the old value is revoked upstream. - Moved:
docs/adr/became decisions/. The twenty records keep their numbers and meaning; the labelADR NNNNis nowDecision NNNNand prose says "record" instead of "ADR". Every path, link, and pointer was retargeted; no decision's meaning changed — this renames the collection and its term only. - Correction: The system-management design record's rule "server class
(public / self-hosted) is a fact about the URL, not the URL" is superseded.
The URL became an ordinary setting, not a sealed secret, in the modal round, so
the ntfy card may name it (a
serverfact). The topic figure'stopic · {class} servernote still carries the private-vs-public fact.
2026-10-13
- Reconciliation against code and runtime:
- Corrected CLI flags across
docs/guide/:source add(--url/--refand--path, not--kind/--branch),schedule add(play kind syntax--kind play --target <inv> -- <playbook>, 6-field cron),check add(--kind, targetname=spec, dynamic netgroups),token new(<name>positional, scopesoperator/readonly/approve), andsilence add(--for,--reason,--alert/--host/--global). - Grounded OpenTofu HTTP state backend URL in reality (
/api/v1/tf/state/<workspace>withLOCK/UNLOCKmethods, not/api/v1/tofu/state/with subpaths). - Clarified MCP agent interface (
docs/guide/agent-mcp.md): corrected token scopes and tool catalog matchinginternal/mcpanddocs/operations/mcp.md. - Replaced non-existent
EXOCOMP_LISTENwith real environment variables indocs/reference/configuration.md. - Reconciled
docs/operations/api.mdwith maintenance restart routes (GET/POST /api/v1/maintenance/restart). - Documented Web UI capabilities in
docs/operations/serve.mdanddocs/operations/sources.md: Git source sync ("Sync now"), schedule on-demand execution ("Run now"), contextual ntfy setup modal, and viewer-local timezone formatting.
- Corrected CLI flags across
2026-10-11
- Restructure: Reorganized
docs/into a user-guide-led, design-rich, and contributor-forward OKF v0.2 bundle:- Created
docs/guide/: index.md, quickstart.md, sources.md, ansible.md, opentofu.md, handoffs.md, secrets.md, checks.md, reactive.md, mobile.md, agent-mcp.md. - Promoted UI design & screenshots front and center in
docs/design/: added gallery.md (full multi-theme and mobile showcase), web-system.md, tui-system.md, and curated visual assets underdocs/design/assets/. - Expanded contributor manual in
docs/contribution/: added dev-setup.md, dev-workflow.md, testing.md, architecture.md, worktrees.md, and migrations.md. - Established
docs/reference/: index.md, cli.md, configuration.md, and exit-codes.md. - Re-scoped
docs/operations/to focus strictly on Day-2 cluster lifecycle, maintenance, disaster recovery, and failover runbooks. - Copied release changelog to repository root
CHANGELOG.md.
- Created
2026-10-10
- Moved:
history/left this bundle. The three candidate designs, the completeness critique, the accepted technical design for v1, and the nine research notes are now in theexocompsection of the lab wiki, which is where work kept for the record and not currently true belongs. This bundle now describes the shipped state only, with no rejected alternatives and no design-phase provenance. - index.md loses its History section, and design/index.md, design/amendments.md, decisions/0001-thin-core-architecture.md and decisions/0002-project-name-exocomp.md state their conclusions inline instead of linking across to another wiki.
- AGENTS.md and the docs-curator role card no longer list
history/in the bundle layout. - Update: Dropped the design handoff captures under
design/reference/: the two canvas PDFs, the
canvas/andrealign/artboard PNGs, and the standalone web and phone dashboard PNGs. Therealign/captures were already stale against the shipped surface, so nothing the code or the web UI depends on is lost. - Update: Dropped the seventeen
reference/tui/frame files that were byte-identical to the golden fixtures under ../internal/tui/testdata/frames/, which is the copy the tests read. - Five design notes that are not fixtures stay:
keymap.txt,colors.txt,copy.txt,states.txt, andREADME.txt.internal/tui/render.go,internal/tui/empty.goandinternal/tui/write.gocite them as the source of the color rule, the empty-state copy, and the keymap contract. - design/index.md and
design/ui-brief.md no longer point at the dropped paths,
and
.pre-commit-config.yamlno longer excludes the emptied directory.
2026-10-06
-
resolver reads local collection artifacts.
-
Decision 0015 gains an addendum: the collections resolver's sandbox grants read on the local
type: dir/type: fileartifact paths a requirements file names, soansible-galaxycan read a sibling checkout'sgalaxy.ymlunder the enforcing tier. The threat model records the read-only widening as an accepted residual.
2026-09-26
-
aggregate check events removed.
-
Removed the opt-in aggregate-check surfaces from operations/reactive.md, operations/mcp.md, and operations/api.md; the now-moot
--limit-hostsresidual is dropped from security/threat-model.md. Decision 0018 is superseded by Decision 0019. -
check_row.aggregate/min_upand migration 0041 remain as inert schema; no drop-column migration is added.
2026-09-26
-
exocomp does not manage cert lifecycle.
-
The v1.1 roadmap's R2 framed cert-expiry checks as including "exocomp's OWN web-UI cert". That premise was wrong: the LAN listener certificate is self-signed with a 10-year validity and trust-on-first-use pinned by fingerprint (
internal/web/tls.go), and a Tailscale tailnet cert or an ACME reverse proxy renews itself. R2 corrected in design/v1.1-roadmap.md; thetlscheck kind stays as a general, unprioritized capability for certificates nothing else renews.
2026-09-17
-
the deployment image ref in the recovery chain.
-
RECOVERY.mdnow carriesimage-ref:at each target root: the ref the daemon read from the unit'sEXOCOMP_IMAGEand stored asdeploy.image_ref. An unset ref omits the line rather than printing an empty value. This is the gap Decision 0016 names — a local tag dies with the host, so the recovery chain must name the image to re-load. -
install.shgains--image-load FILE(podman load -i, ordocker load -ion the Docker tier, before install or rollback) and--image-ref REF. The Quadlet unit and the compose file setEXOCOMP_IMAGEto the image the unit runs, so the stored ref reflects reality.exocomp doctorprints the stored ref in the text report and folds it into the existingoptional_toolsJSON detail (the fixed subsystem list is unchanged). -
operations/disaster-recovery.mddocuments capture (podman save) and load;operations/containers.mdandoperations/machine-output.mdstate the ref.
2026-09-17
-
the doctor toolchain-manifest diff.
-
doctornow diffs each resolved tool version against itsMANIFEST.jsonpin. The comparison folds into the existingoptional_toolshealth entry, so the fixed subsystem list is unchanged. A version off its pin iswarn, neverfail— the Decision 0006 operator escape hatch is a supported state; a version the extraction rule cannot parse is named in the detail without moving the status; and no manifest env at all leaves the entryunknown. The text report marks each divergent line against its pin and prints the active manifest path once. -
operations/machine-output.mdandoperations/containers.mdstate the comparison.
2026-09-17
-
Decision 0016 and the container page.
-
New Decision 0016: the base image is a distributable artifact carrier; uv is bootstrapped when absent, the Python pin is resolved from ansible and frozen, and ansible-core is a PATH-delegated command rather than a forced per-venv dependency. Amends decision records 0006 and 0011.
-
New operations/containers.md: the base image and what it carries, running it as shipped, inheriting to add system packages or Python dependencies, offline and multi-arch builds, and capturing an operator's image for recovery. Copying artifacts into a foreign base is deferred.
-
Correction of fact:
index.mdlabelled its six-row record table "Six accepted decision records"; the bundle now carries sixteen, so the table is retitled a foundational subset and points at the full list at decisions/index.md. -
platform-contract.mdgains an operator-built-image tier row;bill-of-materials.mdlistsuvxand the base image as a digest-pinned distribution artifact;design/byo-runner.mdcross-references Decision 0016 so the deferred in-daemon tier is not confused with the supported image story.
2026-09-15
-
TUI copy deck reconciled to shipped output.
-
design/reference/tui/copy.txtrecorded two strings the shipped TUI never renders. It now matches the binary and its own frames (the frames are the implementation contract — "text IS the implementation"): the footer signal line isdead-man {age} · notify {loud|muted} · {version} ({commit}) built {date}(the deck'sntfy {age} · disk {pct}% · {version}↗predates the shipped signal), and the SILENCED banner variant (banner.go, present inframes/banners-80.txt) is declared beside paused/muted.
2026-09-12
-
base-path round: correction of fact.
-
The plan-review's claim that
http.StripPrefixleavesRequestURIunrewritten is wrong for this toolchain. A probe against go1.26.8 shows StripPrefix rewrites bothURL.PathandURL.RawPath(net/http/server.goStripPrefix), so the handler-visibleRequestURI()is the STRIPPED path. The base-path spine therefore prepends the base path exactly once toRequestURI-derived values (url()/urlWithBase), and the "no double prefix" requirement is met by idempotence, not by assuming the prefix survives the strip.docs/log.mdrecords the fact; code is the source of truth.
2026-09-07
-
responsive round (v0.9).
-
The design pages codify the responsive principles. The web surfaces gained a single 719px phone breakpoint and the rules landed as a new
## Responsive (v0.9)section indesign/INVARIANTS.md(one breakpoint, rows-not-tables on phone, pre logs, the 56px phone shell bar, size-agnostic markup, the 48px floor with its 36px compact-secondary exception, the app-bar meta staying visible on phone); the## Layoutsections of the rootDESIGN.mdanddesign/DESIGN.mdwere rewritten to the same wording, and the breakpoint tokens collapsed to the one phone breakpoint. Structural: the invariants page is extended.
2026-09-06
-
degraded job state + job detail v2.
-
Software change, no structural edit needed here: the job state machine gained the terminal
degradedstate (tolerated unreachable hosts, migration 0034), and the web jobs surface was rebuilt (run card, verdict band, host table, two-line list, rerun/drawer tolerate toggle). Recorded here for bundle-fact coherence: "job state" now includesdegraded; the web and TUI render it in wait (amber) and it is not a failure to CLI callers.
2026-09-06
-
Decision 0015 page added.
-
A new
decisions/0015-per-source-collections.mdpage records the per-source ansible collections isolation decision, superseding Decision 0011's collections decision; the venv, tofu-provider, tofu-modules, and system-package decisions stand. Structural: a page added.
2026-09-02
-
agent brain made local-only.
-
Correction of earlier framing. The 2026-08-31 entry "
brain/lands in.agents/" claimed.agents/brain/is tracked like the rest of.agents/content. It is not: the directory is gitignored and holds local-only working notes (specs, the design handoff, review inbox/outbox), so a reader of this repo cannot open it. contribution/index.md and the CHANGELOG now say plainly the path is local-only; the spec store is gone from the repo.
2026-09-02
-
design invariants page added.
-
A new
design/INVARIANTS.mdpage codifies the design philosophy, hard rules, and component vocabulary into the bundle (previously held only in the untracked design-handoff canon). The repo-rootDESIGN.mdand the wikidesign/DESIGN.mdcross-reference it;AGENTS.mdand both design indexes list it. Structural: a page added.
2026-09-01
-
Netgroups page merged into /checks as a tab.
-
The standalone Netgroups page was removed; netgroups are now a tab on /checks (
?tab=netgroups). The/netgroupsroute 302s to the tab; the write redirects follow. This is the one route change of the design-handoff realignment (F7).
2026-09-01
-
software changelog split from the bundle log.
-
The release narrative moved out of this log. This page now records only bundle-structural history and corrections of fact; software releases, features, and fixes live in operations/CHANGELOG.md, linked from the bundle index, and this page's header says so. The split itself is structural, so it is recorded here; the CHANGELOG is the newest-first release narrative.
2026-09-01
-
memfd run-secret staging rejected, recorded.
-
A
memfd_create(2)staging experiment was revisited and rejected. A long-dormant branch staged each run-secret into an anonymous memfd (no path in any mount,F_ADD_SEALS, mlock) instead of the shipped/dev/shmfile staging (--secret-staging {auto,tmpfs,disk}). The branch was 265 commits behind and never merged; the shipped design already absorbed its rationale and then superseded it. -
Why rejected (code wins). A memfd's fd does not survive a sandboxed run: real
nonocloses every inherited descriptor but stdio before exec, and a memfd has no path a--read-filegrant can name. A sandboxed tofu child can read a staged file under/dev/shmthrough the granted path — the exact case the memfd design could not support (internal/executor/sandbox_e2e_test.go). -
The branch is deleted; the
/dev/shmstaging with its loud disk fallback stands.
2026-09-01
-
list-surface refinements.
-
Docs' UI-stack references corrected. The vendored htmx include is gone; the docs now name the vanilla JS the app actually uses.
2026-09-01
-
approval surface refinements.
-
Log self-correction. Three back-dated entries (list-surface refinements, write-form errors, check-event traceability) now carry their true 09-01 dates; newest-first order restored.
2026-08-31
-
sweep error policy recorded.
-
architecture/reactive.md states the shared sweep error policy — the checks, drift, and job-failures sweeps now say in-place that a per-item failure is logged and the sweep continues (a failed check is still marked due and keeps its interval cadence; a broken check target is skipped so its siblings still probe), and only a structural failure (the sweep's list query) or shutdown stops it.
2026-08-31
-
docs-review pass on checks, rules, and the web.
-
Corrected a false claim about
doctor. security/threat-model.md T33 and design/check-triggered-runs.md §3.2.1 saiddoctorasserts the LAN-only-routing precondition; it has no such probe. Both now record the precondition as documentary, not enforced. -
operations/reactive.md "Checks as an event" states the consequences the feature ships with: a check's interval is floored at the
--sweep-intervaltick (30s default); a host home at daemon start is missed once, fail-safe; hysteresis is fixed at N=3 and a departure withdraws a pending approval only after 3 consecutive down observations (~N·interval lag on the resolve path); the persistedcheck_staterow (status/consecutive/emitted/last_change) survives a restart and backs the /checks "changed N ago" line; the two §3.2.1 preconditions (static lease, no overlay route) are stated where an operator sets up; and the http dial-time guard plus the no-netgroup-on-url caveat are on the page. -
The web paragraph and operations/serve.md browser list gain the shipped surfaces — /checks netgroup chip + recency, the dashboard Checks card, job detail "fired by rule" → /rules + the triggering event, the events
?source=filter, and the read-only /rules page. operations/api.md addsGET /api/v1/netgroupsandGET /api/v1/checksto the read endpoints. -
design/check-triggered-runs.md §4.2 check_state DDL reconciled to migration 0030 (up/down, consecutive, emitted; no
unknown— a missing row is the unobserved state), §5.1 http is 2xx/3xx, §9/Status note rules read-only on the web, and the Open questions close: hysteresis N fixed at 3, retention shipped last-status-only, the http-tailnet caveat, and cooldown keying via0031_rule_fire_dedup.sql; set-event /--limit-hostsstays open.
2026-08-31
-
CLI/web check, rule, netgroup surfaces consolidated.
-
Correction of earlier framing. The "store remains the shared validator" claim is corrected: the CLI and web parsers now unify in store.Parse* / internal/reactive.
2026-08-31
-
threat model: checks and peer stamping rows.
-
security/threat-model.md gains a Checks, netgroups, and peer stamping subsection under the reactive section — T30–T35 record the shipped mitigations (peer-stamped presence, transition-only + hysteresis + per-target cooldown, the static-lease and LAN-only-routing preconditions, cold-start seeding, http status-only) that the code already carried, closing the invariant-8 gap the feature's design §10 owed. New rows are numbered T30+ to avoid renumbering the existing T1–T29 catalog.
-
index.md summary rows for the Reactive layer and Reacting to alerts now mention check probes, netgroups, and peer stamping.
2026-08-31
-
contribution guide and specs store.
-
New page contribution/index.md: the working procedure behind AGENTS.md — the DCO, commit conventions, worktree workflow, verification, and design/review. Linked from the bundle index and from AGENTS.md's "Working here".
-
brain/lands in.agents/—.agents/brain/specs/holds specs for in-flight work (the UI spec for check-triggered runs is the first). It is tracked, like the rest of.agents/content (skills, role cards, workflows); the git-excluded half of.agents/stays the generated workflow scripts. AGENTS.md's layout block names the new directory.
2026-08-31
-
web surface for netgroups and checks.
-
Design reconciled. check-triggered-runs.md §9 drops the in-browser rule-builder promise and records the shipped-subset Status; architecture/reactive.md and operations/reactive.md gained checks/netgroup sections.
2026-08-30
-
check-triggered runs design.
-
New page design/check-triggered-runs.md: proposal (no code) for running governed jobs on a reachability or health transition instead of only a wall clock. Three primitives: checks (named probe-sets —
tcp/ping/http, transition-only events, per-target dedup), network groups (named CIDR sets giving the operator's own vocabulary and classifying a probe-target or webhook-peer address), and a governedplaybookrule action (source checkout, inventory, run-secrets, sandbox) replacing the shell-argv escape hatch. Checks enter the existing reactive pipeline the way drift does (SweepDriftprecedent), so cron stays on the schedule row and a check is a rule listening on--source check; both converge on the one queue. -
Revised after review. Address = location now states its two preconditions (static lease per target; LAN-only routing, never an overlay subnet route) and both get a threat-model row. Transition state lives in a
check_statetable with cold-start seeding that never emits on first observation, so a restart does not fire every presence rule. Phase 2 ships per-target events only; the set-event /--limit-hostsexpansion is deferred. Peer stamping is framed as a network-path signal (LAN vs overlay), not a location verdict. Check transitions require N-consecutive-same-result hysteresis. Cooldown stays per-rule for webhooks (uniform per-dedup-key would let a body-varying webhook bypass the throttle) and is per-target for sweep sources.
2026-08-25
-
QR pairing, schedule detail, sidebar logo.
-
New page operations/pairing.md documents the QR device-pairing payload contract.
2026-08-25
security/threat-model.md corrects the token-mint boundary: a
job can reach the exocomp CLI via an ansible command/local_action or a tofu
local-exec; under the sandboxed tier the data-dir/keys denial (T6) fails it closed, but
under TierLocal (explicit or auto-degraded) it can mint an operator token or read
host.key — documented as a trusted-playbook tier. Also notes the web POST /tokens/new
mint route exists, gated by cookie-session + same-origin + reauth; /api/v1 and /mcp
expose no mint.
2026-08-25
-
sandbox tiers renamed, secure-by-default.
-
Tiers renamed and the default flipped. The job-sandbox tiers are now
opportunistic/enforcing/disabled(wasauto/local-sandboxed/local), and the default — an empty--sandbox/$EXOCOMP_SANDBOX— is nowenforcing: a host that cannot enforce the sandbox fails closed atserve/doctorstartup rather than running jobs unsandboxed.opportunisticis the opt-in that degrades loudly todisabledinstead, anddisabledis the explicit unsandboxed tier. The three old names stay accepted as silent back-compat aliases. Terminology reconciled across architecture/execution.md, operations/serve.md, design/byo-runner.md, security/threat-model.md, decisions/0005-job-sandboxing-nono.md, and the index, runners, cli-run, provision-converge, and SBOM pages.
2026-08-25
-
access-token and inventory hardening.
-
Threat model renumbered. The E/S/R/D/B/U/AI finding-id families were replaced by a sequential T1–T29 catalog in reading order.
2026-08-25
-
source kinds collapsed; runs move to the source page.
-
Decision 0010 addendum and operations/sources.md updated for the git/path (+writable) model; serve.md reflects the source-page launchers.
2026-08-25
operations/serve.md gains a "The browser surface" section: the web UI
is no longer view-only — an operator runs playbooks/commands, plans/applies workspaces, and
manages sources, secrets, tokens, schedules, policies, and runners from the browser. Sensitive
writes re-confirm with the operator's access token; these session form posts stay distinct
from the bearer-only /api/v1.
2026-08-24
-
design system page and top-level README.
-
New page design/DESIGN.md: the web UI design system — color, typography, spacing, and component tokens — sourced from
internal/web. The architecture technical-design that previously held this name moves to history/design/DESIGN.md as provenance. -
New repo-root
README.md, current to shipped reality (OpenTofu, the single MCP-over-HTTP surface, remote CLI, sandbox tiers). -
Voice. Internal build codenames — milestone tags, finding and review ids, process jargon — are removed across the docs and decision records; pages describe current behaviour and read harness-neutral.
2026-08-24
The four target-user personas now live as one crisp definitions page, design/personas.md. The internal persona-review, persona-scenario, and practitioner-gap-review planning pages are removed; their surviving conclusions live in design/v1.1-roadmap.md and design/v1-acceptance.md.
2026-08-24
-
failover page and cross-host lease.
-
New page operations/failover.md: the cold-standby procedure (restic restore, optional Litestream fast-forward, deliberate
serve, re-drive of interrupted work) and the cross-host active lease that fences it above the host-localserve.lock. -
Correction. The lease fences only two daemons opening the same
exocomp.db(a shared volume or network filesystem); it does not fence the Litestream-replica or restic-restore copies, each of which is a separate file. The runbook's restore path relies on the operator confirming the primary is stopped. -
operations/serve.md gained the cross-host half of "one daemon per data dir".
2026-08-24
design/byo-runner.md and
operations/runners.md: per-job memory/CPU caps are enforced by
cgroup v2 direct writes (the container image ships no systemd, so systemd-run is not the
path), opt-in and fail-closed — the default rootless deployment refuses a capped job rather
than running it uncapped. A job selects a runner's caps with --runner. The
container-image tier stays deferred.
2026-08-24
design/bootstrap-first.md and the operations pages describe
run-secret file staging on /dev/shm: per-instance session directories, a
--secret-staging {auto,tmpfs,disk} backend with a loud disk fallback, best-effort mlock,
and unlink-on-exit. exocomp doctor reports the resolved backend and residual posture.
2026-08-24
- DEK reseal (recipient revocation) is crash-safe — staged-then-promoted, with a leftover
keyring.age.nextreconciled on the nextOpen. The residual (a transit-sealed store cannot reconcile without the host key) is recorded open. - The auth-timing decoy KDF is removed; the per-source/per-token fail counter remains the
guard. The accepted residual timing gap is recorded, owned by
internal/web/auth.go.
2026-08-24
-
durable approval and scheduler corrections.
-
operations/ansible-first-bootstrap.md and the bootstrap/handoff/provision pages: a composed-chain
--require-approvalstep is held mid-run as a durable per-step approval, not a CLI confirmation. -
operations/serve.md: schedule catch-up now dedups every fire on the occurrence's scheduled instant, and
last_runadvances only once a fire is enqueued, so a crash no longer double-fires and a failed enqueue is not silently dropped. -
operations/reactive.md:
approval linkneeds its own--public-url/EXOCOMP_PUBLIC_URL; it cannot read the running daemon's value back.
2026-08-23
-
agent-facing surface pages.
-
New pages: operations/remote-access.md (remote CLI, certificate pinning,
--remote/--token), operations/api.md (the/api/v1read and write surface, wire envelope, error-code table), operations/machine-output.md (--output json, the error taxonomy, and the honestly partial exit-code wiring), and operations/runners.md (the runner registry as definitions). -
Corrections. architecture/overview.md:
internal/serviceowns the write verbs, not "all business logic" (reads stay store-direct); the loopback state backend and the operator/api/v1surface are separate rows. -
operations/sources.md documents
secrets rotate/rm,--generate,--expires, and that expiry is a hygiene marker that never gates decryption or injection.
2026-08-23
The stdio MCP server documentation is removed. operations/mcp.md now
describes one programmatic surface — MCP over HTTP on the serve listener, bearer-scoped
(Decision 0009) — with an off-the-shelf http-to-stdio bridge for
stdio-only clients and the agent-aware CLI as the local path.
decisions/0014-agent-facing-surface.md and
design/agent-interface.md are reconciled to this; several pages
(threat model, architecture overview, operations index) were caught up to the removal.
2026-08-23
-
bootstrap and handoff pages.
-
New page operations/ansible-first-bootstrap.md: the
exocomp bootstrap run <playbook> <workspace>ansible-first chain, with the--capture(env) and--capture-file(KUBECONFIG-shaped file) credential handoffs added in later passes. -
New page design/bootstrap-first.md: the proposed ansible-first-then-tofu design for the Kubernetes persona, linked from the v1.1 roadmap.
-
New page operations/sealed-tofu-outputs.md: the credential half of the Terraform→Ansible handoff (
tf-output/<workspace>/<output>sealed and bound undertf:<workspace>). -
New page operations/cli-run.md: the governed
clirun kind — an allow-listed binary under the queue, sandbox, run-secret injection, and approval gate. -
Corrections. operations/terraform-ansible-handoff.md and operations/provision-converge.md updated as the daemon's apply began sealing sensitive outputs on every path;
bootstrap-first.mdStatus updated as its phases shipped (code wins over the design page).
2026-08-22
-
reactive, policy, and run pages.
-
New pages: architecture/reactive.md (webhook ingress, normalized event shape, sandboxed CEL, guardrails, the approval token), operations/reactive.md (wiring senders,
rule/silence/approval/event, thetofu-planschedule), operations/plan-policy.md (the CEL gate overtofu show -json), operations/playbook-run.md (ansible passthrough flags and check-mode drift), and operations/provision-converge.md (the provision→onboard→converge chain and thetf:<workspace>standing inventory). -
The operations index gained rows for the v1.0 pages that had shipped unlinked: run-lifecycle.md, terraform-ansible-handoff.md, and upgrade.md.
2026-08-22
-
design handoffs imported.
-
Web design handoff under design/reference/ (canvas PDF v0.1, artboard captures); design tokens live at
internal/web/tokens.css. -
TUI design handoff under design/reference/tui/ (text frames, keymap, colors, copy, states); the frames are golden fixtures under
internal/tui/testdata/frames/. design/tui-brief.md and design/ui-brief.md record the settled decisions, including the phone approval-surface contract. -
Correction. The printed recovery card's derivation block renders from code, not from the mock: the shipped envelope uses the constant salt
exocomp/v1withinfo = purpose:id(Decision 0003); the mock'sexocommand shorthand is not used (Decision 0002).
2026-08-22
-
Decision records 0008 and 0009 recorded.
-
Decision 0008: durable execution is a step-ledger extension of the job store; DBOS is assessed and deferred (young SQLite path, single maintainer, second runtime).
-
Decision 0009: LAN exposure is secured by local-minted bearer tokens with default self-signed TLS and fingerprint pinning.
2026-08-22
-
keyring-generation and v0.5 reconciliation.
-
Correction. The keyring generation counter lives beside the keyring in
keyring.version, not inside the armoredkeyring.age(age rejects added framing). operations/disaster-recovery.md documentskeyring.versionandMANIFEST.mac, what a restore does with them, andexocomp kit derive/kit verify/identity migrate. -
v0.5 reconciliation against code across operations/serve.md, architecture/execution.md, and sbom/bill-of-materials.md: queue semantics, executor tiers as actually shipped, stale-lock recovery, and drifted module rows corrected.
2026-08-21
The docs/ bundle was created as an OKF v0.2 knowledge base, curated from the
pre-repository design archive. The curated pages summarize; the archive's source documents
were imported byte-identical under history/ — thirteen files, checked
for absolute paths and home directories (none present).
- Sections and pages:
index.md, thislog.md,decisions/(0001–0006, Accepted),architecture/(overview.md,platform-contract.md,execution.md),design/(requirements.md,amendments.md,delivery.md),operations/(bootstrap.md,disaster-recovery.md),sbom/(bill-of-materials.md), andhistory/. - Naming. Most of the archive predates the rename from the working name "control" to exocomp (Decision 0002); curated pages use the current name throughout, and imported history was deliberately not rewritten (see history/index.md).
- Precedence. Where a curated page and a history page disagree, the curated page wins; the twelve amendments override the accepted candidate design.
2026-08-21
-
early corrections against code and source.
-
The design critique enumerates 30 gaps across sections A–H, not 22; the wrong count was corrected on seven pages.
-
install.shgained the documented--restoreand--rollback --image-tagforms, resolving contradictions with the disaster-recovery, bootstrap, and amendments pages in code's favor. -
v0.1 pages reconciled against the shipped code: the run engine is a direct
ansible-playbooksubprocess (notansible-runner), the disaster-recovery staging tree and failure-mode tables match the shipped CLI, andexocomp backup run/restoreare documented as direct invocations outside the queue until the scheduler exists. -
New page sbom/minio-assessment.md: the S3 test fixture moved to SeaweedFS; the operator-store row no longer suggests MinIO for new deployments.