@plurnk/plurnk-contracts 1.21.1 → 1.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/SPEC.md +302 -107
- package/dist/conformance/agui-v1.json +44 -0
- package/dist/schema/{ReasoningPolicy.json → Effort.json} +3 -3
- package/dist/schema/ModelCatalogPage.json +4 -4
- package/dist/schema/ModelRoute.json +7 -7
- package/dist/src/ApplicationPort.d.ts +17 -8
- package/dist/src/ApplicationPort.d.ts.map +1 -1
- package/dist/src/Validator.d.ts +4 -4
- package/dist/src/Validator.d.ts.map +1 -1
- package/dist/src/Validator.js +11 -11
- package/dist/src/Validator.js.map +1 -1
- package/dist/src/index.d.ts +2 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +2 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/types.d.ts +3 -2
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/types.generated.d.ts +6 -9
- package/dist/src/types.generated.d.ts.map +1 -1
- package/dist/src/types.js +4 -2
- package/dist/src/types.js.map +1 -1
- package/package.json +1 -1
- package/plurnk.md +17 -10
package/SPEC.md
CHANGED
|
@@ -11,7 +11,7 @@ runtime-neutral wire envelopes; `@plurnk/plurnk-parser` implements the language
|
|
|
11
11
|
| ------------------------------------------------------------------------------- | --------------------------------------------------- |
|
|
12
12
|
| AST, validators, Problems, results, Notices, text regions and extents | `@plurnk/plurnk-contracts` |
|
|
13
13
|
| Capability and loop policies | `CapabilityPolicy`, `LoopPolicy`, `LoopPolicyRequest`, `PROPOSAL_POLICIES` |
|
|
14
|
-
| Durable
|
|
14
|
+
| Durable effort | `Effort`, `EFFORTS` |
|
|
15
15
|
| Model route and catalog discovery | `ModelRoute`, `ModelCatalogQuery`, `ModelCatalogPage`, `ModelReadiness` |
|
|
16
16
|
| Stopped-world client contract | `ProposalDisposition`, `ProposalProjection` |
|
|
17
17
|
| Client-owned interaction contract | `ClientInteractionRequest`, `ClientInteractionProjection`, `ClientInteractionResolution` |
|
|
@@ -177,7 +177,7 @@ Contracts hold no default for the rest: the daemon's panel supplies it
|
|
|
177
177
|
vocabulary of `proposals`. Capability admission precedes effect
|
|
178
178
|
classification and proposal settlement.
|
|
179
179
|
|
|
180
|
-
§
|
|
180
|
+
§effort-wire `Effort` is exactly `off | adaptive | low |
|
|
181
181
|
medium | high`. The schema owns this shared wire vocabulary. Providers own the
|
|
182
182
|
supported subset and native projection for a selected route; core owns the
|
|
183
183
|
durable worker value.
|
|
@@ -190,8 +190,8 @@ physical limits, capabilities, and local `ModelReadiness`. A readiness cause
|
|
|
190
190
|
contains alternative environment-variable sets—every name within a set is
|
|
191
191
|
required and any set may satisfy the cause. It carries names only, never values,
|
|
192
192
|
and asserts neither credential validity nor endpoint reachability.
|
|
193
|
-
`capabilities.
|
|
194
|
-
{§
|
|
193
|
+
`capabilities.efforts` lists the route's admitted members of
|
|
194
|
+
{§effort-wire}, including supported activation policies; clients do
|
|
195
195
|
not infer fixed efforts from the `reasoning` capability bit. It is not a
|
|
196
196
|
worker's model/spawn intersection or an alias-specific tuning projection.
|
|
197
197
|
|
|
@@ -273,26 +273,21 @@ convention and never demanded ({§fence-closer}, {§closer-fallback}). There are
|
|
|
273
273
|
operation suffixes or heading levels. Complete nested matches take precedence
|
|
274
274
|
over local recovery ({§balanced-fences}).
|
|
275
275
|
|
|
276
|
-
§fence-closer A block opened with N backticks closes at
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
276
|
+
§fence-closer A block opened with N backticks closes at a line made of at least N backticks and
|
|
277
|
+
nothing else but horizontal whitespace, within three spaces of its line start
|
|
278
|
+
({§indented-fences}). Count follows CommonMark: a shorter fence inside the body is body; an equal
|
|
279
|
+
or longer bare fence may close the block or open a nested one, and {§fence-pairing} decides
|
|
280
|
+
which. The compact one-line form closes on its heading line after the modifiers under the same
|
|
281
|
+
rule.
|
|
282
282
|
|
|
283
283
|
§balanced-fences A complete nested interpretation takes precedence over missing-closer
|
|
284
|
-
recovery. Within a body, line-leading labeled
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
and
|
|
290
|
-
|
|
291
|
-
complete inline block is already closed. Preserve every nested body byte, including
|
|
292
|
-
apparent OPs and known executors, without dispatching them. If no complete enclosing
|
|
293
|
-
interpretation exists, retain {§fence-heading-in-body} and {§closer-fallback}. These
|
|
294
|
-
rules apply equally to model programs, stored programs, client operations, and
|
|
295
|
-
reasoning quotations.
|
|
284
|
+
recovery. Within a body, a line-leading labeled fence opens a literal block, and an equal or
|
|
285
|
+
wider bare fence nests where closing there would cost the reading more
|
|
286
|
+
({§fence-pairing}). A nested block ends at its first valid closer, as a CommonMark code block
|
|
287
|
+
does. So a wider outer fence holds any narrower body, finished or not, and equal widths nest
|
|
288
|
+
when every inner block closes. Preserve every nested body byte, including apparent operations
|
|
289
|
+
and known executors, without dispatching them. These rules apply equally to model programs,
|
|
290
|
+
stored programs, client operations, and reasoning quotations.
|
|
296
291
|
|
|
297
292
|
§operation-fences **Accept three or more backticks; teach and render three.** A line-start fence
|
|
298
293
|
of three or more backticks naming a native operation or registered executor opens that
|
|
@@ -311,48 +306,176 @@ horizontal whitespace after it, opens that operation as if it were fenced with t
|
|
|
311
306
|
backticks: no target, no modifiers, and a body that runs to a line that is exactly the name
|
|
312
307
|
again, to the next heading ({§fence-heading-in-body}), or to the end of the turn. A fence inside
|
|
313
308
|
naming nothing known is body; the block expects no closer, so its body is never cut
|
|
314
|
-
back ({§closer-fallback}). It runs, and one warning-severity receipt follows its statement —
|
|
309
|
+
back ({§closer-fallback}). A naked `KILL` alone holds every fence inside it as text ({§naked-kill}). It runs, and one warning-severity receipt follows its statement —
|
|
315
310
|
`` `KILL` opened with no fence; the taught form is three backticks. `` One rule for every native
|
|
316
311
|
operation: a naked `WAIT` parks, a naked `NOTE` takes its text, a naked `READ` meets the ordinary
|
|
317
|
-
missing-target refusal.
|
|
312
|
+
missing-target refusal. A closer the author wrote anyway is still not body: when the body's last line is
|
|
313
|
+
a bare backtick fence that no other fence line in the body pairs with (an odd count of fence lines), that
|
|
314
|
+
line is the block's closer and leaves the body, so `KILL`, then the answer, then a closing fence delivers
|
|
315
|
+
the answer alone. Only the bare name qualifies; a name with anything else on its line is
|
|
318
316
|
the unfenced form and still refuses ({§unfenced-operation}), executors are runtimes rather than
|
|
319
|
-
operations, and reasoning is never read this way.
|
|
320
|
-
|
|
321
|
-
three loops lost to the refusal at the strike threshold.
|
|
317
|
+
operations, and reasoning is never read this way. In 9,196 recorded emissions, all 48 naked
|
|
318
|
+
`KILL` lines were followed by the deliverable.
|
|
322
319
|
|
|
323
320
|
§fence-heading-in-body Outside a complete nested block ({§balanced-fences}), a fence
|
|
324
321
|
line of three or more backticks and a name that is a native operation or a known executor
|
|
325
|
-
is a heading. Inside an open block
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
backticks are never headings ({§operation-fences}). Known executors are `sh`
|
|
329
|
-
the host names in `ParseOptions.executors`.
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
an admission failure, and {§unparsed-tail-boundary} is not involved.
|
|
322
|
+
is a heading. Inside an open block it either ends that block without closing it and opens the
|
|
323
|
+
next statement, or it is a literal example held by the block; the block holds it only while
|
|
324
|
+
the block ends at a real closer, and {§fence-pairing} chooses between the two. Fence lines of
|
|
325
|
+
fewer than three backticks are never headings ({§operation-fences}). Known executors are `sh`
|
|
326
|
+
plus what the host names in `ParseOptions.executors`. Inside a parameterless `KILL` a
|
|
327
|
+
heading never ends the block ({§terminal-kill}).
|
|
328
|
+
|
|
329
|
+
§closer-fallback A block that ends at a heading or at the end of the input has no closer of its
|
|
330
|
+
own; its body is the whole span less one terminating line ending. Where a same-character fence
|
|
331
|
+
narrower than an outermost block stands where its closer belongs, {§fence-pairing} may read it
|
|
332
|
+
as that closer, at the cost of one repair; an unclosed EDIT yields to the native heading after it
|
|
333
|
+
({§unclosed-mutation-yields}). This carries no diagnostic: a missing closer is
|
|
334
|
+
never an admission failure, and {§unparsed-tail-boundary} is not involved.
|
|
339
335
|
|
|
340
336
|
`plurnk.md` shows every operation closed; this recovery is not taught. It sits at the quiet end of
|
|
341
|
-
the scale {§
|
|
337
|
+
the scale {§outside-text} describes: the model opened the operation correctly
|
|
342
338
|
and only failed to close it, so the harness reads what it plainly meant and says nothing.
|
|
343
339
|
A departure that small earns no correction — telling a model its closer was missing costs
|
|
344
340
|
a sentence in every future packet to fix something already fixed.
|
|
345
341
|
|
|
346
|
-
§fence-boundary
|
|
347
|
-
|
|
342
|
+
§fence-boundary Every fence line inside a body takes one of these meanings, chosen for the whole
|
|
343
|
+
input at once by {§fence-pairing}:
|
|
348
344
|
|
|
349
345
|
| Fence encountered inside a body | Meaning |
|
|
350
346
|
|---|---|
|
|
351
|
-
| Part of a complete nested block | Literal body, including its openers and closers |
|
|
352
347
|
| Indented four spaces or more, or by a tab | Body ({§indented-fences}) |
|
|
353
|
-
| Fewer backticks than the block's own | Body |
|
|
354
|
-
| At least the block's backticks, bare | The block's closer |
|
|
355
|
-
|
|
|
348
|
+
| Fewer backticks than the block's own, or another character | Body, or the opener of a nested block |
|
|
349
|
+
| At least the block's backticks, bare | The block's closer, or the opener of a nested block |
|
|
350
|
+
| Labeled, naming nothing known | The opener of a nested block, or body |
|
|
351
|
+
| Three or more backticks naming a native operation or known executor | A heading that ends the block, or a literal example |
|
|
352
|
+
|
|
353
|
+
### §fence-pairing Fence pairing
|
|
354
|
+
|
|
355
|
+
A whole-input pass, `FencePairing`, decides where every block ends before the lexer reads a
|
|
356
|
+
token; the lexer's semantic predicates consult its decision, and ANTLR keeps framing, slots and
|
|
357
|
+
statement composition ({§parser-architecture}). The pass is a least-cost parse of the fence
|
|
358
|
+
lines as a bracket language, in the manner of Aho and Peterson's least-errors parser
|
|
359
|
+
(SIAM J. Comput. 1(4), 1972): every reading of the fences is a derivation, and the pass returns
|
|
360
|
+
the cheapest.
|
|
361
|
+
|
|
362
|
+
§pairing-need **Why a pass ahead of the grammar.** Whether a bare fence closes a block or opens a
|
|
363
|
+
nested one depends on every fence after it, unboundedly. Measured on 10,486 distinct recorded
|
|
364
|
+
emissions:
|
|
365
|
+
|
|
366
|
+
| Alternative | Result |
|
|
367
|
+
|---|---|
|
|
368
|
+
| The fence structure as an ANTLR grammar under SLL prediction | 10,000 accepted, 0.2 ms mean; 486 not: 119 valid only under full LL, 243 needing repair, 113 unrepairable |
|
|
369
|
+
| The same grammar under full LL | A 267 KB packet echo took 4.8 s. Full-context results are not cached: the runtime records that caching them "was slower than interpreting and much more complicated" (`ParserATNSimulator`) |
|
|
370
|
+
| ANTLR's error recovery for the 356 that need repair | `DefaultErrorStrategy` repairs only at the point of detection, by single-token insertion or deletion; it has no least-cost repair over the input |
|
|
371
|
+
| Nongreedy lexer loops | A lexer decision is local, not "globally correct" (ANTLR `doc/wildcard.md`), so a nongreedy body ends at the first closer even when a later one is the block's |
|
|
372
|
+
| CommonMark's rule alone | The first closer of sufficient width closes (CommonMark 0.31.2 §4.5), and CommonMark declines to backtrack because it "would require backtracking… much less efficient". It cuts 110 recorded bodies at an inner bare block |
|
|
373
|
+
| A budgeted depth-first search over stacks | Exhausted its step budget on 20 recorded emissions of 188 to 3,501 fence lines |
|
|
374
|
+
|
|
375
|
+
The ALL(*) paper (Parr, Harwell, Fisher, OOPSLA 2014) states the limits relied on here: SLL either
|
|
376
|
+
behaves like LL or reports an error (Theorem 6.5, §3.2), and an ambiguity resolves to the lowest
|
|
377
|
+
alternative (§4.2), so neither mode chooses among complete readings by cost. The grammars-v4
|
|
378
|
+
Python (`INDENT`/`DEDENT`) and PHP (heredoc) grammars settle block structure the same way:
|
|
379
|
+
outside the grammar, then hand the lexer tokens.
|
|
380
|
+
|
|
381
|
+
§pairing-algorithm **Algorithm.** Each line is classified by the lexer's line-start rules: text, a
|
|
382
|
+
bare fence, a labeled fence, a heading, a closer glued to a heading, or a naked operation name.
|
|
383
|
+
A block's contents read the same whatever lies beneath it on the stack, so the pass summarizes
|
|
384
|
+
each (position, block, what the block holds so far) once. For a nested block, the summary maps
|
|
385
|
+
every place the block could end to its cheapest reading up to there; parents compose their
|
|
386
|
+
children's summaries. An outermost block is evaluated in the root's frame, where only the cost
|
|
387
|
+
to the end of the input matters, so it holds one entry. Evaluation runs on an explicit work
|
|
388
|
+
stack. Candidates are taken in preference order and replace one another only by costing
|
|
389
|
+
strictly less, so each entry is the reading a preference-ordered exhaustive search returns.
|
|
390
|
+
Inside a quotation or a nested block the first valid closer closes, CommonMark's rule, applied
|
|
391
|
+
as a disambiguation filter (Klint and Visser, 1994); an operation body keeps the choice between
|
|
392
|
+
nesting and closing. A block opened by a bare fence must hold a line, except a quotation at the
|
|
393
|
+
top level: two stray fences in a row there are an empty quotation, shown and harmless, rather
|
|
394
|
+
than two repairs that a reading could avoid only by hiding an operation.
|
|
395
|
+
|
|
396
|
+
§pairing-objective **Objective.** A complete reading, one that needs no repair, wins over every
|
|
397
|
+
repaired reading: a complete nested interpretation takes precedence. Each class has its own order.
|
|
398
|
+
|
|
399
|
+
| Counted | Complete readings | Repaired readings | Why |
|
|
400
|
+
|---|---|---|---|
|
|
401
|
+
| Hidden operations: a heading that will not run, written at its block's width or wider | 1, together with the next row | 1 | Every operation the author wrote should run |
|
|
402
|
+
| Repairs: a supplied closer (except a message's run to the end of the input, {§message-run-on}), a fence read as a stray, a narrower closer accepted, a body under an operation that takes none (FIND, READ, COPY, MOVE, targeted KILL), a body not well-formed in the media type its runtime declares ({§executor-invocation}) | none by definition | 2 | The least-errors distance |
|
|
403
|
+
| Literal by declaration: a heading narrower than its block, or no wider than the labeled block or example holding it, or inside a quotation or a KILL, or an executor heading inside a SEND, WORK, FORK or BARE body ({§prose-code-blocks}); a labeled fence in a body read as text | 1, together with the row above | 3 | Every code block the author declared should stand |
|
|
404
|
+
| Supplied closers | 2 | 4 | A block the author opened should end at a fence the author wrote |
|
|
405
|
+
| Other fences read as text | 3 | 5 | The least departure from the fences as written |
|
|
406
|
+
|
|
407
|
+
Complete readings compare exactly as a single least-errors order would. Once every reading of an
|
|
408
|
+
emission needs a repair, its shape is already broken, and saving a repair is not worth an operation
|
|
409
|
+
the author wrote: across the corpus, readings that traded operations for repairs held a WORK in a
|
|
410
|
+
BARE behind two stray fences, wrote 11,485 characters of operation text into a file as an EDIT
|
|
411
|
+
body, and ended a turn's KILL inside a WAIT. A summary keeps, for every place a block could end, the
|
|
412
|
+
best complete reading under each order and the best repaired reading, so the search stays exact:
|
|
413
|
+
a repaired total may take either class for any of its parts.
|
|
414
|
+
|
|
415
|
+
§unclosed-mutation-yields **A mutation body never swallows a native operation.** An example
|
|
416
|
+
inside an EDIT is written with a wider outer fence ({§operation-fences}); a heading narrower than
|
|
417
|
+
the EDIT's fence is literal by declaration and stays text. At the EDIT's own width a native
|
|
418
|
+
operation heading runs, closed or not: read as the body's example it would be a *swallowed*
|
|
419
|
+
operation, and a swallowed operation outranks any number of repairs — a reading that swallows one
|
|
420
|
+
is never complete, and among repaired readings the fewest swallowed wins before every other class.
|
|
421
|
+
So where ```` ```EDIT (b.py) ```` follows ```` ```EDIT (a.py) ```` with no closer between, the
|
|
422
|
+
reading that supplies `a.py`'s closer before that heading wins, both EDITs run, and no operation
|
|
423
|
+
heading is written into a file; the same shape with a closer after the example is fence-identical
|
|
424
|
+
and reads the same way. Of 67 recorded EDIT bodies holding a native heading, 66 use the wider fence
|
|
425
|
+
and read unchanged, and the one at equal width (glm run158) had written a test EDIT's heading and
|
|
426
|
+
body into `functional.py` and never run it. Only EDIT mutates from its body, so only EDIT carries
|
|
427
|
+
the rule: an executor heading inside an EDIT keeps the ordinary reading, and SEND, WORK, FORK and
|
|
428
|
+
BARE bodies keep {§prose-code-blocks}.
|
|
429
|
+
|
|
430
|
+
Equal cost goes to the earlier alternative: nesting before closing in an operation body,
|
|
431
|
+
closing before nesting in a quotation, and a supplied closer before a literal example at a
|
|
432
|
+
heading. An operation example quoted in a body of its own width therefore reads as the body
|
|
433
|
+
closing and the example running; the wider outer fence or the tab offset quotes it
|
|
434
|
+
({§operation-fences}).
|
|
435
|
+
|
|
436
|
+
§terminal-kill **A KILL body is the deliverable.** Inside a parameterless `KILL`, at any depth, a
|
|
437
|
+
heading is a literal example or text and never ends the block; the block ends at its closer or
|
|
438
|
+
the end of the input. Of 796 recorded parameterless KILLs, 9 were followed by any other
|
|
439
|
+
operation, while 62 of 120 SENDs were, so the rule is KILL's alone. It keeps a final report whole
|
|
440
|
+
and never runs a command the report only shows.
|
|
441
|
+
|
|
442
|
+
§prose-code-blocks **A message or a prompt shows code.** Inside a `SEND`, `WORK`, `FORK` or `BARE`
|
|
443
|
+
body, at any depth, a heading that names an executor (` ```sh `, ` ```python3 `) is a code block the
|
|
444
|
+
text shows, exactly as under {§terminal-kill}: it never ends the block and never runs. A native
|
|
445
|
+
operation's heading still ends such a block, since a message is often followed by the author's next
|
|
446
|
+
operation. In the distinct recorded benchmark emissions an executor heading ended an unclosed
|
|
447
|
+
`WORK` body 14 times, a `BARE` body 9 times and a `SEND` body twice; every one inspected (qflash
|
|
448
|
+
run218, run114 and run118, deepdumb run44) was the child's task, the prompt's code or code quoted in
|
|
449
|
+
a report, and reading it as an operation truncated the task and ran the example in the parent.
|
|
450
|
+
|
|
451
|
+
§message-run-on **A message runs to the end of the turn.** A parameterless `KILL`, or a `SEND`,
|
|
452
|
+
`WORK`, `FORK` or `BARE`, whose block reaches the end of the input without its closer takes it
|
|
453
|
+
there with no repair: the text after its last inner block is still the deliverable, the message
|
|
454
|
+
or the task, never outside text. The run counts as a supplied closer, so a reading that closes at
|
|
455
|
+
a real fence still wins, and it never costs an operation: when the reading that runs on hides more
|
|
456
|
+
operations the author wrote than the best repaired reading, the repaired reading stands. Across the
|
|
457
|
+
11,235 distinct recorded benchmark emissions this changes 26 readings: bodies that had ended at an
|
|
458
|
+
inner fence keep what followed it (the qflash run192, run90 and run210 deliverables regain their last
|
|
459
|
+
sections), one echoed transcript (glm run155) runs one more operation, and none loses one.
|
|
460
|
+
|
|
461
|
+
§naked-kill **A naked KILL is the whole rest of the turn.** A parameterless `KILL` opened by its
|
|
462
|
+
name alone ({§naked-operation}) is a completion, and nothing can follow a completion: every fenced
|
|
463
|
+
block inside it, a native operation heading included, is text the deliverable shows, exactly as
|
|
464
|
+
inside a fenced KILL ({§terminal-kill}), and the block ends only at its name alone on a line or at
|
|
465
|
+
the end of the input. No operation the deliverable shows runs. In the rtx5070 demo
|
|
466
|
+
`demo-show-dont-run-sJU8zO` the model, asked to show a deletion without doing it, answered with a
|
|
467
|
+
naked `KILL` whose deliverable quoted ```` ```KILL (notes.md) ````; read as a heading that ended
|
|
468
|
+
the deliverable, the quoted KILL ran and deleted the file. The fenced form of the same answer had
|
|
469
|
+
already read as quotation; this rule makes the two forms one.
|
|
470
|
+
|
|
471
|
+
§pairing-witness **Witnesses.**
|
|
472
|
+
|
|
473
|
+
| Witness | Result |
|
|
474
|
+
|---|---|
|
|
475
|
+
| Every input up to six lines over eleven line shapes, against a forward exhaustive search over explicit stacks under the same moves and class orders | 1,948,716 inputs, 0 differences in chosen cost; the same harness reports 37 differences at four lines when a summary keeps one entry per end regardless of class |
|
|
476
|
+
| The generated matrix: six operations × widths 3–5 × twelve body shapes × four tails | 864 of 864 (`fence-matrix.test.ts`); the four `EDIT · outer 3 · labeled quoted operation` cells read the example as an operation ({§unclosed-mutation-yields}), and in the `next operation` cell the EDIT's written closer, now a stray top-level fence, quotes the operation after it ({§quotation}) |
|
|
477
|
+
| 10,486 recorded emissions | All parse; 0.9 ms mean, 267 ms at most (3,501 fence lines). The work is polynomial in fence lines, cubic at worst, so no step bound is needed |
|
|
478
|
+
| The same, against the single-order objective | 10,466 identical; 19 read more operations, where headings follow unclosed blocks or a closer is glued to the next opener; 1 echoed transcript reads a different operation; none reads fewer |
|
|
356
479
|
|
|
357
480
|
§indented-fences **CommonMark's indentation, everywhere.** A fence line may follow at most three
|
|
358
481
|
spaces; four or more, or a tab, make it indented code. That one rule reads every fence purpose the
|
|
@@ -360,9 +483,8 @@ same way: an opener within three spaces opens, a closer within three closes, a h
|
|
|
360
483
|
three ends an unclosed block, and a body keeps its own lines' indentation. A fence indented
|
|
361
484
|
further is literal wherever it stands — prose outside a block, body inside one — and draws no
|
|
362
485
|
advisory: `plurnk.md` shows its own examples offset, so an offset fence is the page's own form
|
|
363
|
-
and there is no mistake to report
|
|
364
|
-
|
|
365
|
-
(operator, 2026-09-23). Outside an operation, offset text is response text under
|
|
486
|
+
and there is no mistake to report. The parser presumes nothing about why a fence is offset.
|
|
487
|
+
Outside an operation, offset text is response text under
|
|
366
488
|
{§response-text}; inside a body, it stays literal body content.
|
|
367
489
|
|
|
368
490
|
§inline-chain A closer on a heading line, or on a body's closing line, may be
|
|
@@ -380,15 +502,13 @@ The closer is still a closer: the block ends with that physical line and never r
|
|
|
380
502
|
the next operation, which is what a bare heading carrying a matcher would do. A closer followed
|
|
381
503
|
by the next opener is {§inline-chain}, and by nothing is the ordinary {§fence-closer}. There is
|
|
382
504
|
no ambiguity to resolve: a slot begins with `<` or `[` and an opener with a backtick run, so the
|
|
383
|
-
shapes are disjoint
|
|
384
|
-
tolerance. Turning model soup into operations instead of errors is a cardinal imperative").
|
|
505
|
+
shapes are disjoint.
|
|
385
506
|
|
|
386
507
|
§executor-case **An executor tag in any case.** A fence tag that matches a
|
|
387
508
|
registered executor's name case-insensitively opens that executor (`SH` opens
|
|
388
509
|
`sh`), and the statement's `executor` is the registered spelling, so a lookup
|
|
389
510
|
by that name never misses. Operation names stay uppercase by teaching and were
|
|
390
|
-
never written otherwise in 12,000 fences; one `SH` in 1,300 `sh` fences was
|
|
391
|
-
(2026-09-13 census). An unregistered name without an accepted spelling
|
|
511
|
+
never written otherwise in 12,000 fences; one `SH` in 1,300 `sh` fences was. An unregistered name without an accepted spelling
|
|
392
512
|
({§executor-js-spelling}) is still prose ({§interstitial-fence}).
|
|
393
513
|
|
|
394
514
|
§executor-js-spelling When `node` is registered and `js` is not, `js` names
|
|
@@ -419,12 +539,22 @@ nothing registered — opens a
|
|
|
419
539
|
quotation that runs to its matching closer (same character, width at least the opener's) or to
|
|
420
540
|
the end of the input. Everything inside is data: no operation runs there and native tool-call
|
|
421
541
|
markup is not read ({§native-tool-calls}). An operation fenced inside an unlabeled code block
|
|
422
|
-
draws one warning that it was shown, not run.
|
|
423
|
-
heading
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
542
|
+
draws one warning that it was shown, not run. At the top level, a bare fence whose next line is an
|
|
543
|
+
operation heading opens that operation instead ({§forgotten-tag}). A labeled block is an example by
|
|
544
|
+
declaration, and nothing else inside draws an advisory.
|
|
545
|
+
|
|
546
|
+
§forgotten-tag **A tag on the line under a bare fence is the operation.** At the top level, a bare
|
|
547
|
+
fence whose next line is an operation heading, a native name alone or with a slot or an executor's
|
|
548
|
+
name with its operand, opens that operation as if both were written on one line: the heading takes
|
|
549
|
+
its slots, the lines after it are its body, and it closes like any operation. It runs, and one
|
|
550
|
+
warning-severity receipt names the form — `` `READ` ran, though its fence was malformed: the
|
|
551
|
+
opening fence, OP, parameters, and aside share one line. `` Saying that it ran keeps the model from
|
|
552
|
+
issuing it again. Inside a body the same lines stay literal. Measured: of 2,308 naked fences in
|
|
553
|
+
12,797 recorded emissions, 51 open that way and 2,238 hold code or quoted output, which is why a
|
|
554
|
+
bare fence alone draws nothing; in the 10,486-emission fence corpus every one of the 12 that open
|
|
555
|
+
that way was an operation the model meant to run. With the answer carried by the final KILL,
|
|
556
|
+
whose body shows and never runs ({§terminal-kill}), an example the model means only to show lives
|
|
557
|
+
in a body.
|
|
428
558
|
So a model may show plurnk's own operations in an answer. Two exceptions keep programs whole:
|
|
429
559
|
CommonMark's own rule that a backtick opener's line carries no further backtick, so
|
|
430
560
|
```` ```READ (x)``` ```` is inline code and quotes nothing after it; and a bare fence directly under
|
|
@@ -439,17 +569,16 @@ response text under {§response-text}, not an executable program or a completion
|
|
|
439
569
|
example, and shows its own examples offset; the other quoting fences are untaught: a tilde
|
|
440
570
|
fence, an unlabeled fence and an unknown tag all quote. Each is a shape a model reaches for from ordinary Markdown rather than from this
|
|
441
571
|
teaching, so honouring it protects an example the model already believed was safe
|
|
442
|
-
({§
|
|
572
|
+
({§outside-text} places the scale). The offset is the one form that survives every
|
|
443
573
|
fence style.
|
|
444
574
|
|
|
445
|
-
§interstitial-fence
|
|
446
|
-
|
|
447
|
-
|
|
575
|
+
§interstitial-fence Only a native operation or a known executor opens a block. A fence naming
|
|
576
|
+
anything else, or nothing at all, opens no operation: outside a block it quotes under
|
|
577
|
+
{§quotation}, inside a body it is body.
|
|
448
578
|
|
|
449
579
|
§closer-aside A closing fence followed on its line by one aside and nothing else
|
|
450
580
|
is the closer; the aside is outside text. Read as body, that line would be written
|
|
451
|
-
into the edited resource (#758
|
|
452
|
-
```` ```` <!-- remove duplicated Result import --> ```` into a Python file). A
|
|
581
|
+
into the edited resource (#758). A
|
|
453
582
|
closing fence followed by any other text is still body.
|
|
454
583
|
|
|
455
584
|
§heading-slot-order A heading near-miss with exactly one reading is read as that
|
|
@@ -480,9 +609,31 @@ the aside, and `body`/`content`/`command`/`text`/`input` or plain text inside th
|
|
|
480
609
|
call the body; plurnk slots written after the name are kept, a trailing scope's own
|
|
481
610
|
bracket may close the tag. A block keeps its line count where its lines allow, so
|
|
482
611
|
statement positions name the source line; an inline block grows to its fences.
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
612
|
+
Qwen's own shapes read the same way: a flat JSON call whose operation is the value
|
|
613
|
+
of an `op`, `action` or `cmd` key in any case (`{"op": "READ", "path": …, "range": …}`),
|
|
614
|
+
an XML element named by the operation (`<NOTE>…</NOTE>`, `<FIND (path) <1,3></FIND>`,
|
|
615
|
+
`<read path="…"/>`) or by a generic `op` element or function (`<op op="READ" …>`,
|
|
616
|
+
`<op verb="READ" …/>` in `<ops>`, `<op=READ (path) …>`, `<function=OP name="READ" …>`,
|
|
617
|
+
`<function=OP>` around such a JSON call or a plurnk heading), and a plurnk heading written
|
|
618
|
+
as the call's text (`<tool_call>READ (a.py) <60,120>`, `=READ (…)`). Closing tags left over
|
|
619
|
+
from another family (`</parameter>`, `</invoke>`, `</>`) after a call are markup noise;
|
|
620
|
+
`reason` and `description` are the aside; a scope may be a JSON array (`[500,530]`) or a
|
|
621
|
+
`{"start", "end"}` object; an executor's string `input` is its program. A call with an
|
|
622
|
+
unknown name or parameter, or a FIND, READ, EDIT, COPY or MOVE naming no target, leaves the
|
|
623
|
+
whole emission as it was. An emission that already yields an operation is never
|
|
624
|
+
rewritten. No diagnostic, notice or teaching mentions a successful reading (#760).
|
|
625
|
+
|
|
626
|
+
§native-tool-call-receipt **Markup that was not read is named.** When an emission yields no
|
|
627
|
+
operation and carries native tool-call markup that could not be read, the parse reports one
|
|
628
|
+
hard diagnostic at the markup, naming it and the fenced form that runs — `` `<tool_call>` is
|
|
629
|
+
tool-call markup, which plurnk does not run, so nothing ran. An operation is a fenced block:
|
|
630
|
+
three backticks and `READ (django/forms/widgets.py)` on the opening line. `` The form names
|
|
631
|
+
the operation and target the markup itself names where it names them (`sh` for a shell
|
|
632
|
+
command, `NOTE` for a note or narration), and otherwise the generic "the operation with its target,
|
|
633
|
+
such as `READ (path)`". The model believes it
|
|
634
|
+
acted; silence would let it wait on a result that never comes. Of 107 distinct recorded
|
|
635
|
+
no-operation qflash emissions carrying call-like markup, 63 read under {§native-tool-calls}, 42 draw
|
|
636
|
+
this receipt, and 2, a bare JSON object of narration with no tool-call marker, draw neither.
|
|
486
637
|
|
|
487
638
|
§empty-section Both the compact bodyless form and an empty multiline block
|
|
488
639
|
normalize optional bodies to null. Closing fences are conventional, never required
|
|
@@ -519,19 +670,35 @@ has at most one scope; its metadata blocks retain their authored order.
|
|
|
519
670
|
optional target and ignores syntactically valid scope and metadata without diagnostics
|
|
520
671
|
({§send-wait-scope}). Their literal bodies begin below the header.
|
|
521
672
|
|
|
673
|
+
§scope-on-scopeless **A scope on an operation that takes none is dropped, and named.** WORK, FORK,
|
|
674
|
+
BARE and NOTE take no scope, and neither does a SEND without a recipient; a `<…>` slot on such a
|
|
675
|
+
heading, in any position, is skipped and the operation runs, with one warning-severity advisory
|
|
676
|
+
naming the operation's slots and the dropped scope — `` `WORK` takes a target only; the scope
|
|
677
|
+
`<1,-1>` was ignored. A scope selects lines in READ, EDIT and KILL. `` (`` `NOTE` takes no target or
|
|
678
|
+
scope; … ``, `` `SEND` without a recipient takes no scope; … ``). An aside is never a scope, a
|
|
679
|
+
recipient SEND keeps its scope for the recipient ({§send-directed-scope}), and WAIT's is skipped
|
|
680
|
+
unread ({§send-wait-scope}). There is no ambiguity: the operation has one reading with or without
|
|
681
|
+
the slot. Before this, the heading drew the grammar's expected-token diagnostic and the turn was
|
|
682
|
+
dead; in the distinct recorded emissions one heading carried the form (zai run426,
|
|
683
|
+
```` ```WORK (worker://deprecation-implementer) <1,-1> ````), beside two recipient SENDs whose scope
|
|
684
|
+
the recipient refuses at runtime.
|
|
685
|
+
|
|
522
686
|
§heading-inline-body Nonempty body text belongs below the fence header.
|
|
523
687
|
The ingester tolerates body text after horizontal whitespace on the header,
|
|
524
688
|
preserves it, and emits one warning stating that normalization. This does not
|
|
525
689
|
change the meaning of a compact empty block or permit unmatched fences.
|
|
526
690
|
|
|
527
|
-
§bare-option-object A bare option object is the option block
|
|
528
|
-
operation that takes an option block and no bare matcher — SEND, BARE, WORK,
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
{§
|
|
534
|
-
|
|
691
|
+
§bare-option-object A bare option object is the option block, where the house option array owns the
|
|
692
|
+
block. On an operation that takes an option block and no bare matcher — SEND, BARE, WORK, FORK and
|
|
693
|
+
every executor fence — heading text after the slots that is exactly one JSON object `{…}` is read
|
|
694
|
+
as `[{…}]`: the AST carries the array form, the written heading renders it, and one
|
|
695
|
+
warning-severity receipt names the indulgence in place of the {§heading-inline-body} advisory:
|
|
696
|
+
"`SEND` took a bare option object; the taught form is `[{…}]`." The option array is a house
|
|
697
|
+
convention, not a language rule ({§scheme-metadata-modifier}): an executor whose declared body is
|
|
698
|
+
JSON ({§executor-invocation}), an MCP tool, reads the object as its body instead — its arguments,
|
|
699
|
+
written on the heading line — with one warning: "`gitea` took its body on the heading line; the
|
|
700
|
+
body belongs on the lines below it." The host names those executors to the parse
|
|
701
|
+
(`ParseOptions.jsonBodyExecutors`). A heading that already carries a block keeps the object as
|
|
535
702
|
inline body. On FIND, READ and KILL the same text is the matcher
|
|
536
703
|
({§naked-pattern}), because a search for JSON text is legitimate; a bare matcher
|
|
537
704
|
that parses as a JSON object draws one advisory naming the option form ("`{…}`
|
|
@@ -731,9 +898,9 @@ accounting, and observation timing belong to the consuming service.
|
|
|
731
898
|
§read-find-normalization An authored READ is never rewritten into a FIND. A
|
|
732
899
|
glob target on READ keeps its glob, and the runtime fans it out into one exact
|
|
733
900
|
READ per matching path, with the authored scope and matcher ({§read-fan-out}
|
|
734
|
-
in the core SPEC
|
|
901
|
+
in the core SPEC). A model
|
|
735
902
|
that asks to read every file under a glob gets those files, bounded by the
|
|
736
|
-
FIND page and the preview scope, not a catalog it did not ask for
|
|
903
|
+
FIND page and the preview scope, not a catalog it did not ask for. A matcher
|
|
737
904
|
never changes the operation either: READ with a `pattern` on an exact target
|
|
738
905
|
stays READ and renders the selected lines ({§read-pattern}). The survey of
|
|
739
906
|
paths is FIND, and only FIND.
|
|
@@ -927,7 +1094,7 @@ statements remain recoverable when their boundaries are trustworthy.
|
|
|
927
1094
|
|
|
928
1095
|
## §scope-slot 7. Scope markers
|
|
929
1096
|
|
|
930
|
-
The model-facing slot is `<scope>`; the AST field
|
|
1097
|
+
The model-facing slot is `<scope>`; the AST field is
|
|
931
1098
|
`lineMarker`. Numeric scopes preserve ordered components in `LineMarker`;
|
|
932
1099
|
text-coordinate operations use `TextLineMarker`, whose line positions may also
|
|
933
1100
|
carry rendered anchors. The operation owner assigns every component's role.
|
|
@@ -1058,7 +1225,8 @@ The implementation this section describes lives in `@plurnk/plurnk-parser`
|
|
|
1058
1225
|
({§parser-consumers}); this section remains the contract it implements.
|
|
1059
1226
|
|
|
1060
1227
|
ANTLR owns framing, slots and statement composition; AstBuilder produces the
|
|
1061
|
-
schema-owned AST.
|
|
1228
|
+
schema-owned AST. Where each block ends is decided first, over the whole input, by
|
|
1229
|
+
{§fence-pairing}; the lexer's fence predicates consult that decision and never decide it. Registration, effects and authority remain runtime concerns.
|
|
1062
1230
|
|
|
1063
1231
|
```mermaid
|
|
1064
1232
|
stateDiagram-v2
|
|
@@ -1097,41 +1265,37 @@ Quoted blocks remain literal text, including every nested operation-looking line
|
|
|
1097
1265
|
Operation bodies, asides, malformed operation regions and unfenced operation lines
|
|
1098
1266
|
({§unfenced-operation}) are not response text;
|
|
1099
1267
|
nothing at or beyond a lost boundary is recovered as text. The statement and client
|
|
1100
|
-
tiers ignore outside text. Core alone owns
|
|
1268
|
+
tiers ignore outside text. Core alone owns storing it as the turn's outside source ({§outside-text})
|
|
1101
1269
|
and no-operation strikes ({§empty-turn}); parsing never infers delivery or completion
|
|
1102
1270
|
intent.
|
|
1103
1271
|
|
|
1104
1272
|
§unfenced-operation **An operation written without its fence did not run, and the parser says
|
|
1105
1273
|
so.** An outside-text line that opens at column zero with an operation's name and anything else
|
|
1106
1274
|
— `KILL The answer…`, `READ (a.md)`, `KILL (notes.md)` — draws one warning: `` `KILL` has no
|
|
1107
|
-
fence, so it did not run. `` The line is not response text ({§response-text}): it is neither
|
|
1108
|
-
|
|
1109
|
-
2026-09-23); the bare name alone
|
|
1275
|
+
fence, so it did not run. `` The line is not response text ({§response-text}): it is neither stored
|
|
1276
|
+
as outside text nor echoed into the next packet, and the exact emission remains at `ops://`; the bare name alone
|
|
1110
1277
|
opens the operation instead ({§naked-operation}). A registered executor's name followed by an
|
|
1111
1278
|
operand slot — `gitea (list_issues)`, `sh(build.sh)` — draws the same warning under the executor's
|
|
1112
1279
|
own spelling; quoted blocks, offset lines and names inside a sentence draw nothing, since `sh`,
|
|
1113
|
-
`env` and `members` are ordinary words. The model that wrote it believes it ran:
|
|
1114
|
-
|
|
1115
|
-
and the model
|
|
1116
|
-
|
|
1117
|
-
warning and the exclusion together end that echo.
|
|
1280
|
+
`env` and `members` are ordinary words. The model that wrote it believes it ran: stored as
|
|
1281
|
+
outside text ({§outside-text}), an unfenced KILL would sit in the record as an answer never given,
|
|
1282
|
+
and only the warning tells the model otherwise. The warning and the exclusion together keep the
|
|
1283
|
+
line out of the record.
|
|
1118
1284
|
|
|
1119
1285
|
§recorded-emissions **The parser is regressed against emissions models actually produced,
|
|
1120
1286
|
not fixtures we wrote.** `test/fixtures/recorded-emissions.jsonl` holds one real exemplar
|
|
1121
1287
|
of every distinct parse shape observed across the live and demo drills — the operations
|
|
1122
1288
|
authored, whether outside text appeared, how many parameterless KILLs appeared, and
|
|
1123
1289
|
the status the engine recorded at the time. A fixture encodes what we believe a model
|
|
1124
|
-
emits; a recording encodes what one did,
|
|
1125
|
-
|
|
1126
|
-
fixture in it was ours.
|
|
1290
|
+
emits; a recording encodes what one did, so only recordings test the shapes models actually
|
|
1291
|
+
produce (#802, #809).
|
|
1127
1292
|
Shape coverage, not volume, is the point — 120 exemplars are ~60 KB against ~88 MB for
|
|
1128
1293
|
every emission ever recorded. The recorded status is **provenance, never an assertion**:
|
|
1129
1294
|
the contract has changed under these turns and will again, so the replay asserts only that
|
|
1130
1295
|
today's parser still reads each emission the way the corpus says it does. Regenerate with
|
|
1131
1296
|
`scriptify/extract-emission-corpus.ts --write` after a drill; a changed shape is the
|
|
1132
1297
|
contract moving and the diff names every shape that moved with it. The extractor also
|
|
1133
|
-
reports how many recorded turns concluded
|
|
1134
|
-
the drift between what the harness once accepted and what it accepts now.
|
|
1298
|
+
reports how many recorded turns concluded in a way the current contract would reject.
|
|
1135
1299
|
|
|
1136
1300
|
## 12. Public API
|
|
1137
1301
|
|
|
@@ -1150,9 +1314,9 @@ An explicit disposition may sit anywhere in it
|
|
|
1150
1314
|
({§disposition-anywhere}). An omitted WAIT produces no synthesized statement, diagnostic, receipt,
|
|
1151
1315
|
warning, or strike. The authored operations and source remain unchanged.
|
|
1152
1316
|
Unfinished blocks never receive inferred closers.
|
|
1153
|
-
|
|
1154
|
-
the
|
|
1155
|
-
|
|
1317
|
+
A bounded operation error leaves its siblings' facts intact, and a lost boundary
|
|
1318
|
+
leaves the facts before it ({§unparsed-tail-boundary}); running them is the
|
|
1319
|
+
consumer's admission ({§emission-admission}).
|
|
1156
1320
|
|
|
1157
1321
|
The host records programs per turn; no operation acts as a separator between
|
|
1158
1322
|
saved programs. There is no outer Markdown program wrapper; the executable
|
|
@@ -1193,7 +1357,7 @@ among them: the parser is `@plurnk/plurnk-parser`'s ({§parser-consumers}).
|
|
|
1193
1357
|
The remaining values are small pure helpers over those contracts (`isExecution`, `writtenOp`,
|
|
1194
1358
|
`lifecycleOfLoopStatus`, `selectWorkerLoop`, `renderJsonResult`, `formatJsonDocument`,
|
|
1195
1359
|
`aguiConformanceReport`) and the closed name patterns and vocabularies (`RUNTIME_TAG`,
|
|
1196
|
-
`SKILL_NAME`, `
|
|
1360
|
+
`SKILL_NAME`, `EFFORTS`).
|
|
1197
1361
|
|
|
1198
1362
|
§parser-construction-boundary Parser construction components are internal rather
|
|
1199
1363
|
than alternate consumer entry points:
|
|
@@ -1540,7 +1704,7 @@ diagnostics are:
|
|
|
1540
1704
|
position after the closing `/`. Only a leading group of `i`, `m` and `s` lifts;
|
|
1541
1705
|
`(?i:…)` scoped modifiers are valid ECMAScript and pass through untouched.
|
|
1542
1706
|
`plurnk.md` teaches one regex spelling, `/\btimeout\b/i`, with flags after the closing
|
|
1543
|
-
slash; the lift is not taught. Unlike the tolerances on the {§
|
|
1707
|
+
slash; the lift is not taught. Unlike the tolerances on the {§outside-text}
|
|
1544
1708
|
scale, this one forgives a departure the model did not choose: `(?i)` is the spelling
|
|
1545
1709
|
a great many models were trained on, so refusing it would punish an instinct rather
|
|
1546
1710
|
than a mistake ({§naked-pattern} carries `^` for the same reason). The advisory still
|
|
@@ -1550,6 +1714,11 @@ diagnostics are:
|
|
|
1550
1714
|
diagnostic, with or without flags, without assuming what the extra text was
|
|
1551
1715
|
intended to represent. Invalid patterns or flags retain the native
|
|
1552
1716
|
regex failure; no branch silently removes or executes trailing content.
|
|
1717
|
+
- §regex-sed-range **A sed line range is named as one.** A regex matcher written as a sed
|
|
1718
|
+
address range — `/a/,/b/` or `/a/,+N` — is refused as a range, never as invalid flags: the
|
|
1719
|
+
diagnostic says a matcher selects only the lines it matches, gives the one regex that
|
|
1720
|
+
locates the ends (`/a|b/`, or `/a/`) and the scope that then addresses the span
|
|
1721
|
+
(`<first,last>`, or `<N,M>` with M being N plus the range's count).
|
|
1553
1722
|
- §unclosed-regex **A regex that never closes.** A `/pattern` matcher with no closing
|
|
1554
1723
|
`/` is read as the whole pattern with no flags, with one warning-severity advisory
|
|
1555
1724
|
naming the closing slash and the flag position. The reading is deterministic because
|
|
@@ -1577,7 +1746,7 @@ diagnostics are:
|
|
|
1577
1746
|
dialect without slashes or flags: the whole text is the pattern, so
|
|
1578
1747
|
`READ (notes.md) ^Decision:.*` selects lines beginning with `Decision:`.
|
|
1579
1748
|
`^` is deliberately absent from `plurnk.md`'s dialect table and belongs here instead
|
|
1580
|
-
(
|
|
1749
|
+
(#804). It is carried because `^` meaning "anchor" is among the
|
|
1581
1750
|
strongest instincts a model arrives with: it will write `^Decision:.*` whether or not it
|
|
1582
1751
|
was taught to, and the engine honours what it will reach for anyway. Teaching it would
|
|
1583
1752
|
spend hot-path weight on a line that changes no behaviour. The omission is therefore not
|
|
@@ -1597,23 +1766,49 @@ diagnostics are:
|
|
|
1597
1766
|
itself ends in one of those shapes takes the option escape.
|
|
1598
1767
|
`plurnk.md` teaches one order — `OP (path)? <scope|range>? [metadata]? pattern?
|
|
1599
1768
|
<!-- aside -->?` — and free ordering is not taught. Small departure, small
|
|
1600
|
-
reinterpretation ({§
|
|
1769
|
+
reinterpretation ({§outside-text}): every slot the model wrote is present and
|
|
1601
1770
|
unambiguous, so only their sequence differs from the taught form, and nothing is
|
|
1602
1771
|
invented to read it. The advisory names the canonical order rather than refusing,
|
|
1603
1772
|
because the operation the model meant is never in doubt.
|
|
1773
|
+
- §log-heading-notation **The log's heading notation, copied as syntax, is read as the slot it
|
|
1774
|
+
stands for.** A packet's log row heading is `### log:///L/T/S/OP → path pattern · N`
|
|
1775
|
+
({§log-wire-format} in the core SPEC); models copy its notation onto their own headings. Each
|
|
1776
|
+
piece has one reading, so each is read and named with one warning-severity advisory after its
|
|
1777
|
+
statement:
|
|
1778
|
+
|
|
1779
|
+
| Written | Read as | Advisory |
|
|
1780
|
+
|---|---|---|
|
|
1781
|
+
| `READ → sh:///x#stdout <1,50>` | the target, `READ (sh:///x#stdout) <1,50>`; COPY/MOVE take one arrow per operand | `` `→ sh:///x#stdout` is how the log shows an address; it was read as the target. Write the target in parentheses: `READ (sh:///x#stdout) <1,50>`. `` |
|
|
1782
|
+
| `READ (a.py) <1,50> · 900`, `· 320 tokens`, a bare `·` | nothing: the token charge is dropped, on the heading or after a matcher | `` `· 900` is the token charge the log shows on a heading; it is not part of an operation and was ignored. `` |
|
|
1783
|
+
| `FIND (x) /re/ · locate the sign handling` | the aside | `` `· locate the sign handling` was read as the aside; a note on an operation is written `<!-- locate the sign handling -->`. `` |
|
|
1784
|
+
|
|
1785
|
+
The arrow's path runs to the next space, `<` or `[`; a `·` never begins a heading matcher. In
|
|
1786
|
+
distinct recorded benchmark emissions the arrow form opened 40 headings and the charge ended 52,
|
|
1787
|
+
where they drew a missing-target 400 or a false-empty glob match.
|
|
1788
|
+
- §bare-target **A target written without its parentheses is refused with the line that runs.**
|
|
1789
|
+
A FIND, READ or EDIT heading with no target whose heading text opens with a word that is no
|
|
1790
|
+
matcher sigil, `READ a.py <1,4>`, cannot run: the word stands where the target goes, but on FIND it
|
|
1791
|
+
could as well be a pattern. The statement is one hard diagnostic that writes the corrected line —
|
|
1792
|
+
`` `READ` has no target: `a.py` stands where the target goes. Write the target in parentheses:
|
|
1793
|
+
`READ (a.py) <1,4>`. `` A targetless KILL's heading text remains its inline deliverable.
|
|
1794
|
+
- §bare-anchor-scope **An EDIT's anchor without its angle brackets is its scope.** On an EDIT
|
|
1795
|
+
heading, `@abcde` or `@abcde,@fghij` standing alone where the scope goes — nothing but an aside, a
|
|
1796
|
+
closer or the line end after it — is the scope `<@abcde>`, with one warning-severity advisory:
|
|
1797
|
+
`` `@abcde` was read as the scope `<@abcde>`; a scope is written in angle brackets. `` Read as
|
|
1798
|
+
body instead, the anchor would be written into the file, or the EDIT refused for want of a line
|
|
1799
|
+
marker (14 distinct recorded headings). On READ and KILL the same text stays a literal matcher,
|
|
1800
|
+
since `@patch` is a search a model means.
|
|
1604
1801
|
- §matcher-body-redirect **A body beneath those headings.** Text below the heading
|
|
1605
1802
|
of a FIND, READ or targeted KILL is a body, and those operations take none: the builder
|
|
1606
1803
|
keeps the statement without it and raises one warning-severity advisory (`READ
|
|
1607
1804
|
takes no body; the body was ignored. A pattern belongs on the opening fence line
|
|
1608
1805
|
after the path.`), delivered like {§misplaced-aside-advisory} as a
|
|
1609
|
-
`parse_advisory` notice (
|
|
1610
|
-
the model must recover from). One sigil line beneath the heading is the bare form
|
|
1806
|
+
`parse_advisory` notice (a warning, never an error). One sigil line beneath the heading is the bare form
|
|
1611
1807
|
written a line low and still lifts; nothing else is promoted into a matcher from
|
|
1612
1808
|
below the heading, and the advisory never echoes the body.
|
|
1613
1809
|
- §combined-anchor-tolerance **Combined anchor and line number in a scope.** A
|
|
1614
1810
|
text-coordinate scope position written `@hash:L` or `@hash L` is the displayed
|
|
1615
|
-
`@abcde 42:` prefix copied whole
|
|
1616
|
-
row, 2026-09-12): the position is the anchor, the number is dropped, and one
|
|
1811
|
+
`@abcde 42:` prefix copied whole: the position is the anchor, the number is dropped, and one
|
|
1617
1812
|
warning-severity advisory names the anchor-only form. The scope lexes as one
|
|
1618
1813
|
ordinary marker at any text-coordinate operation, either COPY/MOVE operand
|
|
1619
1814
|
included; nothing cascades.
|