@plurnk/plurnk-contracts 1.10.1 → 1.12.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/README.md +2 -3
- package/SPEC.md +190 -85
- package/dist/conformance/agui-v1.json +5 -5
- package/dist/plurnk.gemma.gbnf +4 -3
- package/dist/plurnk.qwen.gbnf +4 -3
- package/dist/schema/CapabilityDescriptor.json +23 -0
- package/dist/schema/CapabilityPolicy.json +18 -0
- package/dist/schema/CapabilityProjection.json +16 -0
- package/dist/schema/CapabilitySelector.json +24 -0
- package/dist/schema/ClientStatement.json +10 -2
- package/dist/schema/LoopPolicy.json +13 -0
- package/dist/schema/MatcherBody.json +8 -8
- package/dist/schema/ParsedPath.json +1 -11
- package/dist/schema/PlurnkStatement.json +76 -34
- package/dist/schema/ProblemProjection.json +38 -0
- package/dist/schema/ProposalProjection.json +2 -2
- package/dist/schema/ProviderUsage.json +1 -1
- package/dist/schema/ResourceSelection.json +12 -2
- package/dist/src/ApplicationPort.d.ts +9 -40
- package/dist/src/ApplicationPort.d.ts.map +1 -1
- package/dist/src/AstBuilder.d.ts +1 -7
- package/dist/src/AstBuilder.d.ts.map +1 -1
- package/dist/src/AstBuilder.js +127 -102
- package/dist/src/AstBuilder.js.map +1 -1
- package/dist/src/CapabilityAdmission.d.ts +9 -0
- package/dist/src/CapabilityAdmission.d.ts.map +1 -0
- package/dist/src/CapabilityAdmission.js +96 -0
- package/dist/src/CapabilityAdmission.js.map +1 -0
- package/dist/src/PlurnkErrorStrategy.d.ts +1 -0
- package/dist/src/PlurnkErrorStrategy.d.ts.map +1 -1
- package/dist/src/PlurnkErrorStrategy.js +140 -1
- package/dist/src/PlurnkErrorStrategy.js.map +1 -1
- package/dist/src/PlurnkParser.d.ts +4 -1
- package/dist/src/PlurnkParser.d.ts.map +1 -1
- package/dist/src/PlurnkParser.js +151 -22
- package/dist/src/PlurnkParser.js.map +1 -1
- package/dist/src/Problems.d.ts +6 -1
- package/dist/src/Problems.d.ts.map +1 -1
- package/dist/src/Problems.js +34 -0
- package/dist/src/Problems.js.map +1 -1
- package/dist/src/TagSignal.d.ts.map +1 -1
- package/dist/src/TagSignal.js +5 -0
- package/dist/src/TagSignal.js.map +1 -1
- package/dist/src/Validator.d.ts +18 -4
- package/dist/src/Validator.d.ts.map +1 -1
- package/dist/src/Validator.js +69 -10
- package/dist/src/Validator.js.map +1 -1
- package/dist/src/generated/plurnkLexer.d.ts +52 -40
- package/dist/src/generated/plurnkLexer.d.ts.map +1 -1
- package/dist/src/generated/plurnkLexer.js +519 -431
- package/dist/src/generated/plurnkLexer.js.map +1 -1
- package/dist/src/generated/plurnkParser.d.ts +165 -92
- package/dist/src/generated/plurnkParser.d.ts.map +1 -1
- package/dist/src/generated/plurnkParser.js +1336 -722
- package/dist/src/generated/plurnkParser.js.map +1 -1
- package/dist/src/generated/plurnkParserVisitor.d.ts +49 -0
- package/dist/src/generated/plurnkParserVisitor.d.ts.map +1 -1
- package/dist/src/generated/plurnkParserVisitor.js +42 -0
- package/dist/src/generated/plurnkParserVisitor.js.map +1 -1
- package/dist/src/index.d.ts +4 -4
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +3 -3
- package/dist/src/index.js.map +1 -1
- package/dist/src/types.d.ts +9 -2
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/types.generated.d.ts +142 -36
- package/dist/src/types.generated.d.ts.map +1 -1
- package/dist/src/types.js +4 -6
- package/dist/src/types.js.map +1 -1
- package/package.json +2 -2
- package/plurnk.md +68 -61
- package/dist/schema/LoopFlags.json +0 -16
package/README.md
CHANGED
|
@@ -49,12 +49,11 @@ The parser entry points deliberately accept different document tiers:
|
|
|
49
49
|
|
|
50
50
|
| Entry point | Accepted input |
|
|
51
51
|
|--------------------------------|-------------------------------------------------------|
|
|
52
|
-
| `PlurnkParser.parse` | One
|
|
52
|
+
| `PlurnkParser.parse` | One operation-bearing model turn; omitted PLAN/SEND are recovered |
|
|
53
53
|
| `PlurnkParser.parseStatements` | A strict sequence of protocol statements |
|
|
54
|
-
| `PlurnkParser.parseLog` |
|
|
54
|
+
| `PlurnkParser.parseLog` | Strict consecutive PLAN-through-SEND turns |
|
|
55
55
|
| `PlurnkParser.parseClient` | Protocol statements plus client-only LOOK and BUFF |
|
|
56
56
|
| `parsePath` | One path or URI using parser-equivalent decomposition |
|
|
57
|
-
| `parseResourceSelection` | One COPY/MOVE destination and optional text scope |
|
|
58
57
|
|
|
59
58
|
See SPEC {§turn-shape} and {§tier-entrypoints} for the tier boundaries. All
|
|
60
59
|
AST, parse-result, schema-derived, and runtime-neutral wire types are exported
|
package/SPEC.md
CHANGED
|
@@ -9,7 +9,7 @@ is the single code API for those contracts.
|
|
|
9
9
|
| Surface | Canonical export or artifact |
|
|
10
10
|
| ------------------------------------------------------------------------------- | --------------------------------------------------- |
|
|
11
11
|
| Parser, AST, validators, Problems, results, Notices, text regions and extents | `@plurnk/plurnk-contracts` |
|
|
12
|
-
|
|
|
12
|
+
| Capability and loop policies with their defaults | `CapabilityPolicy`, `LoopPolicy`, `DEFAULT_CAPABILITY_POLICY`, `DEFAULT_LOOP_POLICY` |
|
|
13
13
|
| Durable reasoning intent | `ReasoningPolicy`, `REASONING_POLICIES` |
|
|
14
14
|
| Model route and catalog discovery | `ModelRoute`, `ModelCatalogQuery`, `ModelCatalogPage`, `ModelReadiness` |
|
|
15
15
|
| Stopped-world client contract | `ProposalDisposition`, `ProposalProjection` |
|
|
@@ -125,15 +125,45 @@ The schemas own the runtime-neutral shapes; core owns their stateful values.
|
|
|
125
125
|
|
|
126
126
|
| Contract | Shape invariant | Runtime responsibility |
|
|
127
127
|
| ------------------------- | ------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
|
|
128
|
-
| `
|
|
128
|
+
| `CapabilityDescriptor` | One routed operation demand with its operation, access class, resource/runtime/tool coordinates, and declared traits | Derive every demand before dispatch |
|
|
129
|
+
| `CapabilityPolicy` | Exact `only`/`deny` selectors; omitted `only` is unrestricted and present empty `only` denies all | Intersect service, workspace, Worker, and loop layers |
|
|
130
|
+
| `CapabilityProjection` | Exact service, workspace, immutable Worker bound, mutable Worker, and normalized effective policies | Expose the resolver's Worker-level cascade to clients without claiming one layer is effective authority |
|
|
131
|
+
| `LoopPolicy` | Complete capability attenuation plus one `review`, `accept`, or `reject` proposal disposition | Snapshot once when the loop is created |
|
|
129
132
|
| `ProposalDisposition` | Client authority, or the loop's exact automatic accept/reject | Compute precedence from effective loop policy, proposal kind, and stale-target truth |
|
|
130
|
-
| `ProposalProjection` | Identity, `{ scheme, authority, pathname }` review target, body/attrs, effective
|
|
133
|
+
| `ProposalProjection` | Identity, `{ scheme, authority, pathname }` review target, body/attrs, effective policy, stale signal, disposition | Derive one validated projection for live delivery and durable reconnect discovery |
|
|
131
134
|
| `ProviderUsage` | Conventional input/output totals with cache and reasoning details | Preserve observed quantities without replacing absence with zero |
|
|
132
135
|
| `ProviderCost` | Exact charged, estimated, or unknown monetary evidence | Normalize one monetary disposition for each physical provider request |
|
|
133
136
|
| `ProviderRequestAccounting` | Usage and cost evidence for one physical provider request | Preserve request order across retries, failover, success, and failure |
|
|
134
137
|
| `ProviderAccounting` | Ordered requests plus deterministic usage and exact-USD projections | Derive loop, protocol, telemetry, and client reporting without a second authority |
|
|
135
138
|
|
|
136
|
-
|
|
139
|
+
§capability-policy-matching A selector is an exact conjunction: every field it
|
|
140
|
+
declares must equal the descriptor, while every selected `trait` must occur in
|
|
141
|
+
the descriptor's trait set. `deny` wins within a layer. When `only` is present, at
|
|
142
|
+
least one selector must match. An empty policy admits everything and an empty
|
|
143
|
+
`only` list admits nothing.
|
|
144
|
+
|
|
145
|
+
§capability-policy-cascade Capability layers are purely subtractive and
|
|
146
|
+
order-independent: a descriptor is admitted only when every layer admits it.
|
|
147
|
+
No Worker or loop can restore service, workspace, or parent authority. A
|
|
148
|
+
composed operation is admitted only when every routed demand survives. These
|
|
149
|
+
descriptors govern routed external authority, not every grammar statement:
|
|
150
|
+
log/program control such as PLAN, OPEN, FOLD, log KILL, and targetless SEND
|
|
151
|
+
creates no capability demand. A known interactive runtime is represented by
|
|
152
|
+
access class `interact`; scheme and runtime manifests contribute traits rather
|
|
153
|
+
than hidden policy behavior.
|
|
154
|
+
|
|
155
|
+
§capability-policy-projection A `CapabilityProjection` reports every durable
|
|
156
|
+
Worker-level layer and their normalized intersection. The `worker` field is the
|
|
157
|
+
only client-mutable layer; `effective` is the authority a new unattenuated loop
|
|
158
|
+
would receive. A client never derives effective authority from the mutable
|
|
159
|
+
layer alone. Per-loop attenuation remains an immutable input to that loop and
|
|
160
|
+
is therefore absent from this durable Worker projection.
|
|
161
|
+
|
|
162
|
+
§loop-policy `DEFAULT_CAPABILITY_POLICY` and `DEFAULT_LOOP_POLICY` are the
|
|
163
|
+
contracts-owned complete defaults. A loop policy is immutable after creation;
|
|
164
|
+
its `capabilities` field only narrows broader authority and its `proposals`
|
|
165
|
+
field chooses one unambiguous downstream settlement posture. Capability
|
|
166
|
+
admission precedes effect classification and proposal settlement.
|
|
137
167
|
|
|
138
168
|
§reasoning-policy-wire `ReasoningPolicy` is exactly `off | adaptive | low |
|
|
139
169
|
medium | high`. The schema owns this shared wire vocabulary. Providers own the
|
|
@@ -167,11 +197,12 @@ facts; core and client interfaces carry only this standard interaction.
|
|
|
167
197
|
§provider-usage `ProviderUsage` records only known non-negative safe-integer
|
|
168
198
|
quantities. `inputTokens` includes every input category; cache reads and cache
|
|
169
199
|
writes are details within it. `outputTokens` includes reasoning; text and
|
|
170
|
-
reasoning are details within it.
|
|
171
|
-
all three are present
|
|
172
|
-
complete detail partition sums to that total.
|
|
173
|
-
explicit zero is provider evidence or an exact
|
|
174
|
-
components. Consumers never estimate a token
|
|
200
|
+
reasoning are details within it. Within one physical request, `totalTokens`
|
|
201
|
+
equals input plus output whenever all three are present, a detail is no greater
|
|
202
|
+
than its containing total, and a complete detail partition sums to that total.
|
|
203
|
+
An omitted field is unknown; an explicit zero is provider evidence or an exact
|
|
204
|
+
derivation from complete known components. Consumers never estimate a token
|
|
205
|
+
category from text length.
|
|
175
206
|
|
|
176
207
|
§provider-cost `ProviderCost` represents one physical provider request's
|
|
177
208
|
monetary disposition. `charged` preserves a provider-reported canonical decimal
|
|
@@ -189,11 +220,14 @@ capacity failover; a later response never replaces an earlier request.
|
|
|
189
220
|
|
|
190
221
|
§provider-accounting `ProviderAccounting.requests` is the source evidence.
|
|
191
222
|
`usage` and `costUsd` are deterministic projections of that ordered set, not
|
|
192
|
-
independent inputs. Each usage field
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
223
|
+
independent inputs. Each usage field sums the requests that report that exact
|
|
224
|
+
quantity; an unreported quantity is skipped rather than invented as zero or
|
|
225
|
+
allowed to erase known evidence. Detail fields are likewise independent sums,
|
|
226
|
+
so heterogeneous request telemetry never implies a complete aggregate
|
|
227
|
+
partition merely because their reported keys overlap. `costUsd` sums every
|
|
228
|
+
USD-expressible request and is `null` only when none is expressible. The empty
|
|
229
|
+
request set projects explicit zero usage and cost. Consumers do not recompute
|
|
230
|
+
provider rates or convert currencies while reading the projection.
|
|
197
231
|
|
|
198
232
|
The parser returns ordered statement, error, and text items. It recovers at a
|
|
199
233
|
trustworthy statement boundary when possible and sets `unparsedTail` when a
|
|
@@ -305,6 +339,7 @@ under {§plan-value}.
|
|
|
305
339
|
| `delimiter` | Heading lane, joined directly to PLAN or OP |
|
|
306
340
|
| `[signal]` | Optional operation-specific signal, preceded by one space |
|
|
307
341
|
| `(path)` | Optional target slot, preceded by one space |
|
|
342
|
+
| `{metadata}` | Optional repeatable scheme-metadata modifier after a target |
|
|
308
343
|
| `<scope>` | Optional numeric scope, preceded by one space |
|
|
309
344
|
| `<!-- … -->` | Optional trailing operation annotation, preceded by one space |
|
|
310
345
|
| line ending | Ends the single-line heading |
|
|
@@ -318,21 +353,25 @@ The following constraints are structural:
|
|
|
318
353
|
ordinary body text.
|
|
319
354
|
- PLAN is the only H1 operation and every non-PLAN operation is H2.
|
|
320
355
|
- A header occupies one physical line.
|
|
321
|
-
- Each admitted signal, target, and scope slot appears at most once.
|
|
356
|
+
- Each admitted signal, target, and scope slot appears at most once. Metadata
|
|
357
|
+
blocks may repeat only immediately after the target.
|
|
358
|
+
- §plan-slotless PLAN accepts no signal, target, metadata, or scope modifier;
|
|
359
|
+
observed modifiers are a bounded hard error naming only the rejected slots.
|
|
322
360
|
- An annotation follows every present modifier and appears at most once.
|
|
323
361
|
- BARE, WORK, FORK, and KILL do not admit a scope slot.
|
|
324
362
|
- An ingested delimiter is `[A-Za-z0-9_]*`; canonical teaching and the GBNF use `0`.
|
|
325
363
|
|
|
326
364
|
§slot-order Canonical producers and the GBNF rail emit signal, then target, then
|
|
327
|
-
scope, then annotation, with one ASCII space before every present
|
|
365
|
+
metadata, then scope, then annotation, with one ASCII space before every present modifier. Slot delimiters make
|
|
328
366
|
their boundaries unambiguous, so the tolerant ANTLR ingester accepts zero or
|
|
329
367
|
more horizontal whitespace characters before each slot and any permutation of
|
|
330
|
-
the
|
|
331
|
-
|
|
368
|
+
the signal, target-with-metadata, and scope admitted by that operation, at most
|
|
369
|
+
once each. Metadata remains attached immediately after its target. Accepted
|
|
370
|
+
spacing and permutation are not second canonical spellings.
|
|
332
371
|
|
|
333
372
|
§heading-inline-body Text that follows the last slot on a heading line — after
|
|
334
373
|
horizontal whitespace, beginning with a character that cannot open a slot (not `[`,
|
|
335
|
-
`(`, or
|
|
374
|
+
`(`, or `<`, nor `{` after a target) — is the first body line: `## EXEC0 [crm] (crm_query) SELECT Id FROM Case` and
|
|
336
375
|
`## FIND0 (src/**) /createCoder/i` parse as their canonical two-line forms. Nothing is
|
|
337
376
|
lost and the stored statement is canonical; the spelling is tolerated and announced:
|
|
338
377
|
one warning-severity advisory follows the statement, naming the heading and the rule
|
|
@@ -348,14 +387,24 @@ authorization, status, or body. An empty comment normalizes to the empty string.
|
|
|
348
387
|
Text containing a newline or lacking the closing `-->` is not an annotation;
|
|
349
388
|
`<!--` elsewhere remains ordinary body text.
|
|
350
389
|
|
|
390
|
+
§scheme-metadata-modifier A target may be followed by zero or more
|
|
391
|
+
single-line `{metadata}` blocks. AstBuilder preserves each block's exact inner
|
|
392
|
+
text and order as the statement's `metadata: string[] | null`; nested braces
|
|
393
|
+
remain balanced content. The blocks are not part of the target: braces inside
|
|
394
|
+
`(path)` remain ordinary path and glob syntax, including `{PLAN,READ}`. The
|
|
395
|
+
language assigns metadata no meaning. A runtime admits it only for a scheme
|
|
396
|
+
that declares the capability, and that scheme exclusively owns interpretation,
|
|
397
|
+
validation, and authorization. An unfinished block or a newline before its
|
|
398
|
+
closing brace is a structural failure.
|
|
399
|
+
|
|
351
400
|
The ingester also accepts several bounded noncanonical forms so it can explain
|
|
352
401
|
or safely execute understandable input:
|
|
353
402
|
|
|
354
403
|
| Tolerated input | Canonical or runtime disposition |
|
|
355
404
|
|---------------------------------------------------|---------------------------------------------------------------------|
|
|
356
|
-
| Reordered admitted slots | Producers retain signal → target → scope order
|
|
405
|
+
| Reordered admitted slots | Producers retain signal → target → metadata → scope order |
|
|
357
406
|
| Missing target on a generally targeted operation | AST carries `null`; the runtime rejects when the target is required |
|
|
358
|
-
|
|
|
407
|
+
| A non-`0` PLAN lane | Model canon uses lane `0` |
|
|
359
408
|
| KILL annotation body | AST preserves it; model teaching leaves the KILL section empty |
|
|
360
409
|
| Dash-separated or comma-space scope numbers | Producers use adjacent comma-separated numbers |
|
|
361
410
|
| Empty content where semantics require a body | The empty section normalizes null; the operation owner rejects it |
|
|
@@ -368,6 +417,7 @@ or safely execute understandable input:
|
|
|
368
417
|
| `delimiter` | `[A-Za-z0-9_]*`, adjacent to PLAN or OP |
|
|
369
418
|
| `[signal]` | Operation-specific tags, identifier, branch, or integer |
|
|
370
419
|
| `(path)` | Local path or scheme URL target; detailed in §5 |
|
|
420
|
+
| `{metadata}` | Repeatable opaque scheme modifier attached after a target |
|
|
371
421
|
| `<scope>` | One or more signed integers or decimals; detailed in §7 |
|
|
372
422
|
| annotation | Optional trailing `<!-- … -->` descriptive text |
|
|
373
423
|
| `body` | Opaque section text before the next same-lane heading or EOF |
|
|
@@ -383,14 +433,14 @@ governed by {§canonical-statement}; runtime conditions remain explicit below.
|
|
|
383
433
|
| FIND | optional add log tags | required target or glob | optional result range | optional matcher |
|
|
384
434
|
| READ | optional add log tags | required target | optional text region | empty |
|
|
385
435
|
| EDIT | optional add log tags | required file or entry | required for an existing target | literal text |
|
|
386
|
-
| COPY | optional add log tags | required source
|
|
387
|
-
| MOVE | optional add log tags | required source
|
|
436
|
+
| COPY | optional add log tags | required source and destination | optional region after each path | empty |
|
|
437
|
+
| MOVE | optional add log tags | required source and destination | optional region after each path | empty |
|
|
388
438
|
| FOLD | optional filter/change tags | optional log selection | optional log-body line scope | optional matcher |
|
|
389
439
|
| OPEN | optional filter/change tags | optional log selection | optional log-body line scope | optional matcher |
|
|
390
440
|
| EXEC | optional executor | optional local working path | optional timeout, poll | optional executor input |
|
|
391
441
|
| BARE | optional add log tags | none | none | required prompt |
|
|
392
|
-
| WORK | optional Git branch
|
|
393
|
-
| FORK | optional Git branch
|
|
442
|
+
| WORK | optional Git branch (refused unless the service enables branch delegation) | required fresh `worker://name` | none | required prompt |
|
|
443
|
+
| FORK | optional Git branch (refused unless the service enables branch delegation) | required context-inheriting `worker://name` | none | required prompt |
|
|
394
444
|
| KILL | optional target-specific code | required target, including a log item | none | empty |
|
|
395
445
|
| SEND | optional target-specific code | optional recipient | optional timeout, poll | message; terminal is nonempty |
|
|
396
446
|
|
|
@@ -400,10 +450,10 @@ Directed SEND and KILL delegate any present code to the addressed target's
|
|
|
400
450
|
operation contract; a live process may interpret a KILL code as a Unix signal,
|
|
401
451
|
but that interpretation does not define KILL generally.
|
|
402
452
|
|
|
403
|
-
§plan-value **PLAN carries one
|
|
404
|
-
|
|
405
|
-
actions are `completed`, open
|
|
406
|
-
`in_progress`. Admission parses the JSON body — one JSON array document in any whitespace layout, including the {§json-result-rendering} spread the log projects — strips unknown
|
|
453
|
+
§plan-value **PLAN carries one installment of the model's running work journal.**
|
|
454
|
+
Its entries record newly made working-memory items: durable findings and decisions
|
|
455
|
+
are `memory`, finished actions are `completed`, open work is `pending`, and active
|
|
456
|
+
priorities are `in_progress`. Admission parses the JSON body — one JSON array document in any whitespace layout, including the {§json-result-rendering} spread the log projects — strips unknown
|
|
407
457
|
entry keys (the model-facing Plan carries no priority: struck 2026-08-24 so the
|
|
408
458
|
log echoes only the canonical shape, starving stale-field habits), and validates
|
|
409
459
|
the canonical bare array: every entry has string `content` and `status` in
|
|
@@ -411,10 +461,11 @@ the canonical bare array: every entry has string `content` and `status` in
|
|
|
411
461
|
malformed-JSON, or otherwise invalid body becomes one `in_progress`
|
|
412
462
|
entry whose content is the exact authored body; admission performs no partial
|
|
413
463
|
repair or list inference. An empty body becomes the planless `[]`
|
|
414
|
-
value. Each PLAN
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
log bodies, and model-packet
|
|
464
|
+
value. Each PLAN is the complete semantic value of that journal installment;
|
|
465
|
+
prior installments remain ordinary curatable log items. The exact `turnOps`
|
|
466
|
+
source remains forensic program evidence, while the normalized array is the sole
|
|
467
|
+
semantic value used by AST, persistence, durable log bodies, and model-packet
|
|
468
|
+
materialization. PLAN is public log content—not
|
|
418
469
|
provider reasoning—and Plurnk initially mints no `_meta` values. Dispatch records
|
|
419
470
|
the canonical value and has no other runtime effect.
|
|
420
471
|
|
|
@@ -432,7 +483,7 @@ commit `272bf799f35a258c6a4107a0410ed361e83683d3`.
|
|
|
432
483
|
|
|
433
484
|
§exec-tag-signal EXEC's bracket slot names its runtime. A bracket whose first character is
|
|
434
485
|
a sign is a tag signal instead — a runtime never starts with `+` or `-` — so
|
|
435
|
-
`## EXEC0 [+fetch]
|
|
486
|
+
`## EXEC0 [+fetch]` and `## EXEC0 [crm] [+schema] (crm_describe)` admit: the tags
|
|
436
487
|
classify the log row exactly as on FIND or READ, the runtime is the explicit one or the
|
|
437
488
|
default shell, and each slot appears at most once.
|
|
438
489
|
|
|
@@ -498,7 +549,7 @@ Mutation semantics:
|
|
|
498
549
|
- An empty body deletes the selected text.
|
|
499
550
|
- `<0>` prepends and `<-1>` appends.
|
|
500
551
|
- `<SL,SC,EL,EC>` deletes the exact exclusive-end region and inserts the body at its start.
|
|
501
|
-
- §
|
|
552
|
+
- §transfer-resource-selections COPY and MOVE require two singular `ResourceSelection` operands on the heading, source first and destination second, and admit no body. Each operand consists of `(path)`, any following `{metadata}`, and an optional following `<scope>`; modifiers bind only to the immediately preceding path. The two operands independently select their resource, channel, scheme metadata, and text region.
|
|
502
553
|
|
|
503
554
|
### §operation-observation Per-operation observations
|
|
504
555
|
|
|
@@ -549,7 +600,6 @@ and path globs share the slot; content matchers belong in the body.
|
|
|
549
600
|
| `scheme://…` | WHATWG-decomposed `UrlPath` | Resolves only when a runtime scheme owns the address |
|
|
550
601
|
| Path glob | Preserved in either path kind | Scheme defines collection selection and ordering |
|
|
551
602
|
| `#channel` fragment | Preserved as `UrlPath.fragment` | Selects a named channel when the scheme supports it |
|
|
552
|
-
| Trailing `{key: value}` | Removed before URL parsing and preserved as ordered `headers` pairs | Addressed scheme interprets request metadata |
|
|
553
603
|
| `?query` | Preserved as ordered `UrlPath.query`; `null` = absent, `""` = `?` | Participates in scheme resource identity |
|
|
554
604
|
|
|
555
605
|
AstBuilder recognizes a URL with the case-insensitive prefix
|
|
@@ -591,15 +641,6 @@ never target content. Glob metacharacters remain legal path data.
|
|
|
591
641
|
|
|
592
642
|
Matching and folder-scope semantics remain runtime concerns.
|
|
593
643
|
|
|
594
|
-
§path-request-metadata A scheme URL may append one or more
|
|
595
|
-
`{key: value}` request-metadata blocks. AstBuilder removes the blocks before
|
|
596
|
-
WHATWG decomposition and preserves them as ordered pairs so order and duplicate
|
|
597
|
-
names survive. Local paths retain braces as ordinary path text. Scheme handlers,
|
|
598
|
-
not the language parser, define the meaning and authorization of the metadata.
|
|
599
|
-
The admitted AST retains exact values for execution; malformed-metadata visitor
|
|
600
|
-
diagnostics identify only the structural fault and source position, never quote
|
|
601
|
-
metadata contents or a native URL parser's input-bearing diagnostic.
|
|
602
|
-
|
|
603
644
|
§worker-name The exported `WORKER_NAME` contract governs names minted for URI
|
|
604
645
|
authority slots: a lowercase DNS label matching
|
|
605
646
|
`[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?`. `RESERVED_AUTHORITIES` contains the
|
|
@@ -611,26 +652,49 @@ ingestion restriction: the parser decomposes arbitrary URL authorities.
|
|
|
611
652
|
|
|
612
653
|
## §matcher-prefix-claims 6. Bulk pattern matching
|
|
613
654
|
|
|
614
|
-
FIND, OPEN, FOLD, and
|
|
615
|
-
preserves the body opaquely; AstBuilder assigns the dialect from its
|
|
616
|
-
characters, then normalizes matcher-bearing READ to FIND under
|
|
655
|
+
FIND, authored READ, OPEN, FOLD, LOOK, and BUFF accept an optional body matcher.
|
|
656
|
+
The lexer preserves the body opaquely; AstBuilder assigns the dialect from its
|
|
657
|
+
leading characters, then normalizes matcher-bearing READ to FIND under
|
|
617
658
|
{§read-find-normalization}.
|
|
618
659
|
A leading prefix claims its dialect. Invalid claimed syntax is a positioned
|
|
619
660
|
visitor error and never falls back to glob matching.
|
|
620
661
|
|
|
662
|
+
- §heading-boundary-recovery A column-0 heading is the trustworthy boundary. After a
|
|
663
|
+
statement-level error the parser discards the rest of that statement and resumes at the
|
|
664
|
+
next heading; the turn shape is decided locally (a terminal SEND is recognized by its own
|
|
665
|
+
disposition signal, never by a whole-turn alternative), so one malformed heading costs one
|
|
666
|
+
diagnostic and every later statement, the terminal SEND included, stands on its own. Any
|
|
667
|
+
other second path slot names the one-slot rule.
|
|
668
|
+
- §scope-slot-tolerance A line scope written inside a path slot (`## COPY0 (worker:///src.md<2,3>)`)
|
|
669
|
+
is read as `(worker:///src.md) <2,3>` — `<` and `>` are not URI characters, so a `<…>` right
|
|
670
|
+
before a slot's closing paren can only be a scope; every path slot of a statement is repaired
|
|
671
|
+
the same way — and the slip is one warning-severity advisory at the `<`, placed right after its
|
|
672
|
+
statement, stating the `(path) <scope>` form that was used. The statement runs; a warning is
|
|
673
|
+
never a strike. A `<` anywhere else in the slot remains the lexer's refusal.
|
|
674
|
+
- §tag-slot-tolerance A tag written as a path ahead of the real path (`## READ0 (+diff) (a.ts)`)
|
|
675
|
+
is read as `[+diff] (a.ts)` — the rewrite keeps the heading's length, so every later position
|
|
676
|
+
stays true — and the slip is one error-severity diagnostic at the first paren, placed right
|
|
677
|
+
after its statement, stating the `[+diff]` correction and that it was used. The statement
|
|
678
|
+
runs with the tag. A heading that already carries a signal is not rewritten: its second path
|
|
679
|
+
slot is blamed at the first paren and the statement is dropped.
|
|
680
|
+
|
|
621
681
|
| Prefix | Dialect | Canonical body | Typed admission | Runtime owner |
|
|
622
682
|
|-----------|----------|--------------------------------------|-----------------------------------|---------------------|
|
|
623
683
|
| `//` | XPath | `//selector` | XPath 1.0 `xpath.parse()` | Mimetype projection |
|
|
624
684
|
| `/` | Regex | `/pattern/flags` | ECMAScript `RegExp` construction | Mimetype projection |
|
|
625
685
|
| `$` | JSONPath | RFC 9535 expression | `json-p3` compilation | Mimetype projection |
|
|
626
686
|
| `~` | Semantic | `~phrase` | Any text after the prefix | Embedding index |
|
|
627
|
-
|
|
|
628
|
-
| none | Glob | Shell glob or literal text |
|
|
687
|
+
| `&` | Graph | `&symbol`, `&<symbol`, or `&>symbol` | Exact shape validation | Symbol index |
|
|
688
|
+
| none | Glob | Shell glob or literal text | Single-line raw string | Mimetype projection |
|
|
629
689
|
|
|
630
690
|
XPath is classified before regex because its prefix is two slashes. Regex
|
|
631
691
|
splitting respects escapes and character classes; `\/` represents a literal
|
|
632
692
|
slash. The AST stores regex `pattern` and `flags`, not a compiled object.
|
|
633
|
-
Semantic
|
|
693
|
+
Semantic matchers require no parse step. Graph admission validates its direction
|
|
694
|
+
and non-whitespace symbol before runtime. Every other leading character remains
|
|
695
|
+
in the fallback glob/literal dialect; `@(...)` is therefore an extglob group and
|
|
696
|
+
bare `@text` remains literal matcher text. Rendered READ coordinates are
|
|
697
|
+
structural output rows, not a reserved matcher prefix. Scope carries semantic
|
|
634
698
|
threshold and result-range information rather than changing the matcher body.
|
|
635
699
|
|
|
636
700
|
AstBuilder validation is compile-only and never evaluates a document. Matcher
|
|
@@ -638,11 +702,10 @@ evaluation belongs to the runtime's selected mimetype, embedding, or symbol
|
|
|
638
702
|
implementation. A matcher admission error is local to its statement; later
|
|
639
703
|
statements remain recoverable when their boundaries are trustworthy.
|
|
640
704
|
|
|
641
|
-
- §pattern-body-single-line
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
specific implicit close rule.
|
|
705
|
+
- §pattern-body-single-line Every matcher body is one physical line. AstBuilder
|
|
706
|
+
rejects multiline bodies before dialect classification, while GBNF excludes
|
|
707
|
+
line terminators. A regex that matches a newline uses the two-character `\n`
|
|
708
|
+
escape. Non-matcher operation bodies remain multiline.
|
|
646
709
|
- §pattern-body-leading-colon The GBNF rail forbids `:` as the first matcher
|
|
647
710
|
character. Empty matchers and later colons remain valid; a regex such as
|
|
648
711
|
`/^:needle/` expresses a pattern beginning with a literal colon.
|
|
@@ -665,7 +728,7 @@ The operation column names the canonical AST operation after
|
|
|
665
728
|
| COPY/MOVE source | 0/1/2/4 text coordinates | Region copied or moved from the selected source |
|
|
666
729
|
| COPY/MOVE destination | 0/1/2/4 text coordinates after target | Region replaced or insertion point at the destination |
|
|
667
730
|
| OPEN / FOLD | 0/1/2 body-relative line coordinates | Whole log body when absent; one physical line or inclusive range when present |
|
|
668
|
-
| EXEC | `timeout[,poll]` | Spawn lifetime bound and poll cadence in
|
|
731
|
+
| EXEC | `timeout[,poll]` | Spawn lifetime bound and poll cadence in minutes |
|
|
669
732
|
| Terminal SEND `[202]` | `timeout[,poll]` | Bounded or indefinite wait and optional poll cadence |
|
|
670
733
|
|
|
671
734
|
Text coordinates use the algebra in {§text-scope-semantics}: one integer is a
|
|
@@ -775,7 +838,7 @@ disposition. The shape rules ARE structural:
|
|
|
775
838
|
non-disposition code, targeted or pathless, empty body allowed.
|
|
776
839
|
- §terminal-body-nonempty The GBNF rail requires a non-empty terminal SEND body — a constrained
|
|
777
840
|
turn cannot end empty-handed. ANTLR remains tolerant during ingestion.
|
|
778
|
-
- §park-202-only The **park** rides `[202]` only: `<T>` (wait up to T
|
|
841
|
+
- §park-202-only The **park** rides `[202]` only: `<T>` (wait up to T minutes),
|
|
779
842
|
`<T,P>` (adds a poll cadence, mirroring EXEC's slot), `<-1>`
|
|
780
843
|
(indefinite; the join's own liveness bounds it). See §7 for the
|
|
781
844
|
GBNF-strict / ANTLR-tolerant split.
|
|
@@ -817,6 +880,9 @@ stateDiagram-v2
|
|
|
817
880
|
SLOTS --> TARGET: target opener
|
|
818
881
|
TARGET --> TARGET: balanced literals / target escapes
|
|
819
882
|
TARGET --> SLOTS: target close at depth zero
|
|
883
|
+
SLOTS --> METADATA: metadata opener after target
|
|
884
|
+
METADATA --> METADATA: balanced inner braces
|
|
885
|
+
METADATA --> SLOTS: metadata close at depth zero
|
|
820
886
|
SLOTS --> SLOTS: scope token
|
|
821
887
|
SLOTS --> SLOTS: trailing annotation
|
|
822
888
|
SLOTS --> BODY: heading line end
|
|
@@ -826,8 +892,9 @@ stateDiagram-v2
|
|
|
826
892
|
|
|
827
893
|
The first H1 PLAN establishes the turn lane. DEFAULT recognizes only an H1
|
|
828
894
|
PLAN or H2 minted operation carrying that exact lane. SLOTS admits
|
|
829
|
-
operation-appropriate signal, target, and scope openers in any
|
|
830
|
-
by an optional annotation; the parser grammar enforces
|
|
895
|
+
operation-appropriate signal, target-with-metadata, and scope openers in any
|
|
896
|
+
order, followed by an optional annotation; the parser grammar enforces
|
|
897
|
+
at-most-once slot multiplicity and keeps repeatable metadata attached to its target.
|
|
831
898
|
Signal submodes select tags, integer,
|
|
832
899
|
or identifier tokens by operation family. TARGET preserves balanced inner
|
|
833
900
|
parentheses and recognized target escapes. BODY emits opaque text until a
|
|
@@ -840,7 +907,7 @@ provider reasoning cannot become the turn anchor.
|
|
|
840
907
|
|
|
841
908
|
RecordingListener captures lexer and parser failures; AstBuilder adds visitor
|
|
842
909
|
failures. PlurnkErrorStrategy recovers at structural heading boundaries where
|
|
843
|
-
possible. EOF is a valid body boundary. An unfinished signal or
|
|
910
|
+
possible. EOF is a valid body boundary. An unfinished signal, target, or metadata block produces
|
|
844
911
|
`unparsedTail`; no later input is trustworthy.
|
|
845
912
|
|
|
846
913
|
## §whitespace-contract 11. Whitespace and interstatement text
|
|
@@ -849,9 +916,10 @@ possible. EOF is a valid body boundary. An unfinished signal or target produces
|
|
|
849
916
|
|-----------------------------|---------------------------------------|-----------------------------------------------------------|
|
|
850
917
|
| Heading marker | `# PLAN0` or `## OP0` at column zero | The initial PLAN may directly follow leading TEXT; subsequent headings retain exact depth and column |
|
|
851
918
|
| Between OP and delimiter | Adjacent | Must remain adjacent |
|
|
852
|
-
| Before each
|
|
919
|
+
| Before each modifier | One ASCII space | Zero or more horizontal whitespace characters |
|
|
853
920
|
| Inside signal | Adjacent values | Horizontal whitespace is ignored; newline is invalid |
|
|
854
921
|
| Inside target | Path alias plus target escapes | Balanced literals tolerated; newline is invalid |
|
|
922
|
+
| Inside scheme metadata | Scheme-defined single-line content | Balanced braces tolerated; newline is invalid |
|
|
855
923
|
| Inside scope | Comma-separated numbers | Dash separator and one post-comma space are also accepted |
|
|
856
924
|
| Before annotation | One ASCII space | Zero or more horizontal whitespace characters |
|
|
857
925
|
| Inside annotation | One-line prose padded by one space | Any single-line text through the first closing `-->` |
|
|
@@ -878,25 +946,33 @@ and wire types come from generated schemas; the small hand-maintained parser
|
|
|
878
946
|
types cover ordered parse items and `PlurnkParseError`, which JSON Schema cannot
|
|
879
947
|
express. Consumers never receive ANTLR parse-tree or token types.
|
|
880
948
|
|
|
881
|
-
§turn-shape `PlurnkParser.parse` accepts exactly one model turn
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
949
|
+
§turn-shape `PlurnkParser.parse` accepts exactly one model turn containing at
|
|
950
|
+
least one parsed source operation. Canonical generation begins with H1 PLAN,
|
|
951
|
+
ends with a disposition-coded H2 SEND, and never repeats PLAN mid-turn. When no
|
|
952
|
+
valid leading PLAN was parsed, the parser prepends an empty PLAN; when no valid
|
|
953
|
+
terminal SEND was parsed, it appends a bodyless `SEND [102]`. Either default
|
|
954
|
+
carries {§parser-position} `UNKNOWN_POSITION` and one exact hard diagnostic
|
|
955
|
+
stating the observed boundary failure and applied default. The source text
|
|
956
|
+
remains unchanged.
|
|
957
|
+
An authored terminal SEND still ends the source turn: a same-lane operation or
|
|
958
|
+
other hard error after it is outside the trustworthy boundary. Tolerated TEXT
|
|
959
|
+
may appear only before the first operation; after that point, nonstructural text
|
|
960
|
+
is section body content. `parseLog` remains strict canonical PLAN-through-SEND
|
|
961
|
+
input, and GBNF remains strict canonical generation.
|
|
886
962
|
|
|
887
963
|
§document-fence `PlurnkParser.parse` additionally admits one outer Markdown code
|
|
888
964
|
fence whose opening line is exactly ```` ```plurnk ```` and whose closing line,
|
|
889
965
|
when present, is ```` ``` ````. The fence encloses the complete
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
966
|
+
model turn and projects neither text nor body content into the AST. Its opener
|
|
967
|
+
commits the document to either that closer or EOF immediately after the turn.
|
|
968
|
+
This is document framing, not another statement grammar, and
|
|
893
969
|
no other parser tier admits it. GBNF continues to shape the paired form.
|
|
894
970
|
|
|
895
971
|
§tier-entrypoints Each parser entry point owns one document tier:
|
|
896
972
|
|
|
897
973
|
| Entry point | Accepted document | Result statement type |
|
|
898
974
|
|--------------------------------|----------------------------------------------------------------|-----------------------|
|
|
899
|
-
| `PlurnkParser.parse` | One
|
|
975
|
+
| `PlurnkParser.parse` | One operation-bearing model turn, bare with optional TEXT or inside one outer `plurnk` fence; omitted PLAN/SEND recover to defaults | `PlurnkStatement` |
|
|
900
976
|
| `PlurnkParser.parseStatements` | Zero or more protocol statements and hidden whitespace | `PlurnkStatement` |
|
|
901
977
|
| `PlurnkParser.parseLog` | One or more consecutive same-lane PLAN-anchored turns | `PlurnkStatement` |
|
|
902
978
|
| `PlurnkParser.parseClient` | H2 protocol statements plus read-shaped LOOK/BUFF commands | `ClientStatement` |
|
|
@@ -913,15 +989,16 @@ following supported consumer values. All other root exports are TypeScript types
|
|
|
913
989
|
|---------------------------------------|---------------------------------------------------------------------|---------------------------------------------|
|
|
914
990
|
| `PlurnkParser` | Four document-tier entry points listed above | {§parser-architecture}, {§tier-entrypoints} |
|
|
915
991
|
| `PlurnkParseError` | JSON-serializable positioned parser diagnostic | {§parse-diagnostics} |
|
|
916
|
-
| `parsePath
|
|
992
|
+
| `parsePath` | Parser-equivalent target admission | {§path-syntax}, {§tier-entrypoints} |
|
|
917
993
|
| `PathSyntax` | Target-slot spelling and exact-versus-glob classification | {§path-parentheses}, {§path-glob} |
|
|
918
994
|
| `Validator` | Validation and assertion against the owning JSON Schemas | {§wire-entrypoint} |
|
|
919
995
|
| `InvalidNoticeError` | Typed failure from `Validator.assertNotice` | {§notice} |
|
|
920
996
|
| `InvalidProblemDetailsError` | Typed failure from `Validator.assertProblemDetails` | {§problem-details} |
|
|
997
|
+
| `InvalidProblemProjectionError` | Typed failure from `Validator.assertProblemProjection` | {§problem-projection} |
|
|
921
998
|
| `InvalidOperationResultError` | Typed failure from `Validator.assertOperationResult` | {§operation-result} |
|
|
922
999
|
| `InvalidTextRegionError` | Typed failure from `Validator.assertTextRegion` | {§text-region} |
|
|
923
1000
|
| `InvalidRangeExtentError` | Typed failure from `Validator.assertRangeExtent` | {§range-extent} |
|
|
924
|
-
| `Problems` | RFC 9457 Problem construction
|
|
1001
|
+
| `Problems` | RFC 9457 Problem construction and model projection | {§problem-details}, {§problem-projection} |
|
|
925
1002
|
| `PLURNK_OPS` | Runtime tuple from which the closed `PlurnkOp` union is derived | {§canonical-statement} |
|
|
926
1003
|
| `WORKER_NAME`, `RESERVED_AUTHORITIES` | Authority minting predicate and internal reserved names | {§worker-name} |
|
|
927
1004
|
| `UNKNOWN_POSITION` | Frozen sentinel for an AST statement without retained parsed source | {§parser-position} |
|
|
@@ -931,7 +1008,7 @@ than alternate consumer entry points:
|
|
|
931
1008
|
|
|
932
1009
|
| Internal component | Boundary |
|
|
933
1010
|
|--------------------------------------------|---------------------------------------------------------------------------------------------------------------|
|
|
934
|
-
| `AstBuilder` | Consumes generated ANTLR contexts; `PlurnkParser
|
|
1011
|
+
| `AstBuilder` | Consumes generated ANTLR contexts; `PlurnkParser` and `parsePath` own its API |
|
|
935
1012
|
| `PlurnkErrorStrategy`, `RecordingListener` | Assemble parser recovery and diagnostics around `antlr4ng`; consumers receive `PlurnkParseError` values |
|
|
936
1013
|
| `Jsonplurnk` test helper | Independently checks the Core-owned {§jsonplurnk} renderer corpus; it is neither shipped code nor a root API |
|
|
937
1014
|
|
|
@@ -1063,6 +1140,20 @@ Internal invariant violations throw and preserve their cause. An external
|
|
|
1063
1140
|
protocol may require its own error envelope; its adapter maps that envelope to
|
|
1064
1141
|
or from the canonical Problem without creating another PLURNK failure contract.
|
|
1065
1142
|
|
|
1143
|
+
§problem-projection `ProblemProjection` is the sole compact model-packet view of
|
|
1144
|
+
an exact `ProblemDetails`. `Problems.project(problem, context)` validates both
|
|
1145
|
+
representations and rejects a status that contradicts the enclosing row.
|
|
1146
|
+
|
|
1147
|
+
| Projection member | Contract |
|
|
1148
|
+
|-------------------|----------|
|
|
1149
|
+
| `type`, `detail` | Always retained; together they identify the stable class and occurrence-specific cause |
|
|
1150
|
+
| `stage`, `recovery`, `retryable`, extensions | Retained only when present and not exactly duplicated by the enclosing row |
|
|
1151
|
+
| `title`, `status`, `instance` | Forbidden; the exact Problem owns stable title and occurrence identity while the enclosing packet row already owns model-facing status and address |
|
|
1152
|
+
|
|
1153
|
+
Projection never mutates or replaces the exact Problem. Durable storage,
|
|
1154
|
+
external protocols, clients, and forensic artifacts continue to receive the
|
|
1155
|
+
complete RFC 9457 object.
|
|
1156
|
+
|
|
1066
1157
|
### 13.6 Notices
|
|
1067
1158
|
|
|
1068
1159
|
§notice A `Notice` is a transient, nonterminal observation. It cannot determine durable
|
|
@@ -1214,9 +1305,12 @@ and 3.30.2](https://docs.oasis-open.org/sarif/sarif/v2.1.0/sarif-v2.1.0.html).
|
|
|
1214
1305
|
`severity` distinguishes a hard error from a non-fatal advisory. The parser is
|
|
1215
1306
|
the sole and complete owner of syntax-error messaging because it holds the
|
|
1216
1307
|
parse state, lexer mode, and expected-token set that no consumer has. It
|
|
1217
|
-
produces the final diagnostic message, deduplicated expected-token lists,
|
|
1218
|
-
turn-shape
|
|
1219
|
-
|
|
1308
|
+
produces the final diagnostic message, deduplicated expected-token lists, and
|
|
1309
|
+
turn-shape diagnostics. No valid leading PLAN yields ``No valid leading PLAN
|
|
1310
|
+
was parsed; an empty `# PLAN0` was used.``; no valid terminal SEND yields ``No
|
|
1311
|
+
valid terminal SEND was parsed; `## SEND0 [102]` was used.``; source with no
|
|
1312
|
+
parsed operation yields `no valid Plurnk operation was found.` Targeted
|
|
1313
|
+
diagnostics are:
|
|
1220
1314
|
|
|
1221
1315
|
- §signal-scope-redirect **EXEC scope in the signal slot.** When EXEC's
|
|
1222
1316
|
`[signal]` slot (executor-ident mode) hits a leading `-` or digit —
|
|
@@ -1225,17 +1319,21 @@ turn-shape imperatives (begin with `# PLAN0`, end with a terminal
|
|
|
1225
1319
|
`## EXEC0 <-1,300>`” instead of a raw `unrecognized character`. The redirect is
|
|
1226
1320
|
EXEC-scoped because its signal mode is exclusive; SEND/KILL are untouched.
|
|
1227
1321
|
- §matcher-body-redirect **Matcher body in the slot region.** When the
|
|
1228
|
-
post-target
|
|
1322
|
+
post-target modifier region begins with `$`, `~`, or `@` with no whitespace
|
|
1229
1323
|
before it, the lexer redirects the unambiguous matcher to body content below the
|
|
1230
1324
|
OP heading instead of returning the generic slot list (after whitespace it is
|
|
1231
1325
|
already the inline body, {§heading-inline-body}). Slash-led regex and XPath are
|
|
1232
1326
|
excluded because `/` can be target data.
|
|
1327
|
+
- §bare-target-redirect **A `(target)` on BARE.** BARE takes no `(path)`; a model that
|
|
1328
|
+
writes its prompt, or the prompt's address, into a parenthesized slot (`## BARE0
|
|
1329
|
+
(What day is it?)`, `## BARE0 (prompt:///1/1)`) is told that the prompt is the body
|
|
1330
|
+
line beneath the heading, with the heading's own opener, instead of the generic
|
|
1331
|
+
slot list. Two operator sessions on 2026-08-26 produced exactly these shapes.
|
|
1233
1332
|
- §combined-anchor-line-redirect **Combined anchor and line number in a scope.**
|
|
1234
1333
|
A text-coordinate scope containing `@hash:L` or `@hash L` is one bounded hard
|
|
1235
1334
|
error: `a scope position accepts one line coordinate; use the \`@hash\` anchor
|
|
1236
1335
|
without its displayed line number`. A malformed header scope is consumed as
|
|
1237
|
-
one token
|
|
1238
|
-
boundary; neither produces a punctuation cascade.
|
|
1336
|
+
one token at either COPY/MOVE operand; neither produces a punctuation cascade.
|
|
1239
1337
|
- §misplaced-target-advisory **Mutation target in the signal slot.** When a
|
|
1240
1338
|
mutating op (EDIT/COPY/MOVE) parses with a null `(target)` and a path-shaped
|
|
1241
1339
|
`[signal]` element (a `/` or a dotted extension), the message redirects the
|
|
@@ -1243,15 +1341,22 @@ turn-shape imperatives (begin with `# PLAN0`, end with a terminal
|
|
|
1243
1341
|
\`[…]\` tag slot; a target goes in \`(…)\`. Try \`## EDIT0 (path)\``). It is
|
|
1244
1342
|
gated on a path-shaped signal so a genuine additive-tag signal is not mis-steered
|
|
1245
1343
|
toward a path it lacks.
|
|
1344
|
+
- §matcher-in-signal-slot **Matcher in the signal slot.** A tag term whose name
|
|
1345
|
+
begins with a matcher prefix (`/`, `$`, `~`, `&`) is never a tag: `## FIND0
|
|
1346
|
+
[/require/] (**.go)` used to apply a folksonomic tag named `/require/` and
|
|
1347
|
+
return unsearched rows. The canonicalizer refuses the term, so the builder
|
|
1348
|
+
raises one heading-positioned error naming the body rule (`` `[/require/]` is not
|
|
1349
|
+
a tag - a matcher belongs in the body beneath the heading; `[+tag]` adds,
|
|
1350
|
+
`[tag]` filters ``); the statement drops and its siblings run. Matcher
|
|
1351
|
+
characters inside a name (`slash/inside`) stay legal.
|
|
1246
1352
|
- §misplaced-annotation-advisory **Annotation in the body.** A READ or FIND whose
|
|
1247
1353
|
body is solely an HTML comment (`<!-- … -->`) can never carry a matcher: it is
|
|
1248
1354
|
the annotation the model put on the line below the heading. The builder takes
|
|
1249
1355
|
the comment as the annotation when the heading has none, builds the operation
|
|
1250
|
-
with no body, and raises one warning-severity advisory
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
matcher, as before.
|
|
1356
|
+
with no body, and raises one warning-severity advisory stating that observed
|
|
1357
|
+
normalization; the parser places the advisory right after its statement and
|
|
1358
|
+
the service delivers it as a `parse_advisory` notice with its position. A body
|
|
1359
|
+
with any other content is a matcher, as before.
|
|
1255
1360
|
|
|
1256
1361
|
§error-shape The diagnostic class determines how much guidance the parser may
|
|
1257
1362
|
provide:
|