@cotal-ai/core 0.16.0 → 0.18.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.
Files changed (145) hide show
  1. package/dist/acls.d.ts +21 -0
  2. package/dist/acls.d.ts.map +1 -1
  3. package/dist/acls.js +44 -1
  4. package/dist/acls.js.map +1 -1
  5. package/dist/artifact.d.ts +45 -0
  6. package/dist/artifact.d.ts.map +1 -0
  7. package/dist/artifact.js +82 -0
  8. package/dist/artifact.js.map +1 -0
  9. package/dist/backup-config.d.ts +9 -2
  10. package/dist/backup-config.d.ts.map +1 -1
  11. package/dist/backup-config.js +6 -2
  12. package/dist/backup-config.js.map +1 -1
  13. package/dist/broker-tls.d.ts +70 -0
  14. package/dist/broker-tls.d.ts.map +1 -0
  15. package/dist/broker-tls.js +195 -0
  16. package/dist/broker-tls.js.map +1 -0
  17. package/dist/canonical.d.ts +14 -1
  18. package/dist/canonical.d.ts.map +1 -1
  19. package/dist/canonical.js +21 -1
  20. package/dist/canonical.js.map +1 -1
  21. package/dist/channels.js +4 -4
  22. package/dist/channels.js.map +1 -1
  23. package/dist/endpoint-action.d.ts +108 -3
  24. package/dist/endpoint-action.d.ts.map +1 -1
  25. package/dist/endpoint-action.js +209 -20
  26. package/dist/endpoint-action.js.map +1 -1
  27. package/dist/endpoint-binding.d.ts +138 -8
  28. package/dist/endpoint-binding.d.ts.map +1 -1
  29. package/dist/endpoint-binding.js +233 -26
  30. package/dist/endpoint-binding.js.map +1 -1
  31. package/dist/endpoint-contract-store.d.ts +30 -1
  32. package/dist/endpoint-contract-store.d.ts.map +1 -1
  33. package/dist/endpoint-contract-store.js +100 -29
  34. package/dist/endpoint-contract-store.js.map +1 -1
  35. package/dist/endpoint-envelope.d.ts +15 -37
  36. package/dist/endpoint-envelope.d.ts.map +1 -1
  37. package/dist/endpoint-envelope.js +93 -44
  38. package/dist/endpoint-envelope.js.map +1 -1
  39. package/dist/endpoint-error.d.ts +33 -0
  40. package/dist/endpoint-error.d.ts.map +1 -0
  41. package/dist/endpoint-error.js +34 -0
  42. package/dist/endpoint-error.js.map +1 -0
  43. package/dist/endpoint-grants.d.ts +63 -7
  44. package/dist/endpoint-grants.d.ts.map +1 -1
  45. package/dist/endpoint-grants.js +118 -9
  46. package/dist/endpoint-grants.js.map +1 -1
  47. package/dist/endpoint-invoke.d.ts +138 -0
  48. package/dist/endpoint-invoke.d.ts.map +1 -0
  49. package/dist/endpoint-invoke.js +393 -0
  50. package/dist/endpoint-invoke.js.map +1 -0
  51. package/dist/endpoint-records.d.ts.map +1 -1
  52. package/dist/endpoint-records.js +17 -0
  53. package/dist/endpoint-records.js.map +1 -1
  54. package/dist/endpoint-serve-kv.d.ts +97 -0
  55. package/dist/endpoint-serve-kv.d.ts.map +1 -0
  56. package/dist/endpoint-serve-kv.js +336 -0
  57. package/dist/endpoint-serve-kv.js.map +1 -0
  58. package/dist/endpoint-serve.d.ts.map +1 -1
  59. package/dist/endpoint-serve.js +21 -1
  60. package/dist/endpoint-serve.js.map +1 -1
  61. package/dist/endpoint-service.d.ts +1 -1
  62. package/dist/endpoint-service.d.ts.map +1 -1
  63. package/dist/endpoint-service.js +34 -10
  64. package/dist/endpoint-service.js.map +1 -1
  65. package/dist/endpoint-session-rail.d.ts +127 -0
  66. package/dist/endpoint-session-rail.d.ts.map +1 -0
  67. package/dist/endpoint-session-rail.js +325 -0
  68. package/dist/endpoint-session-rail.js.map +1 -0
  69. package/dist/endpoint-session.d.ts +1 -115
  70. package/dist/endpoint-session.d.ts.map +1 -1
  71. package/dist/endpoint-session.js +4 -316
  72. package/dist/endpoint-session.js.map +1 -1
  73. package/dist/endpoint-subjects.d.ts +20 -1
  74. package/dist/endpoint-subjects.d.ts.map +1 -1
  75. package/dist/endpoint-subjects.js +20 -1
  76. package/dist/endpoint-subjects.js.map +1 -1
  77. package/dist/endpoint-verbs.d.ts +1 -2
  78. package/dist/endpoint-verbs.d.ts.map +1 -1
  79. package/dist/endpoint-verbs.js +6 -6
  80. package/dist/endpoint-verbs.js.map +1 -1
  81. package/dist/endpoint.d.ts +157 -11
  82. package/dist/endpoint.d.ts.map +1 -1
  83. package/dist/endpoint.js +471 -47
  84. package/dist/endpoint.js.map +1 -1
  85. package/dist/evict.d.ts +47 -0
  86. package/dist/evict.d.ts.map +1 -1
  87. package/dist/evict.js +191 -59
  88. package/dist/evict.js.map +1 -1
  89. package/dist/identity.d.ts +34 -0
  90. package/dist/identity.d.ts.map +1 -1
  91. package/dist/identity.js +46 -0
  92. package/dist/identity.js.map +1 -1
  93. package/dist/index.d.ts +8 -0
  94. package/dist/index.d.ts.map +1 -1
  95. package/dist/index.js +8 -0
  96. package/dist/index.js.map +1 -1
  97. package/dist/kv-scan.d.ts +8 -0
  98. package/dist/kv-scan.d.ts.map +1 -1
  99. package/dist/kv-scan.js +8 -0
  100. package/dist/kv-scan.js.map +1 -1
  101. package/dist/lease.d.ts +12 -5
  102. package/dist/lease.d.ts.map +1 -1
  103. package/dist/lease.js.map +1 -1
  104. package/dist/lifecycle-saga.d.ts +174 -0
  105. package/dist/lifecycle-saga.d.ts.map +1 -0
  106. package/dist/lifecycle-saga.js +418 -0
  107. package/dist/lifecycle-saga.js.map +1 -0
  108. package/dist/lifecycle-state.d.ts +202 -0
  109. package/dist/lifecycle-state.d.ts.map +1 -0
  110. package/dist/lifecycle-state.js +347 -0
  111. package/dist/lifecycle-state.js.map +1 -0
  112. package/dist/parts.d.ts +13 -0
  113. package/dist/parts.d.ts.map +1 -0
  114. package/dist/parts.js +17 -0
  115. package/dist/parts.js.map +1 -0
  116. package/dist/provision.d.ts +124 -15
  117. package/dist/provision.d.ts.map +1 -1
  118. package/dist/provision.js +578 -121
  119. package/dist/provision.js.map +1 -1
  120. package/dist/schema-profile.d.ts +3 -2
  121. package/dist/schema-profile.d.ts.map +1 -1
  122. package/dist/schema-profile.js +242 -18
  123. package/dist/schema-profile.js.map +1 -1
  124. package/dist/session-browser.d.ts +15 -0
  125. package/dist/session-browser.d.ts.map +1 -0
  126. package/dist/session-browser.js +14 -0
  127. package/dist/session-browser.js.map +1 -0
  128. package/dist/session-terminal-frames.d.ts +36 -0
  129. package/dist/session-terminal-frames.d.ts.map +1 -0
  130. package/dist/session-terminal-frames.js +149 -0
  131. package/dist/session-terminal-frames.js.map +1 -0
  132. package/dist/spaces.d.ts.map +1 -1
  133. package/dist/spaces.js +6 -1
  134. package/dist/spaces.js.map +1 -1
  135. package/dist/streams.d.ts +168 -1
  136. package/dist/streams.d.ts.map +1 -1
  137. package/dist/streams.js +299 -21
  138. package/dist/streams.js.map +1 -1
  139. package/dist/subjects.d.ts +34 -36
  140. package/dist/subjects.d.ts.map +1 -1
  141. package/dist/subjects.js +46 -35
  142. package/dist/subjects.js.map +1 -1
  143. package/dist/types.d.ts +27 -1
  144. package/dist/types.d.ts.map +1 -1
  145. package/package.json +6 -1
@@ -37,6 +37,15 @@ export declare function retirementFrontierStreams(space: string): string[];
37
37
  * grant — and `allow_direct=false`: every fence on it is a leader-served revision-pinned CAS,
38
38
  * and Direct Get's follower/mirror reads would defeat read-your-writes (§13.1). */
39
39
  export declare function epAuthBucket(space: string): string;
40
+ /** The per-space SESSION ledger store (P2 item 6, §13.6): the `session.<id>` rows the manager's
41
+ * session plane CASes over. DEDICATED — split out of the auth bucket deliberately. KV reads are
42
+ * subject-BLIND (a `STREAM.MSG.GET` on a bucket serves any key, the campaign's known vector class),
43
+ * so co-locating session rows with credentials + gates would let the standing session-ledger cred read
44
+ * the whole control plane. A dedicated bucket makes that blind read STRUCTURALLY confined to session
45
+ * rows and nothing else. `allow_direct=false` for the SAME reason the auth bucket carries it: every
46
+ * ledger fence is a leader-served revision-pinned CAS (the one-use `createIssuing`, the finalize +
47
+ * terminal updates), and Direct Get's follower/mirror reads would defeat read-your-writes (§13.1). */
48
+ export declare function sessionsBucket(space: string): string;
40
49
  /** EPJ duplicate window: the server MINIMUM (100 ms), set explicitly. A `0` is not accepted
41
50
  * (it normalizes to the 120 s default), and native dedupe is deliberately NOT relied upon —
42
51
  * submitters never set `Nats-Msg-Id`, and a wide window is exactly the cross-caller
@@ -75,13 +84,62 @@ export interface EndpointStreamOptions {
75
84
  }
76
85
  /**
77
86
  * Create (idempotently) the §13.12 per-space control-surface resources: the seven JetStream
78
- * streams, the work-pool WorkQueue, and the two KV buckets. Privileged runs at space setup.
79
- * `jsm.streams.add`/`kvm.create` are idempotent for an identical config and FAIL LOUD on a
80
- * config delta, which is wanted: a drifted resource is an operator error, never silently adopted.
87
+ * streams, the work-pool WorkQueue, and the KV buckets (records + auth + the §13.6 session ledger).
88
+ * Privileged — runs at space setup. `jsm.streams.add`/`kvm.create` are idempotent for an identical
89
+ * config and FAIL LOUD on a config delta, which is wanted: a drifted resource is an operator error,
90
+ * never silently adopted.
81
91
  *
82
- * Sessions (`eps`) are deliberately absent: core-only, never captured (§13.12).
92
+ * The session byte SUBJECTS (`eps`) are deliberately absent: core-only, never captured (§13.12).
93
+ * Only the durable `session.<id>` ledger rows are captured — in their own dedicated bucket
94
+ * ({@link createSessionsStore}), never the auth bucket.
83
95
  */
84
96
  export declare function createEndpointStreams(jsm: JetStreamManager, kvm: Kvm, space: string, opts?: EndpointStreamOptions): Promise<void>;
97
+ /**
98
+ * Ensure the per-space CONTRACT store (EPC) exists with its normative shape (§13.7/§13.12) —
99
+ * content-addressed artifacts, one immutable message per digest subject, create-only mediated
100
+ * publication, NO age eviction (artifacts are permanent). allow_direct: the subject-scoped
101
+ * last-by-subject read IS the fetch path.
102
+ *
103
+ * PER-SUBJECT IMMUTABILITY is BROKER-ENFORCED, not left to publisher cooperation (the append-shadow
104
+ * blocker, live-confirmed by the panel). The create-only fence `Nats-Expected-Last-Subject-Sequence:
105
+ * 0` is a publisher-SET header the `epc.*` publish grant cannot compel, so a non-cooperative
106
+ * grant-holder could APPEND a second message to an already-published digest subject; `last_by_subj`
107
+ * would then return that shadow and a fail-closed read would make the honest artifact permanently
108
+ * unfetchable (deny_delete/deny_purge block recovery — an operator-reprovision-only DoS, and at
109
+ * §13.11's ep-only cut the SOLE contract path). The store closes this at the SOURCE:
110
+ * `max_msgs_per_subject: 1` + `discard: new` + `discard_new_per_subject: true` makes a second
111
+ * publish to an occupied digest subject BROKER-REJECTED (err 10077) regardless of headers, so a
112
+ * digest subject holds exactly one message forever. `deny_delete`/`deny_purge` then keep that one
113
+ * message from being removed. (The read path additionally defends itself version-agnostically —
114
+ * {@link fetchContractArtifact} prefers the create-only winner over any shadow — so a broker or a
115
+ * legacy stream that lacked the per-subject cap is still safe.)
116
+ *
117
+ * Create-or-verify-AND-harden, safe at every authority-daemon boot (the {@link
118
+ * ensureAuthorityStores} discipline): a fresh space gets the store created with the full shape; a
119
+ * CLEAN pre-existing store (incl. a pre-hardening one from an earlier release, OR the config-A
120
+ * footgun `max_msgs_per_subject:1` + `discard:old` that would DELETE the honest artifact) is UPDATED
121
+ * to the three config-B flags (idempotent, like the records store's rollup/deny update) and then
122
+ * VERIFIED - a shape that cannot be brought to config B FAILS LOUD, never silently adopted.
123
+ *
124
+ * The config-B upgrade ENFORCES per-subject immutability GOING FORWARD; it does NOT heal a shadow
125
+ * that predates it. Applying `max_msgs_per_subject:1` trims each subject to its newest message, so a
126
+ * legacy store that ALREADY holds a shadow (some digest subject with >1 message) would have the
127
+ * honest create-only winner trimmed away and the shadow cemented. Rather than silently cement it,
128
+ * the upgrade REFUSES LOUD on such a store (`messages > num_subjects`), so the operator reprovisions
129
+ * a clean store. This is a narrow guard: a fresh deploy is born at config B and never reaches it.
130
+ *
131
+ * FAIL-LOUD IS THE AGENT'S DEFENSE (critic completeness item): because this verify refuses to serve
132
+ * unless all three config-B flags are present, the manager NEVER serves an un-hardened EPC store —
133
+ * so a shadow-append cannot exist on any store an agent reads. That is why the ordinary agent
134
+ * baseline needs only the subject-scoped `last_by_subj` read (never the bare `next_by_subj` the
135
+ * shadow fallback uses): on every store the manager actually serves, `last_by_subj` always verifies
136
+ * and the fallback never triggers. The {@link fetchContractArtifact} create-only-winner fallback is
137
+ * defense-in-depth for the publisher path (the executor, which holds `next_by_subj`) and for a
138
+ * hypothetical un-hardened store the manager would refuse to serve anyway. On the pinned broker
139
+ * floor (nats-server >= 2.12, well past the 2.9 that added `discard_new_per_subject`) config B always
140
+ * lands; an older broker that ignores the flag is caught here and the daemon fails to start.
141
+ */
142
+ export declare function ensureContractStore(jsm: JetStreamManager, space: string): Promise<void>;
85
143
  /**
86
144
  * Ensure the two per-space AUTHORITY stores exist with their normative shape (§13.12):
87
145
  *
@@ -98,6 +156,18 @@ export declare function createEndpointStreams(jsm: JetStreamManager, kvm: Kvm, s
98
156
  * silently adopted (§13.12: the flags are load-bearing for deny-new and the barrier CAS fences).
99
157
  */
100
158
  export declare function ensureAuthorityStores(jsm: JetStreamManager, kvm: Kvm, space: string): Promise<void>;
159
+ /** Create (idempotently) the per-space SESSION ledger store (P2 item 6, §13.6): the DEDICATED
160
+ * {@link sessionsBucket} the manager's session plane CASes `session.<id>` rows over. Kept OUT of
161
+ * {@link ensureAuthorityStores} deliberately — the auth path never touches session rows, and the
162
+ * manager provisions this store from its own boot — but it wears the SAME authority-store shape as
163
+ * the auth bucket: `allow_direct=false` (every ledger fence is a leader-served revision-pinned CAS,
164
+ * and Direct Get's follower reads would defeat read-your-writes, §13.1) plus the per-key TTL
165
+ * machinery (a terminal/expired session row can carry a delete-marker TTL). The dedication is the
166
+ * security substance: the standing session-ledger cred's `kv.get` is a bucket-blind body-selected read,
167
+ * and a bucket holding ONLY `session.>` rows makes that read expose nothing but session state — the
168
+ * structural fix for the §13.9 subject-blindness a shared auth bucket would carry (creds + gates).
169
+ * Create-or-verify, safe at every manager boot; a drifted store FAILS LOUD (§13.12). */
170
+ export declare function createSessionsStore(jsm: JetStreamManager, kvm: Kvm, space: string): Promise<void>;
101
171
  /** `poolD = pool_<e>_<pool>` — parses uniquely from its LAST `_` because a pool token contains
102
172
  * no `_` (`[a-z0-9-]`) while `<e>` may. */
103
173
  export declare function poolDurable(endpoint: string, pool: string): string;
@@ -321,6 +391,60 @@ export declare function commitPrincipalGrants(space: string, endpoint: string, c
321
391
  publish: string[];
322
392
  subscribe: string[];
323
393
  };
394
+ /** The SELF-MEDIATED GOAL-WRITER profile (P2 item 2 "spawn becomes an action"): a standing
395
+ * connection that both BINDS a goal at accept AND COMMITS its terminal, for an endpoint that
396
+ * accepts action goals INLINE on its ephemeral serve handler (Model B) rather than through a
397
+ * separate canonicalizer + effects executor. It is exactly {@link commitPrincipalGrants} (the
398
+ * `goal.*.*.*.*.result` terminal + `$KV.<records>.goal.<e>.>` record write + the two leader-served
399
+ * `STREAM.MSG.GET` fencing reads the substrate uses) PLUS the ONE row commitPrincipalGrants
400
+ * deliberately leaves to the canonicalizer — the goal `.bind` leaf
401
+ * (`epf.<e>.goal.*.*.*.*.bind`) — so this single principal owns the whole `accepted → terminal`
402
+ * goal-fact chain of its OWN endpoint. The endpoint's SERVE credential
403
+ * ({@link import("./endpoint-grants.js").epServePublishRows}) holds NONE of these: a serve
404
+ * connection is broker-DENIED every goal write, which is the item-2 privilege separation (the
405
+ * dedicated writer is minted on a distinct connection, the serve rails stay serve-only). All of
406
+ * commitPrincipalGrants' D32 residuals carry unchanged (payload-blind create-only publish; raw
407
+ * `$KV` cannot enforce the per-key CAS the substrate layers on; the two body-selected
408
+ * `STREAM.MSG.GET` reads expose EPF + records space-wide). The reply inbox is connection-scoped
409
+ * (`_INBOX_<connId>.>`). The `eff`/`wrk`/`receipt`/`cp`/`lease` families in the commit-principal
410
+ * base are inert for a goal-only endpoint (the manager writes none) but are the commit-principal
411
+ * profile's standard ceiling; a tighter goal-only ceiling is a follow-up if the panel prefers it. */
412
+ export declare function goalWriterGrants(space: string, endpoint: string, connId: string): {
413
+ publish: string[];
414
+ subscribe: string[];
415
+ };
416
+ /** The manager's SESSION-LEDGER rows (P2 item 6): the standing connection that owns the §13.6
417
+ * session ledger and NOTHING else. It holds NO session rail — not the wildcard it used to hold,
418
+ * not an exact one. That is the whole point of the split.
419
+ *
420
+ * §13.6 gives the ledger a job the byte rails do not have: it is "a DURABLE named authority that
421
+ * survives the serving endpoint", the thing that still knows what to revoke after the endpoint
422
+ * serving a session is gone. So it is standing and renewable, while the rails it records are
423
+ * per-session, exact-subject, and die with their session ({@link import("./provision.js").Profile}
424
+ * `session-serving` / `session-caller`). An earlier revision fused the two into one standing
425
+ * credential carrying `eps.<endpoint>.*.<epoch>.{in,out}`, which contradicted §13.9:2526 ("no
426
+ * standing EPS grant exists on either side") and let one credential read and write every live
427
+ * session's bytes at that epoch. Splitting on the lifetime boundary is what removes the wildcard:
428
+ * the standing half no longer has rails to widen.
429
+ *
430
+ * Its store is the DEDICATED {@link sessionsBucket}, NOT the auth bucket. The write is
431
+ * `$KV.<sessions>.session.*` (create-only CAS + revision-pinned update; `sessionLedgerKey` is the
432
+ * single-token `session.<id>`). The read is a bucket-blind leader `STREAM.MSG.GET` (allow_direct=
433
+ * false, so `kv.get` is a body-selected read that cannot be key-pinned) — but the dedicated bucket
434
+ * holds ONLY `session.>` rows, so that blind read exposes nothing but session ledger state,
435
+ * structurally closing the §13.9 subject-blindness the auth bucket carries (creds + gates). The
436
+ * reply inbox is connection-scoped. NO auth-bucket, records-bucket, or messaging-plane grant.
437
+ *
438
+ * NAMED RESIDUAL: `session.*` is one token wide and carries no endpoint component, because a
439
+ * `sessionId` is an opaque unguessable token with no endpoint inside it. So this credential can
440
+ * read and CAS any session row in its space, including another endpoint's. That was equally true
441
+ * of the credential it replaces; it is not a regression, and it is confined to ledger STATE — row
442
+ * state and credential ids — never to session bytes, which now require a per-session credential
443
+ * this profile cannot mint. */
444
+ export declare function sessionLedgerGrants(space: string, connId: string): {
445
+ publish: string[];
446
+ subscribe: string[];
447
+ };
324
448
  /** The CONTRACT PUBLISHER principal's rows (§13.9 matrix "Contract-artifact publication" +
325
449
  * the trusted-infra half of "Contract-artifact read"): publish `epc.*` (the digest-hex is ONE
326
450
  * subject token; create-only rides `Nats-Expected-Last-Subject-Sequence: 0` at the typed path,
@@ -332,10 +456,16 @@ export declare function commitPrincipalGrants(space: string, endpoint: string, c
332
456
  * connection-scoped (`_INBOX_<connId>.>`, never the account-wide default).
333
457
  *
334
458
  * D32 residuals, EXPLICIT: (1) the `epc.*` publish is payload-blind — a compromised publisher
335
- * can flood NEW digest subjects with garbage artifacts (verify-on-read refuses to SERVE
336
- * non-canonical or digest-mismatched bytes, and an existing digest subject is CAS-protected,
337
- * so it can waste storage but never corrupt or replace a published artifact); (2) the raw JS
338
- * API request carries a caller-selected reply subject (the same confused-deputy injection
459
+ * can publish garbage artifacts at NEW (previously-unused) digest subjects (verify-on-read refuses
460
+ * to SERVE non-canonical or digest-mismatched bytes, so this is a bounded storage flood carrying
461
+ * no authority). It can NOT overwrite, shadow, or replace an EXISTING published artifact: the EPC
462
+ * store's shape ({@link ensureContractStore}: `max_msgs_per_subject:1` + discard-new-per-subject)
463
+ * makes a second publish to an occupied digest subject broker-REJECTED regardless of the
464
+ * create-only header, so per-subject immutability is broker-enforced, not publisher-cooperative.
465
+ * (Earlier revisions relied on the cooperative create-only header alone and a fail-closed read,
466
+ * which the panel's live repro showed a non-cooperative publisher could defeat by raw append — a
467
+ * permanent shadow-DoS; the stream shape + the create-only-winner read fallback close it.) (2) the
468
+ * raw JS API request carries a caller-selected reply subject (the same confused-deputy injection
339
469
  * class as every API-holding profile). */
340
470
  export declare function contractPublisherGrants(space: string, connId: string): {
341
471
  publish: string[];
@@ -1 +1 @@
1
- {"version":3,"file":"endpoint-binding.d.ts","sourceRoot":"","sources":["../src/endpoint-binding.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"endpoint-binding.d.ts","sourceRoot":"","sources":["../src/endpoint-binding.ts"],"names":[],"mappings":"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"}
@@ -9,7 +9,7 @@
9
9
  * created by exactly one trusted principal (provisioner or the owning infra principal) and the
10
10
  * §13.9 grant rows are generated against these same names and filters.
11
11
  */
12
- import { AckPolicy, DeliverPolicy, RetentionPolicy, StorageType, } from "@nats-io/jetstream";
12
+ import { AckPolicy, DeliverPolicy, DiscardPolicy, RetentionPolicy, StorageType, } from "@nats-io/jetstream";
13
13
  import { nanos } from "@nats-io/transport-node";
14
14
  import { spacePrefix, token, assertInboxConnId } from "./subjects.js";
15
15
  import { endpointToken, assertIdToken, assertGrantId, assertPoolToken, assertLifecycleToken, callerTokens, } from "./endpoint-subjects.js";
@@ -44,6 +44,17 @@ export function retirementFrontierStreams(space) {
44
44
  export function epAuthBucket(space) {
45
45
  return `cotal_auth_${token(space)}`;
46
46
  }
47
+ /** The per-space SESSION ledger store (P2 item 6, §13.6): the `session.<id>` rows the manager's
48
+ * session plane CASes over. DEDICATED — split out of the auth bucket deliberately. KV reads are
49
+ * subject-BLIND (a `STREAM.MSG.GET` on a bucket serves any key, the campaign's known vector class),
50
+ * so co-locating session rows with credentials + gates would let the standing session-ledger cred read
51
+ * the whole control plane. A dedicated bucket makes that blind read STRUCTURALLY confined to session
52
+ * rows and nothing else. `allow_direct=false` for the SAME reason the auth bucket carries it: every
53
+ * ledger fence is a leader-served revision-pinned CAS (the one-use `createIssuing`, the finalize +
54
+ * terminal updates), and Direct Get's follower/mirror reads would defeat read-your-writes (§13.1). */
55
+ export function sessionsBucket(space) {
56
+ return `cotal_sessions_${token(space)}`;
57
+ }
47
58
  // ---- §13.12 retention knobs (documented defaults, overridable per space policy) ----
48
59
  /** EPJ duplicate window: the server MINIMUM (100 ms), set explicitly. A `0` is not accepted
49
60
  * (it normalizes to the 120 s default), and native dedupe is deliberately NOT relied upon —
@@ -70,11 +81,14 @@ export const EP_TIMER_MAX_AGE_MS = 31 * 24 * 60 * 60 * 1000;
70
81
  export const EP_AUTH_MARKER_TTL_MS = 60 * 60 * 1000;
71
82
  /**
72
83
  * Create (idempotently) the §13.12 per-space control-surface resources: the seven JetStream
73
- * streams, the work-pool WorkQueue, and the two KV buckets. Privileged runs at space setup.
74
- * `jsm.streams.add`/`kvm.create` are idempotent for an identical config and FAIL LOUD on a
75
- * config delta, which is wanted: a drifted resource is an operator error, never silently adopted.
84
+ * streams, the work-pool WorkQueue, and the KV buckets (records + auth + the §13.6 session ledger).
85
+ * Privileged — runs at space setup. `jsm.streams.add`/`kvm.create` are idempotent for an identical
86
+ * config and FAIL LOUD on a config delta, which is wanted: a drifted resource is an operator error,
87
+ * never silently adopted.
76
88
  *
77
- * Sessions (`eps`) are deliberately absent: core-only, never captured (§13.12).
89
+ * The session byte SUBJECTS (`eps`) are deliberately absent: core-only, never captured (§13.12).
90
+ * Only the durable `session.<id>` ledger rows are captured — in their own dedicated bucket
91
+ * ({@link createSessionsStore}), never the auth bucket.
78
92
  */
79
93
  export async function createEndpointStreams(jsm, kvm, space, opts = {}) {
80
94
  const p = spacePrefix(space);
@@ -148,24 +162,109 @@ export async function createEndpointStreams(jsm, kvm, space, opts = {}) {
148
162
  storage: StorageType.File,
149
163
  allow_direct: false,
150
164
  });
151
- // EPC — content-addressed contract artifacts: one immutable message per digest subject,
152
- // create-only mediated publication, NO age eviction (artifacts are permanent). allow_direct:
153
- // the subject-scoped last-by-subject read IS the fetch path. Permanence is BROKER-ENFORCED,
154
- // not just configured-by-omission: deny_delete/deny_purge reject the message-delete and purge
155
- // APIs even from a stream-API-holding principal, so a digest subject cannot be emptied and
156
- // re-created through them. Per §13.12 the flags alone are NOT the whole claim: permanence is
157
- // their COMBINATION with the retention floor (no age eviction, no teardown), verify-on-read
158
- // pinning WHAT a subject carries, and stream management held by no profile.
159
- await jsm.streams.add({
160
- name: epcStreamName(space),
161
- subjects: [`${p}.epc.>`],
162
- retention: RetentionPolicy.Limits,
163
- storage: StorageType.File,
164
- allow_direct: true,
165
- deny_delete: true,
166
- deny_purge: true,
167
- });
165
+ await ensureContractStore(jsm, space);
168
166
  await ensureAuthorityStores(jsm, kvm, space);
167
+ // P2 item 6: the DEDICATED §13.6 session ledger bucket. The eps byte SUBJECTS stay core-only and
168
+ // uncaptured (above), but the `session.<id>` ledger rows are a captured authority KV — kept in
169
+ // their own bucket so the manager's standing session-ledger cred's bucket-blind STREAM.MSG.GET reads
170
+ // ONLY session rows (the §13.9 subject-blindness structural fix). Provisioned here so every mesh
171
+ // that ensures the endpoint streams (auth + open both run this at the manager's boot) has it.
172
+ await createSessionsStore(jsm, kvm, space);
173
+ }
174
+ /**
175
+ * Ensure the per-space CONTRACT store (EPC) exists with its normative shape (§13.7/§13.12) —
176
+ * content-addressed artifacts, one immutable message per digest subject, create-only mediated
177
+ * publication, NO age eviction (artifacts are permanent). allow_direct: the subject-scoped
178
+ * last-by-subject read IS the fetch path.
179
+ *
180
+ * PER-SUBJECT IMMUTABILITY is BROKER-ENFORCED, not left to publisher cooperation (the append-shadow
181
+ * blocker, live-confirmed by the panel). The create-only fence `Nats-Expected-Last-Subject-Sequence:
182
+ * 0` is a publisher-SET header the `epc.*` publish grant cannot compel, so a non-cooperative
183
+ * grant-holder could APPEND a second message to an already-published digest subject; `last_by_subj`
184
+ * would then return that shadow and a fail-closed read would make the honest artifact permanently
185
+ * unfetchable (deny_delete/deny_purge block recovery — an operator-reprovision-only DoS, and at
186
+ * §13.11's ep-only cut the SOLE contract path). The store closes this at the SOURCE:
187
+ * `max_msgs_per_subject: 1` + `discard: new` + `discard_new_per_subject: true` makes a second
188
+ * publish to an occupied digest subject BROKER-REJECTED (err 10077) regardless of headers, so a
189
+ * digest subject holds exactly one message forever. `deny_delete`/`deny_purge` then keep that one
190
+ * message from being removed. (The read path additionally defends itself version-agnostically —
191
+ * {@link fetchContractArtifact} prefers the create-only winner over any shadow — so a broker or a
192
+ * legacy stream that lacked the per-subject cap is still safe.)
193
+ *
194
+ * Create-or-verify-AND-harden, safe at every authority-daemon boot (the {@link
195
+ * ensureAuthorityStores} discipline): a fresh space gets the store created with the full shape; a
196
+ * CLEAN pre-existing store (incl. a pre-hardening one from an earlier release, OR the config-A
197
+ * footgun `max_msgs_per_subject:1` + `discard:old` that would DELETE the honest artifact) is UPDATED
198
+ * to the three config-B flags (idempotent, like the records store's rollup/deny update) and then
199
+ * VERIFIED - a shape that cannot be brought to config B FAILS LOUD, never silently adopted.
200
+ *
201
+ * The config-B upgrade ENFORCES per-subject immutability GOING FORWARD; it does NOT heal a shadow
202
+ * that predates it. Applying `max_msgs_per_subject:1` trims each subject to its newest message, so a
203
+ * legacy store that ALREADY holds a shadow (some digest subject with >1 message) would have the
204
+ * honest create-only winner trimmed away and the shadow cemented. Rather than silently cement it,
205
+ * the upgrade REFUSES LOUD on such a store (`messages > num_subjects`), so the operator reprovisions
206
+ * a clean store. This is a narrow guard: a fresh deploy is born at config B and never reaches it.
207
+ *
208
+ * FAIL-LOUD IS THE AGENT'S DEFENSE (critic completeness item): because this verify refuses to serve
209
+ * unless all three config-B flags are present, the manager NEVER serves an un-hardened EPC store —
210
+ * so a shadow-append cannot exist on any store an agent reads. That is why the ordinary agent
211
+ * baseline needs only the subject-scoped `last_by_subj` read (never the bare `next_by_subj` the
212
+ * shadow fallback uses): on every store the manager actually serves, `last_by_subj` always verifies
213
+ * and the fallback never triggers. The {@link fetchContractArtifact} create-only-winner fallback is
214
+ * defense-in-depth for the publisher path (the executor, which holds `next_by_subj`) and for a
215
+ * hypothetical un-hardened store the manager would refuse to serve anyway. On the pinned broker
216
+ * floor (nats-server >= 2.12, well past the 2.9 that added `discard_new_per_subject`) config B always
217
+ * lands; an older broker that ignores the flag is caught here and the daemon fails to start.
218
+ */
219
+ export async function ensureContractStore(jsm, space) {
220
+ const name = epcStreamName(space);
221
+ const subject = `${spacePrefix(space)}.epc.>`;
222
+ const hardening = { max_msgs_per_subject: 1, discard: DiscardPolicy.New, discard_new_per_subject: true };
223
+ if (await jsm.streams.info(name).catch(() => undefined) === undefined) {
224
+ await jsm.streams.add({
225
+ name,
226
+ subjects: [subject],
227
+ retention: RetentionPolicy.Limits,
228
+ storage: StorageType.File,
229
+ allow_direct: true,
230
+ deny_delete: true,
231
+ deny_purge: true,
232
+ ...hardening,
233
+ });
234
+ }
235
+ else {
236
+ // Upgrade path: an EPC stream from a pre-hardening release lacks the per-subject cap. Add it
237
+ // idempotently (a live update of max_msgs_per_subject + discard settings is allowed and, tested,
238
+ // leaves a CLEAN store's artifacts intact). A stream that WON'T take the update surfaces at the
239
+ // verify below.
240
+ const info = await jsm.streams.info(name);
241
+ const cur = info.config;
242
+ if (cur.max_msgs_per_subject !== 1 || cur.discard !== DiscardPolicy.New || cur.discard_new_per_subject !== true) {
243
+ // HEAL-OR-FAIL, never cement (critic upgrade-trim residual): applying max_msgs_per_subject:1
244
+ // TRIMS each subject to its NEWEST message. On a CLEAN legacy store (create-only, ≤1 message
245
+ // per subject) that trims nothing. But if a legacy store ALREADY holds a shadow (a raw append
246
+ // left a subject with >1 message, from before this hardening existed), the trim would keep the
247
+ // NEWEST (the shadow) and DELETE the honest create-only winner - cementing the shadow
248
+ // permanently. `messages > num_subjects` is exactly "some subject has more than one message",
249
+ // so refuse the upgrade LOUD there: the operator reprovisions a clean store rather than the
250
+ // daemon silently trim-cementing a pre-existing shadow. (Fresh deploys are born at config B and
251
+ // never reach this; the check only guards a legacy store that was shadowed before its first
252
+ // config-B boot.)
253
+ const { messages, num_subjects } = info.state;
254
+ if (messages > 0 && (num_subjects === undefined || messages > num_subjects))
255
+ throw new Error(`the contract store ${name} is a pre-hardening stream that cannot be proven clean (${messages} messages across ${String(num_subjects)} subjects) - a subject holding more than one message means a shadow-append predates this immutability upgrade, and applying the per-subject cap would TRIM to the newest (shadow) message and delete the honest artifact; reprovision a clean store rather than cement the shadow (SPEC 13.7/13.12)`);
256
+ await jsm.streams.update(name, { ...cur, ...hardening });
257
+ }
258
+ }
259
+ const cfg = (await jsm.streams.info(name)).config;
260
+ if (cfg.allow_direct !== true || cfg.deny_delete !== true || cfg.deny_purge !== true)
261
+ throw new Error(`the contract store ${name} has a drifted shape (allow_direct=${String(cfg.allow_direct)}, deny_delete=${String(cfg.deny_delete)}, deny_purge=${String(cfg.deny_purge)}); an authority store is never silently adopted - reprovision it (SPEC 13.12)`);
262
+ if (cfg.max_msgs_per_subject !== 1 || cfg.discard !== DiscardPolicy.New || cfg.discard_new_per_subject !== true)
263
+ throw new Error(`the contract store ${name} does not enforce per-subject immutability (max_msgs_per_subject=${String(cfg.max_msgs_per_subject)}, discard=${String(cfg.discard)}, discard_new_per_subject=${String(cfg.discard_new_per_subject)}); a digest subject must hold exactly one broker-immutable message or an append-shadow can DoS the store - reprovision it (SPEC 13.7/13.12)`);
264
+ if (!Array.isArray(cfg.subjects) || cfg.subjects.length !== 1 || cfg.subjects[0] !== subject)
265
+ throw new Error(`the contract store ${name} does not carry exactly the subject ${subject} (got ${JSON.stringify(cfg.subjects)}); a stream that captures anything else is not the contract store - reprovision it (SPEC 13.12)`);
266
+ if (cfg.storage !== "file")
267
+ throw new Error(`the contract store ${name} has storage ${JSON.stringify(cfg.storage)}, not file; a non-durable contract store forgets permanent artifacts on restart - reprovision it (SPEC 13.12)`);
169
268
  }
170
269
  /**
171
270
  * Ensure the two per-space AUTHORITY stores exist with their normative shape (§13.12):
@@ -209,6 +308,27 @@ export async function ensureAuthorityStores(jsm, kvm, space) {
209
308
  throw new Error(`the auth store ${authBucket} has a drifted shape (allow_direct=${String(authCfg.allow_direct)}, allow_msg_ttl=${String(authCfg.allow_msg_ttl)}); an authority store is never silently adopted - reprovision it (SPEC 13.12)`);
210
309
  assertAuthorityStoreBinding(authCfg, authBucket);
211
310
  }
311
+ /** Create (idempotently) the per-space SESSION ledger store (P2 item 6, §13.6): the DEDICATED
312
+ * {@link sessionsBucket} the manager's session plane CASes `session.<id>` rows over. Kept OUT of
313
+ * {@link ensureAuthorityStores} deliberately — the auth path never touches session rows, and the
314
+ * manager provisions this store from its own boot — but it wears the SAME authority-store shape as
315
+ * the auth bucket: `allow_direct=false` (every ledger fence is a leader-served revision-pinned CAS,
316
+ * and Direct Get's follower reads would defeat read-your-writes, §13.1) plus the per-key TTL
317
+ * machinery (a terminal/expired session row can carry a delete-marker TTL). The dedication is the
318
+ * security substance: the standing session-ledger cred's `kv.get` is a bucket-blind body-selected read,
319
+ * and a bucket holding ONLY `session.>` rows makes that read expose nothing but session state — the
320
+ * structural fix for the §13.9 subject-blindness a shared auth bucket would carry (creds + gates).
321
+ * Create-or-verify, safe at every manager boot; a drifted store FAILS LOUD (§13.12). */
322
+ export async function createSessionsStore(jsm, kvm, space) {
323
+ const bucket = sessionsBucket(space);
324
+ const stream = `KV_${bucket}`;
325
+ if (await jsm.streams.info(stream).catch(() => undefined) === undefined)
326
+ await kvm.create(bucket, { allow_direct: false, markerTTL: EP_AUTH_MARKER_TTL_MS });
327
+ const cfg = (await jsm.streams.info(stream)).config;
328
+ if (cfg.allow_direct !== false || cfg.allow_msg_ttl !== true)
329
+ throw new Error(`the sessions store ${bucket} has a drifted shape (allow_direct=${String(cfg.allow_direct)}, allow_msg_ttl=${String(cfg.allow_msg_ttl)}); an authority store is never silently adopted - reprovision it (SPEC 13.12)`);
330
+ assertAuthorityStoreBinding(cfg, bucket);
331
+ }
212
332
  /** The store-BINDING half of the verify (SPEC 13.12): a stream wearing an authority bucket's name
213
333
  * must BE that KV bucket — exactly the one `$KV.<bucket>.>` subject (an extra captured subject
214
334
  * would put foreign bodies inside every body-selected MSG.GET grant on the stream) and durable
@@ -712,6 +832,9 @@ export function commitPrincipalGrants(space, endpoint, connId) {
712
832
  const p = spacePrefix(space);
713
833
  const records = recordsBucket(space);
714
834
  const publish = [
835
+ // ONE terminal subject per goal (SPEC:1394, the §13.9 "Result/receipt/terminal/resume facts"
836
+ // row): the exact-arity `…result` leaf, never an `…result.*` epoch-scoped variant — a per-epoch
837
+ // subject hid a legitimate pre-restart winner from every reader.
715
838
  `${p}.epf.${e}.goal.*.*.*.*.result`,
716
839
  `${p}.epf.${e}.eff.>`,
717
840
  `${p}.epf.${e}.receipt.>`,
@@ -726,6 +849,84 @@ export function commitPrincipalGrants(space, endpoint, connId) {
726
849
  ];
727
850
  return { publish, subscribe: [`_INBOX_${assertInboxConnId(connId)}.>`] };
728
851
  }
852
+ /** The SELF-MEDIATED GOAL-WRITER profile (P2 item 2 "spawn becomes an action"): a standing
853
+ * connection that both BINDS a goal at accept AND COMMITS its terminal, for an endpoint that
854
+ * accepts action goals INLINE on its ephemeral serve handler (Model B) rather than through a
855
+ * separate canonicalizer + effects executor. It is exactly {@link commitPrincipalGrants} (the
856
+ * `goal.*.*.*.*.result` terminal + `$KV.<records>.goal.<e>.>` record write + the two leader-served
857
+ * `STREAM.MSG.GET` fencing reads the substrate uses) PLUS the ONE row commitPrincipalGrants
858
+ * deliberately leaves to the canonicalizer — the goal `.bind` leaf
859
+ * (`epf.<e>.goal.*.*.*.*.bind`) — so this single principal owns the whole `accepted → terminal`
860
+ * goal-fact chain of its OWN endpoint. The endpoint's SERVE credential
861
+ * ({@link import("./endpoint-grants.js").epServePublishRows}) holds NONE of these: a serve
862
+ * connection is broker-DENIED every goal write, which is the item-2 privilege separation (the
863
+ * dedicated writer is minted on a distinct connection, the serve rails stay serve-only). All of
864
+ * commitPrincipalGrants' D32 residuals carry unchanged (payload-blind create-only publish; raw
865
+ * `$KV` cannot enforce the per-key CAS the substrate layers on; the two body-selected
866
+ * `STREAM.MSG.GET` reads expose EPF + records space-wide). The reply inbox is connection-scoped
867
+ * (`_INBOX_<connId>.>`). The `eff`/`wrk`/`receipt`/`cp`/`lease` families in the commit-principal
868
+ * base are inert for a goal-only endpoint (the manager writes none) but are the commit-principal
869
+ * profile's standard ceiling; a tighter goal-only ceiling is a follow-up if the panel prefers it. */
870
+ export function goalWriterGrants(space, endpoint, connId) {
871
+ const base = commitPrincipalGrants(space, endpoint, connId);
872
+ const e = endpointToken(endpoint);
873
+ const bindLeaf = `${spacePrefix(space)}.epf.${e}.goal.*.*.*.*.bind`;
874
+ // must-5 Q-B — the reconcile index: the goal-writer records each accepted goal under
875
+ // `goalidx.<e>.<caller triple>.<goalId>` (create-only) before the bind and deletes it at the
876
+ // terminal, so a successor incarnation can settle orphaned goals. Key-pinned to THIS endpoint's
877
+ // index subtree; the goal-writer holds NO records CONSUMER.CREATE (the boot sweep enumerates the
878
+ // index over the PROVISIONER, never this standing connection).
879
+ const indexRow = `$KV.${recordsBucket(space)}.goalidx.${e}.>`;
880
+ // must-5 (a) — the own-gate currency belt: the manager reads its OWN issuance gate
881
+ // (`epgate.<e>.<iid>`) over this connection before the first-terminal-fact CAS and skips a
882
+ // superseded commit. The auth store is `allow_direct=false`, so the read is a body-selected
883
+ // leader `STREAM.MSG.GET` that cannot be key-pinned to the single gate key — the SAME residual
884
+ // class the `endpoint-serve-executor` carries (reads any auth-bucket row = gate + ledger
885
+ // metadata, never bearer bytes), here on a standing rather than one-shot connection. The manager
886
+ // reads ONLY `epgate.<e>.<iid>`; (a) is the fast-fail belt, (b) barrier-revoke is the durable fence.
887
+ const gateRead = `${JSAPI}.STREAM.MSG.GET.KV_${epAuthBucket(space)}`;
888
+ return { publish: [bindLeaf, indexRow, gateRead, ...base.publish], subscribe: base.subscribe };
889
+ }
890
+ /** The manager's SESSION-LEDGER rows (P2 item 6): the standing connection that owns the §13.6
891
+ * session ledger and NOTHING else. It holds NO session rail — not the wildcard it used to hold,
892
+ * not an exact one. That is the whole point of the split.
893
+ *
894
+ * §13.6 gives the ledger a job the byte rails do not have: it is "a DURABLE named authority that
895
+ * survives the serving endpoint", the thing that still knows what to revoke after the endpoint
896
+ * serving a session is gone. So it is standing and renewable, while the rails it records are
897
+ * per-session, exact-subject, and die with their session ({@link import("./provision.js").Profile}
898
+ * `session-serving` / `session-caller`). An earlier revision fused the two into one standing
899
+ * credential carrying `eps.<endpoint>.*.<epoch>.{in,out}`, which contradicted §13.9:2526 ("no
900
+ * standing EPS grant exists on either side") and let one credential read and write every live
901
+ * session's bytes at that epoch. Splitting on the lifetime boundary is what removes the wildcard:
902
+ * the standing half no longer has rails to widen.
903
+ *
904
+ * Its store is the DEDICATED {@link sessionsBucket}, NOT the auth bucket. The write is
905
+ * `$KV.<sessions>.session.*` (create-only CAS + revision-pinned update; `sessionLedgerKey` is the
906
+ * single-token `session.<id>`). The read is a bucket-blind leader `STREAM.MSG.GET` (allow_direct=
907
+ * false, so `kv.get` is a body-selected read that cannot be key-pinned) — but the dedicated bucket
908
+ * holds ONLY `session.>` rows, so that blind read exposes nothing but session ledger state,
909
+ * structurally closing the §13.9 subject-blindness the auth bucket carries (creds + gates). The
910
+ * reply inbox is connection-scoped. NO auth-bucket, records-bucket, or messaging-plane grant.
911
+ *
912
+ * NAMED RESIDUAL: `session.*` is one token wide and carries no endpoint component, because a
913
+ * `sessionId` is an opaque unguessable token with no endpoint inside it. So this credential can
914
+ * read and CAS any session row in its space, including another endpoint's. That was equally true
915
+ * of the credential it replaces; it is not a regression, and it is confined to ledger STATE — row
916
+ * state and credential ids — never to session bytes, which now require a per-session credential
917
+ * this profile cannot mint. */
918
+ export function sessionLedgerGrants(space, connId) {
919
+ const SESS = sessionsBucket(space);
920
+ return {
921
+ publish: [
922
+ `$KV.${SESS}.session.*`, // ledger create/update — single-token key (`session.<id>`)
923
+ `${JSAPI}.STREAM.MSG.GET.KV_${SESS}`, // kv.get: leader-served body-selected read, confined to the sessions bucket
924
+ `${JSAPI}.STREAM.INFO.KV_${SESS}`, // Kvm bind probe (§13.12)
925
+ `${JSAPI}.INFO`, // JS-API context info (KV client)
926
+ ],
927
+ subscribe: [`_INBOX_${assertInboxConnId(connId)}.>`], // connection-scoped reply inbox
928
+ };
929
+ }
729
930
  /** The CONTRACT PUBLISHER principal's rows (§13.9 matrix "Contract-artifact publication" +
730
931
  * the trusted-infra half of "Contract-artifact read"): publish `epc.*` (the digest-hex is ONE
731
932
  * subject token; create-only rides `Nats-Expected-Last-Subject-Sequence: 0` at the typed path,
@@ -737,10 +938,16 @@ export function commitPrincipalGrants(space, endpoint, connId) {
737
938
  * connection-scoped (`_INBOX_<connId>.>`, never the account-wide default).
738
939
  *
739
940
  * D32 residuals, EXPLICIT: (1) the `epc.*` publish is payload-blind — a compromised publisher
740
- * can flood NEW digest subjects with garbage artifacts (verify-on-read refuses to SERVE
741
- * non-canonical or digest-mismatched bytes, and an existing digest subject is CAS-protected,
742
- * so it can waste storage but never corrupt or replace a published artifact); (2) the raw JS
743
- * API request carries a caller-selected reply subject (the same confused-deputy injection
941
+ * can publish garbage artifacts at NEW (previously-unused) digest subjects (verify-on-read refuses
942
+ * to SERVE non-canonical or digest-mismatched bytes, so this is a bounded storage flood carrying
943
+ * no authority). It can NOT overwrite, shadow, or replace an EXISTING published artifact: the EPC
944
+ * store's shape ({@link ensureContractStore}: `max_msgs_per_subject:1` + discard-new-per-subject)
945
+ * makes a second publish to an occupied digest subject broker-REJECTED regardless of the
946
+ * create-only header, so per-subject immutability is broker-enforced, not publisher-cooperative.
947
+ * (Earlier revisions relied on the cooperative create-only header alone and a fail-closed read,
948
+ * which the panel's live repro showed a non-cooperative publisher could defeat by raw append — a
949
+ * permanent shadow-DoS; the stream shape + the create-only-winner read fallback close it.) (2) the
950
+ * raw JS API request carries a caller-selected reply subject (the same confused-deputy injection
744
951
  * class as every API-holding profile). */
745
952
  export function contractPublisherGrants(space, connId) {
746
953
  const publish = [