@plurnk/plurnk-contracts 1.10.0 → 1.11.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 +149 -75
- 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/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.map +1 -1
- package/dist/src/PlurnkErrorStrategy.js +51 -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 +86 -21
- 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/Validator.d.ts +17 -4
- package/dist/src/Validator.d.ts.map +1 -1
- package/dist/src/Validator.js +65 -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 +166 -92
- package/dist/src/generated/plurnkParser.d.ts.map +1 -1
- package/dist/src/generated/plurnkParser.js +1318 -705
- 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 +3 -2
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/types.generated.d.ts +140 -34
- 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 +58 -44
- 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
|
|
@@ -305,6 +335,7 @@ under {§plan-value}.
|
|
|
305
335
|
| `delimiter` | Heading lane, joined directly to PLAN or OP |
|
|
306
336
|
| `[signal]` | Optional operation-specific signal, preceded by one space |
|
|
307
337
|
| `(path)` | Optional target slot, preceded by one space |
|
|
338
|
+
| `{metadata}` | Optional repeatable scheme-metadata modifier after a target |
|
|
308
339
|
| `<scope>` | Optional numeric scope, preceded by one space |
|
|
309
340
|
| `<!-- … -->` | Optional trailing operation annotation, preceded by one space |
|
|
310
341
|
| line ending | Ends the single-line heading |
|
|
@@ -318,21 +349,25 @@ The following constraints are structural:
|
|
|
318
349
|
ordinary body text.
|
|
319
350
|
- PLAN is the only H1 operation and every non-PLAN operation is H2.
|
|
320
351
|
- A header occupies one physical line.
|
|
321
|
-
- Each admitted signal, target, and scope slot appears at most once.
|
|
352
|
+
- Each admitted signal, target, and scope slot appears at most once. Metadata
|
|
353
|
+
blocks may repeat only immediately after the target.
|
|
354
|
+
- §plan-slotless PLAN accepts no signal, target, metadata, or scope modifier;
|
|
355
|
+
observed modifiers are a bounded hard error naming only the rejected slots.
|
|
322
356
|
- An annotation follows every present modifier and appears at most once.
|
|
323
357
|
- BARE, WORK, FORK, and KILL do not admit a scope slot.
|
|
324
358
|
- An ingested delimiter is `[A-Za-z0-9_]*`; canonical teaching and the GBNF use `0`.
|
|
325
359
|
|
|
326
360
|
§slot-order Canonical producers and the GBNF rail emit signal, then target, then
|
|
327
|
-
scope, then annotation, with one ASCII space before every present
|
|
361
|
+
metadata, then scope, then annotation, with one ASCII space before every present modifier. Slot delimiters make
|
|
328
362
|
their boundaries unambiguous, so the tolerant ANTLR ingester accepts zero or
|
|
329
363
|
more horizontal whitespace characters before each slot and any permutation of
|
|
330
|
-
the
|
|
331
|
-
|
|
364
|
+
the signal, target-with-metadata, and scope admitted by that operation, at most
|
|
365
|
+
once each. Metadata remains attached immediately after its target. Accepted
|
|
366
|
+
spacing and permutation are not second canonical spellings.
|
|
332
367
|
|
|
333
368
|
§heading-inline-body Text that follows the last slot on a heading line — after
|
|
334
369
|
horizontal whitespace, beginning with a character that cannot open a slot (not `[`,
|
|
335
|
-
`(`, or
|
|
370
|
+
`(`, or `<`, nor `{` after a target) — is the first body line: `## EXEC0 [crm] (crm_query) SELECT Id FROM Case` and
|
|
336
371
|
`## FIND0 (src/**) /createCoder/i` parse as their canonical two-line forms. Nothing is
|
|
337
372
|
lost and the stored statement is canonical; the spelling is tolerated and announced:
|
|
338
373
|
one warning-severity advisory follows the statement, naming the heading and the rule
|
|
@@ -348,14 +383,24 @@ authorization, status, or body. An empty comment normalizes to the empty string.
|
|
|
348
383
|
Text containing a newline or lacking the closing `-->` is not an annotation;
|
|
349
384
|
`<!--` elsewhere remains ordinary body text.
|
|
350
385
|
|
|
386
|
+
§scheme-metadata-modifier A target may be followed by zero or more
|
|
387
|
+
single-line `{metadata}` blocks. AstBuilder preserves each block's exact inner
|
|
388
|
+
text and order as the statement's `metadata: string[] | null`; nested braces
|
|
389
|
+
remain balanced content. The blocks are not part of the target: braces inside
|
|
390
|
+
`(path)` remain ordinary path and glob syntax, including `{PLAN,READ}`. The
|
|
391
|
+
language assigns metadata no meaning. A runtime admits it only for a scheme
|
|
392
|
+
that declares the capability, and that scheme exclusively owns interpretation,
|
|
393
|
+
validation, and authorization. An unfinished block or a newline before its
|
|
394
|
+
closing brace is a structural failure.
|
|
395
|
+
|
|
351
396
|
The ingester also accepts several bounded noncanonical forms so it can explain
|
|
352
397
|
or safely execute understandable input:
|
|
353
398
|
|
|
354
399
|
| Tolerated input | Canonical or runtime disposition |
|
|
355
400
|
|---------------------------------------------------|---------------------------------------------------------------------|
|
|
356
|
-
| Reordered admitted slots | Producers retain signal → target → scope order
|
|
401
|
+
| Reordered admitted slots | Producers retain signal → target → metadata → scope order |
|
|
357
402
|
| Missing target on a generally targeted operation | AST carries `null`; the runtime rejects when the target is required |
|
|
358
|
-
|
|
|
403
|
+
| A non-`0` PLAN lane | Model canon uses lane `0` |
|
|
359
404
|
| KILL annotation body | AST preserves it; model teaching leaves the KILL section empty |
|
|
360
405
|
| Dash-separated or comma-space scope numbers | Producers use adjacent comma-separated numbers |
|
|
361
406
|
| Empty content where semantics require a body | The empty section normalizes null; the operation owner rejects it |
|
|
@@ -368,6 +413,7 @@ or safely execute understandable input:
|
|
|
368
413
|
| `delimiter` | `[A-Za-z0-9_]*`, adjacent to PLAN or OP |
|
|
369
414
|
| `[signal]` | Operation-specific tags, identifier, branch, or integer |
|
|
370
415
|
| `(path)` | Local path or scheme URL target; detailed in §5 |
|
|
416
|
+
| `{metadata}` | Repeatable opaque scheme modifier attached after a target |
|
|
371
417
|
| `<scope>` | One or more signed integers or decimals; detailed in §7 |
|
|
372
418
|
| annotation | Optional trailing `<!-- … -->` descriptive text |
|
|
373
419
|
| `body` | Opaque section text before the next same-lane heading or EOF |
|
|
@@ -383,14 +429,14 @@ governed by {§canonical-statement}; runtime conditions remain explicit below.
|
|
|
383
429
|
| FIND | optional add log tags | required target or glob | optional result range | optional matcher |
|
|
384
430
|
| READ | optional add log tags | required target | optional text region | empty |
|
|
385
431
|
| 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
|
|
432
|
+
| COPY | optional add log tags | required source and destination | optional region after each path | empty |
|
|
433
|
+
| MOVE | optional add log tags | required source and destination | optional region after each path | empty |
|
|
388
434
|
| FOLD | optional filter/change tags | optional log selection | optional log-body line scope | optional matcher |
|
|
389
435
|
| OPEN | optional filter/change tags | optional log selection | optional log-body line scope | optional matcher |
|
|
390
436
|
| EXEC | optional executor | optional local working path | optional timeout, poll | optional executor input |
|
|
391
437
|
| BARE | optional add log tags | none | none | required prompt |
|
|
392
|
-
| WORK | optional Git branch
|
|
393
|
-
| FORK | optional Git branch
|
|
438
|
+
| WORK | optional Git branch (refused unless the service enables branch delegation) | required fresh `worker://name` | none | required prompt |
|
|
439
|
+
| FORK | optional Git branch (refused unless the service enables branch delegation) | required context-inheriting `worker://name` | none | required prompt |
|
|
394
440
|
| KILL | optional target-specific code | required target, including a log item | none | empty |
|
|
395
441
|
| SEND | optional target-specific code | optional recipient | optional timeout, poll | message; terminal is nonempty |
|
|
396
442
|
|
|
@@ -400,10 +446,10 @@ Directed SEND and KILL delegate any present code to the addressed target's
|
|
|
400
446
|
operation contract; a live process may interpret a KILL code as a Unix signal,
|
|
401
447
|
but that interpretation does not define KILL generally.
|
|
402
448
|
|
|
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
|
|
449
|
+
§plan-value **PLAN carries one installment of the model's running work journal.**
|
|
450
|
+
Its entries record newly made working-memory items: durable findings and decisions
|
|
451
|
+
are `memory`, finished actions are `completed`, open work is `pending`, and active
|
|
452
|
+
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
453
|
entry keys (the model-facing Plan carries no priority: struck 2026-08-24 so the
|
|
408
454
|
log echoes only the canonical shape, starving stale-field habits), and validates
|
|
409
455
|
the canonical bare array: every entry has string `content` and `status` in
|
|
@@ -411,10 +457,11 @@ the canonical bare array: every entry has string `content` and `status` in
|
|
|
411
457
|
malformed-JSON, or otherwise invalid body becomes one `in_progress`
|
|
412
458
|
entry whose content is the exact authored body; admission performs no partial
|
|
413
459
|
repair or list inference. An empty body becomes the planless `[]`
|
|
414
|
-
value. Each PLAN
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
log bodies, and model-packet
|
|
460
|
+
value. Each PLAN is the complete semantic value of that journal installment;
|
|
461
|
+
prior installments remain ordinary curatable log items. The exact `turnOps`
|
|
462
|
+
source remains forensic program evidence, while the normalized array is the sole
|
|
463
|
+
semantic value used by AST, persistence, durable log bodies, and model-packet
|
|
464
|
+
materialization. PLAN is public log content—not
|
|
418
465
|
provider reasoning—and Plurnk initially mints no `_meta` values. Dispatch records
|
|
419
466
|
the canonical value and has no other runtime effect.
|
|
420
467
|
|
|
@@ -432,7 +479,7 @@ commit `272bf799f35a258c6a4107a0410ed361e83683d3`.
|
|
|
432
479
|
|
|
433
480
|
§exec-tag-signal EXEC's bracket slot names its runtime. A bracket whose first character is
|
|
434
481
|
a sign is a tag signal instead — a runtime never starts with `+` or `-` — so
|
|
435
|
-
`## EXEC0 [+fetch]
|
|
482
|
+
`## EXEC0 [+fetch]` and `## EXEC0 [crm] [+schema] (crm_describe)` admit: the tags
|
|
436
483
|
classify the log row exactly as on FIND or READ, the runtime is the explicit one or the
|
|
437
484
|
default shell, and each slot appears at most once.
|
|
438
485
|
|
|
@@ -498,7 +545,7 @@ Mutation semantics:
|
|
|
498
545
|
- An empty body deletes the selected text.
|
|
499
546
|
- `<0>` prepends and `<-1>` appends.
|
|
500
547
|
- `<SL,SC,EL,EC>` deletes the exact exclusive-end region and inserts the body at its start.
|
|
501
|
-
- §
|
|
548
|
+
- §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
549
|
|
|
503
550
|
### §operation-observation Per-operation observations
|
|
504
551
|
|
|
@@ -549,7 +596,6 @@ and path globs share the slot; content matchers belong in the body.
|
|
|
549
596
|
| `scheme://…` | WHATWG-decomposed `UrlPath` | Resolves only when a runtime scheme owns the address |
|
|
550
597
|
| Path glob | Preserved in either path kind | Scheme defines collection selection and ordering |
|
|
551
598
|
| `#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
599
|
| `?query` | Preserved as ordered `UrlPath.query`; `null` = absent, `""` = `?` | Participates in scheme resource identity |
|
|
554
600
|
|
|
555
601
|
AstBuilder recognizes a URL with the case-insensitive prefix
|
|
@@ -591,15 +637,6 @@ never target content. Glob metacharacters remain legal path data.
|
|
|
591
637
|
|
|
592
638
|
Matching and folder-scope semantics remain runtime concerns.
|
|
593
639
|
|
|
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
640
|
§worker-name The exported `WORKER_NAME` contract governs names minted for URI
|
|
604
641
|
authority slots: a lowercase DNS label matching
|
|
605
642
|
`[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?`. `RESERVED_AUTHORITIES` contains the
|
|
@@ -611,9 +648,9 @@ ingestion restriction: the parser decomposes arbitrary URL authorities.
|
|
|
611
648
|
|
|
612
649
|
## §matcher-prefix-claims 6. Bulk pattern matching
|
|
613
650
|
|
|
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
|
|
651
|
+
FIND, authored READ, OPEN, FOLD, LOOK, and BUFF accept an optional body matcher.
|
|
652
|
+
The lexer preserves the body opaquely; AstBuilder assigns the dialect from its
|
|
653
|
+
leading characters, then normalizes matcher-bearing READ to FIND under
|
|
617
654
|
{§read-find-normalization}.
|
|
618
655
|
A leading prefix claims its dialect. Invalid claimed syntax is a positioned
|
|
619
656
|
visitor error and never falls back to glob matching.
|
|
@@ -624,13 +661,17 @@ visitor error and never falls back to glob matching.
|
|
|
624
661
|
| `/` | Regex | `/pattern/flags` | ECMAScript `RegExp` construction | Mimetype projection |
|
|
625
662
|
| `$` | JSONPath | RFC 9535 expression | `json-p3` compilation | Mimetype projection |
|
|
626
663
|
| `~` | Semantic | `~phrase` | Any text after the prefix | Embedding index |
|
|
627
|
-
|
|
|
628
|
-
| none | Glob | Shell glob or literal text |
|
|
664
|
+
| `&` | Graph | `&symbol`, `&<symbol`, or `&>symbol` | Exact shape validation | Symbol index |
|
|
665
|
+
| none | Glob | Shell glob or literal text | Single-line raw string | Mimetype projection |
|
|
629
666
|
|
|
630
667
|
XPath is classified before regex because its prefix is two slashes. Regex
|
|
631
668
|
splitting respects escapes and character classes; `\/` represents a literal
|
|
632
669
|
slash. The AST stores regex `pattern` and `flags`, not a compiled object.
|
|
633
|
-
Semantic
|
|
670
|
+
Semantic matchers require no parse step. Graph admission validates its direction
|
|
671
|
+
and non-whitespace symbol before runtime. Every other leading character remains
|
|
672
|
+
in the fallback glob/literal dialect; `@(...)` is therefore an extglob group and
|
|
673
|
+
bare `@text` remains literal matcher text. Rendered READ coordinates are
|
|
674
|
+
structural output rows, not a reserved matcher prefix. Scope carries semantic
|
|
634
675
|
threshold and result-range information rather than changing the matcher body.
|
|
635
676
|
|
|
636
677
|
AstBuilder validation is compile-only and never evaluates a document. Matcher
|
|
@@ -638,11 +679,10 @@ evaluation belongs to the runtime's selected mimetype, embedding, or symbol
|
|
|
638
679
|
implementation. A matcher admission error is local to its statement; later
|
|
639
680
|
statements remain recoverable when their boundaries are trustworthy.
|
|
640
681
|
|
|
641
|
-
- §pattern-body-single-line
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
specific implicit close rule.
|
|
682
|
+
- §pattern-body-single-line Every matcher body is one physical line. AstBuilder
|
|
683
|
+
rejects multiline bodies before dialect classification, while GBNF excludes
|
|
684
|
+
line terminators. A regex that matches a newline uses the two-character `\n`
|
|
685
|
+
escape. Non-matcher operation bodies remain multiline.
|
|
646
686
|
- §pattern-body-leading-colon The GBNF rail forbids `:` as the first matcher
|
|
647
687
|
character. Empty matchers and later colons remain valid; a regex such as
|
|
648
688
|
`/^:needle/` expresses a pattern beginning with a literal colon.
|
|
@@ -665,7 +705,7 @@ The operation column names the canonical AST operation after
|
|
|
665
705
|
| COPY/MOVE source | 0/1/2/4 text coordinates | Region copied or moved from the selected source |
|
|
666
706
|
| COPY/MOVE destination | 0/1/2/4 text coordinates after target | Region replaced or insertion point at the destination |
|
|
667
707
|
| 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
|
|
708
|
+
| EXEC | `timeout[,poll]` | Spawn lifetime bound and poll cadence in minutes |
|
|
669
709
|
| Terminal SEND `[202]` | `timeout[,poll]` | Bounded or indefinite wait and optional poll cadence |
|
|
670
710
|
|
|
671
711
|
Text coordinates use the algebra in {§text-scope-semantics}: one integer is a
|
|
@@ -775,7 +815,7 @@ disposition. The shape rules ARE structural:
|
|
|
775
815
|
non-disposition code, targeted or pathless, empty body allowed.
|
|
776
816
|
- §terminal-body-nonempty The GBNF rail requires a non-empty terminal SEND body — a constrained
|
|
777
817
|
turn cannot end empty-handed. ANTLR remains tolerant during ingestion.
|
|
778
|
-
- §park-202-only The **park** rides `[202]` only: `<T>` (wait up to T
|
|
818
|
+
- §park-202-only The **park** rides `[202]` only: `<T>` (wait up to T minutes),
|
|
779
819
|
`<T,P>` (adds a poll cadence, mirroring EXEC's slot), `<-1>`
|
|
780
820
|
(indefinite; the join's own liveness bounds it). See §7 for the
|
|
781
821
|
GBNF-strict / ANTLR-tolerant split.
|
|
@@ -817,6 +857,9 @@ stateDiagram-v2
|
|
|
817
857
|
SLOTS --> TARGET: target opener
|
|
818
858
|
TARGET --> TARGET: balanced literals / target escapes
|
|
819
859
|
TARGET --> SLOTS: target close at depth zero
|
|
860
|
+
SLOTS --> METADATA: metadata opener after target
|
|
861
|
+
METADATA --> METADATA: balanced inner braces
|
|
862
|
+
METADATA --> SLOTS: metadata close at depth zero
|
|
820
863
|
SLOTS --> SLOTS: scope token
|
|
821
864
|
SLOTS --> SLOTS: trailing annotation
|
|
822
865
|
SLOTS --> BODY: heading line end
|
|
@@ -826,8 +869,9 @@ stateDiagram-v2
|
|
|
826
869
|
|
|
827
870
|
The first H1 PLAN establishes the turn lane. DEFAULT recognizes only an H1
|
|
828
871
|
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
|
|
872
|
+
operation-appropriate signal, target-with-metadata, and scope openers in any
|
|
873
|
+
order, followed by an optional annotation; the parser grammar enforces
|
|
874
|
+
at-most-once slot multiplicity and keeps repeatable metadata attached to its target.
|
|
831
875
|
Signal submodes select tags, integer,
|
|
832
876
|
or identifier tokens by operation family. TARGET preserves balanced inner
|
|
833
877
|
parentheses and recognized target escapes. BODY emits opaque text until a
|
|
@@ -840,7 +884,7 @@ provider reasoning cannot become the turn anchor.
|
|
|
840
884
|
|
|
841
885
|
RecordingListener captures lexer and parser failures; AstBuilder adds visitor
|
|
842
886
|
failures. PlurnkErrorStrategy recovers at structural heading boundaries where
|
|
843
|
-
possible. EOF is a valid body boundary. An unfinished signal or
|
|
887
|
+
possible. EOF is a valid body boundary. An unfinished signal, target, or metadata block produces
|
|
844
888
|
`unparsedTail`; no later input is trustworthy.
|
|
845
889
|
|
|
846
890
|
## §whitespace-contract 11. Whitespace and interstatement text
|
|
@@ -849,9 +893,10 @@ possible. EOF is a valid body boundary. An unfinished signal or target produces
|
|
|
849
893
|
|-----------------------------|---------------------------------------|-----------------------------------------------------------|
|
|
850
894
|
| Heading marker | `# PLAN0` or `## OP0` at column zero | The initial PLAN may directly follow leading TEXT; subsequent headings retain exact depth and column |
|
|
851
895
|
| Between OP and delimiter | Adjacent | Must remain adjacent |
|
|
852
|
-
| Before each
|
|
896
|
+
| Before each modifier | One ASCII space | Zero or more horizontal whitespace characters |
|
|
853
897
|
| Inside signal | Adjacent values | Horizontal whitespace is ignored; newline is invalid |
|
|
854
898
|
| Inside target | Path alias plus target escapes | Balanced literals tolerated; newline is invalid |
|
|
899
|
+
| Inside scheme metadata | Scheme-defined single-line content | Balanced braces tolerated; newline is invalid |
|
|
855
900
|
| Inside scope | Comma-separated numbers | Dash separator and one post-comma space are also accepted |
|
|
856
901
|
| Before annotation | One ASCII space | Zero or more horizontal whitespace characters |
|
|
857
902
|
| Inside annotation | One-line prose padded by one space | Any single-line text through the first closing `-->` |
|
|
@@ -878,25 +923,33 @@ and wire types come from generated schemas; the small hand-maintained parser
|
|
|
878
923
|
types cover ordered parse items and `PlurnkParseError`, which JSON Schema cannot
|
|
879
924
|
express. Consumers never receive ANTLR parse-tree or token types.
|
|
880
925
|
|
|
881
|
-
§turn-shape `PlurnkParser.parse` accepts exactly one model turn
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
926
|
+
§turn-shape `PlurnkParser.parse` accepts exactly one model turn containing at
|
|
927
|
+
least one parsed source operation. Canonical generation begins with H1 PLAN,
|
|
928
|
+
ends with a disposition-coded H2 SEND, and never repeats PLAN mid-turn. When no
|
|
929
|
+
valid leading PLAN was parsed, the parser prepends an empty PLAN; when no valid
|
|
930
|
+
terminal SEND was parsed, it appends a bodyless `SEND [102]`. Either default
|
|
931
|
+
carries {§parser-position} `UNKNOWN_POSITION` and one exact hard diagnostic
|
|
932
|
+
stating the observed boundary failure and applied default. The source text
|
|
933
|
+
remains unchanged.
|
|
934
|
+
An authored terminal SEND still ends the source turn: a same-lane operation or
|
|
935
|
+
other hard error after it is outside the trustworthy boundary. Tolerated TEXT
|
|
936
|
+
may appear only before the first operation; after that point, nonstructural text
|
|
937
|
+
is section body content. `parseLog` remains strict canonical PLAN-through-SEND
|
|
938
|
+
input, and GBNF remains strict canonical generation.
|
|
886
939
|
|
|
887
940
|
§document-fence `PlurnkParser.parse` additionally admits one outer Markdown code
|
|
888
941
|
fence whose opening line is exactly ```` ```plurnk ```` and whose closing line,
|
|
889
942
|
when present, is ```` ``` ````. The fence encloses the complete
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
943
|
+
model turn and projects neither text nor body content into the AST. Its opener
|
|
944
|
+
commits the document to either that closer or EOF immediately after the turn.
|
|
945
|
+
This is document framing, not another statement grammar, and
|
|
893
946
|
no other parser tier admits it. GBNF continues to shape the paired form.
|
|
894
947
|
|
|
895
948
|
§tier-entrypoints Each parser entry point owns one document tier:
|
|
896
949
|
|
|
897
950
|
| Entry point | Accepted document | Result statement type |
|
|
898
951
|
|--------------------------------|----------------------------------------------------------------|-----------------------|
|
|
899
|
-
| `PlurnkParser.parse` | One
|
|
952
|
+
| `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
953
|
| `PlurnkParser.parseStatements` | Zero or more protocol statements and hidden whitespace | `PlurnkStatement` |
|
|
901
954
|
| `PlurnkParser.parseLog` | One or more consecutive same-lane PLAN-anchored turns | `PlurnkStatement` |
|
|
902
955
|
| `PlurnkParser.parseClient` | H2 protocol statements plus read-shaped LOOK/BUFF commands | `ClientStatement` |
|
|
@@ -913,15 +966,16 @@ following supported consumer values. All other root exports are TypeScript types
|
|
|
913
966
|
|---------------------------------------|---------------------------------------------------------------------|---------------------------------------------|
|
|
914
967
|
| `PlurnkParser` | Four document-tier entry points listed above | {§parser-architecture}, {§tier-entrypoints} |
|
|
915
968
|
| `PlurnkParseError` | JSON-serializable positioned parser diagnostic | {§parse-diagnostics} |
|
|
916
|
-
| `parsePath
|
|
969
|
+
| `parsePath` | Parser-equivalent target admission | {§path-syntax}, {§tier-entrypoints} |
|
|
917
970
|
| `PathSyntax` | Target-slot spelling and exact-versus-glob classification | {§path-parentheses}, {§path-glob} |
|
|
918
971
|
| `Validator` | Validation and assertion against the owning JSON Schemas | {§wire-entrypoint} |
|
|
919
972
|
| `InvalidNoticeError` | Typed failure from `Validator.assertNotice` | {§notice} |
|
|
920
973
|
| `InvalidProblemDetailsError` | Typed failure from `Validator.assertProblemDetails` | {§problem-details} |
|
|
974
|
+
| `InvalidProblemProjectionError` | Typed failure from `Validator.assertProblemProjection` | {§problem-projection} |
|
|
921
975
|
| `InvalidOperationResultError` | Typed failure from `Validator.assertOperationResult` | {§operation-result} |
|
|
922
976
|
| `InvalidTextRegionError` | Typed failure from `Validator.assertTextRegion` | {§text-region} |
|
|
923
977
|
| `InvalidRangeExtentError` | Typed failure from `Validator.assertRangeExtent` | {§range-extent} |
|
|
924
|
-
| `Problems` | RFC 9457 Problem construction
|
|
978
|
+
| `Problems` | RFC 9457 Problem construction and model projection | {§problem-details}, {§problem-projection} |
|
|
925
979
|
| `PLURNK_OPS` | Runtime tuple from which the closed `PlurnkOp` union is derived | {§canonical-statement} |
|
|
926
980
|
| `WORKER_NAME`, `RESERVED_AUTHORITIES` | Authority minting predicate and internal reserved names | {§worker-name} |
|
|
927
981
|
| `UNKNOWN_POSITION` | Frozen sentinel for an AST statement without retained parsed source | {§parser-position} |
|
|
@@ -931,7 +985,7 @@ than alternate consumer entry points:
|
|
|
931
985
|
|
|
932
986
|
| Internal component | Boundary |
|
|
933
987
|
|--------------------------------------------|---------------------------------------------------------------------------------------------------------------|
|
|
934
|
-
| `AstBuilder` | Consumes generated ANTLR contexts; `PlurnkParser
|
|
988
|
+
| `AstBuilder` | Consumes generated ANTLR contexts; `PlurnkParser` and `parsePath` own its API |
|
|
935
989
|
| `PlurnkErrorStrategy`, `RecordingListener` | Assemble parser recovery and diagnostics around `antlr4ng`; consumers receive `PlurnkParseError` values |
|
|
936
990
|
| `Jsonplurnk` test helper | Independently checks the Core-owned {§jsonplurnk} renderer corpus; it is neither shipped code nor a root API |
|
|
937
991
|
|
|
@@ -1063,6 +1117,20 @@ Internal invariant violations throw and preserve their cause. An external
|
|
|
1063
1117
|
protocol may require its own error envelope; its adapter maps that envelope to
|
|
1064
1118
|
or from the canonical Problem without creating another PLURNK failure contract.
|
|
1065
1119
|
|
|
1120
|
+
§problem-projection `ProblemProjection` is the sole compact model-packet view of
|
|
1121
|
+
an exact `ProblemDetails`. `Problems.project(problem, context)` validates both
|
|
1122
|
+
representations and rejects a status that contradicts the enclosing row.
|
|
1123
|
+
|
|
1124
|
+
| Projection member | Contract |
|
|
1125
|
+
|-------------------|----------|
|
|
1126
|
+
| `type`, `detail` | Always retained; together they identify the stable class and occurrence-specific cause |
|
|
1127
|
+
| `stage`, `recovery`, `retryable`, extensions | Retained only when present and not exactly duplicated by the enclosing row |
|
|
1128
|
+
| `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 |
|
|
1129
|
+
|
|
1130
|
+
Projection never mutates or replaces the exact Problem. Durable storage,
|
|
1131
|
+
external protocols, clients, and forensic artifacts continue to receive the
|
|
1132
|
+
complete RFC 9457 object.
|
|
1133
|
+
|
|
1066
1134
|
### 13.6 Notices
|
|
1067
1135
|
|
|
1068
1136
|
§notice A `Notice` is a transient, nonterminal observation. It cannot determine durable
|
|
@@ -1214,9 +1282,12 @@ and 3.30.2](https://docs.oasis-open.org/sarif/sarif/v2.1.0/sarif-v2.1.0.html).
|
|
|
1214
1282
|
`severity` distinguishes a hard error from a non-fatal advisory. The parser is
|
|
1215
1283
|
the sole and complete owner of syntax-error messaging because it holds the
|
|
1216
1284
|
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
|
-
|
|
1285
|
+
produces the final diagnostic message, deduplicated expected-token lists, and
|
|
1286
|
+
turn-shape diagnostics. No valid leading PLAN yields ``No valid leading PLAN
|
|
1287
|
+
was parsed; an empty `# PLAN0` was used.``; no valid terminal SEND yields ``No
|
|
1288
|
+
valid terminal SEND was parsed; `## SEND0 [102]` was used.``; source with no
|
|
1289
|
+
parsed operation yields `no valid Plurnk operation was found.` Targeted
|
|
1290
|
+
diagnostics are:
|
|
1220
1291
|
|
|
1221
1292
|
- §signal-scope-redirect **EXEC scope in the signal slot.** When EXEC's
|
|
1222
1293
|
`[signal]` slot (executor-ident mode) hits a leading `-` or digit —
|
|
@@ -1225,17 +1296,21 @@ turn-shape imperatives (begin with `# PLAN0`, end with a terminal
|
|
|
1225
1296
|
`## EXEC0 <-1,300>`” instead of a raw `unrecognized character`. The redirect is
|
|
1226
1297
|
EXEC-scoped because its signal mode is exclusive; SEND/KILL are untouched.
|
|
1227
1298
|
- §matcher-body-redirect **Matcher body in the slot region.** When the
|
|
1228
|
-
post-target
|
|
1299
|
+
post-target modifier region begins with `$`, `~`, or `@` with no whitespace
|
|
1229
1300
|
before it, the lexer redirects the unambiguous matcher to body content below the
|
|
1230
1301
|
OP heading instead of returning the generic slot list (after whitespace it is
|
|
1231
1302
|
already the inline body, {§heading-inline-body}). Slash-led regex and XPath are
|
|
1232
1303
|
excluded because `/` can be target data.
|
|
1304
|
+
- §bare-target-redirect **A `(target)` on BARE.** BARE takes no `(path)`; a model that
|
|
1305
|
+
writes its prompt, or the prompt's address, into a parenthesized slot (`## BARE0
|
|
1306
|
+
(What day is it?)`, `## BARE0 (prompt:///1/1)`) is told that the prompt is the body
|
|
1307
|
+
line beneath the heading, with the heading's own opener, instead of the generic
|
|
1308
|
+
slot list. Two operator sessions on 2026-08-26 produced exactly these shapes.
|
|
1233
1309
|
- §combined-anchor-line-redirect **Combined anchor and line number in a scope.**
|
|
1234
1310
|
A text-coordinate scope containing `@hash:L` or `@hash L` is one bounded hard
|
|
1235
1311
|
error: `a scope position accepts one line coordinate; use the \`@hash\` anchor
|
|
1236
1312
|
without its displayed line number`. A malformed header scope is consumed as
|
|
1237
|
-
one token
|
|
1238
|
-
boundary; neither produces a punctuation cascade.
|
|
1313
|
+
one token at either COPY/MOVE operand; neither produces a punctuation cascade.
|
|
1239
1314
|
- §misplaced-target-advisory **Mutation target in the signal slot.** When a
|
|
1240
1315
|
mutating op (EDIT/COPY/MOVE) parses with a null `(target)` and a path-shaped
|
|
1241
1316
|
`[signal]` element (a `/` or a dotted extension), the message redirects the
|
|
@@ -1247,11 +1322,10 @@ turn-shape imperatives (begin with `# PLAN0`, end with a terminal
|
|
|
1247
1322
|
body is solely an HTML comment (`<!-- … -->`) can never carry a matcher: it is
|
|
1248
1323
|
the annotation the model put on the line below the heading. The builder takes
|
|
1249
1324
|
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.
|
|
1325
|
+
with no body, and raises one warning-severity advisory stating that observed
|
|
1326
|
+
normalization; the parser places the advisory right after its statement and
|
|
1327
|
+
the service delivers it as a `parse_advisory` notice with its position. A body
|
|
1328
|
+
with any other content is a matcher, as before.
|
|
1255
1329
|
|
|
1256
1330
|
§error-shape The diagnostic class determines how much guidance the parser may
|
|
1257
1331
|
provide:
|
package/dist/plurnk.gemma.gbnf
CHANGED
|
@@ -55,8 +55,8 @@ plan ::= "# PLAN0" annotation-slot? "\n" section-body-ne "\n"
|
|
|
55
55
|
find ::= "## FIND0" add-tags-slot? target-slot line-slot? annotation-slot? "\n" | "## FIND0" add-tags-slot? target-slot line-slot? annotation-slot? "\n" pattern-body-ne "\n"
|
|
56
56
|
read ::= "## READ0" add-tags-slot? target-slot text-line-slot? annotation-slot? "\n" | "## READ0" add-tags-slot? target-slot text-line-slot? annotation-slot? "\n" pattern-body-ne "\n"
|
|
57
57
|
edit ::= "## EDIT0" add-tags-slot? target-slot text-line-slot? annotation-slot? "\n" | "## EDIT0" add-tags-slot? target-slot text-line-slot? annotation-slot? "\n" section-body-ne "\n"
|
|
58
|
-
copy ::= "## COPY0" add-tags-slot? target-slot text-line-slot?
|
|
59
|
-
move ::= "## MOVE0" add-tags-slot? target-slot text-line-slot?
|
|
58
|
+
copy ::= "## COPY0" add-tags-slot? target-slot text-line-slot? target-slot text-line-slot? annotation-slot? "\n"
|
|
59
|
+
move ::= "## MOVE0" add-tags-slot? target-slot text-line-slot? target-slot text-line-slot? annotation-slot? "\n"
|
|
60
60
|
open ::= "## OPEN0" log-selection text-line-slot? annotation-slot? "\n" | "## OPEN0" log-selection text-line-slot? annotation-slot? "\n" pattern-body-ne "\n"
|
|
61
61
|
fold ::= "## FOLD0" log-selection text-line-slot? annotation-slot? "\n" | "## FOLD0" log-selection text-line-slot? annotation-slot? "\n" pattern-body-ne "\n"
|
|
62
62
|
exec ::= "## EXEC0" exec-slot? target-slot? line-slot? annotation-slot? "\n" | "## EXEC0" exec-slot? target-slot? line-slot? annotation-slot? "\n" section-body-ne "\n"
|
|
@@ -122,7 +122,8 @@ root-gemma ::= channel sep framed-turn
|
|
|
122
122
|
add-tags-slot ::= " " add-tags
|
|
123
123
|
curation-tags-slot ::= " " curation-tags
|
|
124
124
|
log-target-slot ::= " (log:" target-atom+ ")"
|
|
125
|
-
target-slot ::= " " target
|
|
125
|
+
target-slot ::= " " target metadata-slot*
|
|
126
|
+
metadata-slot ::= " {" [^\x00-\x08\x0B-\x0C\x0E-\x1F\x7F\n\r{}]* "}"
|
|
126
127
|
line-slot ::= " " line
|
|
127
128
|
text-line-slot ::= " " text-line
|
|
128
129
|
exec-slot ::= " " exec-sig
|
package/dist/plurnk.qwen.gbnf
CHANGED
|
@@ -55,8 +55,8 @@ plan ::= "# PLAN0" annotation-slot? "\n" section-body-ne "\n"
|
|
|
55
55
|
find ::= "## FIND0" add-tags-slot? target-slot line-slot? annotation-slot? "\n" | "## FIND0" add-tags-slot? target-slot line-slot? annotation-slot? "\n" pattern-body-ne "\n"
|
|
56
56
|
read ::= "## READ0" add-tags-slot? target-slot text-line-slot? annotation-slot? "\n" | "## READ0" add-tags-slot? target-slot text-line-slot? annotation-slot? "\n" pattern-body-ne "\n"
|
|
57
57
|
edit ::= "## EDIT0" add-tags-slot? target-slot text-line-slot? annotation-slot? "\n" | "## EDIT0" add-tags-slot? target-slot text-line-slot? annotation-slot? "\n" section-body-ne "\n"
|
|
58
|
-
copy ::= "## COPY0" add-tags-slot? target-slot text-line-slot?
|
|
59
|
-
move ::= "## MOVE0" add-tags-slot? target-slot text-line-slot?
|
|
58
|
+
copy ::= "## COPY0" add-tags-slot? target-slot text-line-slot? target-slot text-line-slot? annotation-slot? "\n"
|
|
59
|
+
move ::= "## MOVE0" add-tags-slot? target-slot text-line-slot? target-slot text-line-slot? annotation-slot? "\n"
|
|
60
60
|
open ::= "## OPEN0" log-selection text-line-slot? annotation-slot? "\n" | "## OPEN0" log-selection text-line-slot? annotation-slot? "\n" pattern-body-ne "\n"
|
|
61
61
|
fold ::= "## FOLD0" log-selection text-line-slot? annotation-slot? "\n" | "## FOLD0" log-selection text-line-slot? annotation-slot? "\n" pattern-body-ne "\n"
|
|
62
62
|
exec ::= "## EXEC0" exec-slot? target-slot? line-slot? annotation-slot? "\n" | "## EXEC0" exec-slot? target-slot? line-slot? annotation-slot? "\n" section-body-ne "\n"
|
|
@@ -111,7 +111,8 @@ root-qwen-response ::= "<think>\n" root-qwen
|
|
|
111
111
|
add-tags-slot ::= " " add-tags
|
|
112
112
|
curation-tags-slot ::= " " curation-tags
|
|
113
113
|
log-target-slot ::= " (log:" target-atom+ ")"
|
|
114
|
-
target-slot ::= " " target
|
|
114
|
+
target-slot ::= " " target metadata-slot*
|
|
115
|
+
metadata-slot ::= " {" [^\x00-\x08\x0B-\x0C\x0E-\x1F\x7F\n\r{}]* "}"
|
|
115
116
|
line-slot ::= " " line
|
|
116
117
|
text-line-slot ::= " " text-line
|
|
117
118
|
exec-slot ::= " " exec-sig
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://schemas.plurnk.xyz/v0/CapabilityDescriptor.json",
|
|
4
|
+
"title": "CapabilityDescriptor",
|
|
5
|
+
"description": "One fully routed operation demand evaluated by the capability-policy cascade.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": ["operation", "access", "traits"],
|
|
8
|
+
"additionalProperties": false,
|
|
9
|
+
"properties": {
|
|
10
|
+
"operation": {
|
|
11
|
+
"enum": ["FIND", "READ", "EDIT", "COPY", "MOVE", "SEND", "EXEC", "BARE", "WORK", "FORK", "KILL"]
|
|
12
|
+
},
|
|
13
|
+
"scheme": { "type": "string", "pattern": "^[a-z][a-z0-9+.-]*$" },
|
|
14
|
+
"runtime": { "type": "string", "pattern": "^[a-z][a-z0-9+.-]*$" },
|
|
15
|
+
"tool": { "type": "string", "minLength": 1 },
|
|
16
|
+
"access": { "enum": ["observe", "mutate", "execute", "interact", "control"] },
|
|
17
|
+
"traits": {
|
|
18
|
+
"type": "array",
|
|
19
|
+
"items": { "type": "string", "pattern": "^[a-z][a-z0-9-]*$" },
|
|
20
|
+
"uniqueItems": true
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://schemas.plurnk.xyz/v0/CapabilityPolicy.json",
|
|
4
|
+
"title": "CapabilityPolicy",
|
|
5
|
+
"description": "One purely subtractive capability-policy layer. Deny wins; when only is present, a demand must match at least one selector.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"properties": {
|
|
9
|
+
"only": {
|
|
10
|
+
"type": "array",
|
|
11
|
+
"items": { "$ref": "https://schemas.plurnk.xyz/v0/CapabilitySelector.json" }
|
|
12
|
+
},
|
|
13
|
+
"deny": {
|
|
14
|
+
"type": "array",
|
|
15
|
+
"items": { "$ref": "https://schemas.plurnk.xyz/v0/CapabilitySelector.json" }
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|