This plan says what OCX is for and what finishing it means: the objective,
the precepts that guard it, the gaps between the intended product and the
code, the parity it must reach and the phases that get it there.
README.md holds the axioms and virtues,
ARCHITECTURE.md how OCX is put together,
USAGE.md the concrete commands and artifacts, and
HISTORY.md how it got here. Beyond these phases, the long-term
direction of OCX's building blocks, which reaches past this project, is in
ROADMAP.md. When wording here conflicts with them, they
govern and this plan must be corrected.
What it is for
OCX gets coding work done by people and agents together, with every step on a Fossil record that anyone with access can read later.
- A task has one hash: a ticket or a forum thread. Its specification, questions, progress, evidence and result stay together on that record.
- Any agent can take the task: a person in the browser, a Claude or Codex client, or a local model such as Gemma. Each works to the same task and report contract, and each result names the login that produced it, so runners can be compared on the same saved tasks.
- Each change states its intent, how it is expressed and what demonstrates it. CI and independent reviewers attach their verdicts to that check-in.
- Acceptance stays with a person: merging and serving a release are explicit, attributed actions, and a release can be rolled back.
Precepts
Each precept is a testable consequence of a README axiom and virtue. The
existing IDs remain stable for their guards: C derives from Clarity
(README axioms 2 and 3), I from Loose Coupling (axioms 1 and 5), and
A from Demonstrability (axioms 1 and 4). The latter two prefixes retain
the older names Interchangeability and Accountability; they do not introduce
extra axioms or virtues. Parsimony (axioms 1 and 4) also shapes precepts C1
(File Boundedness), C7 (Pinned Interfaces), and I7 (Single Process Site): each
bounds a different source of needless complexity. A precept without a guard
spec is a memory, not a mechanism. The ledger spec fails when a precept has no
spec tagged # precept: <id>.
The cooperative premise in Axiom 3 is not a security assumption. Axioms 4 and 5 account for fallibility and the consequences of integration, so the derived controls remain necessary: precept I4 (Server-Only Writer) limits access to the served repository, precept I6 (Pluggable Confinement) specifies a replaceable confinement mechanism, and precept A2 (Artifact Audit) records review verdicts.
Conflict check, done before admission:
- Precept C2 (Single Owner) and precept I4 (Server-Only Writer) agree: the repository owns durable facts, while ephemeral facts stay outside it.
- Precept I1 (Runner Isolation) and precept I4 (Server-Only Writer) agree: a runner's clone is its own.
- Precept A4 (Staged Deployment) and precept I4 (Server-Only Writer) agree: deployment does not write a repository.
- Precept A2 (Artifact Audit) and precept C2 (Single Owner) agree: an audit is a tag on the check-in it judges, not a config row.
No precept requires an agent to open a served repository, so precept I4 (Server-Only Writer) has no exception.
| Id | Name | README virtue | If … then … | Guard |
|---|---|---|---|---|
| C1 | File Boundedness | Clarity, Parsimony | If a part is to be read whole, then no source, spec or Markdown file exceeds 400 lines, and every document renders with its links leading somewhere. | spec/guards/size_spec.cr, spec/guards/documents_spec.cr |
| C2 | Single Owner | Clarity | If a fact is to have one owner, then no code writes runtime or ephemeral state into any repository's config table. | spec/guards/config_state_spec.cr |
| C3 | Stated Change | Clarity | If a change is to be stated, then its check-in comment carries Intent, Expression, and Demonstrates lines. | spec/guards/checkin_spec.cr |
| C4 | Question Shape | Clarity | If a question is put to a person, then OCX frames it in the question shape (question, references, optional options and stakes); the notation is never typed by an agent or a person. | spec/guards/question_spec.cr |
| C5 | Canonical Naming | Clarity | If the project is named in code, then the name is OCX; the origin names appear only under a History heading. | spec/guards/naming_spec.cr |
| C6 | Explicit Arguments | Clarity | If configuration is to be stated, then it is an explicit argument; no code, guard, or CI step reads an environment variable, except that the program's wrapper takes from it by value the variables Fossil describes a CGI request with (the repository, user, capabilities, nonce and base path; the method, query, sub-path, body length, HTTPS flag, host and Referer) the build settings that hold no secret, and the terminal's type (TERM), which a run at a terminal passes on (the maintainer, 7242762209), and of the rest only their names. |
spec/guards/environment_spec.cr |
| C7 | Pinned Interfaces | Clarity, Parsimony | If an interface is to be relied on, then it is listed in docs/interfaces.md with the spec that pins it, or the rebuild slice it is pending for, and every notation head the code writes is listed there. | spec/guards/interfaces_spec.cr |
| I1 | Runner Isolation | Loose Coupling | If a runner is to be replaceable, then its CLI's invocation and output formats live only in its adapter, and the adapter has a conformance spec that runs the real CLI. | spec/guards/runner_adapter_spec.cr |
| I2 | Repository Portability | Loose Coupling | If a repository is to be replaceable, then no source names a specific repository or host path; the repository is always a parameter. | spec/guards/repository_neutral_spec.cr |
| I3 | Pinned Toolchain | Loose Coupling | If the toolchain is to be replaceable, then CI prints and pins the dependency ledger, compiler included; a developer's run on another compiler is reported as not a gate result, and the merge gate refuses any compiler but the pin. | spec/guards/dependency_ledger_spec.cr, spec/gate/compiler_gate_spec.cr |
| I4 | Server-Only Writer | Loose Coupling | If Fossil is the store, then only the Fossil server, and the programs it spawns to answer a request, open a served repository; every agent works in its own clone under its own login and syncs. | spec/host/served_writers_spec.cr |
| I5 | Rollback Journal | Loose Coupling | If a served repository is to stay compatible with remote clients, then it runs in rollback-journal mode, never WAL. | spec/host/journal_mode_spec.cr |
| I6 | Pluggable Confinement | Loose Coupling | If a session is to be confined, then the confinement is a written plan and one replaceable call site: bwrap is named in one source file and started in one place, so another mechanism can take the same plan. |
spec/guards/confinement_spec.cr |
| I7 | Single Process Site | Loose Coupling, Parsimony | If an external program is to be replaceable, then src/ starts it in exactly one place: one Process call per program, inside the function that wraps it, which is where another implementation takes over; callers reach it only through operations named for what they do, its transport private and its command words and SQL in its module. The maintainer's standing rule, stated 2026-09-23 after fossil was started from four places and only one of them had been kept from the console's environment, and 2026-10-07 after Fossil.run passed fossil's words through. |
spec/guards/external_programs_spec.cr |
| A1 | Visible Evidence | Demonstrability | If a change is to be shown, then the demonstration its check-in names exists in the tree. | spec/guards/checkin_spec.cr |
| A2 | Artifact Audit | Demonstrability | If a unit is to be trusted, then its audit is a Fossil tag named audited on the check-in itself, whose author is the login that added it and whose value begins with the verdict pass or fail; the suite prints coverage and verdicts. |
spec/guards/audit_spec.cr |
| A3 | Parity Gate | Demonstrability | If a merge is proposed, then the precept ledger has zero gaps and every row of its chosen parity contract cites a demonstrated check-in. | spec/guards/ledger_spec.cr, spec/guards/parity_spec.cr, spec/gate/parity_gate_spec.cr |
| A4 | Staged Deployment | Demonstrability | If a build is to be shown before it is served, then serving is a separate, named step: OCX's served link resolves into a release, never into a checkout. | spec/host/deploy_spec.cr |
| A5 | Origin Home | Demonstrability | If a run is to be shown, then its outcome is written to the artifact that prompted it, never to a new ticket or thread of its own. | spec/guards/outcome_home_spec.cr |
Host guards for precept I4 (Server-Only Writer), precept I5 (Rollback
Journal), and precept A4 (Staged Deployment) live under spec/host/, tagged
host, and run with crystal run ci.cr -- host; a bare crystal spec runs
them too, and tells the truth about the host it runs on. They take nothing from configuration: the served
directory and the served CGI root are read from the running Fossil server's own
command line (--repolist, --extroot), and when no server runs here they are
pending with that reason, never silently green. On 2026-09-21 they failed on
the live host: three served repositories were in WAL mode, migrated in place
the next day, and the served CGI links resolved into a checkout. Precept A4
(Staged Deployment) judges OCX's own link; trunk's stand until the maintainer
takes them down (HISTORY.md decision 17).
Functional gaps
The architecture describes the finished product, not the state of this checkout. This table is the current gap inventory. Three places are kept apart in it:
- Reference: the implementation on
ocx-human-feedbackas it stood when theocx2branch was reset (ae8abac268). The code areferenceorgaprow names (src/ocx/…, "this branch") is there. - Here: this checkout, the
ocx2branch, whosesrc/the reset emptied; each slice brings back what it states (docs/slices.md), and ahererow names its check-ins. - Demonstrated here: a passing spec on this branch and a live demonstration, needed before a row is called demonstrated.
reference means code exists on the reference branch but nothing here and
no end-to-end outcome is demonstrated; gap means the needed behavior is
absent or regressed everywhere; evaluate means a prior branch has a
candidate whose value or fit still needs testing; here means this branch
has the code and its specs but not yet the whole demonstration, and the row
says what is still to show. ocx and trunk evidence identifies designs to
inspect, not proof that they work. The list is the product gap inventory, not
a decision to block a merge on every row.
| Functionality | Check-in on this branch | Current evidence, gap and next demonstration | State |
|---|---|---|---|
| Shared records | — | src/ocx/turns.cr and src/ocx/definitions.cr exist. Show a JSON definition, a human post, one agent response and derived standing on the same hash, with no duplicate answer. |
reference |
| Agent work units | — | Workspace.create, Launch.start and workspace serve exist as separate steps; creation still permits a file clone and keeps a second password file. Show one tool, from the CLI and a POST, that creates a workspace binding record, the unit's own login, HTTPS clone and branch, and a separate tool that runs a task in it with its runner and grant (docs/slices.md, slices 1 and 3). A person makes the login in Fossil's user pages; creating, which needs admin or setup, sets a fresh random password on it and clones with it in the URL, so only the clone remembers it and the login has one live workspace (HISTORY.md decision 29); no password enters a post, an MCP request or a model's request. |
gap |
| Confined execution | — | Bubblewrap has a written plan, but the current sandbox can expose the workspace clone and no cgroup meter is demonstrated. Show that the child reaches its own workspace and not the served repository or another unit's, and CPU, memory and process limits with usage recorded at task end. Verify that termination and over-limit failure are reported on the record. | gap |
| Event-driven work | — | The hook, ocxd and served loop exist; ocxd already parents and reaps launched tasks. ../wake is only an edge-triggered latency hint. Demonstrate daemon startup reconciliation from synced records, one child per claimed work unit, supervision through exit, restart recovery after lost hints and failed sync, and a recovery trigger for a live daemon if a hint is lost with no later event. The current daemon's in-memory handled set and launch-note path do not prove this. |
reference |
| Distributed work: forum node | — | The existing /ext/ocx/status JSON endpoint can report a remote thread's agent state; a live SSE status stream is pending. Show a node accepting a local forum post under its local Fossil login, syncing it to the remote repository, observing remote status through SSE with status-endpoint polling fallback, and syncing the response back to the same local thread. Verify the two nodes keep separate credentials and permissions. |
gap |
| Distributed work: execution node | — | The clone-and-record design permits a target node, but periodic HTTPS sync, local hook activation, bounded on-target CI logs and result sync are not demonstrated. Show a separately provisioned node sync a task, run it on real target hardware after local after-receive processing, tag or post its result under its own login, and sync that evidence to the origin. An exclusive job still needs a server-serialized claim; a declared independent target run does not. | gap |
| Comparable agents | — | The CGI has human views and this branch has a five-tool native runner, but they do not yet present the same work-unit contract as Claude/Codex over MCP. trunk has an Ollama loop and four-task battery: gemma4_31b and codex-crystal-gemma4 passed 5/8 trials. Run one saved task through human CGI, one MCP client and named local Gemma; compare edits, checks and reports, including failures. |
reference |
| Visible model exchanges | — | This branch writes the final answer to the record but does not post each raw model exchange. Post the exact request JSON, including system/task messages and advertised tool schemas, and the exact response JSON, including model output and tool calls, plus tool results, to the prompting thread or ticket before the next step. Record model identity and tool-definition revision. Keep session credentials outside the model request; reject unsafe or oversize payloads before sending rather than truncate audit evidence afterward. | gap |
| Project context | — | A manifest creates read-only peer checkouts. Show a revision-pinned view and a separate live-status query to the peer's own record; define refresh behavior so a snapshot is not called current status. | reference |
| Grounded search | — | trunk has src/vec_search.cr, indexing code and specs; this branch has none. Restore an artifact-linked search slice for people and agents. Resolve where derived vectors live without letting an agent write the served repository file. |
gap |
| Grounded search: documentation freshness | — | trunk has src/vec_staleness.cr, but its model contradiction test is pending. Show a known stale claim found and a current claim left unflagged, with source links and a human-reviewable result. |
evaluate |
| Model improvement | — | trunk has a conditioned-model builder, input digest and recorded smokes; those establish prompt packaging, not trained weight changes or reliable coding. Restore repeatable evaluations, compare against a baseline and promote only a model that passes edit tasks. |
evaluate |
| Branch contributions | — | Workspace defaults to a task branch, but no explicit contribution target or gated proposal is demonstrated. Record work branch and target branch in the specification; show a check-in on the work branch, CI and independent audit, then an attributed proposal or acceptance on the target. Fossil login permission is repository-wide, so also detect and report wrong-branch changes. |
gap |
| Reviewable changes | — | Audit tags, CI guards and a coverage ratchet exist; CI still fails on earlier check-in-format and self-audit expectations. Show a local model's cited review report on a check-in, then a distinct login's audited verdict and a CI service login's ci verdict. Meter the local review task and measure CI time before calling either free or fast. |
reference |
| Consistent tools | 650b95f70f, 726c53ba93 | A tool is one typed definition, and the CLI, the web page, MCP and the hook are generic walks over it: every schema is derived from its types, and list is the one source of every tool list, MCP's tools/list included (HISTORY.md decisions 32 and 33; spec/ocx/styles_spec.cr). Still to show: grants projected with it, Claude and Codex attaching to a work-unit-bound MCP server and invoking the same tools, a bounded task delegated to Gemma, and the daemon, not the idle client, driving the next turn on a hook. |
here |
| Reversible releases | 7cc1f59d7e, cfd31d7024, 31dad9ff8e | stage checks, builds, smokes and offers a release; accept copies it whole into the root and serves it, and stops when what is offered is served already; rollback serves the previous one again. A change is taken only from a POST from the site's own page, by Fossil's own check (HISTORY.md decisions 30 and 35), and the preview accepts only a node's first release (decision 31). On 2026-10-06 the maintainer accepted a7a5e719eb90 from ollama.openbeagle.org's page. Still to show: a rollback there, and a later release accepted from the active page, each served link resolving to an immutable accepted copy. |
here |
Failure demonstrations for the first work-unit slice:
| Scenario | Required observation and response |
|---|---|
| A wake arrives during a task, or a hint is lost while idle | After a task, query the record again before blocking; after a lost idle hint, recover by the chosen retry or reconnect mechanism. Serve.run already does the first, but does not prove the second. |
| Sync fails or arrives while scratch has edits | Do not act on a stale clone or overwrite scratch. Bound retries, show unsynced to the human, and resume from the record after sync. |
| A model reply is malformed, too large or exceeds its step, token or time budget | Record a typed failure on the origin before another model step. If posting is unavailable, retain a local pending diagnostic and publish it after sync recovers; never claim the record has it already. Do not commit or propose unverified edits. The current native runner can commit written files after its step budget fails. |
| A sandbox plan exposes another unit's workspace or a served repository path | Refuse launch and prove the child cannot resolve another unit's workspace or the served repository; meter resource use and record an over-limit exit. The current sandbox binds the whole workspace read-write. |
| A release or audit arrives without its prerequisite evidence | Refuse acceptance until stage smoke and checks finish; require a distinct reviewer login for an audited verdict. The current stage code smokes before offering, and host/link and audit guards exist; a release was accepted live on 2026-10-06, but a refused acceptance and the identity proofs remain. |
These are test cases, not numerical risk scores. SQLite supports WAL as a concurrent journal mode; WAL does not by itself imply corruption. Precept I5 (Rollback Journal) remains OCX's served repository contract. The host guard detects departures; a deliberate server-owned maintenance action changes journal mode, not an unreviewed startup script or a process outside precept I4 (Server-Only Writer).
trunk also offers a web chat workflow and a single-binary CLI/CGI surface.
Compare their user benefit and failure modes before adding either to the
README. Retain the outcome if it improves the task contract; do not transplant
its polling loop, repository-config runtime cursors or checkout-served release
merely to recover the feature.
Node synchronization and Fossil backoffice
Fossil's backoffice --poll N
periodically runs backoffice jobs on named local repositories; it does not
initiate HTTPS sync. Fossil's own secondary nodes
use scheduled fossil sync. An execution node therefore needs an explicit
periodic sync of its own clone under its own remembered login. The interval
sets task and result latency; no model process or tokens are needed between
syncs. Evaluate backoffice polling only for timely processing of artifacts
already received in that clone, rather than as a substitute for network sync.
After-receive hooks
run from backoffice after artifacts arrive, including on a client clone, but
can be delayed; their input may omit arrivals older than 24 hours. Reconcile
the full record after startup and each successful sync. The hook documentation
also says it runs while Fossil holds a write transaction. Under precept I5
(Rollback Journal), a hook must not synchronously query that same repository:
hand the received hashes to a node-local pipe, return, then let the daemon
query after the transaction ends. Today's Wake.hook opens the repository in
the hook and needs a contention test and a corrected handoff before this path
can be called reliable. Keep any periodic backoffice process on the node's
clone; a separately launched process must not open the central served file
under precept I4 (Server-Only Writer).
The forum node's remote status read is separate from sync. The current
/ext/ocx/status?thread=ROOT endpoint returns JSON; SSE is still to be
implemented, with authenticated status polling as fallback. The answer itself
arrives through Fossil sync. Prove the local forum post, remote agent answer,
live status and returned post all refer to the same thread hash.
Work-unit and tool contract
Creating a work unit and running a task in it are separate tools, each reachable from every entry point (HISTORY.md decision 29; docs/slices.md, slices 1 and 3). The unit's single JSON specification on the record names the origin, agent login, work branch, contribution target, node selection, runner, grant and resource budget; defaults require only record and agent. The node-local binding and directory are derived from that specification, not a second user-facing workspace definition. A new unit on the same record has its own explicit id.
A tool is one typed definition across CGI, CLI and MCP (HISTORY.md decisions
32 and 33): its name, summary, needed capability, typed input and output, and
one method that takes every step through a log honoring dry_run; each entry
point reads its own input into the typed input and writes the answer in its
own layout, from the types alone. Still to come: the executor receives a bound
work unit and validates its grant, and the first work-unit tool is ocx.read,
a bounded artifact or path range, never raw clone SQLite.
The bound MCP surface for Claude and Codex is deliberately small:
| Tool | Result and boundary |
|---|---|
ocx.context |
Work specification, standing, branches, node and effective grants for this unit. |
ocx.read |
Bounded record, source or diff excerpt from the unit's clone; no repository database or secret. |
ocx.edit |
Validated patch to the unit's scratch tree only. |
ocx.check |
Named allowlisted check with bounded output and metered usage. |
ocx.report |
Answer or cited review report on the prompting record, as the bound login. |
ocx.delegate |
A bounded local-model subtask under a separately named and provisioned agent login. |
ocx.propose |
Candidate diff and target branch for host-side validation; it does not merge or attach an audit verdict. |
The Gemma baseline starts with the first five tools; delegation and proposal appear only when the grant and task need them. Each unit's clone remembers its own login's password. The node gives a confined CLI child a work-unit-bound local MCP endpoint; a small stdio adapter serves clients that expect a child MCP process. The endpoint exposes only the granted operations and is revoked when the task exits. The daemon receives hook hints, reconciles records, starts the client with the task prompt and supervises its cgroup until exit; an idle Claude or Codex process is not required to watch for new work.
The daemon and hook run under node/server service identities, not Fossil agent logins. A provisioned agent login authors its unit's posts and check-ins; a delegated local model uses its own login; CI and independent auditors use their own logins for tags. The specification records these roles, and a service note declares when the daemon posted on behalf of a unit. Fossil's repository-wide capabilities set the outer limit; the work-unit grant narrows tool access and does not pretend to restrict Fossil check-ins to a branch. Node claims must prevent two nodes from executing an exclusive job while allowing a declared independent review or comparison on both. A server-spawned CGI serializes the claim, records it on the same hash and issues a bounded lease; a stale lease can be replaced under an explicit expiry and recovery rule. Clone sync alone cannot arbitrate simultaneous claims. Prove contention and crash recovery before distributing execution.
A unit's login is made by a person in Fossil's own user pages (HISTORY.md decision 29, which replaces decisions 24 and 26 to 28 on this branch). Creating its workspace needs admin or setup: it sets a fresh random password on the login and clones over HTTPS with it in the URL, so only the clone's remembered remote holds it and older clones of the login stop syncing. Never copy a password into a JSON post, MCP request or synced artifact. The unit commits and syncs as its own login; integration into the target requires a separately attributed acceptance or explicit gate policy.
The Fossil capability reference
sets the outer permissions: g clones, o reads code, 2 reads forum,
r reads tickets, 4 posts forum entries without moderation, and i syncs
writes. In particular, i accepts more than check-ins; it cannot express
"this branch only" or "audit tag only." OCX grants such as read, edit,
check, report, delegate, propose and audit narrow the mediated operations,
while separate provisioned logins and host-side validation distinguish
agent, CI and reviewer acts. Test the effective Fossil caps on each project,
including inherited category caps, before granting a work unit.
For Gemma, start with inspect, bounded read, patch, verify and finish. Give one saved edit task a fixed step and byte budget; add a tool only when the task shows it is needed. Post each exact Ollama request and response JSON, the advertised schemas and the tool result to the prompting record before the next model step. Keep session credentials outside requests and refuse unsafe or oversize exchanges before sending; do not truncate the record afterward. Choose the smallest available Gemma variant that can run the task and record its exact model identity. Its first proof is three independent runs of the saved task, each with the correct change, passing focused checks, a completed record reply and the full exchange under the fixed budget; score failed runs too. A larger model may diagnose a failure, but does not replace this proof. Trunk's four-task battery and structured tool/result loop are starting evidence. Its fuller prompt passed 7/16 trials against 4/16 for the terse variant, so Parsimony means the shortest sufficient prompt, measured by the task, not the fewest words. Its 192-step default, ambient repository configuration, repeated schema/dispatch tables and local-only raw logs are not the target contract.
Parity contract
The maintainer has not yet chosen which branch merges into which target or
which functional subset that merge must carry; the slices to ocx parity and
past it are in docs/slices-parity.md. The gate
remains red until the scope is written here as rows, each with a check-in on
this branch and a live demonstration reviewed by the maintainer. A future
feature in the gap inventory above need not block a smaller, honest merge.
| Behaviour | Check-in | Demonstration | Status |
|---|---|---|---|
| Merge target and required subset chosen on the record | — | Record the decision and the demonstrated check-ins for the selected functions here. | open |
Phases
- Make the baseline truthful. Resolve the existing guard failures on this branch without pretending the earlier check-ins had demonstrations they did not have. Record the distinction between spec coverage, host evidence and live user evidence. Choose one small Gemma edit task and write its minimal input, output, tool and verification contract before adding machinery.
- Prove one agent work unit. Restore HTTPS creation, which sets the password of the unit's own login, made in Fossil's user pages (HISTORY.md decision 29), and run a task in it as a separate tool; tools are already one typed definition across CGI, CLI and MCP (decisions 32 and 33). A confined Gemma task reads selected artifacts, edits scratch and posts exact exchanges. Show hook wake, daemon supervision, restart recovery and a metered cgroup result.
- Prove clients, nodes and contribution. Bind Claude and Codex to the same
MCP surface and show the daemon starts each on a record change. Delegate a
bounded subtask to local Gemma under its own login. Show a locally written
forum post sync to a remote agent, status through SSE with
/ext/ocx/statusfallback, and its reply sync back. Show periodic sync delivering a task to target hardware, its local hook starting CI, and bounded output returning by sync. Test backoffice timing, exclusive claims and an independent target run. Propose a checked work-branch change with attributed acceptance. - Prove review and release. Record a cited local-model review, a separate auditor verdict and CI service verdict on one check-in, and measure their costs. A built release was staged and accepted through the served interface on 2026-10-06 (a7a5e719eb90); roll one back there too.
- Extend only what the Gemma slice needs. Compare its saved tasks against a hosted runner and add grounded search, documentation freshness and model improvement only with separate evidence of user benefit. Preserve the result, not trunk's polling, storage or oversized prompt machinery.
- Compare branches before merging. Revisit this table with live evidence
from the current branch. Decide which remaining
trunkfunctions improve the README's product, and record explicit deferrals for those that do not.
Working rules
- A unit is a slice, never a file. The first unit of a phase is the thinnest end-to-end slice that achieves the phase's intent; later units deepen it; types are extracted from working slices, not declared ahead of them. A check-in whose only claim is "here is a file" has no intent.
- Parsimony admission. State the minimal contract and fixed work budget for each slice. A new tool, state file, abstraction or model step earns its place by a demonstrated need in that slice: a scenario's step, or a test that demonstrates a tool. What loses its use is removed, not guarded (the maintainer, 2026-10-08). A Gemma failure prompts inspection of the task and interface before increasing model size or adding machinery.
- Check-in format. Title line; then
Intent:(what for),Expression:(what changed),Demonstrates:(the spec file orcrystal runcommand that shows it, which must exist). Cite any precept in prose or a check-in comment by ID and name, such asprecept C6 (Explicit Arguments). Guards: precept C3 (Stated Change) and precept A1 (Visible Evidence). - One CI command.
crystal run ci.cr: dependency ledger, format check, tree guards and coverage ratchet.-- hostadds the host guards;-- merge-gateadds the parity and compiler gates. On a compiler other than the pin the result says so and is not a gate result. The ratchet detects coverage loss; it does not make the suite faster. CI and tools take explicit arguments, with only the served CGI request fields excepted by precept C6 (Explicit Arguments). - Audit by sample. An audit is a tag named
auditedon the check-in, whose value is a verdict,passorfail, a colon, and the note; the auditor and time are the tag artifact's own. Slice 0.5 strippedauditfrom this branch (2b7ea5bea9), so the acceptedocxrelease'sauditadds one meanwhile; the web timeline and Stone can do the same. A tag records a verdict about a check-in; a ticket records work arising from it, so a failing audit usually yields both. Absence means unaudited and is visible. Precept A2 (Artifact Audit) prints coverage and the verdicts. The meaning is on the wiki pagetag/audited. - Decisions. The maintainer carries five to ten decisions a day. Ask only when blocking, one question at a time, in the question shape, on the artifact the work came from. Otherwise say what will be done and do it.
- Notation is OCX's. The pre-prompt that relates a task to a provider's context (a system prompt and tools for a model, the question shape for a person) is mechanical and composed by OCX. Every exact model request, advertised tool schema, raw response and tool result belongs on the prompting Fossil record, before the next model step; no session credential enters that exchange. The answer returns over the same ticket, thread or check-in. From the database's view, a person and an agent differ only by login and by the notation OCX added.
- Runtime layout. A work unit's node-local directory is derived from its record specification and holds its own login's clone, which remembers that login's password, a checkout, scratch and a confinement plan. The child uses the clone directly; the sandbox keeps the served repository and other units' workspaces out of reach. The unit syncs as its own login and never opens the served repository file. A local binding must agree with the record specification.
- Maintainer-owned host scripts. Agents do not edit
scripts/without approval on the record, as HISTORY.md decision 22 requires. - Documentation authority. Change the README when changing purpose, axioms or virtues, ARCHITECTURE.md when changing intended functionality, and USAGE.md when changing an interface; change this plan for the gap, implementation choice, evidence and schedule. Neither a green spec nor an old decision silently changes those documents.
- Name. OCX, everywhere it can be used.
Open design questions and deliberate deferrals
- Wake recovery: A pipe or remote hint can be dropped while a daemon stays alive. Startup sync alone cannot bound that delay. Preserve hook-driven work without an agent-side model polling loop: prove a server-backed retry and acknowledgement or a reconnecting event stream with record reconciliation. A target node's scheduled Fossil sync also reconciles remote work. Record latency and resource cost; no idle model calls are needed.
- Node registration: Periodic target sync needs no server-initiated node endpoint. Add remote wake delivery only when measured latency requires it; then keep node addresses and delivery credentials in explicit host provisioning inputs, never in synced records or Fossil config. A remote hint carries only a hash and never authorizes work.
- Objective test: The README states what OCX is for, but not yet a repeatable threshold for useful coding work. Comparing two runners on the same task tests substitution; a task that also produces a reviewed change would test usefulness. Choose that benchmark before claiming progress.
- Crystal server replacement: The README scopes direct SQLite work outside serving to clones and offline tools. The query-only served CGI of historical decision 20 is a server-spawned request handler under precept I4 (Server-Only Writer). Any Crystal replacement for Fossil's server must assume that same ownership and demonstrate concurrency, locking and rollback-journal behavior before opening a served repository.
- Scope of replacement: The README allows Fossil, Crystal and Linux to change over time. The current guards demonstrate only specific seams, not that any of those three can be replaced now. Make replacements answer a measured need before adding abstraction for them.
- Branch permissions: Fossil grants check-in permission to a login, not to one branch. Keep branch ownership visible and review wrong-branch check-ins; do not describe the sandbox as server-side branch authorization.
- External program wrappers: Fossil's reads pass one contract spec by two
implementations, the program and direct SQLite (
spec/ocx/fossil_spec.cr); its writes and an artifact's content have only the program's so far. - Merge evidence: The current gate checks a row's
shownword and the existence of its check-in, but not that the check-in belongs to the chosen branch or that the maintainer saw the live behavior. Strengthen the gate after the merge scope is chosen. - Search storage:
trunkkeeps a local vector cache and unversioned transfer blobs in a repository. Reconcile that with precept I4 (Server-Only Writer) and with clone isolation before importing it; the search result and artifact provenance matter more than its first storage layout. - Releases beyond a staging server: before a server with private code or costly downtime (HISTORY.md decision 31): the preview as its own OS user; acceptance recorded as an artifact (digest, full check-in, node, login, time), with accept hashing the files; trust across nodes by a key held off the server; reproducible builds, shown by building one check-in twice; and a per-agent or drop-only staged area.
- Model refinement: Prompt conditioning and a few-shot corpus are not weight training. Defer any training claim until reproducible evaluations show an improvement over the base model on coding work.
- Idle work and failures: A hook avoids polling for new work, but a failed sync needs a bounded retry or another explicit recovery signal. A pipe reader that cannot launch a runner must not be shown as an agent able to answer.