@plurnk/plurnk-contracts 2.0.0 → 3.0.1
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/.env.defaults +1 -1
- package/README.md +3 -5
- package/SPEC.md +103 -112
- package/dist/conformance/agui-v1.json +4 -1
- package/dist/schema/ClientInteractionProjection.json +2 -1
- package/dist/schema/Notice.json +1 -1
- package/dist/schema/OperationResult.json +2 -3
- package/dist/schema/ProposalDisposition.json +4 -5
- package/dist/schema/ProposalPolicy.json +7 -0
- package/dist/schema/ProposalProjection.json +2 -2
- package/dist/schema/WorkerOwner.json +21 -0
- package/dist/src/ApplicationPort.d.ts +27 -9
- package/dist/src/ApplicationPort.d.ts.map +1 -1
- package/dist/src/Functionality.d.ts +2 -1
- package/dist/src/Functionality.d.ts.map +1 -1
- package/dist/src/Validator.d.ts +5 -6
- package/dist/src/Validator.d.ts.map +1 -1
- package/dist/src/Validator.js +11 -26
- package/dist/src/Validator.js.map +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/types.d.ts +2 -2
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/types.generated.d.ts +14 -29
- package/dist/src/types.generated.d.ts.map +1 -1
- package/dist/src/types.js +4 -3
- package/dist/src/types.js.map +1 -1
- package/package.json +2 -2
- package/plurnk.md +14 -12
- package/dist/schema/LoopPolicy.json +0 -41
- package/dist/schema/LoopPolicyRequest.json +0 -16
package/.env.defaults
CHANGED
|
@@ -7,5 +7,5 @@ PLURNK_HOST=127.0.0.1
|
|
|
7
7
|
# The daemon's TCP port, shared by all client interfaces.
|
|
8
8
|
PLURNK_PORT=1066
|
|
9
9
|
# The whole URL a client dials instead: a remote portal, or a daemon bound to an address no
|
|
10
|
-
# client can dial (0.0.0.0). Unset = http://$PLURNK_HOST:$PLURNK_PORT.
|
|
10
|
+
# client can dial (0.0.0.0). Unset = http://$PLURNK_HOST:$PLURNK_PORT/agui.
|
|
11
11
|
# PLURNK_AGUI_URL=
|
package/README.md
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
# @plurnk/plurnk-contracts
|
|
2
2
|
|
|
3
3
|
The single authority for PLURNK's model-facing language contract, its AST,
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
{§root-value-api}.
|
|
4
|
+
shared schemas and types, runtime-neutral Problems, operation results,
|
|
5
|
+
Notices, and text coordinates. See SPEC {§root-value-api}.
|
|
7
6
|
|
|
8
7
|
## Install
|
|
9
8
|
|
|
@@ -27,8 +26,7 @@ Requires Node.js 26 or newer.
|
|
|
27
26
|
JSON Schema owns shared wire shapes, generated TypeScript projects those
|
|
28
27
|
shapes, and ANTLR owns accepted model-language syntax. See SPEC
|
|
29
28
|
{§contract-representations}. An operator who wants constrained sampling on a
|
|
30
|
-
llama-server route writes their own GBNF and points `PLURNK_PROVIDERS_GBNF` at
|
|
31
|
-
it; this package ships no grammar profile.
|
|
29
|
+
llama-server route writes their own GBNF and points `PLURNK_PROVIDERS_GBNF` at it.
|
|
32
30
|
|
|
33
31
|
## Parser
|
|
34
32
|
|
package/SPEC.md
CHANGED
|
@@ -10,7 +10,7 @@ runtime-neutral wire envelopes; `@plurnk/plurnk-parser` implements the language
|
|
|
10
10
|
| Surface | Canonical export or artifact |
|
|
11
11
|
| ------------------------------------------------------------------------------- | --------------------------------------------------- |
|
|
12
12
|
| AST, validators, Problems, results, Notices, text regions and extents | `@plurnk/plurnk-contracts` |
|
|
13
|
-
| Capability and
|
|
13
|
+
| Capability admission and approval ownership | `CapabilityPolicy`, `WorkerOwner`, `ProposalPolicy`, `PROPOSAL_POLICIES` |
|
|
14
14
|
| Durable effort | `Effort`, `EFFORTS` |
|
|
15
15
|
| Model route and catalog discovery | `ModelRoute`, `ModelCatalogQuery`, `ModelCatalogPage`, `ModelReadiness` |
|
|
16
16
|
| Stopped-world client contract | `ProposalDisposition`, `ProposalProjection` |
|
|
@@ -28,8 +28,8 @@ runtime-neutral wire envelopes; `@plurnk/plurnk-parser` implements the language
|
|
|
28
28
|
|
|
29
29
|
§contract-representations JSON Schema is authoritative for shared data shapes. TypeScript types are
|
|
30
30
|
generated from the schemas; ANTLR is authoritative for accepted model-language
|
|
31
|
-
syntax.
|
|
32
|
-
|
|
31
|
+
syntax. An operator's own GBNF is carried verbatim to a llama-server route by
|
|
32
|
+
the providers package.
|
|
33
33
|
|
|
34
34
|
§agui-discovery-contract `AguiDiscovery` is the complete installed AG-UI+
|
|
35
35
|
surface at one instant. `schemaVersion` identifies its discovery shape;
|
|
@@ -128,7 +128,7 @@ meaning, including registered scheme resolution, target existence, tag
|
|
|
128
128
|
selection, text-region bounds, result ordering, full-text ranking, mutation
|
|
129
129
|
effects, and executor behavior.
|
|
130
130
|
|
|
131
|
-
### §contract-proposal-projection
|
|
131
|
+
### §contract-proposal-projection Admission policy and stopped-world projection
|
|
132
132
|
|
|
133
133
|
The schemas own the runtime-neutral shapes; core owns their stateful values.
|
|
134
134
|
|
|
@@ -137,9 +137,10 @@ The schemas own the runtime-neutral shapes; core owns their stateful values.
|
|
|
137
137
|
| `CapabilityDescriptor` | One routed operation demand with its operation, access class, resource/runtime/tool coordinates, and declared traits | Derive every demand before dispatch |
|
|
138
138
|
| `CapabilityPolicy` | Exact `only`/`deny` selectors; omitted `only` is unrestricted and present empty `only` denies all | Intersect service and workspace layers |
|
|
139
139
|
| `CapabilityProjection` | Exact service, workspace, and normalized effective policies | Expose the resolver's workspace cascade without claiming one layer is effective authority |
|
|
140
|
-
| `
|
|
141
|
-
| `
|
|
142
|
-
| `
|
|
140
|
+
| `WorkerOwner` | Nonempty address, unique client-tool names, and whether it is interactive | Persist by workspace; inherit through worker creation |
|
|
141
|
+
| `ProposalPolicy` | `review`, `accept`, or `reject` | Read the server's disposition knob at the proposal boundary |
|
|
142
|
+
| `ProposalDisposition` | Review, or automatic accept/reject with optional outcome | Select once for the pending gate |
|
|
143
|
+
| `ProposalProjection` | Identity, review target, body/attrs, owner, stale signal, disposition | One validated projection for live delivery and reconnect |
|
|
143
144
|
| `ProviderUsage` | Conventional input/output totals with cache and reasoning details | Preserve observed quantities without replacing absence with zero |
|
|
144
145
|
| `ProviderCost` | Exact charged, estimated, or unknown monetary evidence | Normalize one monetary disposition for each physical provider request |
|
|
145
146
|
| `ProviderRequestAccounting` | Usage and cost evidence for one physical provider request | Preserve request order across retries, failover, success, and failure |
|
|
@@ -163,19 +164,18 @@ than hidden policy behavior.
|
|
|
163
164
|
|
|
164
165
|
§capability-policy-projection A `CapabilityProjection` reports every durable
|
|
165
166
|
workspace layer and their normalized intersection: `service`, `workspace`, and
|
|
166
|
-
`effective`. Only `workspace` is client-mutable. Workers and loops
|
|
167
|
-
capability policy
|
|
168
|
-
policy.
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
classification and proposal settlement.
|
|
167
|
+
`effective`. Only `workspace` is client-mutable. Workers and loops store no
|
|
168
|
+
capability policy and inherit no bound; every actor uses the same live workspace
|
|
169
|
+
policy. Core derives one further ring per asking worker from its owner, and it only
|
|
170
|
+
removes interaction runtimes ({§owner-interaction-ring}). A client never derives
|
|
171
|
+
effective authority from the mutable layer alone.
|
|
172
|
+
|
|
173
|
+
§proposal-policy `ProposalPolicy` names one server disposition; `PROPOSAL_POLICIES`
|
|
174
|
+
is its schema-owned vocabulary. `WorkerOwner` carries an address, the client-tool
|
|
175
|
+
names that recipient implements, and `interactive`: whether a person attends it. Neither
|
|
176
|
+
contains resource permissions or
|
|
177
|
+
message-carried authority. Core owns persistence, inheritance and settlement
|
|
178
|
+
({§worker-ownership}, {§proposal-disposition}); capability admission precedes approval.
|
|
179
179
|
|
|
180
180
|
§effort-wire `Effort` is exactly `off | adaptive | low |
|
|
181
181
|
medium | high | xhigh | max`. The schema owns this shared wire vocabulary. Providers own the
|
|
@@ -314,7 +314,8 @@ column-zero line outside any block containing a native operation's name and at m
|
|
|
314
314
|
`<!-- aside -->`, with only horizontal whitespace otherwise, opens that operation as if it were
|
|
315
315
|
fenced with the taught three backticks. The aside retains its ordinary meaning: no target or
|
|
316
316
|
modifiers are inferred. Its body runs to a line that is exactly the name
|
|
317
|
-
again, to the next heading ({§fence-heading-in-body}), or to the end of the turn
|
|
317
|
+
again, to the next heading ({§fence-heading-in-body}), or to the end of the turn, except
|
|
318
|
+
parameterless KILL always takes the remaining answer region ({§terminal-kill}). A fence inside
|
|
318
319
|
naming nothing known is body; the block expects no closer, so its body is never cut
|
|
319
320
|
back ({§closer-fallback}). A naked `KILL` alone holds every fence inside it as text ({§naked-kill}). It runs, and one warning-severity receipt follows its statement —
|
|
320
321
|
`` `KILL` opened with no fence; the taught form is three backticks. `` One rule for every native
|
|
@@ -330,8 +331,8 @@ read this way.
|
|
|
330
331
|
§fence-heading-in-body Outside a complete nested block ({§balanced-fences}), a fence
|
|
331
332
|
line of three or more backticks and a name that is a native operation or a known executor
|
|
332
333
|
is a heading. Inside an open block it either ends that block without closing it and opens the
|
|
333
|
-
next statement, or it is a literal example held by the block
|
|
334
|
-
the
|
|
334
|
+
next statement, or it is a literal example held by the block. {§fence-pairing} chooses between
|
|
335
|
+
the two; parameterless KILL always holds the remaining input ({§terminal-kill}). Fence lines of
|
|
335
336
|
fewer than three backticks are never headings ({§operation-fences}). Known executors are `sh`
|
|
336
337
|
plus what the host names in `ParseOptions.executors`. Inside a parameterless `KILL` a
|
|
337
338
|
heading never ends the block ({§terminal-kill}).
|
|
@@ -445,11 +446,13 @@ heading. An operation example quoted in a body of its own width therefore reads
|
|
|
445
446
|
closing and the example running; the wider outer fence or the tab offset quotes it
|
|
446
447
|
({§operation-fences}).
|
|
447
448
|
|
|
448
|
-
§terminal-kill **A KILL
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
and
|
|
449
|
+
§terminal-kill **A parameterless KILL starts the final answer region.** Once its heading is
|
|
450
|
+
recognized as an operation, the rest of the input is its literal body. A fence cannot return
|
|
451
|
+
that region to executable operations or outside text. Apparent operations, receipts and malformed
|
|
452
|
+
fences within it are answer text. An actual enclosing closer at the end is framing, not body;
|
|
453
|
+
an earlier fence remains body. Compact and recovered naked spellings obey the same boundary.
|
|
454
|
+
Quoted KILL examples do not open this region; targeted KILL retains ordinary statement framing.
|
|
455
|
+
Earlier operations still execute and completion remains subject to {§kill-conclusion}.
|
|
453
456
|
|
|
454
457
|
§prose-code-blocks **A message or a prompt shows code.** Inside a `SEND`, `WORK`, `FORK` or `BARE`
|
|
455
458
|
body, at any depth, a heading that names an executor (` ```sh `, ` ```python3 `) is a code block the
|
|
@@ -460,8 +463,8 @@ operation. In the distinct recorded benchmark emissions an executor heading ende
|
|
|
460
463
|
run218, run114 and run118, deepdumb run44) was the child's task, the prompt's code or code quoted in
|
|
461
464
|
a report, and reading it as an operation truncated the task and ran the example in the parent.
|
|
462
465
|
|
|
463
|
-
§message-run-on **A message runs to the end of the turn.** A
|
|
464
|
-
|
|
466
|
+
§message-run-on **A message runs to the end of the turn.** A `SEND`, `WORK`, `FORK` or `BARE`
|
|
467
|
+
whose block reaches the end of the input without its closer takes it
|
|
465
468
|
there with no repair: the text after its last inner block is still the deliverable, the message
|
|
466
469
|
or the task, never outside text. The run counts as a supplied closer, so a reading that closes at
|
|
467
470
|
a real fence still wins, and it never costs an operation: when the reading that runs on hides more
|
|
@@ -470,11 +473,9 @@ operations the author wrote than the best repaired reading, the repaired reading
|
|
|
470
473
|
inner fence keep what followed it (the qflash run192, run90 and run210 deliverables regain their last
|
|
471
474
|
sections), one echoed transcript (glm run155) runs one more operation, and none loses one.
|
|
472
475
|
|
|
473
|
-
§naked-kill **A naked KILL
|
|
474
|
-
a fence ({§naked-operation}), with or without an aside,
|
|
475
|
-
|
|
476
|
-
inside a fenced KILL ({§terminal-kill}), and the block ends only at its name alone on a line or at
|
|
477
|
-
the end of the input. No operation the deliverable shows runs.
|
|
476
|
+
§naked-kill **A naked KILL obeys the same answer boundary.** A parameterless `KILL` opened without
|
|
477
|
+
a fence ({§naked-operation}), with or without an aside, takes the remaining input under
|
|
478
|
+
{§terminal-kill}. A repeated name can close it only at the end; it never exposes later operations.
|
|
478
479
|
|
|
479
480
|
§pairing-witness **Witnesses.**
|
|
480
481
|
|
|
@@ -683,10 +684,7 @@ repeat the complete selection/metadata group per operand. ANTLR accepts
|
|
|
683
684
|
adjacent slots and scope/metadata permutations within a selection without
|
|
684
685
|
changing ownership or making them distinct canonical forms. Each selection
|
|
685
686
|
has at most one scope; its metadata blocks retain their authored order. A second scope
|
|
686
|
-
is refused
|
|
687
|
-
(`<91> <@abcde>`, a copied row prefix) recovers to the anchor alone, two other single
|
|
688
|
-
positions to one scope with both ends (`<@abcde> <-1>` to `<@abcde,-1>`), and anything
|
|
689
|
-
else to one operation per selection.
|
|
687
|
+
is refused; the recovery is the scope's working form ({§parse-recovery}).
|
|
690
688
|
|
|
691
689
|
§lifecycle-slots NOTE accepts no target, scope, or metadata. WAIT retains its
|
|
692
690
|
optional target and duration under {§send-wait-scope}. Their literal bodies begin
|
|
@@ -716,14 +714,11 @@ are never split. Each URI inherits its slot's scope and metadata and compiles th
|
|
|
716
714
|
BARE and NOTE take no scope, and neither does a SEND without a recipient; a `<…>` slot on such a
|
|
717
715
|
heading, in any position, is skipped and the operation runs, with one warning-severity advisory
|
|
718
716
|
naming the operation's slots and the dropped scope — `` `WORK` takes a target only; the scope
|
|
719
|
-
`<1,-1>` was ignored.
|
|
717
|
+
`<1,-1>` was ignored. `` (`` `NOTE` takes no target or
|
|
720
718
|
scope; … ``, `` `SEND` without a recipient takes no scope; … ``). An aside is never a scope, a
|
|
721
719
|
recipient SEND keeps its scope for the recipient ({§send-directed-scope}), and WAIT follows
|
|
722
720
|
{§send-wait-scope}. There is no ambiguity: the operation has one reading with or without
|
|
723
|
-
the slot.
|
|
724
|
-
dead; in the distinct recorded emissions one heading carried the form (zai run426,
|
|
725
|
-
```` ```WORK (worker://deprecation-implementer) <1,-1> ````), beside two recipient SENDs whose scope
|
|
726
|
-
the recipient refuses at runtime.
|
|
721
|
+
the slot.
|
|
727
722
|
|
|
728
723
|
§heading-inline-body Nonempty body text belongs below the fence header. Text after the slots
|
|
729
724
|
on the heading line is read by the operation's shape, by the builder that reads that operation,
|
|
@@ -755,9 +750,8 @@ written on the heading line — under {§heading-inline-body}. The host names th
|
|
|
755
750
|
(`ParseOptions.jsonBodyExecutors`). A heading that already carries a block keeps the object as
|
|
756
751
|
inline body. On FIND, READ and KILL the same text is the matcher
|
|
757
752
|
({§naked-pattern}), because a search for JSON text is legitimate; a bare matcher
|
|
758
|
-
that parses as a JSON object draws one advisory
|
|
759
|
-
|
|
760
|
-
learned in the turn it happens.
|
|
753
|
+
that parses as a JSON object draws one advisory saying so: "`{…}` was read as the
|
|
754
|
+
matcher." ({§diagnostic-observation}).
|
|
761
755
|
|
|
762
756
|
§operation-aside The final header modifier may be one single-line HTML
|
|
763
757
|
comment. AstBuilder removes its delimiters and surrounding whitespace into
|
|
@@ -790,8 +784,8 @@ Worker; the shared reader withholds both from the owner's options.
|
|
|
790
784
|
|
|
791
785
|
§matcher-option **`pattern` is the matcher, and it lives in the heading.** On
|
|
792
786
|
FIND, READ, KILL, EDIT, and each COPY/MOVE operand, the option
|
|
793
|
-
`[{"pattern": "<matcher>"}]` carries the matcher string
|
|
794
|
-
|
|
787
|
+
`[{"pattern": "<matcher>"}]` carries the matcher string: the leading prefix
|
|
788
|
+
claims its dialect under {§matcher-prefix-claims}, and
|
|
795
789
|
AstBuilder lifts it into the statement's `matcher` (`MatcherBody | null`),
|
|
796
790
|
positioned dialect errors included. A block that carries only `pattern`
|
|
797
791
|
leaves `metadata: null` for the owner; beside other keys the block stays with
|
|
@@ -800,10 +794,9 @@ language lifts only from one block that parses as a JSON array of objects;
|
|
|
800
794
|
anything else lifts nothing and reaches the owner's `400` untouched. A
|
|
801
795
|
`pattern` that is present but not a string is the language's own positioned
|
|
802
796
|
diagnostic, as is a matcher of a claimed dialect that fails admission. FIND,
|
|
803
|
-
READ, and targeted KILL take no body: a body beneath their heading is
|
|
804
|
-
the operation still runs, with one warning-severity advisory naming the
|
|
805
|
-
|
|
806
|
-
on the opening fence line after the path.`); it is never silently read as a
|
|
797
|
+
READ, and targeted KILL take no body: a body beneath their heading is not used and
|
|
798
|
+
the operation still runs, with one warning-severity advisory naming the lines not
|
|
799
|
+
used (`FIND takes no body; lines 4–6 were not used.`); it is never silently read as a
|
|
807
800
|
matcher, and it never strikes ({§matcher-body-redirect}). The heading line itself
|
|
808
801
|
is the matcher's home ({§naked-pattern}). A body that is only an HTML comment is
|
|
809
802
|
still the aside under {§misplaced-aside-advisory}. EDIT keeps its literal body:
|
|
@@ -853,10 +846,10 @@ repetition and strike rules still apply.
|
|
|
853
846
|
|
|
854
847
|
§reasoning-operations The shared fence parser admits complete, line-leading NOTE,
|
|
855
848
|
FIND and READ statements from exposed provider reasoning. Admission is part of
|
|
856
|
-
the language
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
849
|
+
the language. Other backtick or tilde code blocks are opaque; heading and
|
|
850
|
+
missing-closer recovery cannot escape them or complete an unfinished reasoning
|
|
851
|
+
operation. Blockquoted and inline examples are not headings. Other reasoned
|
|
852
|
+
operations never execute.
|
|
860
853
|
|
|
861
854
|
Operations are admitted only after the provider response completes; their
|
|
862
855
|
presence never interrupts generation. Selected operations precede the content
|
|
@@ -905,8 +898,7 @@ one park with the earliest bound, including the configured bound for each bare W
|
|
|
905
898
|
|
|
906
899
|
§send-directed-scope A recipient SEND carries an optional numeric scope after
|
|
907
900
|
its target and metadata through to the addressed owner, which assigns its
|
|
908
|
-
semantics or refuses it; worker actors refuse one (`scope-unsupported`, 400)
|
|
909
|
-
because later and recurring delivery belong to the schedule family. A
|
|
901
|
+
semantics or refuses it; worker actors refuse one (`scope-unsupported`, 400). A
|
|
910
902
|
targetless message takes no scope. A scope never changes the message body or
|
|
911
903
|
disposition.
|
|
912
904
|
|
|
@@ -925,12 +917,11 @@ Without a scope, KILL retires or deletes the whole target; with one, it removes
|
|
|
925
917
|
that span — of a log body's packet projection or of an entry's content. Core owns the
|
|
926
918
|
one-way semantics: there is no operation that restores a scoped-away log body.
|
|
927
919
|
|
|
928
|
-
§
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
bounded header diagnostic that selects nothing.
|
|
920
|
+
§bracket-metadata-slot Brackets are the owner's metadata modifier: the runtime
|
|
921
|
+
or MCP service is the fence name, and tool input belongs in the body. A bracket
|
|
922
|
+
block that leads an executor fence or follows a target is metadata for that
|
|
923
|
+
owner; a bracket before the target of a non-executor OP is one bounded header
|
|
924
|
+
diagnostic that selects nothing.
|
|
934
925
|
|
|
935
926
|
The `<scope>` slot is optional where admitted and its domain is OP-specific. FIND
|
|
936
927
|
scopes ordered results. Executions and SEND scope owner-defined timing. READ, EDIT, COPY,
|
|
@@ -987,7 +978,7 @@ same bare spelling the receipt used: a model that appends the channel to the pat
|
|
|
987
978
|
shown addresses the same entry, and so does one that writes it after the parenthesis,
|
|
988
979
|
`(page.html) #readable`, which {§naked-pattern} reads as the channel. `raw` is therefore always the path alone; a
|
|
989
980
|
bare path never contains a literal `#`, and `PlurnkParser.stringify` renders the channel back.
|
|
990
|
-
Without a `#` the field is absent
|
|
981
|
+
Without a `#` the field is absent.
|
|
991
982
|
|
|
992
983
|
§read-exact-target READ targets one exact resource (a local path or scheme
|
|
993
984
|
URL, with optional `#channel` fragment or `[metadata]`) and has no body. A
|
|
@@ -1299,8 +1290,8 @@ operation receives empty-turn recovery, not successful completion ({§empty-turn
|
|
|
1299
1290
|
|
|
1300
1291
|
The model may supply WAIT or request completion with parameterless KILL. The host, not the grammar, owns
|
|
1301
1292
|
turn boundaries and adjudicates the loop's actual obligations. Asking
|
|
1302
|
-
the human
|
|
1303
|
-
disposition. The shape rules ARE structural:
|
|
1293
|
+
the human uses the native `question` executor tool, offered only when a person attends the
|
|
1294
|
+
worker's owner ({§owner-interaction-ring}), not a disposition. The shape rules ARE structural:
|
|
1304
1295
|
|
|
1305
1296
|
- §send-mid-reservation WAIT is reserved ({§turn-disposition}).
|
|
1306
1297
|
A turn admits any number of lifecycle declarations, anywhere among its
|
|
@@ -1311,6 +1302,8 @@ disposition. The shape rules ARE structural:
|
|
|
1311
1302
|
dispositions until the other admitted operations settle
|
|
1312
1303
|
({§op-execution-order}). Nothing is dropped and no diagnostic is raised for
|
|
1313
1304
|
position. Omission does not synthesize a disposition ({§turn-shape}).
|
|
1305
|
+
This applies to WAIT, not to the literal answer region opened by parameterless KILL
|
|
1306
|
+
({§terminal-kill}).
|
|
1314
1307
|
- SEND is communication: an optional recipient path and an optional body.
|
|
1315
1308
|
- §park-202-only WAIT joins live work: an open stream or a live
|
|
1316
1309
|
child. With none, it continues. Its optional duration bounds parking ({§send-wait-scope});
|
|
@@ -1459,7 +1452,7 @@ among them: the parser is `@plurnk/plurnk-parser`'s ({§parser-consumers}).
|
|
|
1459
1452
|
| `TurnDisposition` | The one turn disposition and its recognition | {§turn-disposition} |
|
|
1460
1453
|
| `CapabilityAdmission` | Admission of a capability descriptor against policy layers | {§capability-admission} |
|
|
1461
1454
|
| `PLURNK_OPS`, `INTERNAL_ROW_OPS`, `PLURNK_FENCE` | The closed operation alphabet and the language's fence | {§canonical-statement} |
|
|
1462
|
-
| `PROPOSAL_POLICIES`
|
|
1455
|
+
| `PROPOSAL_POLICIES` | Server proposal disposition vocabulary | {§proposal-policy} |
|
|
1463
1456
|
| `WORKER_NAME` | Authority minting predicate | {§worker-name} |
|
|
1464
1457
|
| `UNKNOWN_POSITION` | Frozen sentinel for an AST statement without retained parsed source | {§parser-position} |
|
|
1465
1458
|
|
|
@@ -1562,12 +1555,19 @@ schema, this suffix invariant, and Problem status equality.
|
|
|
1562
1555
|
| 100–399 | `problem` is forbidden |
|
|
1563
1556
|
| 400–599 | One RFC 9457 `problem` object is required |
|
|
1564
1557
|
|
|
1565
|
-
|
|
1566
|
-
|
|
1558
|
+
Producer-specific success fields and Problem Details extension members remain
|
|
1559
|
+
open. A malformed result is
|
|
1567
1560
|
an internal producer contract violation; it is not converted into a second
|
|
1568
1561
|
model-facing failure envelope.
|
|
1569
1562
|
|
|
1570
|
-
### 13.5 Problem Details
|
|
1563
|
+
### 13.5 Diagnostics and Problem Details
|
|
1564
|
+
|
|
1565
|
+
§diagnostic-observation **A diagnostic says what happened, never why.** Every Problem `detail`
|
|
1566
|
+
and `recovery`, parse diagnostic and notice names what was read, what was done with it, and
|
|
1567
|
+
where, and may show the working form of the construct it read or refused. It never names a cause
|
|
1568
|
+
or an intent the input does not establish: no likely mistake, no reconstruction of what the author
|
|
1569
|
+
meant, no alternative the producer did not apply, and no form the language no longer has. Each
|
|
1570
|
+
sentence presupposes only what the producer itself decided.
|
|
1571
1571
|
|
|
1572
1572
|
§problem-details `ProblemDetails` requires `type`, `title`, `status`, and `detail`;
|
|
1573
1573
|
`instance` is optional until a durable host can attach the occurrence URI.
|
|
@@ -1585,8 +1585,8 @@ model-facing failure envelope.
|
|
|
1585
1585
|
| extensions | Factual producer-known operands or constraints |
|
|
1586
1586
|
|
|
1587
1587
|
`detail` is failure truth; `recovery` is not a second explanation. Producers do
|
|
1588
|
-
not
|
|
1589
|
-
|
|
1588
|
+
not blame the model, restate status, or expose an implementation accident as the
|
|
1589
|
+
cause ({§diagnostic-observation}). General syntax and workflow teaching remain in the model
|
|
1590
1590
|
packet rather than being repeated in every Problem.
|
|
1591
1591
|
|
|
1592
1592
|
`Problems.create(owner, code, status, detail, extensions?, options?)` derives a
|
|
@@ -1764,17 +1764,14 @@ class PlurnkParseError extends Error {
|
|
|
1764
1764
|
```
|
|
1765
1765
|
|
|
1766
1766
|
§parse-recovery **Every hard diagnostic carries its working form.** A `severity: "error"`
|
|
1767
|
-
diagnostic names, in `recovery`, the form
|
|
1768
|
-
carries the operation's canonical line (`` `READ (path) <L,M>? pattern? <!-- aside -->?`
|
|
1769
|
-
opening fence line; READ takes no body. ``), a refused
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
carries none, since its statement ran. A refused matcher carries the same pair into its own
|
|
1776
|
-
operation's Problem ({§matcher-refusal}). Before this, a refused regex (`/*url*/`, DeepSeek run429)
|
|
1777
|
-
reported `Nothing to repeat` with no way forward and the turn was spent.
|
|
1767
|
+
diagnostic names, in `recovery`, the form of the construct it refused, in the model's terms: a
|
|
1768
|
+
refused heading carries the operation's canonical line (`` `READ (path) <L,M>? pattern? <!-- aside -->?`
|
|
1769
|
+
on the opening fence line; READ takes no body. ``), a refused scope the scope's form, and a refused
|
|
1770
|
+
matcher its dialect's form with an example (`` A pattern is a regex written `/pattern/flags`, such
|
|
1771
|
+
as `/timeout/i`. ``). The working form is the language's, never a reconstruction of the input
|
|
1772
|
+
({§diagnostic-observation}). The runtime projects `recovery` as the Problem's `recovery` beside the
|
|
1773
|
+
verbatim `message`; an advisory carries none, since its statement ran. A refused matcher carries
|
|
1774
|
+
the same pair into its own operation's Problem ({§matcher-refusal}).
|
|
1778
1775
|
|
|
1779
1776
|
§parser-position Parser source locations are points, not text regions. An AST
|
|
1780
1777
|
statement's `position` identifies the first backtick of its header; a diagnostic
|
|
@@ -1870,15 +1867,9 @@ diagnostics are:
|
|
|
1870
1867
|
`FIND (src/parser.ts) [{"pattern": "/\\bparse\\w+\\b/"}]`. `^` claims the regex
|
|
1871
1868
|
dialect without slashes or flags: the whole text is the pattern, so
|
|
1872
1869
|
`READ (notes.md) ^Decision:.*` selects lines beginning with `Decision:`.
|
|
1873
|
-
`^` is deliberately absent from `plurnk.md`'s dialect table
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
was taught to, and the engine honours what it will reach for anyway. Teaching it would
|
|
1877
|
-
spend hot-path weight on a line that changes no behaviour. The omission is therefore not
|
|
1878
|
-
drift between the teaching and the engine, and closing it in either direction is a
|
|
1879
|
-
regression: restoring the row pays for nothing, and retiring the prefix makes the
|
|
1880
|
-
pretrained spelling a glob that matches a literal caret — silence in place of the
|
|
1881
|
-
selection the model asked for.
|
|
1870
|
+
`^` is deliberately absent from `plurnk.md`'s dialect table: a model writes the anchor
|
|
1871
|
+
whether or not it is taught, so the engine honours it without spending hot-path teaching
|
|
1872
|
+
on it. The omission is not drift between the teaching and the engine.
|
|
1882
1873
|
- §trailing-slots **Slots after the matcher peel off the right.** The heading text after
|
|
1883
1874
|
the matcher is read backwards: a trailing `<!-- aside -->`, a trailing `<scope>` in the
|
|
1884
1875
|
shapes the lexer admits (result positions on FIND, text coordinates elsewhere) and a
|
|
@@ -1916,9 +1907,9 @@ diagnostics are:
|
|
|
1916
1907
|
- §bare-target **A target written without its parentheses is refused with the line that runs.**
|
|
1917
1908
|
A FIND, READ or EDIT heading with no target whose heading text opens with a word that is no
|
|
1918
1909
|
matcher sigil, `READ a.py <1,4>`, cannot run: the word stands where the target goes, but on FIND it
|
|
1919
|
-
could as well be a pattern. The statement is one hard diagnostic
|
|
1920
|
-
`` `READ` has no target: `a.py` stands where the target goes.
|
|
1921
|
-
|
|
1910
|
+
could as well be a pattern. The statement is one hard diagnostic,
|
|
1911
|
+
`` `READ` has no target: `a.py` stands where the target goes. ``, whose recovery is the operation's
|
|
1912
|
+
working form ({§parse-recovery}). A targetless KILL's heading text remains its inline deliverable.
|
|
1922
1913
|
- §bare-anchor-scope **An EDIT's anchor without its angle brackets is its scope.** On an EDIT
|
|
1923
1914
|
heading, `@abcde` or `@abcde,@fghij` standing alone where the scope goes — nothing but an aside, a
|
|
1924
1915
|
closer or the line end after it — is the scope `<@abcde>`, with one warning-severity advisory:
|
|
@@ -1927,9 +1918,9 @@ diagnostics are:
|
|
|
1927
1918
|
marker (14 distinct recorded headings). On READ and KILL the same text stays a literal matcher,
|
|
1928
1919
|
since `@patch` is a search a model means.
|
|
1929
1920
|
- §matcher-body-redirect **Unread body text on bodyless operations.** FIND, READ and bodyless
|
|
1930
|
-
KILL keep the statement but
|
|
1931
|
-
`READ takes no body;
|
|
1932
|
-
|
|
1921
|
+
KILL keep the statement but do not use text the matcher did not consume, with one warning
|
|
1922
|
+
naming where it stands: `READ takes no body; lines 4–38 were not used.`, or `the text after its
|
|
1923
|
+
heading on line 3` when it shares the heading's line. KILL's advisory says `This KILL`, limiting the claim to that invocation:
|
|
1933
1924
|
parameterless completion and log distillation bodies remain valid. Delivered like
|
|
1934
1925
|
{§misplaced-aside-advisory} as a `parse_advisory` notice (a warning, never an error).
|
|
1935
1926
|
One sigil line beneath a bodyless heading is the bare form written a line low and still lifts;
|
|
@@ -1960,33 +1951,33 @@ diagnostics are:
|
|
|
1960
1951
|
with any other content is ignored under the same advisory path
|
|
1961
1952
|
({§matcher-body-redirect}).
|
|
1962
1953
|
|
|
1963
|
-
§error-shape The diagnostic class determines
|
|
1964
|
-
|
|
1954
|
+
§error-shape The diagnostic class determines the parts of a message; every class says what
|
|
1955
|
+
happened, never why ({§diagnostic-observation}). Advisories belong to one successfully built statement. A rejected
|
|
1965
1956
|
statement emits its hard diagnostic, not normalization advisories; neither a
|
|
1966
1957
|
rejection nor an internal exception carries advisories into another statement
|
|
1967
1958
|
or parser invocation.
|
|
1968
1959
|
|
|
1969
|
-
| Class
|
|
1970
|
-
|
|
1971
|
-
| Hard fact
|
|
1972
|
-
|
|
|
1973
|
-
|
|
|
1974
|
-
| Boundary loss | `unparsedTail` | Where trust ends, which header slot remains open, and why later input is undefined. |
|
|
1960
|
+
| Class | Surface | Message contract |
|
|
1961
|
+
|---------------|-----------------------|-------------------------------------------------------------------------------------------------------------------|
|
|
1962
|
+
| Hard fact | `severity: "error"` | What was read, where, and the constraint it violates, in PLURNK vocabulary; `recovery` is the construct's working form ({§parse-recovery}). |
|
|
1963
|
+
| Advisory | `severity: "warning"` | What was read and what was done with it, read as a named construct or not used, and where; the statement remains admitted. |
|
|
1964
|
+
| Boundary loss | `unparsedTail` | Where trust ends and which header slot remains open; later input is undefined. |
|
|
1975
1965
|
|
|
1976
1966
|
All messages use PLURNK protocol vocabulary: opening fence, closing fence, target,
|
|
1977
1967
|
scope, line marker, body, section boundary, or space between slots. They never
|
|
1978
1968
|
expose ANTLR rule or token names. They refer to a slot or
|
|
1979
|
-
feature rather than an implementation rule. Generic tutoring,
|
|
1980
|
-
|
|
1969
|
+
feature rather than an implementation rule. Generic tutoring, coordinate
|
|
1970
|
+
restatement and multiple repair strategies are forbidden, and no message names an
|
|
1971
|
+
intent ({§diagnostic-observation}).
|
|
1981
1972
|
Unexpected top-level text immediately after a closed operation identifies that
|
|
1982
1973
|
operation's opening line, closing line, and matching backtick count.
|
|
1983
1974
|
|
|
1984
1975
|
Examples of canonical hard facts:
|
|
1985
1976
|
|
|
1986
1977
|
- `unrecognized character '<' in target`
|
|
1987
|
-
- `
|
|
1978
|
+
- `unrecognized character '[' in the sh header`
|
|
1988
1979
|
- `unrecognized character 'X' in statement header`
|
|
1989
|
-
- `
|
|
1980
|
+
- `unrecognized character '[' in the WAIT header`
|
|
1990
1981
|
- `expected ')'; got ':'`
|
|
1991
1982
|
|
|
1992
1983
|
Each malformed statement produces at most one hard error. The first recorded
|
|
@@ -70,8 +70,11 @@
|
|
|
70
70
|
"model": null,
|
|
71
71
|
"loopId": null,
|
|
72
72
|
"packetCount": 0,
|
|
73
|
+
"waitUntil": null,
|
|
73
74
|
"preparation": [],
|
|
74
|
-
"activity": null
|
|
75
|
+
"activity": null,
|
|
76
|
+
"children": 0,
|
|
77
|
+
"descendants": { "requests": 0, "usage": null, "knownUsage": null, "costUsd": null, "knownCostUsd": null }
|
|
75
78
|
}
|
|
76
79
|
},
|
|
77
80
|
"budget": {}
|
|
@@ -4,13 +4,14 @@
|
|
|
4
4
|
"title": "ClientInteractionProjection",
|
|
5
5
|
"description": "The runtime-neutral client-interface projection of one pending client interaction. Live delivery and reconnect discovery expose this same shape.",
|
|
6
6
|
"type": "object",
|
|
7
|
-
"required": ["interactionId", "workerId", "loopId", "turnId", "request"],
|
|
7
|
+
"required": ["interactionId", "workerId", "loopId", "turnId", "recipient", "request"],
|
|
8
8
|
"additionalProperties": false,
|
|
9
9
|
"properties": {
|
|
10
10
|
"interactionId": { "type": "integer", "minimum": 1 },
|
|
11
11
|
"workerId": { "type": "integer", "minimum": 1 },
|
|
12
12
|
"loopId": { "type": "integer", "minimum": 1 },
|
|
13
13
|
"turnId": { "type": "integer", "minimum": 1 },
|
|
14
|
+
"recipient": { "type": "string", "minLength": 1 },
|
|
14
15
|
"request": { "$ref": "https://schemas.plurnk.xyz/v0/ClientInteractionRequest.json" }
|
|
15
16
|
}
|
|
16
17
|
}
|
package/dist/schema/Notice.json
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"kind": {
|
|
16
16
|
"type": "string",
|
|
17
17
|
"minLength": 1,
|
|
18
|
-
"description": "Open discriminator within a source. Examples include `
|
|
18
|
+
"description": "Open discriminator within a source. Examples include `output_unaccounted`, `search_progress`, and `turn_awaiting_model`."
|
|
19
19
|
},
|
|
20
20
|
"level": {
|
|
21
21
|
"enum": ["error", "warn", "info"],
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
3
|
"$id": "https://schemas.plurnk.xyz/v0/OperationResult.json",
|
|
4
4
|
"title": "OperationResult",
|
|
5
|
-
"description": "Universal PLURNK operation result. Producer-owned metadata is open, but failures always carry one RFC 9457 Problem Details object
|
|
5
|
+
"description": "Universal PLURNK operation result. Producer-owned metadata is open, but failures always carry one RFC 9457 Problem Details object.",
|
|
6
6
|
"type": "object",
|
|
7
7
|
"required": ["status"],
|
|
8
8
|
"additionalProperties": true,
|
|
@@ -17,8 +17,7 @@
|
|
|
17
17
|
},
|
|
18
18
|
"range": {
|
|
19
19
|
"$ref": "https://schemas.plurnk.xyz/v0/RangeExtent.json"
|
|
20
|
-
}
|
|
21
|
-
"error": false
|
|
20
|
+
}
|
|
22
21
|
},
|
|
23
22
|
"oneOf": [
|
|
24
23
|
{
|
|
@@ -2,22 +2,21 @@
|
|
|
2
2
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
3
|
"$id": "https://schemas.plurnk.xyz/v0/ProposalDisposition.json",
|
|
4
4
|
"title": "ProposalDisposition",
|
|
5
|
-
"description": "The one core-owned settlement decision
|
|
5
|
+
"description": "The one core-owned settlement decision. Review waits for the worker's owner; accept and reject carry the automatic resolution core applies.",
|
|
6
6
|
"oneOf": [
|
|
7
7
|
{
|
|
8
8
|
"type": "object",
|
|
9
|
-
"required": ["
|
|
9
|
+
"required": ["decision"],
|
|
10
10
|
"additionalProperties": false,
|
|
11
11
|
"properties": {
|
|
12
|
-
"
|
|
12
|
+
"decision": { "const": "review" }
|
|
13
13
|
}
|
|
14
14
|
},
|
|
15
15
|
{
|
|
16
16
|
"type": "object",
|
|
17
|
-
"required": ["
|
|
17
|
+
"required": ["decision"],
|
|
18
18
|
"additionalProperties": false,
|
|
19
19
|
"properties": {
|
|
20
|
-
"owner": { "const": "loop" },
|
|
21
20
|
"decision": { "enum": ["accept", "reject"] },
|
|
22
21
|
"outcome": { "type": "string", "minLength": 1 }
|
|
23
22
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://schemas.plurnk.xyz/v0/ProposalPolicy.json",
|
|
4
|
+
"title": "ProposalPolicy",
|
|
5
|
+
"description": "Server disposition for proposals. Review requires the worker's owner; accept and reject settle within core.",
|
|
6
|
+
"enum": ["review", "accept", "reject"]
|
|
7
|
+
}
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"target",
|
|
14
14
|
"body",
|
|
15
15
|
"attrs",
|
|
16
|
-
"
|
|
16
|
+
"owner",
|
|
17
17
|
"disposition"
|
|
18
18
|
],
|
|
19
19
|
"additionalProperties": false,
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
},
|
|
43
43
|
"body": { "type": "string" },
|
|
44
44
|
"attrs": { "type": "object", "additionalProperties": true },
|
|
45
|
-
"
|
|
45
|
+
"owner": { "type": "string", "minLength": 1 },
|
|
46
46
|
"disposition": { "$ref": "https://schemas.plurnk.xyz/v0/ProposalDisposition.json" }
|
|
47
47
|
}
|
|
48
48
|
}
|