Skip to content

Commit 1061080

Browse files
docs(vrs): intent is code, a version is a module, peer code is executed
Three decisions from the plans-as-code pivot. 0012 — intent is authored as code and identity is declared. A dependency becomes a variable, so a reference cannot be invented or mistyped; a revision becomes a function of its predecessor, so dropping a step is unrepresentable rather than refused; a Step's identity is the name it is declared under. Minting, write-back, provenance checking and the minted- reference ledger all disappear together. Load-bearing and nearly missed: the derived identity must be part of the hashed content, or renaming a declaration re-identifies a Step invisibly. 0013 — the evidence vocabulary stays undeclared. Declaring it would put vocabulary inside plan identity, so widening an enum would mint a version of every plan carrying it with no change in intent. And no declaration can reach across versions anyway, since evidence is evaluated at the current frontier and the recorded version is provenance, not scope. The defect is caught better by cross-checking a write against criteria already stored — naming the criterion that was meant rather than reporting a type error. 0014 — a version is a module, and peer code is executed. Supersedes 0009. The import idiom requires a prior version to BE a module, and the objection to hashing source dissolves: a committed version is never reformatted, so identity changing under alteration is the detection mechanism, not a fragility. The consequence is stated rather than discovered — reading a plan evaluates everything it imports, and under replication those modules were authored elsewhere. A generated-binding shim was considered and rejected as buying less than it costs. What makes it acceptable is the capability boundary, which is now protecting against a peer rather than an accident. Also CMP-R11: starting a plan must be trivial. Made a requirement rather than a preference because the vision claims nothing should tempt anyone to keep plans elsewhere, and a checklist is always cheaper — a tool heavier at the first step loses before its guarantees can matter. Testable: an agent given a small task either reaches for it or does not. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ini/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 3180a78 commit 1061080

5 files changed

Lines changed: 334 additions & 4 deletions
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
# Intent is authored as code, and identity is declared
2+
3+
Status: accepted
4+
5+
Supersedes the authoring surface of
6+
[0010](./0010-intent-is-authored-as-a-document-then-committed.md) and the
7+
minting mechanism of [0004](./0004-stepref-is-minted-not-content-derived.md).
8+
9+
## Context
10+
11+
Decision 0010 moved authoring from command arguments into a document, because a
12+
composition assembled inside one process has nowhere durable to live. That
13+
diagnosis was right and its consequences held: retries became idempotent,
14+
reconciliation became derivable.
15+
16+
But the document carried three problems it could not solve. A reference had to
17+
be minted and written back, so a value the author never chose still had to
18+
survive in a file the author edits. A dependency was a reference typed as a
19+
string, so it could be mistyped or invented — an editing experiment across
20+
several document formats found that where a reference sits determines whether an
21+
author fabricates one, and that a plausible fabrication is the worst available
22+
outcome. And a document restates the whole plan to change one line, so the
23+
authoring surface was permanently exposed to a class of silent loss that had to
24+
be refused at commit rather than prevented.
25+
26+
## Evidence and Argument
27+
28+
Expressing intent in a programming language dissolves all three, because a
29+
language already has the mechanisms a document was imitating.
30+
31+
A dependency is a **variable**, so a reference is never typed and cannot be
32+
invented, mistyped, or omitted. A revision is a **function of its predecessor**
33+
that takes edits, additions, and retirements, so there is no parameter capable of
34+
removing a step and the silent-loss class is unrepresentable rather than
35+
refused. A cross-plan reference is an **import**, resolved and checked rather
36+
than spelled.
37+
38+
Identity follows from the same observation. A minted reference existed because
39+
content addressing breaks under rewording. But a declaration already has a
40+
stable, author-given, tool-checked handle — its **exported name**. Rewording the
41+
work does not touch it; renaming it breaks every importer loudly, where a
42+
mistyped random value fails silently. So identity can be *declared* rather than
43+
minted, and the entire apparatus that existed to make a random value durable —
44+
minting, write-back, provenance checking, and a ledger recording what was minted
45+
— disappears.
46+
47+
This was proven rather than assumed. Evaluation is deterministic across
48+
repetitions and across engine versions; identity survives rewording; a retired
49+
step is carried forward and marked rather than omitted; a plan that reads the
50+
clock is refused; and renaming a declaration in a committed version changes its
51+
hash, so re-identification is detectable.
52+
53+
That last property is conditional and was nearly missed: it holds **only because
54+
the derived identity is part of the hashed content**. Before that, renaming a
55+
declaration silently re-identified a step while the hash stayed constant. The
56+
requirement is therefore load-bearing, not incidental.
57+
58+
The cost is real and stated plainly: intent is now a program, so evaluating it
59+
demands determinism and a capability boundary — see
60+
[0011](./0011-the-javascript-runtime-is-embedded-not-invoked.md).
61+
62+
## Options
63+
64+
| Option | Tradeoffs |
65+
| --- | --- |
66+
| Intent as code, identity declared | References cannot be invented; dropping is unrepresentable; cross-plan references are checked; no minting apparatus at all. Intent becomes a program that must be evaluated safely and deterministically |
67+
| Intent as a document, references minted | No evaluation and no capability boundary; a reference must be minted and made durable, dropping must be refused rather than prevented, and every dependency is a string an author can get wrong |
68+
| Intent as a document, identity content-derived | No minting; identity breaks the moment work is reworded, which is the ordinary case |
69+
| Intent as code, references still minted | Keeps a mechanism the language makes unnecessary, and reintroduces a value the author neither chose nor can verify |
70+
71+
## Decision
72+
73+
Intent is authored as code, evaluated to a canonical form, and stored
74+
immutably.
75+
76+
A Step's identity is the **name it is declared under**, qualified by its Plan. It
77+
is not minted, not random, and not derived from content. It is assigned where the
78+
Step is first declared and carried forward by revision, so a Step that outlives
79+
many versions keeps the identity it was born with.
80+
81+
A Step declared without a name has no identity and is refused. A name is never
82+
reused once retired.
83+
84+
**The derived identity is part of the hashed content.** Without this, renaming a
85+
declaration re-identifies a Step invisibly.
86+
87+
A revision is expressed as a function of its predecessor. It may edit, add, and
88+
retire; it has no way to remove. Steps are carried forward, so omission is not
89+
expressible and the drop-refusal of 0010 becomes unnecessary rather than
90+
enforced.
91+
92+
Dependencies and cross-plan references are ordinary language references.
93+
94+
## Consequences
95+
96+
- Minting, write-back, reference provenance, and the minted-reference ledger are
97+
all removed. Four mechanisms and one invented concept disappear together.
98+
- A rejected commit leaves authored content untouched, because nothing needs to
99+
be written back into it. What 0010 could only approximate becomes literally
100+
true.
101+
- Renaming a declaration is a change of identity. For a Step carried forward
102+
this cannot arise, since it descends from its original declaration rather than
103+
being re-declared; for a newly declared Step before commit it is harmless. It
104+
is only consequential when editing already-committed source, which is
105+
detectable and is itself a violation.
106+
- A Step must be a named declaration. Anonymous construction is refused, which
107+
is a constraint on how intent is written.
108+
- Intent is a program. Everything about determinism and capability in 0011
109+
follows from this decision, and neither can be relaxed independently.
110+
- The authored form and the stored form are now different artifacts. The stored
111+
form is what replicates, what is hashed, and what is read; it is never
112+
authored by hand.
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
# The evidence vocabulary stays undeclared
2+
3+
Status: accepted
4+
5+
## Context
6+
7+
Compass fixes the structure of a Plan and rejects unknown fields in it. It fixes
8+
nothing about the words used inside an acceptance criterion — the kinds of
9+
evidence and their attributes are supplied entirely by whoever writes the plan,
10+
and are validated by nobody.
11+
12+
That produces a specific, silent defect. A criterion naming one spelling and an
13+
evidence record naming another leaves the criterion *valid* and permanently
14+
unsatisfied. Readiness reports the step as waiting, forever, in a way
15+
indistinguishable from work that simply is not done.
16+
17+
The obvious remedy is to make the vocabulary declared, so criterion and evidence
18+
are checked against one definition.
19+
20+
## Evidence and Argument
21+
22+
Two findings, each sufficient on its own, argue against declaring it.
23+
24+
**A declaration would put the vocabulary inside plan identity.** Identity is a
25+
hash of the whole body, so a vocabulary carried in a version means widening an
26+
enum or adding an attribute mints a substantive new version of *every plan that
27+
uses it* — with no change to intent whatsoever. A system whose central claim is
28+
that a version means intent changed would then manufacture versions nobody
29+
authored. Keeping the declaration outside the version instead makes it a
30+
dangling reference under replication, since the catalog replicates as files with
31+
no resolution root.
32+
33+
**No declaration can reach across versions anyway.** Evidence is evaluated
34+
against the criterion at the current frontier, not against the version it was
35+
recorded under; the recorded version is provenance, not evaluation scope.
36+
Validation is therefore only ever possible at write time, and a narrowing
37+
revision leaves previously-valid evidence inert under every later criterion — the
38+
original symptom, now with a declaration certifying the evidence as fine.
39+
40+
Against that, the defect is fully catchable without any declaration. The
41+
criteria are already in the version being written against, so a record can be
42+
checked against them at write time using only what is in memory. The domain of
43+
each attribute is derivable from the values the plan's own criteria bind — the
44+
plan supplies its own enumeration without declaring one. The resulting
45+
diagnostic is *better* than a declaration would give: not that a value is
46+
ill-typed, but which criterion was meant and how it differs.
47+
48+
Two subtleties were found by prototyping the naive form and breaking it.
49+
Negation is idiomatic — "no known failure" — so a record matching the inner term
50+
of a negated criterion is not a mistake to correct but an outcome to report; only
51+
positively-stated criteria may suggest a correction. And a near-match is not
52+
evidence of a mistake, because a genuine alternative outcome differs from the
53+
expected one by exactly as much as a misspelling does. Both are handled by
54+
scoping to polarity and deriving the domain from the plan's own corpus, and the
55+
residual — a legitimate value no criterion happens to mention — is irreducible
56+
and is why this reports rather than refuses.
57+
58+
## Options
59+
60+
| Option | Tradeoffs |
61+
| --- | --- |
62+
| Undeclared, with a write-time cross-check | Catches the defect with a better diagnostic, no dependency, no schema, no effect on identity; cannot see values no criterion mentions, so it warns rather than refuses |
63+
| Declared, carried inside the version | Exact validation and static detection of unsatisfiable criteria; puts vocabulary inside identity, so a vocabulary change mints versions nobody authored |
64+
| Declared, carried outside the version | Identity untouched; becomes a dangling reference under replication, and a fix cannot reach what is already committed |
65+
| Undeclared, no checking at all | Nothing to build; the defect stays silent and indistinguishable from unfinished work |
66+
67+
## Decision
68+
69+
The evidence vocabulary remains undeclared. Compass does not define, validate, or
70+
adjudicate what evidence means.
71+
72+
When a record is written, it is cross-checked against the acceptance criteria it
73+
could contribute to. A value outside the domain those criteria establish is
74+
reported, naming the criterion it most likely intended. This reports; it never
75+
refuses, because the derivable domain is necessarily incomplete.
76+
77+
A record matching a negated criterion is reported as consequential rather than
78+
mistaken: it will withdraw acceptance rather than grant it.
79+
80+
An attribute no criterion mentions remains accepted in silence. Matching is a
81+
subset relation by design, and evidence may legitimately carry more context than
82+
any criterion demands.
83+
84+
Separately, a criterion that **contradicts itself** is detected when it is
85+
written. This is a strictly smaller claim than deciding whether a criterion can
86+
be satisfied — which is undecidable here, since satisfaction may depend on
87+
whether a named actor ever acts — and being smaller, it is a claim that can
88+
always be kept.
89+
90+
## Consequences
91+
92+
- Compass stays domain-neutral. Nothing in it names a kind of work, which is why
93+
a plan for writing or research is expressible on the same terms as one for
94+
software.
95+
- The defect is caught where it is made, with a diagnostic that names the
96+
criterion rather than the type.
97+
- Some misspellings are missed — those whose value is plausible for a criterion
98+
that does not exist. This is the accepted ceiling.
99+
- Compass records claims and does not certify their meaning, consistent with
100+
evidence being a claim whose author is recorded rather than adjudicated.
101+
- A narrowing revision can strand previously-recorded evidence. Nothing here
102+
prevents that, and reporting it is a separate concern from validating a write.
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# A version is a module, and peer code is executed
2+
3+
Status: accepted
4+
5+
Supersedes [0009](./0009-kdl-is-parsed-upstream-and-rendered-canonically-here.md).
6+
7+
## Context
8+
9+
Decision 0012 makes intent a program, so that a dependency is a variable and a
10+
prior Step is referenced by importing it. That idiom only works if a prior
11+
version **is a module** — a reference cannot be imported from a document.
12+
13+
An earlier design kept a separate stored form and treated the authored source as
14+
transient. That is incoherent with the import idiom and was carried for one
15+
reason: the belief that hashing source makes formatting identity-bearing, and
16+
therefore fragile.
17+
18+
## Evidence and Argument
19+
20+
The objection dissolves on inspection. A committed version is immutable — nobody
21+
reformats one, because doing so is not an edit but a forgery. Identity changing
22+
under reformatting is not a fragility; it is the detection mechanism. A content
23+
hash carried in the filename makes any alteration of committed source visible,
24+
which is precisely the guarantee wanted.
25+
26+
So a version is a module, stored as authored, named by the hash of its bytes.
27+
There is no second artifact, no canonical renderer to own, and no divergence
28+
possible between what was written and what was stored.
29+
30+
The consequence has to be stated rather than discovered: **reading a plan
31+
evaluates it, and evaluating a version evaluates every version and plan it
32+
imports.** Under replication those modules were authored elsewhere. Compass
33+
therefore executes code that arrived from another machine.
34+
35+
This was considered against two alternatives. Storing an evaluated form
36+
alongside the source only half-helps, since a successor importing a predecessor
37+
still evaluates the original. Generating data-only binding modules and importing
38+
those would avoid executing foreign authored logic entirely, at the cost of a
39+
generated artifact per version, a generator to keep honest, and an import that no
40+
longer refers to the module actually written.
41+
42+
The direct form is chosen. A plan is code; running a peer's plan is running a
43+
peer's code, and pretending otherwise by interposing a generated shim buys less
44+
than it costs — the shim is still executed, and the honesty is worse.
45+
46+
What makes this acceptable is not trust but the evaluation environment. A plan
47+
runs against an explicitly constructed global with no clock, no filesystem, no
48+
network, no dynamic code construction, and no capability the host did not name.
49+
A hostile plan can compute; it cannot reach anything.
50+
51+
## Options
52+
53+
| Option | Tradeoffs |
54+
| --- | --- |
55+
| A version is a module, imported directly | The import idiom works as written; one artifact; alteration detectable by hash. Reading executes code authored elsewhere |
56+
| A version is a module plus a stored evaluated form | Reads avoid evaluation; a successor still evaluates its predecessor, so foreign execution is only reduced, and two artifacts can disagree |
57+
| Imports resolve to generated data-only bindings | Foreign authored logic never runs; adds a generated artifact and a generator per version, and an import stops referring to the module written |
58+
| A version is a document; references are spelled | No execution at all; loses the import idiom, and returns every reference to a string that can be mistyped or invented |
59+
60+
## Decision
61+
62+
A committed version is the authored module, stored unchanged and named by the
63+
hash of its bytes.
64+
65+
Altering committed source changes its hash and is detected. Committed source is
66+
never rewritten, reformatted, or migrated in place.
67+
68+
Reading a plan evaluates it and everything it imports. **Compass executes modules
69+
authored on other machines.** This is a deliberate consequence of intent being
70+
code, not an oversight, and it is the reason the evaluation environment in 0011
71+
is a correctness boundary rather than a convenience.
72+
73+
Evaluation is bounded. A plan that does not terminate, or that allocates without
74+
limit, is stopped and reported — executing foreign code makes resource
75+
exhaustion a reachable state rather than a theoretical one.
76+
77+
## Consequences
78+
79+
- One artifact per version. The authored form and the stored form are the same
80+
thing, so they cannot drift.
81+
- Identity is the hash of source bytes. Whitespace is therefore significant, and
82+
that is deliberate: it is what makes tampering visible.
83+
- Reads are expensive, because they evaluate. A derived, rebuildable index is
84+
no longer an optimisation but a requirement for reading at scale.
85+
- The capability boundary carries far more weight than when only local drafts
86+
were evaluated. Every exclusion in 0011 is now protecting against a peer rather
87+
than against an accident, and relaxing any of them is a change to this
88+
decision.
89+
- Execution must be bounded in time and memory. A denial of service is now the
90+
most plausible hostile act, and it is the one the capability list does not
91+
address.
92+
- A plan cannot be read on a machine that lacks its imports. An unreplicated
93+
import is worse than a missing predecessor: the plan cannot be evaluated at
94+
all, rather than merely showing an incomplete lineage.

context/06-evals/spec.md

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,16 @@ asserted:
105105
| evidence contradicts | acceptance is a current reading, not a latch — CMP.DM-R12 |
106106
| a claim without standing | predicates bind recorded fields — decision 0008 |
107107
| a plan that is not code | the model is domain-neutral |
108-
109-
The last one is deliberate. Nothing in the model mentions code, and a suite
110-
composed only of engineering scenarios would quietly make that claim false by
111-
never testing it.
108+
| an agent given a small task | starting is trivial — CMP-R11 |
109+
110+
The domain-neutral scenario is deliberate. Nothing in the model mentions code,
111+
and a suite composed only of engineering scenarios would quietly make that claim
112+
false by never testing it.
113+
114+
The last scenario is of a different kind and is the only one that cannot be
115+
asserted mechanically. CMP-R11 claims starting a plan is trivial enough that
116+
nobody reaches for a checklist instead — which is a claim about behaviour under
117+
choice, not about output. It is measured by giving an agent a small planning task
118+
with Compass available and observing whether it uses it, and it fails when the
119+
agent writes its own list. A scenario that merely drives the commands would prove
120+
the commands work while leaving the claim untested.

context/requirements.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,3 +88,16 @@ for one layer:
8888
store a wrong value is permanent. This constrains identity, ordering, and
8989
deduplication in particular: none of them may rest on something an actor
9090
chooses.
91+
92+
- **CMP-R11 Starting a plan must be trivial.** Beginning a plan must cost one
93+
command and produce something immediately workable, with nothing to import,
94+
configure, or look up. Ceremony must scale with a plan's size, never with the
95+
act of starting one.
96+
97+
This is a requirement rather than an ergonomic preference because the vision
98+
claims nothing about the tool should tempt anyone to keep plans elsewhere, and
99+
a hand-written checklist is always available and always cheap. A tool that is
100+
heavier at the first step loses to the checklist before any of its guarantees
101+
can matter. Whether it holds is observable — an agent given a small planning
102+
task either reaches for Compass or does not — so it is testable rather than
103+
asserted.

0 commit comments

Comments
 (0)