Skip to content

Commit 41c24e1

Browse files
docs(vrs): decompose into five subsystems along the realization axis
The flat tree conflated what a Plan IS with how it is stored. Separating them gives the hierarchy a real axis: the data model is mechanism-agnostic, and the on-disk catalog is one realization of it. VRS.SUB-R02 asks for exactly this ("substantial data models become child VRS nodes"), and it is why refines: edges here carry weight rather than decorate. 01-data-model CMP.DM-* lineage, identity, divergence, progress, acceptance, readiness — no storage knowledge 02-artifacts CMP.FS-* layout, content identity, admission, integrity, repair — one realization 03-surface CMP.SURF-* the sanctioned way to read and change a Plan 04-cli CMP.CLI-* operator interface; adds no semantics 05-integrations CMP.INT-* catalog form and replication, consumed Root keeps what must be true of the system (CMP-R01..R09) plus the assumptions and tradeoffs; each node refines it for one layer. Dependency direction is one-way: the model does not know it lives in files, and the files do not know a CLI exists. PlanPort renamed to Plan Surface — "port" imported a pattern name into the vocabulary without saying what the thing does. PlanReceipt shortened to Receipt. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QzRc44KbA3wfYYKFF9UDMa agent-session-id: cdf2c185-eeb3-4a4d-8ce0-52885f145cac agent-tool: Claude Code agent-tool-version: 2.1.215 agent-model: claude-opus-4-8 agent-runtime-profile: /nix/store/acr8a3l2v366jgmwiq8xdrhgz1py0db5-coding-agent-runtime-profile/share/coding-agents/profile.json agent-skills-manifest: /nix/store/sj1v5j91h8v8d1w9lca4040302lwrd6v-agent-skills-corpus/share/agent-skills/manifest.json tooling-profile: dotfiles@unknown-dirty
1 parent 0a9cdfb commit 41c24e1

15 files changed

Lines changed: 765 additions & 395 deletions

File tree

context/.decisions/0001-compass-is-an-independent-authority.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ paths, schemas, event envelopes, or storage layouts.
4343

4444
Other systems compose with Compass through opaque references, mutations,
4545
queries, and receipts. They may record operational facts referencing a
46-
PlanReceipt, but such facts never become Compass state. Compass exposes no
46+
Receipt, but such facts never become Compass state. Compass exposes no
4747
subcommand inside another tool's CLI namespace; a facade would make the
4848
namespace imply authority.
4949

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# Requirements: Data Model
2+
3+
> **Role.** What a Plan *is*, independent of how it is stored. This node defines
4+
> lineage, identity, divergence, progress, acceptance, and readiness as logical
5+
> structure; [02-artifacts](../02-artifacts/requirements.md) realizes it as
6+
> files. Each requirement `refines:` a `CMP-R*`.
7+
8+
## Requirements
9+
10+
### Lineage
11+
12+
- **CMP.DM-R01 A Plan is a lineage of versions.** Each version records its
13+
predecessors, so the history of intent is reconstructible from the versions
14+
alone. _refines: CMP-R02._
15+
16+
- **CMP.DM-R02 Every version carries a Rationale.** The reason for the revision
17+
is part of the version, not metadata about it. _refines: CMP-R03._
18+
19+
- **CMP.DM-R03 Head is derived.** The frontier of a Plan is computed from the
20+
lineage rather than recorded, so no stored value can disagree with the
21+
versions. Head is a set; ordinarily it has one member.
22+
_refines: CMP-R02, CMP-R04._
23+
24+
- **CMP.DM-R04 Divergence is a state, not an error.** Versions sharing a
25+
predecessor are both valid and both reported. _refines: CMP-R04._
26+
27+
- **CMP.DM-R05 Divergence resolves by authorship.** Reconciliation is an
28+
ordinary version naming every predecessor it reconciles, with its own
29+
Rationale. Nothing reconciles automatically, and a reconciliation may itself
30+
diverge. _refines: CMP-R03, CMP-R04._
31+
32+
- **CMP.DM-R06 An absent predecessor is not divergence.** A version whose
33+
predecessor is unknown must be distinguished from one that disagrees. The
34+
first ordinarily means state is still arriving; treating it as the second
35+
writes permanent intent to resolve a transient condition.
36+
_refines: CMP-R04, CMP-R05._
37+
38+
- **CMP.DM-R07 Versions are attributable.** Each version records its author and
39+
a logical time ordered against other versions of the same Plan. Reconciling
40+
divergence requires knowing who wrote each side and in what order.
41+
_refines: CMP-R03, CMP-R04._
42+
43+
### Identity
44+
45+
- **CMP.DM-R08 References are minted, not derived.** A Plan reference and a Step
46+
reference are minted at creation and are independent of content, so revising
47+
text preserves identity and a reader can follow one unit of work across the
48+
whole lineage. _refines: CMP-R02._
49+
50+
- **CMP.DM-R09 References survive concurrent minting.** Two machines minting at
51+
the same time, without a coordinator, must not produce the same reference.
52+
_refines: CMP-R04._
53+
54+
- **CMP.DM-R10 Retired references are final.** A reference is never reused after
55+
retirement, and identity changes — split, merge, replacement — are stated
56+
explicitly rather than inherited silently. _refines: CMP-R02._
57+
58+
### Progress and acceptance
59+
60+
- **CMP.DM-R11 Progress is append-only.** Progress records never alter intent
61+
and never create a version. Correction is a further record, never an edit.
62+
_refines: CMP-R02._
63+
64+
- **CMP.DM-R12 Acceptance is evaluable.** A Step's acceptance criterion is
65+
expressible in a form Compass can evaluate against recorded evidence. Prose
66+
may accompany it but is not the criterion, because readiness cannot fold over
67+
prose. _refines: CMP-R01._
68+
69+
- **CMP.DM-R13 Only Compass judges completion.** An external record never
70+
completes a Step; completion follows from the Step's own acceptance criterion.
71+
_refines: CMP-R01._
72+
73+
### Readiness
74+
75+
- **CMP.DM-R14 Readiness is derived.** What can be worked on now follows from
76+
the Step graph at head, accepted progress, and gates. It is part of the model,
77+
not a projection over it. _refines: CMP-R01._
78+
79+
- **CMP.DM-R15 Readiness explains itself.** Every answer names the unsatisfied
80+
dependencies and gates. An answer that cannot say why is neither trustworthy
81+
nor debuggable, and this constrains what an acceptance criterion may express.
82+
_refines: CMP-R01._
83+
84+
- **CMP.DM-R16 Readiness is defined under divergence.** With more than one head
85+
member, readiness is reported per member and labelled. It never selects a side
86+
and never merges graphs, which would assert intent nobody authored. The normal
87+
state of the system must not be an undefined state of its primary query.
88+
_refines: CMP-R04._

context/01-data-model/spec.md

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# Spec: Data Model
2+
3+
Realizes [requirements.md](./requirements.md). Storage is specified in
4+
[02-artifacts](../02-artifacts/spec.md) and is deliberately absent here.
5+
6+
## Plan
7+
8+
A Plan is a lineage of Versions plus the Progress recorded against them. It is
9+
named by a minted `PlanRef`.
10+
11+
## Version
12+
13+
| Field | Meaning |
14+
| --- | --- |
15+
| `plan` | the Plan this version belongs to |
16+
| `parent` | each predecessor; none for the first, several for a reconciliation |
17+
| `author` | who authored the revision |
18+
| `at` | logical time, ordered against other versions of this Plan |
19+
| `why` | the Rationale — required |
20+
| `goal` | the intent being pursued |
21+
| `step` | zero or more Steps |
22+
| `retired` | optional decommission flag |
23+
24+
`at` is a logical counter, not wall-clock time: machines disagree about clocks
25+
and agree about causality, and ordering two sides of a divergence is a causal
26+
question.
27+
28+
A version is identified by its content. Two versions with identical content are
29+
the same version; any difference makes a different one. This is what makes
30+
divergence observable rather than a lost write — see
31+
[02-artifacts](../02-artifacts/spec.md) for how identity is computed.
32+
33+
## Step
34+
35+
A Step carries a minted `StepRef`, the intended work, `depends_on` edges, an
36+
optional `supersedes` naming the Step it replaces, and an acceptance criterion.
37+
38+
Step identity is minted rather than derived from content, because a Step's
39+
reference must survive rewording of the same intended work. Version identity is
40+
derived from content, because a version's identity *should* change whenever its
41+
bytes do. The two layers want opposite properties and therefore use different
42+
mechanisms; this asymmetry is deliberate.
43+
44+
## Lineage, head, divergence
45+
46+
Head is the set of versions with no successor, computed by walking the lineage.
47+
48+
- **Divergence** — two or more versions share a predecessor. Both are valid.
49+
- **Reconciliation** — an ordinary version naming several predecessors.
50+
- **Orphan** — a version whose predecessor is unknown locally.
51+
52+
Divergence and orphan are superficially alike and must not be conflated: the
53+
first is a disagreement about intent, the second is ordinarily incomplete
54+
replication. Reconciling an orphan writes permanent intent to paper over a
55+
transient gap.
56+
57+
A reconciliation can itself diverge, because nothing serializes authorship. Two
58+
machines observing one divergence may each reconcile it differently, producing a
59+
new divergence between the reconciliations. Compass reports this; it does not
60+
resolve it. This is the cost of CMP-T01, and it is why convergence is a reported
61+
condition rather than an assumed one.
62+
63+
## Progress
64+
65+
A Progress record names a Plan, a Step, the version it was observed against, an
66+
actor, and a payload: start, update, handoff, completion, evidence.
67+
68+
Records are additive. A record against a superseded Step is attributed forward
69+
through `supersedes`; a record against a retired Step is retained but does not
70+
contribute to readiness.
71+
72+
## Acceptance
73+
74+
An acceptance criterion is a predicate over recorded evidence. It answers
75+
whether a Step is done, from what has actually been observed, without asking a
76+
judge.
77+
78+
The predicate vocabulary is unresolved (DQ03). Its shape is constrained by
79+
CMP.DM-R15: a predicate that cannot report which of its parts failed makes
80+
readiness unexplainable, so expressive power that costs explainability is not a
81+
good trade here.
82+
83+
## Readiness
84+
85+
A Step is ready when it is not retired, its acceptance criterion is not yet
86+
satisfied, and every Step it depends on has a satisfied criterion.
87+
88+
Every answer carries its reasons — which dependency or gate is unsatisfied.
89+
90+
Under divergence, readiness is computed per head member and labelled with it.
91+
Merging the graphs would produce a plan nobody wrote; picking a side would hide
92+
a disagreement the model exists to surface.

context/01-integrations/requirements.md

Lines changed: 0 additions & 62 deletions
This file was deleted.
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# Requirements: Artifacts
2+
3+
> **Role.** One realization of the [data model](../01-data-model/requirements.md)
4+
> as files on disk: layout, identity, admission, integrity, and repair. The
5+
> model does not depend on this realization; this node depends on the model.
6+
> Each requirement `refines:` a `CMP-R*` or a `CMP.DM-R*`.
7+
8+
## Requirements
9+
10+
### Layout and identity
11+
12+
- **CMP.FS-R01 The catalog root is configuration.** No storage location is
13+
compiled in. _refines: CMP-R06._
14+
15+
- **CMP.FS-R02 Version identity is the content.** A version's stored identity is
16+
a hash of its content, so identical content is one version and any difference
17+
is another. This is what makes divergence survive replication instead of
18+
becoming a lost write. _refines: CMP.DM-R03, CMP.DM-R04._
19+
20+
- **CMP.FS-R03 Content hashes never address Steps.** Step references are minted
21+
values carried in the document, never derived from it.
22+
_refines: CMP.DM-R08._
23+
24+
- **CMP.FS-R04 Nothing records head.** No file names the current version. A
25+
stored head is a cell two writers can contend on, and union replication cannot
26+
merge one. _refines: CMP.DM-R03._
27+
28+
- **CMP.FS-R05 Paths are machine-agnostic.** Authored content refers to
29+
locations by variable rather than absolute path, so one catalog is valid on
30+
machines with different layouts. An unresolvable reference fails loudly;
31+
resolving it to an empty or plausible path is worse than failing.
32+
_refines: CMP-R06._
33+
34+
### Admission
35+
36+
- **CMP.FS-R06 Admission is deliberate.** A file becomes state only in an
37+
expected location and only when its content matches its recorded identity.
38+
Parsing successfully is not sufficient. Under no-delete replication a wrongly
39+
admitted file is permanent. _refines: CMP-R07._
40+
41+
- **CMP.FS-R07 Identity mismatch is rejection.** A file whose content does not
42+
match its identity is refused with a clear error, not accepted with a warning.
43+
The mismatch is precisely the corruption signal.
44+
_refines: CMP-R07, CMP.FS-R02._
45+
46+
- **CMP.FS-R08 Received files are untrusted.** Files arriving by replication are
47+
admitted on the same terms as local ones. No property conferred by the local
48+
filesystem may be assumed to have survived the wire.
49+
_refines: CMP-R07._
50+
51+
### Integrity and repair
52+
53+
- **CMP.FS-R09 Intent resists accidental edit.** Written intent is stored so
54+
that an in-place edit fails visibly rather than succeeding silently. This
55+
guards against error, not against a determined writer.
56+
_refines: CMP-R02, CMP-T02._
57+
58+
- **CMP.FS-R10 The lineage is checkable.** Compass verifies that every version
59+
matches its identity and that every recorded predecessor is present, and
60+
reports what is broken and where. _refines: CMP-R07._
61+
62+
- **CMP.FS-R11 Repair never rewrites history.** Recovery from damage proceeds by
63+
authoring new content that records the damage and continues from the last
64+
intact predecessor. Editing or deleting a damaged version cascades through
65+
every descendant, and deletion returns on the next sync.
66+
_refines: CMP-R07, CMP-R02._
67+
68+
- **CMP.FS-R12 Retirement is content.** Decommissioning is an authored flag.
69+
Deletion is never the mechanism. _refines: CMP-R02._
70+
71+
- **CMP.FS-R13 Unwritable content stays written.** Content that should never
72+
have been recorded cannot be recalled from replicas. Compass can mark it inert
73+
and flag it; it cannot make it absent. This is a property to design around,
74+
not a gap to close. _refines: CMP-T03._

0 commit comments

Comments
 (0)