@plurnk/plurnk-contracts 1.20.0 → 1.21.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 CHANGED
@@ -267,58 +267,52 @@ input
267
267
  `````
268
268
 
269
269
  §section-boundary Every statement is one backtick block. Its header occupies one
270
- physical line: a fence of at least three backticks ({§operation-fences}), an optional numeric delimiter
271
- ({§numeric-delimiter}), then the name and its slots. A closer is shown by
270
+ physical line: a fence of at least three backticks ({§operation-fences}), then the name
271
+ and its slots. A closer is shown by
272
272
  convention and never demanded ({§fence-closer}, {§closer-fallback}). There are no
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 and delimiter D (its digits, possibly
277
- none) closes at the first unclaimed line made of at least N backticks,
278
- exactly D, and nothing else but horizontal whitespace. Count follows CommonMark: a
279
- shorter fence inside the body is body; an equal or longer bare fence closes a bare
280
- block unless it closes a balanced nested block ({§balanced-fences}). The delimiter
281
- compares exactly: a bare fence never closes a delimited block,
282
- and a delimited fence never closes a bare one. The compact one-line form closes on
283
- its heading line after the modifiers under the same rule.
276
+ §fence-closer A block opened with N backticks closes at the first unclaimed line made of
277
+ at least N backticks and nothing else but horizontal whitespace, within three spaces of
278
+ its line start ({§indented-fences}). Count follows CommonMark: a shorter fence inside the
279
+ body is body; an equal or longer bare fence closes the block unless {§balanced-fences}
280
+ claims it for a nested block. The compact one-line form closes on its heading line after
281
+ the modifiers under the same rule.
284
282
 
285
283
  §balanced-fences A complete nested interpretation takes precedence over missing-closer
286
- recovery. Within an undelimited body, line-leading labeled fences open literal
287
- blocks; their matching closers close the innermost block first. The enclosing
288
- block and its nested blocks must all close, with matching widths and delimiters
289
- under {§fence-closer}. Equal opener/closer totals alone are insufficient. A complete
290
- inline block is already closed; a numerically delimited block is opaque until its
291
- own closer. Preserve every nested body byte, including apparent OPs and known
292
- executors, without dispatching them. If no complete enclosing interpretation exists,
293
- retain {§fence-heading-in-body} and {§closer-fallback}. These rules apply equally to
294
- model programs, stored programs, client operations, and reasoning quotations.
295
-
296
- §numeric-delimiter Digits between the opening backticks and the name (an opener
297
- carrying `42EDIT (x)`) identify the block, and only a fence carrying `42` closes it.
298
- This explicitly protects bare fences and headings, including incomplete examples.
299
- The delimiter is syntax, never AST or persistence
300
- state; `PlurnkParser.frame` chooses one when the body it wraps holds a heading line
301
- of four or more backticks ({§statement-rendering}).
302
-
303
- §operation-fences **Accept three or more backticks; teach and render four.** A top-level,
304
- unindented fence of three or more backticks naming a native operation or registered executor
305
- opens that operation. A three-backtick opener ran, and one warning-severity receipt follows its
306
- statement — `` `KILL` ran with three backticks; the taught fence is four. `` — because three is
307
- the habit and four is the taught form: a four-backtick fence holds any body, including
308
- three-backtick code. Indentation and enclosing quotations remain inert ({§quotation}); shorter
309
- fences inside a body are never promoted to operations ({§fence-heading-in-body}). `plurnk.md`
310
- teaches exactly four; other accepted widths are not taught. Every producer of a statement — the
311
- parser, a client composing `/look`, a client's tab-completion — writes `PLURNK_FENCE` rather than
312
- its own literal (plurnk/plurnk#92).
284
+ recovery. Within a body, line-leading labeled fences open literal blocks. A bare fence
285
+ closes the innermost open block of exactly its width, otherwise the outermost open block
286
+ narrower than it; the narrower blocks it steps over are literal body, and a wider or
287
+ differently fenced block inside stops it. So a wider outer fence holds any narrower body,
288
+ finished or not, and equal widths nest when every inner block closes. The enclosing block
289
+ and its nested blocks must all
290
+ close under {§fence-closer}; equal opener/closer totals alone are insufficient, and a
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.
296
+
297
+ §operation-fences **Accept three or more backticks; teach and render three.** A line-start fence
298
+ of three or more backticks naming a native operation or registered executor opens that
299
+ operation ({§indented-fences}), and no width draws a receipt. Three is the taught form and the
300
+ rendered form; a wider fence is the same statement, and it is how a body holding fence lines of
301
+ its own is held: an opener wider than any of them ({§balanced-fences}). Enclosing quotations
302
+ remain inert ({§quotation}), and a fence inside an intact block is never promoted to an
303
+ operation ({§fence-heading-in-body}). `plurnk.md` teaches exactly three and shows the wider
304
+ fence only as the nesting form. Every producer of a statement — the parser, a client composing
305
+ `/look`, a client's tab-completion — writes `PLURNK_FENCE` rather than its own literal
306
+ (plurnk/plurnk#92).
313
307
 
314
308
  §naked-operation **A native operation's name alone on a line opens it without a fence.** A
315
309
  column-zero line outside any block that is exactly an operation's name, with nothing but
316
- horizontal whitespace after it, opens that operation as if it were fenced with the taught four
310
+ horizontal whitespace after it, opens that operation as if it were fenced with the taught three
317
311
  backticks: no target, no modifiers, and a body that runs to a line that is exactly the name
318
- again, to the next four-backtick heading, or to the end of the turn. Narrower fences inside are
319
- body, as inside any four-backtick block; the block expects no closer, so its body is never cut
312
+ again, to the next heading ({§fence-heading-in-body}), or to the end of the turn. A fence inside
313
+ naming nothing known is body; the block expects no closer, so its body is never cut
320
314
  back ({§closer-fallback}). It runs, and one warning-severity receipt follows its statement —
321
- `` `KILL` opened with no fence; the taught form is four backticks. `` One rule for every native
315
+ `` `KILL` opened with no fence; the taught form is three backticks. `` One rule for every native
322
316
  operation: a naked `WAIT` parks, a naked `NOTE` takes its text, a naked `READ` meets the ordinary
323
317
  missing-target refusal. Only the bare name qualifies; a name with anything else on its line is
324
318
  the unfenced form and still refuses ({§unfenced-operation}), executors are runtimes rather than
@@ -327,54 +321,49 @@ operations, and reasoning is never read this way. Measured before it was accepte
327
321
  three loops lost to the refusal at the strike threshold.
328
322
 
329
323
  §fence-heading-in-body Outside a complete nested block ({§balanced-fences}), a fence
330
- line of three or more backticks, optional digits, and a name that is a native operation
331
- or a known executor is a heading. Inside an open block its width must also reach the block's
332
- opening width, capped at four: a three-backtick heading ends only a three-backtick block, and a
333
- four-backtick heading ends any block. A qualifying heading ends that block without closing it
334
- ({§closer-fallback}) and opens the next statement. Fence lines of fewer than three
324
+ 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 of any width it ends that block without closing it
326
+ ({§closer-fallback}) and opens the next statement: a wider fence holds the narrower headings
327
+ inside it only while it closes ({§balanced-fences}). Fence lines of fewer than three
335
328
  backticks are never headings ({§operation-fences}). Known executors are `sh` plus what
336
- the host names in `ParseOptions.executors`. Consequences: a three-backtick executor line inside
337
- a four-backtick block is body, a closer glued to the next opener (eight backticks then `READ`)
338
- can never swallow an unbalanced turn, and a numeric delimiter preserves quoted headings even
339
- when their own fences are incomplete.
329
+ the host names in `ParseOptions.executors`. Consequences: a closer glued to the next opener
330
+ (six backticks then `READ`) can never swallow an unbalanced turn, and no unclosed block, however
331
+ wide, swallows the operations after it.
340
332
 
341
333
  §closer-fallback A block that ends at a heading or at the end of the input has no
342
- closer of its own. Its body is cut back to its last bare fence line (any count,
343
- optional digits), which is the closer the author meant, and one terminating line
334
+ closer of its own. Its body is cut back to its last bare fence line (any count, within
335
+ three spaces of its line start), which is the closer the author meant, and one terminating line
344
336
  ending goes with it; when no bare fence line exists the body is the whole span less
345
337
  one terminating line ending. This carries no diagnostic: a missing closer is never
346
338
  an admission failure, and {§unparsed-tail-boundary} is not involved.
347
339
 
348
- `plurnk.md` teaches that operations *"begin and end with exactly four backticks, both
349
- immediately after a newline"*; this recovery is not taught. It sits at the quiet end of
340
+ `plurnk.md` shows every operation closed; this recovery is not taught. It sits at the quiet end of
350
341
  the scale {§response-text-note} describes: the model opened the operation correctly
351
342
  and only failed to close it, so the harness reads what it plainly meant and says nothing.
352
343
  A departure that small earns no correction — telling a model its closer was missing costs
353
344
  a sentence in every future packet to fix something already fixed.
354
345
 
355
346
  §fence-boundary Balanced nesting is resolved before local recovery. Otherwise,
356
- fences are read by count and delimiter, except for the heading rule above:
347
+ fences are read by count, except for the heading rule above:
357
348
 
358
349
  | Fence encountered inside a body | Meaning |
359
350
  |---|---|
360
351
  | Part of a complete nested block | Literal body, including its openers and closers |
352
+ | Indented four spaces or more, or by a tab | Body ({§indented-fences}) |
361
353
  | Fewer backticks than the block's own | Body |
362
- | At least the block's backticks, bare, block undelimited | The block's closer |
363
- | At least the block's backticks carrying the block's delimiter | The block's closer |
364
- | At least the block's backticks with any other delimiter | Body |
365
- | At least the block's backticks, capped at four, naming a native operation or known executor | A heading: ends the block, opens the next statement |
366
-
367
- §indented-fences Leading horizontal whitespace before a CLOSER is not part of the fence: an
368
- indented closer, heading-that-ends-a-block, or closer fallback still closes, and a body keeps its
369
- own lines' indentation. An OPENER is different: an operation's backticks follow a newline
370
- directly (operator, 2026-09-18), so an indented fence opens a quotation, never an operation —
371
- CommonMark reads an indented block as code, and `plurnk.md` shows its own examples that way. This
372
- reverses the 2026-09-12 tolerance (then measured at five to ten percent of emissions on
373
- GLM-5.3-flash; 2.8% of that lane's emissions today). An offset fence is prose and draws no advisory:
374
- `plurnk.md` instructs the model to offset any example it does not intend to execute, so the form
375
- is correct by construction and there is no mistake to report (operator, 2026-09-21). The parser
376
- presumes nothing about why a fence is offset. Outside an operation, that quotation is
377
- response text under {§response-text}; inside a body, it stays literal body content.
354
+ | At least the block's backticks, bare | The block's closer |
355
+ | Three or more backticks naming a native operation or known executor | A heading: ends the block, opens the next statement |
356
+
357
+ §indented-fences **CommonMark's indentation, everywhere.** A fence line may follow at most three
358
+ spaces; four or more, or a tab, make it indented code. That one rule reads every fence purpose the
359
+ same way: an opener within three spaces opens, a closer within three closes, a heading within
360
+ three ends an unclosed block, and a body keeps its own lines' indentation. A fence indented
361
+ further is literal wherever it stands — prose outside a block, body inside one — and draws no
362
+ 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 (operator, 2026-09-21). The parser presumes nothing about why a fence is offset. This one
364
+ rule replaces the column-zero opener (operator, 2026-09-18) and the lenient closer beside it
365
+ (operator, 2026-09-23). Outside an operation, offset text is response text under
366
+ {§response-text}; inside a body, it stays literal body content.
378
367
 
379
368
  §inline-chain A closer on a heading line, or on a body's closing line, may be
380
369
  followed on that same line by the next opener; the closer still closes, and the
@@ -386,7 +375,7 @@ text there is the heading's own and is read under {§transparent-inline-closer}.
386
375
  closing fence on a heading line followed by more of that heading — a `<scope>`, an
387
376
  `[option block]`, a `<!-- aside -->`, or a naked matcher — does not end the reading: the
388
377
  heading keeps taking its slots under {§trailing-slots} and {§naked-pattern}, exactly as though
389
- the closer were absent, so ````` ````READ (a.md)```` ````` `<1,2>` is the same operation as `READ (a.md) <1,2>`.
378
+ the closer were absent, so ```` ```READ (a.md)``` ```` `<1,2>` is the same operation as `READ (a.md) <1,2>`.
390
379
  The closer is still a closer: the block ends with that physical line and never reaches down for
391
380
  the next operation, which is what a bare heading carrying a matcher would do. A closer followed
392
381
  by the next opener is {§inline-chain}, and by nothing is the ordinary {§fence-closer}. There is
@@ -413,7 +402,7 @@ identity; absent `node`, the shorthand grants no executable capability.
413
402
  line: prose, then heading after heading with no line ending anywhere. Two
414
403
  rules absorb it. The next opener on a heading's own line, after the heading's
415
404
  slots, ends that heading's block bodyless and opens ({§empty-section}), so
416
- `````EDIT (a.rs) <60,66> <!-- drop --> ````EDIT (b.rs) <31,38>` is two scoped
405
+ ````EDIT (a.rs) <60,66> <!-- drop --> ```EDIT (b.rs) <31,38>` is two scoped
417
406
  deletions. Literal inline bodies follow {§heading-inline-body}.
418
407
 
419
408
  §anchor-digits In a text scope, `@` followed by one to four digits cannot be a
@@ -425,28 +414,33 @@ line takes the rest of the line as the aside, with one warning-severity advisory
425
414
  A closed aside followed by more text is unchanged.
426
415
 
427
416
  §quotation **A fence that opens no operation quotes.** Outside a body, a line-start fence that
428
- is not an operation heading — unlabeled, tagged like a code block (`ts`, `json`), indented,
429
- or naming nothing registered — opens a
417
+ is not an operation heading — unlabeled, tagged like a code block (`ts`, `json`), or naming
418
+ nothing registered — opens a
430
419
  quotation that runs to its matching closer (same character, width at least the opener's) or to
431
420
  the end of the input. Everything inside is data: no operation runs there and native tool-call
432
421
  markup is not read ({§native-tool-calls}). An operation fenced inside an unlabeled code block
433
- draws one warning that it was shown, not run; a labeled block is an example by declaration, and
434
- nothing else inside draws an advisory.
435
- So a model may show plurnk's own operations in an answer. Three exceptions keep programs whole:
422
+ draws one warning that it was shown, not run. An unlabeled fence whose first line is an operation
423
+ heading is the operation with its tag forgotten, and draws one warning — `` `READ` inside an
424
+ unlabeled fence did not run; the tag is the operation. `` — a native name alone or with a slot, an
425
+ executor's name with its operand (of 2,308 naked fences in 12,797 recorded emissions, 51 open that
426
+ way and 2,238 hold code or quoted output, which is why the fence itself draws nothing). A labeled
427
+ block is an example by declaration, and nothing else inside draws an advisory.
428
+ So a model may show plurnk's own operations in an answer. Two exceptions keep programs whole:
436
429
  CommonMark's own rule that a backtick opener's line carries no further backtick, so
437
- ```` ```READ (x)``` ```` is inline code and quotes nothing after it; a bare fence directly under a
438
- line carrying a fence run, which is an orphaned closer and quotes nothing; and a tag that is a
439
- missed operation — an unknown name at operation width — which still draws one warning; an
440
- offset example draws none. Quotation outside an operation is
430
+ ```` ```READ (x)``` ```` is inline code and quotes nothing after it; and a bare fence directly under
431
+ a line carrying a fence run, which is an orphaned closer and quotes nothing. An unknown tag at
432
+ any width is a code block and draws nothing, unless its line carries a target slot, `(…)`: that
433
+ is an operation the model missed by its tag, and it draws one warning — `` `OP` is not an
434
+ operation or a known executor here. `` An offset example draws nothing either
435
+ ({§indented-fences}). Quotation outside an operation is
441
436
  response text under {§response-text}, not an executable program or a completion envelope.
442
437
 
443
- `plurnk.md` teaches exactly one way to make an example inert — *"tab offset any example OP
444
- you do not intend to execute"* — and the other quoting fences are
445
- not taught: a tilde fence, an unlabeled fence and an unknown three-backtick tag all quote
446
- too. Each is a shape a model reaches for from ordinary Markdown rather than from this
438
+ `plurnk.md` names the tab offset as the form for an example, in the aside of its nesting
439
+ example, and shows its own examples offset; the other quoting fences are untaught: a tilde
440
+ 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
447
441
  teaching, so honouring it protects an example the model already believed was safe
448
- ({§response-text-note} places the scale). The taught offset remains the one form a
449
- model should rely on, because it is the only one that survives every fence style.
442
+ ({§response-text-note} places the scale). The offset is the one form that survives every
443
+ fence style.
450
444
 
451
445
  §interstitial-fence Superseded by {§quotation}: an unlabeled fence no longer opens nothing, it
452
446
  quotes. (It in turn replaced the retired unlabeled-fence SEND of the fences chapter, whose
@@ -471,15 +465,24 @@ reading, with no diagnostic and no teaching (#758):
471
465
  Tokens keep their source positions; only their order in the stream changes.
472
466
 
473
467
  §native-tool-calls An emission that yields no operation may be a model's native
474
- tool-call markup (DeepSeek's `<||DSML|| calls>` block) naming a plurnk operation or
475
- a known executor. Each `invoke` is read as that operation's canonical fence:
476
- `path`/`target` fill the target, `scope`/`range`/`lines` the scope, `pattern` a
477
- matcher option, `aside` the aside, and `body`/`content`/`command` or plain lines
478
- inside the invoke the body; plurnk slots written after the invoke name are kept.
479
- Each block keeps its line count, so statement positions still name the source
480
- line. An invoke with an unknown name or parameter leaves the whole emission as it
481
- was. An emission that already yields an operation is never rewritten. No
482
- diagnostic, notice or teaching mentions the reading (#760).
468
+ tool-call markup naming a plurnk operation or a known executor, and every popular
469
+ family is read the same way: DeepSeek's `<||DSML|| calls>` and Anthropic-style
470
+ `<function_calls>` blocks of `invoke` elements with `parameter` children; the
471
+ `<tool_call>` family as `<function=NAME>` with `<parameter=key>` children (Qwen,
472
+ MiMo), as a JSON object with `name` and `arguments` (Hermes and kin), or as a name
473
+ followed by `<arg_key>`/`<arg_value>` pairs (GLM); a bare `<function=NAME>` element
474
+ (Llama); Mistral's `[TOOL_CALLS]` JSON array; Llama's `<|python_tag|>` JSON object; and
475
+ Kimi's `<|tool_call_begin|>` sections. Each call is read as that operation's
476
+ canonical fence: `path`/`target`/`file_path`/`file`/`resource`/`uri` fill the target,
477
+ `scope`/`range`/`lines` the scope, as do `start`/`end` written apart and `offset`/`limit`
478
+ (a first line and a count), `pattern`/`regex`/`query` a matcher option, `aside`
479
+ the aside, and `body`/`content`/`command`/`text`/`input` or plain text inside the
480
+ call the body; plurnk slots written after the name are kept, a trailing scope's own
481
+ bracket may close the tag. A block keeps its line count where its lines allow, so
482
+ statement positions name the source line; an inline block grows to its fences.
483
+ A call with an unknown name or parameter leaves the whole emission as it was. An
484
+ emission that already yields an operation is never rewritten. No diagnostic, notice
485
+ or teaching mentions the reading (#760).
483
486
 
484
487
  §empty-section Both the compact bodyless form and an empty multiline block
485
488
  normalize optional bodies to null. Closing fences are conventional, never required
@@ -489,10 +492,9 @@ normalize optional bodies to null. Closing fences are conventional, never requir
489
492
  runtime fences from the shared AST, with one blank line between operations.
490
493
  Every closing fence occupies its own line, including bodyless operations;
491
494
  inline fences remain accepted input, not generated examples.
492
- It chooses at least four backticks and more than any run within the body, and a
493
- numeric delimiter whenever the body holds a heading line of four or more backticks
494
- ({§fence-heading-in-body}), preserving body bytes on reparse. Fence length and
495
- delimiter are syntax, not AST or persistence state. Core-authored programs use
495
+ It chooses at least three backticks and more than any run within the body
496
+ ({§balanced-fences}), preserving body bytes on reparse. Fence length is syntax,
497
+ not AST or persistence state. Core-authored programs use
496
498
  this serializer and the ordinary admission parser. Rendering preserves a matcher
497
499
  beside owner metadata, not only a matcher carried inside its `pattern` option.
498
500
 
@@ -1090,7 +1092,8 @@ under {§turn-ops-log-curation}; body bytes and source positions are unchanged.
1090
1092
  The model-turn entry point returns each non-whitespace text span outside operation
1091
1093
  regions as an ordered `text` item with its exact content and source position.
1092
1094
  Quoted blocks remain literal text, including every nested operation-looking line.
1093
- Operation bodies, asides and malformed operation regions are not response text;
1095
+ Operation bodies, asides, malformed operation regions and unfenced operation lines
1096
+ ({§unfenced-operation}) are not response text;
1094
1097
  nothing at or beyond a lost boundary is recovered as text. The statement and client
1095
1098
  tiers ignore outside text. Core alone owns filing it as a NOTE ({§response-text-note})
1096
1099
  and no-operation strikes ({§empty-turn}); parsing never infers delivery or completion
@@ -1099,12 +1102,17 @@ intent.
1099
1102
  §unfenced-operation **An operation written without its fence did not run, and the parser says
1100
1103
  so.** An outside-text line that opens at column zero with an operation's name and anything else
1101
1104
  — `KILL The answer…`, `READ (a.md)`, `KILL (notes.md)` — draws one warning: `` `KILL` has no
1102
- fence, so it did not run. `` The line stays response text ({§response-text}); the bare name alone
1103
- opens the operation instead ({§naked-operation}), and quoted blocks, offset lines, names inside a
1104
- sentence and executor tags draw nothing. The model that wrote it believes it ran: filed as a NOTE
1105
- ({§response-text-note}), an unfenced KILL read back as an answer already given, and the model
1106
- repeated it until the cycle detector ended the loop (`demo-overflow-recovery-AC4Ul4`; the same
1107
- shape defeated SEND recovery and a count of invalid characters; operator, 2026-09-22).
1105
+ fence, so it did not run. `` The line is not response text ({§response-text}): it is neither filed as
1106
+ a NOTE nor echoed into the next packet, and the exact emission remains at `ops://` (operator,
1107
+ 2026-09-23); the bare name alone
1108
+ opens the operation instead ({§naked-operation}). A registered executor's name followed by an
1109
+ operand slot — `gitea (list_issues)`, `sh(build.sh)` — draws the same warning under the executor's
1110
+ own spelling; quoted blocks, offset lines and names inside a sentence draw nothing, since `sh`,
1111
+ `env` and `members` are ordinary words. The model that wrote it believes it ran: while the line was
1112
+ still filed as a NOTE ({§response-text-note}), an unfenced KILL read back as an answer already given,
1113
+ and the model repeated it until the cycle detector ended the loop (`demo-overflow-recovery-AC4Ul4`;
1114
+ the same shape defeated SEND recovery and a count of invalid characters; operator, 2026-09-22). The
1115
+ warning and the exclusion together end that echo.
1108
1116
 
1109
1117
  §recorded-emissions **The parser is regressed against emissions models actually produced,
1110
1118
  not fixtures we wrote.** `test/fixtures/recorded-emissions.jsonl` holds one real exemplar
@@ -1540,6 +1548,14 @@ diagnostics are:
1540
1548
  diagnostic, with or without flags, without assuming what the extra text was
1541
1549
  intended to represent. Invalid patterns or flags retain the native
1542
1550
  regex failure; no branch silently removes or executes trailing content.
1551
+ - §unclosed-regex **A regex that never closes.** A `/pattern` matcher with no closing
1552
+ `/` is read as the whole pattern with no flags, with one warning-severity advisory
1553
+ naming the closing slash and the flag position. The reading is deterministic because
1554
+ the heading's own boundaries bound it ({§naked-pattern}: the matcher runs to the end
1555
+ of the heading, and an aside is lexed apart from it). A bare `/` with nothing after
1556
+ it has no pattern to read and is refused as `invalid-operation-syntax` naming what
1557
+ is missing. A matcher with a second unescaped `/` is not unclosed: it is
1558
+ `/pattern/flags`, and invalid flags keep their native failure with the escape hint.
1543
1559
  - §naked-pattern **The matcher rides the heading bare.** After the path, and any
1544
1560
  scope or option block, the rest of a FIND, READ or KILL heading line is the
1545
1561
  matcher, in whichever dialect its first characters claim
@@ -1679,6 +1695,6 @@ runtime constructs this; the parser provides the fields):
1679
1695
  "column": 12,
1680
1696
  "source": "parser",
1681
1697
  "severity": "error",
1682
- "message": "READ block opened at line 1 but was not closed with 4 backticks"
1698
+ "message": "READ block opened at line 1 but was not closed with 3 backticks"
1683
1699
  }
1684
1700
  ```
@@ -2,7 +2,7 @@ export * from "./types.generated.ts";
2
2
  import type { ClientStatement, LoopPolicy, Position, PlurnkStatement, ProviderRequestAccounting, ReasoningPolicy } from "./types.generated.ts";
3
3
  import type PlurnkParseError from "./PlurnkParseError.ts";
4
4
  export declare const PLURNK_OPS: readonly ["FIND", "READ", "EDIT", "COPY", "MOVE", "SEND", "BARE", "WORK", "FORK", "KILL", "NOTE", "WAIT"];
5
- export declare const PLURNK_FENCE = "````";
5
+ export declare const PLURNK_FENCE = "```";
6
6
  export type PlurnkOp = (typeof PLURNK_OPS)[number];
7
7
  export type RuntimeTag = Lowercase<string>;
8
8
  export declare const RUNTIME_TAG: RegExp;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAEA,cAAc,sBAAsB,CAAC;AAKrC,OAAO,KAAK,EACR,eAAe,EACf,UAAU,EACV,QAAQ,EACR,eAAe,EACf,yBAAyB,EACzB,eAAe,EAClB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,gBAAgB,MAAM,uBAAuB,CAAC;AAM1D,eAAO,MAAM,UAAU,YACnB,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAC9E,MAAM,EAAE,MAAM,CACR,CAAC;AAGX,eAAO,MAAM,YAAY,SAAS,CAAC;AAEnC,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;AAKnD,MAAM,MAAM,UAAU,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;AAC3C,eAAO,MAAM,WAAW,QAAwB,CAAC;AACjD,eAAO,MAAM,gBAAgB,EAAE,WAAW,CAAC,MAAM,CAAmC,CAAC;AACrF,eAAO,MAAM,aAAa,OAAQ,MAAM,GAAG,IAAI,GAAG,SAAS,KAAG,EAAE,IAAI,UAAyF,CAAC;AAC9J,eAAO,MAAM,WAAW,GAAI,CAAC,SAAS;IAAE,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,aAAa,CAAC,KAAG,SAAS,IAAI,OAAO,CAAC,CAAC,EAAE;IAAE,OAAO,EAAE,UAAU,CAAA;CAAE,CAChH,CAAC;AAG3B,eAAO,MAAM,SAAS,GAAI,CAAC,SAAS,eAAe,GAAG,eAAe,aAAa,CAAC,KAAG,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,GAAG,UACT,CAAC;AAK5G,MAAM,WAAW,uBAAuB;IACpC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,MAAM,yBAAyB,GAAG,CACpC,UAAU,EAAE,yBAAyB,KACpC,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnB,MAAM,MAAM,uBAAuB,GAAG,CAClC,QAAQ,EAAE,uBAAuB,KAChC,OAAO,CAAC,yBAAyB,CAAC,CAAC;AAIxC,eAAO,MAAM,kBAAkB,EAE1B,SAAS,eAAe,EAAE,CAAC;AAGhC,eAAO,MAAM,iBAAiB,EAEzB,SAAS,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;AAGxC,eAAO,MAAM,WAAW,QAAqC,CAAC;AAG9D,eAAO,MAAM,UAAU,QAAiE,CAAC;AAGzF,eAAO,MAAM,gBAAgB,EAAE,QAAQ,CAAC,QAAQ,CAAyC,CAAC;AAI1F,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC;AAI9B,MAAM,MAAM,SAAS,CAAC,CAAC,GAAG,eAAe,IACnC;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,SAAS,EAAE,CAAC,CAAA;CAAE,GACnC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAA;CAAE,GACrD;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,gBAAgB,CAAA;CAAE,CAAC;AAEjD,MAAM,MAAM,WAAW,CAAC,CAAC,GAAG,eAAe,IAAI;IAC3C,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;IACtB,YAAY,CAAC,EAAE;QAAE,IAAI,EAAE,QAAQ,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CACrD,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAEA,cAAc,sBAAsB,CAAC;AAKrC,OAAO,KAAK,EACR,eAAe,EACf,UAAU,EACV,QAAQ,EACR,eAAe,EACf,yBAAyB,EACzB,eAAe,EAClB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,gBAAgB,MAAM,uBAAuB,CAAC;AAM1D,eAAO,MAAM,UAAU,YACnB,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAC9E,MAAM,EAAE,MAAM,CACR,CAAC;AAGX,eAAO,MAAM,YAAY,QAAQ,CAAC;AAElC,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;AAKnD,MAAM,MAAM,UAAU,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;AAC3C,eAAO,MAAM,WAAW,QAAwB,CAAC;AACjD,eAAO,MAAM,gBAAgB,EAAE,WAAW,CAAC,MAAM,CAAmC,CAAC;AACrF,eAAO,MAAM,aAAa,OAAQ,MAAM,GAAG,IAAI,GAAG,SAAS,KAAG,EAAE,IAAI,UAAyF,CAAC;AAC9J,eAAO,MAAM,WAAW,GAAI,CAAC,SAAS;IAAE,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,aAAa,CAAC,KAAG,SAAS,IAAI,OAAO,CAAC,CAAC,EAAE;IAAE,OAAO,EAAE,UAAU,CAAA;CAAE,CAChH,CAAC;AAG3B,eAAO,MAAM,SAAS,GAAI,CAAC,SAAS,eAAe,GAAG,eAAe,aAAa,CAAC,KAAG,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,GAAG,UACT,CAAC;AAK5G,MAAM,WAAW,uBAAuB;IACpC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,MAAM,yBAAyB,GAAG,CACpC,UAAU,EAAE,yBAAyB,KACpC,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnB,MAAM,MAAM,uBAAuB,GAAG,CAClC,QAAQ,EAAE,uBAAuB,KAChC,OAAO,CAAC,yBAAyB,CAAC,CAAC;AAIxC,eAAO,MAAM,kBAAkB,EAE1B,SAAS,eAAe,EAAE,CAAC;AAGhC,eAAO,MAAM,iBAAiB,EAEzB,SAAS,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;AAGxC,eAAO,MAAM,WAAW,QAAqC,CAAC;AAG9D,eAAO,MAAM,UAAU,QAAiE,CAAC;AAGzF,eAAO,MAAM,gBAAgB,EAAE,QAAQ,CAAC,QAAQ,CAAyC,CAAC;AAI1F,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC;AAI9B,MAAM,MAAM,SAAS,CAAC,CAAC,GAAG,eAAe,IACnC;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,SAAS,EAAE,CAAC,CAAA;CAAE,GACnC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAA;CAAE,GACrD;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,gBAAgB,CAAA;CAAE,CAAC;AAEjD,MAAM,MAAM,WAAW,CAAC,CAAC,GAAG,eAAe,IAAI;IAC3C,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;IACtB,YAAY,CAAC,EAAE;QAAE,IAAI,EAAE,QAAQ,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CACrD,CAAC"}
package/dist/src/types.js CHANGED
@@ -12,7 +12,7 @@ export const PLURNK_OPS = [
12
12
  "NOTE", "WAIT",
13
13
  ];
14
14
  // {§operation-fences} — canonical teaching/rendering width; ingestion also accepts three.
15
- export const PLURNK_FENCE = "````";
15
+ export const PLURNK_FENCE = "```";
16
16
  export const RUNTIME_TAG = /^[a-z][a-z0-9+.-]*$/;
17
17
  export const INTERNAL_ROW_OPS = new Set(["extension", "error"]);
18
18
  export const isExecutionOp = (op) => typeof op === "string" && !INTERNAL_ROW_OPS.has(op) && RUNTIME_TAG.test(op);
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,oFAAoF;AACpF,cAAc,sBAAsB,CAAC;AAErC,OAAO,gBAAgB,MAAM,2BAA2B,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAC/E,OAAO,qBAAqB,MAAM,gCAAgC,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACzF,OAAO,qBAAqB,MAAM,gCAAgC,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAWzF,0EAA0E;AAC1E,6CAA6C;AAE7C,4FAA4F;AAC5F,MAAM,CAAC,MAAM,UAAU,GAAG;IACtB,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9E,MAAM,EAAE,MAAM;CACR,CAAC;AAEX,0FAA0F;AAC1F,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAC;AAQnC,MAAM,CAAC,MAAM,WAAW,GAAG,qBAAqB,CAAC;AACjD,MAAM,CAAC,MAAM,gBAAgB,GAAwB,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;AACrF,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,EAA6B,EAAoB,EAAE,CAAC,OAAO,EAAE,KAAK,QAAQ,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC9J,MAAM,CAAC,MAAM,WAAW,GAAG,CAAiD,SAAY,EAAoD,EAAE,CAC1I,SAAS,IAAI,SAAS,CAAC;AAC3B,6FAA6F;AAC7F,kBAAkB;AAClB,MAAM,CAAC,MAAM,SAAS,GAAG,CAA8C,SAAY,EAA4C,EAAE,CAC7H,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAA6C,CAAC;AAkB5G,2EAA2E;AAC3E,uEAAuE;AACvE,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,CAC3C,qBAAqB,CAAC,IAAyB,CACpB,CAAC;AAEhC,oEAAoE;AACpE,MAAM,CAAC,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,CAC1C,gBAAgB,CAAC,UAAU,CAAC,SAAS,CAAC,IAAiC,CACpC,CAAC;AAExC,wFAAwF;AACxF,MAAM,CAAC,MAAM,WAAW,GAAG,kCAAkC,CAAC;AAE9D,mFAAmF;AACnF,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,MAAM,CAAC,qBAAqB,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;AAEzF,sFAAsF;AACtF,MAAM,CAAC,MAAM,gBAAgB,GAAuB,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,oFAAoF;AACpF,cAAc,sBAAsB,CAAC;AAErC,OAAO,gBAAgB,MAAM,2BAA2B,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAC/E,OAAO,qBAAqB,MAAM,gCAAgC,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACzF,OAAO,qBAAqB,MAAM,gCAAgC,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAWzF,0EAA0E;AAC1E,6CAA6C;AAE7C,4FAA4F;AAC5F,MAAM,CAAC,MAAM,UAAU,GAAG;IACtB,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9E,MAAM,EAAE,MAAM;CACR,CAAC;AAEX,0FAA0F;AAC1F,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,CAAC;AAQlC,MAAM,CAAC,MAAM,WAAW,GAAG,qBAAqB,CAAC;AACjD,MAAM,CAAC,MAAM,gBAAgB,GAAwB,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;AACrF,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,EAA6B,EAAoB,EAAE,CAAC,OAAO,EAAE,KAAK,QAAQ,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC9J,MAAM,CAAC,MAAM,WAAW,GAAG,CAAiD,SAAY,EAAoD,EAAE,CAC1I,SAAS,IAAI,SAAS,CAAC;AAC3B,6FAA6F;AAC7F,kBAAkB;AAClB,MAAM,CAAC,MAAM,SAAS,GAAG,CAA8C,SAAY,EAA4C,EAAE,CAC7H,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAA6C,CAAC;AAkB5G,2EAA2E;AAC3E,uEAAuE;AACvE,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,CAC3C,qBAAqB,CAAC,IAAyB,CACpB,CAAC;AAEhC,oEAAoE;AACpE,MAAM,CAAC,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,CAC1C,gBAAgB,CAAC,UAAU,CAAC,SAAS,CAAC,IAAiC,CACpC,CAAC;AAExC,wFAAwF;AACxF,MAAM,CAAC,MAAM,WAAW,GAAG,kCAAkC,CAAC;AAE9D,mFAAmF;AACnF,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,MAAM,CAAC,qBAAqB,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;AAEzF,sFAAsF;AACtF,MAAM,CAAC,MAAM,gBAAgB,GAAuB,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plurnk/plurnk-contracts",
3
- "version": "1.20.0",
3
+ "version": "1.21.0",
4
4
  "description": "Canonical PLURNK language contract, schemas, generated types, and runtime-neutral wire contracts",
5
5
  "keywords": [
6
6
  "plurnk",
package/plurnk.md CHANGED
@@ -1,95 +1,81 @@
1
1
  # Plurnk Harness
2
2
 
3
- Pattern Lookup Universal Resource NetworK: find anything by pattern, read it by address, change it by operation.
4
-
5
3
  ## Plurnk OP Syntax
6
4
 
7
- ````OP (path)? <scope|range>? [metadata]? pattern? <!-- aside -->?
5
+ ```OP (path)? <scope|range>? [metadata]? pattern? <!-- aside -->?
8
6
  body?
9
- ````
7
+ ```
10
8
 
11
9
  > [!IMPORTANT]
12
- > YOU MUST use valid Plurnk OPs.
13
-
14
- > [!TIP]
15
- > YOU SHOULD tab offset any example OP you do not intend to execute.
16
-
17
- * `[metadata]`: optional one-line special configuration.
18
- * `<!-- aside -->`: optional terse explanation.
19
- * Parameters and the aside stay on the OP line; the body starts on the next.
10
+ > YOU MUST ONLY use valid Plurnk OPs, with all parameters and the optional terse aside on the fenced OP line.
20
11
 
21
12
  ## Core Plurnk OPs
22
13
 
23
- * NOTE: Reasoning scratchpad for remembering model conclusions, decisions, and facts.
14
+ * NOTE: Reasoning scratchpad for recording conclusions, decisions, and facts.
24
15
  * FIND: List matching paths, or the match locations inside one path.
25
16
  * READ: Read files, entries, streams, or only the lines a pattern selects.
26
17
  * EDIT: Create a file or entry; replace existing text by scope or by pattern.
27
18
  * COPY: (path) <scope>? (path) <scope>? - Copy files, entries, streams, or text regions.
28
19
  * MOVE: (path) <scope>? (path) <scope>? - Move files, entries, streams, or text regions.
29
- * KILL: End things — delete an entry, stop a process, retire log items, or end the loop with final deliverable response.
20
+ * KILL: End things — delete an entry, stop a process, retire log items, or end the loop.
30
21
  * WORK: Deploy a child worker (fresh log).
31
22
  * FORK: Deploy a forked worker (forked log).
32
- * BARE: Deploy an isolated inference query (no log or tools).
23
+ * BARE: Deploy an isolated inference on the fence body (no log or tools).
33
24
  * WAIT: Yield until the next wake: a child worker's result or a stream's end.
34
25
  * SEND: Message endpoints or workers.
35
26
 
36
27
  ## Workflow Management
37
28
 
38
29
  > [!IMPORTANT]
39
- > The loop continues until KILLed with a turn that contains ONLY a parameterless KILL (with optional final deliverable response in body).
40
-
41
- > [!WARNING]
42
- > YOU MAY NOT end the loop with KILL before all other OPs, child workers, and streams are resolved and reviewed.
30
+ > YOU MUST deliver the final response as a turn with ONLY a single parameterless KILL with the response in the body:
43
31
 
44
- ````KILL
45
- The answer is **42**.
46
- ````
47
-
48
- > [!TIP]
49
- > Free text, NOTEs, and other messages are not the final deliverable response.
32
+ ```KILL
33
+ This is an example final deliverable response. It's alone. All child workers and streams are resolved and reviewed.
34
+ ```
50
35
 
51
36
  ## Workspace Navigation
52
37
 
53
- ````FIND (src/**/*.ts) /TODO/ <!-- paths with matches -->
54
- ````
38
+ ```FIND (src/**/*.ts) /TODO/ <!-- paths with matches -->
39
+ ```
55
40
 
56
- ````READ (belfry.md) /\bbats?\b/i <!-- only the lines matching "bat" or "bats" -->
57
- ````
41
+ ```READ (belfry.md) /\bbats?\b/i <!-- only the lines matching "bat" or "bats" -->
42
+ ```
58
43
 
59
- * `(path)` may be a glob, permitting bulk operations.
60
- * Log item paths nest: `log:///1/2/3/READ` is loop/turn/item/operation.
44
+ * `(path)` may be a glob/extglob, permitting bulk operations.
45
+ * Log item paths nest: `log:///1/2/3/READ` is loop/turn/item/OP.
61
46
  * FIND results hold one inner array per path: its channels, default first; append `#channel` to select another.
62
- * Percent-encode `(` as `%28` and `)` as `%29`.
47
+ * Percent-encode in paths `(` as `%28` and `)` as `%29`.
63
48
 
64
49
  ## File Editing
65
50
 
66
- ````EDIT (example.md) <@abcde>
51
+ ```EDIT (example.md) <@abcde>
67
52
  literal replacement text
68
- ````
53
+ ```
69
54
 
70
- ````EDIT (books.xml) //book[price > 35.00] <!-- an empty body removes each match -->
71
- ````
55
+ ```EDIT (books.xml) //book[price > 35.00] <!-- an empty body removes each match -->
56
+ ```
72
57
 
73
- ````42EDIT (edit-example.md) <!-- resolve nested OP conflicts with matching numeric delimiters after fencing -->
74
- ````EDIT (edit-example.md)
75
- OPs always begin and end with exactly four backticks, both immediately after a newline.
58
+ ````EDIT (edit-example.md) <!-- Nesting can be resolved with increased outer fences. Examples can use tabbed offset. -->
59
+ ```EDIT (create-example.md)
60
+ When representing markdown, `~~~` notation can disambiguate nested content.
61
+ ```
76
62
  ````
77
- ````42
78
63
 
79
64
  > [!TIP]
80
65
  > The EDIT body is literal text. YOU SHOULD address lines by `<@hash>` or `<@start,@end>`; stale targets are rejected.
81
66
 
82
- > [!TIP]
83
- > Creating a file creates missing parent directories.
84
-
85
67
  ## Delegation
86
68
 
87
- ````WORK (worker://reviewer) [{"env": {"NODE_ENV": "test"}}] <!-- the child's result lands in your log -->
88
- Review src/ for unhandled promise rejections.
89
- ````
69
+ ```WORK (worker://alice) <!-- the child's result lands in your log -->
70
+ The child's complete task.
71
+ ```
90
72
 
91
- ````KILL (sh:///ab3d5678) <!-- stops a running command -->
92
- ````
73
+ ```BARE
74
+ A self-contained prompt.
75
+ ```
76
+
77
+ ```KILL (sh:///ab3d5678) <!-- stops a running command -->
78
+ ```
93
79
 
94
80
  > [!TIP]
95
81
  > `SEND (worker://name)` messages a live worker.
@@ -99,11 +85,8 @@ Pattern Lookup Universal Resource NetworK: find anything by pattern, read it by
99
85
  > [!CAUTION]
100
86
  > logTokensTotal must not exceed logTokensMax. Successful log KILL receipts are not shown.
101
87
 
102
- ````KILL (log:///1/[1-7]/*/{NOTE,READ}) <!-- removes matching log items, recovering context -->
103
- ````
104
-
105
- ````KILL (log:///**/READ) <17,-1> <!-- trims each item's log lines from 17 on, recovering context -->
106
- ````
88
+ ```KILL (log:///1/[1-7]/*/{NOTE,READ}) <17, -1> <!-- trims matching log items, recovering context -->
89
+ ```
107
90
 
108
91
  ## `<scope|range>`
109
92
 
@@ -117,12 +100,6 @@ Pattern Lookup Universal Resource NetworK: find anything by pattern, read it by
117
100
  | `<SL,SC,EL,EC>` | start included, end excluded — `<2,3,3,6>` is line 2 column 3 through line 3 column 5 |
118
101
  | `<0>`, `<-1>` | prepend / append on mutations; as an end line, `-1` is the last line |
119
102
 
120
- > [!CAUTION]
121
- > The hash anchor and line number (`@abcde 42:`) shown on editable text are not content.
122
-
123
- > [!TIP]
124
- > Log items often present partial preview ranges. READ more if it's relevant and you have the logTokensMax room for it.
125
-
126
103
  ## `pattern`
127
104
 
128
105
  > [!TIP]
@@ -135,4 +112,4 @@ Pattern Lookup Universal Resource NetworK: find anything by pattern, read it by
135
112
  | `$` | jsonpath (RFC 9535) | `$.items[?(@.price>500)]` |
136
113
  | `~` | full-text (SQLite FTS5) | `~retry` |
137
114
  | `&` | graph (treesitter symbols) | `&sym`, `&<sym`, `&>sym` |
138
- | none | literal or extglob | `?(export )?(async )function *` |
115
+ | none | literal or glob/extglob | `?(export )?(async )function *` |