Repository navigation
Commit f10c2c8
authored
* ✨ Make `<Plan>` a text component that produces approved source (#722)
`<Plan>` no longer declares a return. Its rendering is the approved program
source: bare, it emits those exact bytes where the component is written; with
`as`, ordinary text capture binds them and nothing is emitted. Neither form
evaluates the source.
Exact bytes are not prose, so a declaring host may say that what its component
renders is source. Segments such a component produced carry that fact to the
emission loop, which is outside every scope the invocation owned, and the
Output Api carries it to the presentation middleware — whitespace normalization
and terminal formatting both pass exact writes through untouched while the
prose around them is presented as before.
A tenth draft that still fails its check after its repairs no longer opens a
review. There is no decision left to offer, so the workflow asks the coding
agent once, automatically, why the attempts did not work, treats that answer as
inert text, and ends without a Plan. The authored exhaustion ending went with
the review it belonged to.
One Plan-artifact record retains the invocation identity, the instruction
identity, the approved source, its digest and the successful admission
together, replacing the per-candidate admission record. The instruction
identity is retained again in the frozen inputs, so a continuation whose
instructions render differently is refused there — as stale input, before a
directory, a provider, a turn or a review exists.
Claude-Session: https://claude.ai/code/session_01DNPFLq52HVSu3NH6WczYLf
* 🔒 Close the exact-source disposition and both Plan record protocols (#722)
The trusted declaration's exact-source disposition is durable. It is retained
in the declared-markdown selection as the closed shape `exact: true`, absence
meaning ordinary prose, hostile-parsed as a fifth member the record may or may
not carry, and compared against the current declaration including absence. A
continuation whose origin, digest and bytes are unchanged but whose disposition
moved is refused before it can publish those bytes — as prose where a program
was recorded, or the reverse.
Both Plan records are closed protocols. The frozen inputs hold exactly `syntax`
and `instruction`; the artifact holds exactly `invocation`, `instruction`,
`source`, `digest` and `admission`. A member missing, a member this version
does not know, or a member of the wrong type is a record that cannot be read
rather than one to fill a default into, and the invocation identity, the source
digest and the successful admission are still checked on top of that shape.
Both unreadable-record refusals are raised as durability failures, for the
reason the changed-instruction refusal already was: they happen while the
journal still holds entries the run will never reach, and an ordinary failure
there is replaced by the completion's divergence report — so the person read a
count of unreached entries instead of what was wrong with their history.
Terminal formatting is held to the same bypass as whitespace normalization, and
both directions are now proven: exact bytes keep their heading, fence,
emphasis markers, trailing spaces and blank runs, while the prose on either
side of the write is still formatted.
Claude-Session: https://claude.ai/code/session_01DNPFLq52HVSu3NH6WczYLf
* ✅ Hold the compiled binary to the text-mode `<Plan>` (#722)
The compiled-binary probe still expected a declared return from the packaged
Component, and the `smoke` job is where that surfaced: import-based test
selection cannot see a subprocess boundary, so no local affected-test run
reaches it.
The binary reports what it embedded, and what it embedded is now a text
component. The origin and digest assertions above the failure had already
passed, which is how we know the compile carried the new Component rather than
an older copy — the expectation was stale, not the build.
The scripted-review type loses the decision that went with the review a tenth
unrepairable draft no longer reaches. Nothing scripts it any more.
Claude-Session: https://claude.ai/code/session_01DNPFLq52HVSu3NH6WczYLf
* 🔒 Make exact source a provenance rather than a field (#722)
Exact-source presentation was read from `ComponentDefinition.exact` and from
`TextSegment.exact` — public data on objects an import can produce. Ordinary
`Component.importComponent` middleware could therefore answer an open name with
a definition of its own carrying the disposition, and core would publish that
handler's bytes unpresented.
It is now derived from two facts no answer can write: that canonical execution
authorized the import for a name this execution closed, and that this host's
own admitted declaration for that name states exact source. The admission holds
the disposition, because a declaration crosses on an ExecutionInstallation by
value before any middleware exists, while a definition is an object a handler
can copy and answer with.
Which segments an expansion produced as source is recorded against those
objects' identity rather than on them. A segment scanned from a document,
parsed from a journal or written by a handler is simply not in that record —
where a field would have been supplied, membership cannot be.
Both public opt-ins are gone rather than replaced: there is no `exact` on
`ComponentDefinition` or `TextSegment`, and no new one anywhere a document,
package, frontmatter or middleware can reach.
The durable protocol is unchanged and now stated as the two closed shapes it
is, with every other spelling refused. The specification and architecture say
what the implementation does, and the acceptance tables gain the rows this work
introduced: a Tier DM table for declared-Markdown selection and exact source,
and the WN and TF rows for the two presentation bypasses.
Claude-Session: https://claude.ai/code/session_01DNPFLq52HVSu3NH6WczYLf
* 🐛 Give the exact-source record to the run that owns it (#722)
The record of which segments an expansion produced as source was a
module-scoped `WeakSet`, which `local/no-module-scoped-registry` refuses: one
table shared by every execution the process performs, surviving the run that
filled it and reachable from no caller's scope. CI caught it where a local lint
run did not, because the failure was one error among a thousand warnings.
It is now created inside the execution that owns it and handed down through
context, beside the segment-cause table it sits next to — reclaimed with the
run, answering nothing during the next. The security property is unchanged and
is what it always was: membership is keyed by the identity of the segment
objects canonical expansion marked, so nothing a document, a package or an
import can supply is able to join it. The context is exported for the two core
modules that produce and consume the mark and reaches neither public package
entrypoint.
The emission paths read that record once, where reading is an ordinary
operation rather than a durable one.
Claude-Session: https://claude.ai/code/session_01DNPFLq52HVSu3NH6WczYLf
* 🔒 Pass the exact-source record by value rather than through a context (#722)
An Effection context resolves by name, and a name is not a secret. Storing the
exact-source record under `xmd.exact-source` therefore published it: an ordinary
function component could build a context with that name, retrieve the
execution's own WeakSet, replace the `has` it inherited, and have its prose
emitted with no whitespace normalization and no terminal formatting. That is an
authority escalation, and it is what AGENTS.md rule 15 means by refusing to let
security enforcement trust replaceable context state.
The record is now created inside the execution that owns it and handed down by
value on the private `ExpansionAuthority` canonical core already carries its
import authority and identity domains on. Marking and emission receive it
explicitly. Nothing a document, a component, middleware or a separately loaded
copy can name reaches that object, and it is reclaimed with the execution that
made it.
What the correction does not do is trade one hole for another: no module-scoped
registry, no symbol or property brand on the segments, no secret context name —
a name that must stay unguessed is still a name — and no new public opt-in.
Eligibility is unchanged, and is still canonical authorization together with the
host's admitted declaration.
DM53 is the attack, end to end: middleware answers an open name with a function
component that builds that context, corrupts whatever it finds, and returns
prose carrying emphasis, trailing spaces and blank runs through both real
presentation middlewares. It fails at 34e8c48 and passes here.
Claude-Session: https://claude.ai/code/session_01DNPFLq52HVSu3NH6WczYLf
1 parent 257f8d4 commit f10c2c8
29 files changed
Lines changed: 1905 additions & 186 deletions
File tree
- packages
- cli
- src
- documents
- tests
- document-suites/plan
- agents
- support
- core
- src
- components
- output
- tests
- scripts/tests
- specs
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
43 | 43 | | |
44 | 44 | | |
45 | 45 | | |
46 | | - | |
| 46 | + | |
47 | 47 | | |
48 | 48 | | |
49 | 49 | | |
| |||
3561 | 3561 | | |
3562 | 3562 | | |
3563 | 3563 | | |
3564 | | - | |
3565 | | - | |
3566 | | - | |
3567 | | - | |
3568 | | - | |
3569 | | - | |
| 3564 | + | |
| 3565 | + | |
| 3566 | + | |
| 3567 | + | |
| 3568 | + | |
| 3569 | + | |
| 3570 | + | |
| 3571 | + | |
3570 | 3572 | | |
3571 | 3573 | | |
3572 | 3574 | | |
| 3575 | + | |
| 3576 | + | |
| 3577 | + | |
| 3578 | + | |
| 3579 | + | |
| 3580 | + | |
| 3581 | + | |
| 3582 | + | |
| 3583 | + | |
| 3584 | + | |
| 3585 | + | |
| 3586 | + | |
| 3587 | + | |
| 3588 | + | |
| 3589 | + | |
| 3590 | + | |
| 3591 | + | |
| 3592 | + | |
3573 | 3593 | | |
3574 | 3594 | | |
3575 | 3595 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
7 | | - | |
8 | | - | |
9 | 7 | | |
10 | | - | |
11 | | - | |
12 | | - | |
13 | | - | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
14 | 12 | | |
15 | 13 | | |
16 | 14 | | |
| |||
21 | 19 | | |
22 | 20 | | |
23 | 21 | | |
24 | | - | |
25 | | - | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
26 | 25 | | |
27 | 26 | | |
28 | 27 | | |
| |||
37 | 36 | | |
38 | 37 | | |
39 | 38 | | |
40 | | - | |
| 39 | + | |
41 | 40 | | |
42 | 41 | | |
43 | 42 | | |
| |||
48 | 47 | | |
49 | 48 | | |
50 | 49 | | |
51 | | - | |
52 | 50 | | |
53 | 51 | | |
54 | 52 | | |
55 | 53 | | |
56 | 54 | | |
57 | | - | |
58 | 55 | | |
59 | 56 | | |
60 | 57 | | |
| |||
162 | 159 | | |
163 | 160 | | |
164 | 161 | | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
165 | 188 | | |
166 | 189 | | |
167 | | - | |
| 190 | + | |
| 191 | + | |
168 | 192 | | |
169 | 193 | | |
170 | 194 | | |
171 | 195 | | |
172 | 196 | | |
173 | 197 | | |
174 | | - | |
175 | | - | |
176 | | - | |
| 198 | + | |
| 199 | + | |
177 | 200 | | |
178 | 201 | | |
179 | 202 | | |
| |||
184 | 207 | | |
185 | 208 | | |
186 | 209 | | |
187 | | - | |
188 | | - | |
189 | | - | |
| 210 | + | |
190 | 211 | | |
191 | 212 | | |
192 | 213 | | |
| |||
226 | 247 | | |
227 | 248 | | |
228 | 249 | | |
229 | | - | |
230 | | - | |
231 | | - | |
| 250 | + | |
232 | 251 | | |
233 | 252 | | |
234 | 253 | | |
235 | 254 | | |
236 | 255 | | |
237 | 256 | | |
238 | 257 | | |
239 | | - | |
240 | | - | |
241 | | - | |
242 | 258 | | |
243 | | - | |
244 | | - | |
245 | | - | |
246 | | - | |
247 | | - | |
248 | | - | |
249 | | - | |
250 | | - | |
251 | | - | |
252 | | - | |
253 | | - | |
254 | | - | |
255 | | - | |
256 | | - | |
257 | | - | |
258 | | - | |
259 | 259 | | |
260 | 260 | | |
261 | 261 | | |
| |||
286 | 286 | | |
287 | 287 | | |
288 | 288 | | |
289 | | - | |
| 289 | + | |
290 | 290 | | |
291 | 291 | | |
292 | 292 | | |
293 | | - | |
294 | | - | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
295 | 296 | | |
296 | 297 | | |
297 | | - | |
298 | | - | |
| 298 | + | |
299 | 299 | | |
300 | 300 | | |
301 | 301 | | |
302 | 302 | | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
0 commit comments