@fabricorg/webhook-delivery 0.2.1 → 0.2.3

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 (3) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/README.md +12 -12
  3. package/package.json +3 -3
package/CHANGELOG.md CHANGED
@@ -1,5 +1,42 @@
1
1
  # @fabricorg/webhook-delivery
2
2
 
3
+ ## 0.2.3
4
+
5
+ ### Patch Changes
6
+
7
+ - d09f378: Refresh packed workspace dependency ranges for the Host stored-record erasure capability.
8
+ - be0938a: Refresh packed Host dependency consumers for the exported store conformance suites.
9
+ Existing peer ranges accept the additive minor release.
10
+ - 0d4204e: Keep Host peer consumers in the release plan with the additive recorded-approval capability.
11
+ Existing peer ranges accept this minor release; no dependency range change is required.
12
+ - 1e46ff0: Add opt-in `idempotency.recordRefusals` to reserve keyed terminal submission refusals.
13
+ The new `submission_refused` status is inert, and refusal identity includes actor type.
14
+ Defaults retain the free-key refusal behavior. Admission-declaring actions omit refusal
15
+ digests to preserve their pre-admission parameter boundary; refusal rows store fixed evidence
16
+ without parameters, proposal or provenance attributes. Recorded errors confirm persistence,
17
+ and store failures surface unchanged. Apply migration 15 and upgrade all hosts sharing a
18
+ database before activation. Unauthorized callers can occupy keys, and callbacks returning
19
+ false during outages can permanently reserve them. Refusal codes must be fixed action codes.
20
+
21
+ With recording enabled, an empty string is a present idempotency key. Stores preserve empty
22
+ key and authorization-binding identities on hydration, and memory insertion arbitrates empty
23
+ keys consistently with PostgreSQL. Default Host submissions keep their keyless empty-string behavior.
24
+
25
+ Generic creation and status-update methods reject `submission_refused` as a write input;
26
+ the narrow refusal insert owns new refusal rows and their fixed payloads.
27
+
28
+ Validate request-only metadata before recording an eligible refusal so malformed submissions
29
+ leave their keys free. The public tenant-isolation kit adds an optional recorded-refusal scope
30
+ check, including ordinary creation against a refusal in another scope. Its result list gains
31
+ `fabric.tenancy.submission-refusal-scoped.v1`; stores without the method skip that check.
32
+ A PostgreSQL store must have migration 15 applied (`ensureSchema()`) before running the kit, or the new check fails.
33
+
34
+ ## 0.2.2
35
+
36
+ ### Patch Changes
37
+
38
+ - 08274e6: Refresh dependent packages for Platform Host approval expiry, verification evidence, and opt-in atomic lifecycle events.
39
+
3
40
  ## 0.2.1
4
41
 
5
42
  ### Patch Changes
package/README.md CHANGED
@@ -10,8 +10,8 @@ pnpm add @fabricorg/webhook-delivery@^0.1.0 @fabricorg/platform@^1.7.0 @fabricor
10
10
  ```
11
11
 
12
12
  - **Peers.** `@fabricorg/platform` `^1.7.0` and `@fabricorg/platform-host` `^7.3.0`. Platform 1.7.0
13
- defines `ActionDefinition.admitSubmission` and Host 7.3.0 runs it before it records a
14
- submission. Every operator action declares the check, so against an older Host the actions
13
+ defines `ActionDefinition.admitSubmission` and Host 7.3.0 runs it before it persists
14
+ submission parameters. Every operator action declares the check, so against an older Host the actions
15
15
  refuse at execution as `admission_not_enforced` ([Secrets and parameters](#secrets-and-parameters)).
16
16
  `@fabricorg/platform` is imported for types only.
17
17
  - **Runtime.** Node.js 20 or newer; run 22.23.4, 24.22.1, or 26.12.1 or newer in the same release line in production for
@@ -476,8 +476,8 @@ The suite creates one database per run and one schema per store pair.
476
476
  `tests/store-contract.ts` is a record of named cases, each taking a factory that builds both
477
477
  stores from an injected clock and horizon. `tests/memory-stores.test.ts` runs it against the
478
478
  memory stores, and `tests/postgres-live.test.ts` runs the same record against PostgreSQL. It
479
- follows Host's `tests/outbox-requeue-contract.ts`, which is test-only, so the suite is not
480
- exported from the package. Two cycle-level records run the same way against both stores:
479
+ uses the factory-per-case pattern also used by Host's published `outboxRequeueChecks`
480
+ in `src/outbox-requeue-conformance.ts`; this webhook suite remains test-only. Two cycle-level records run the same way against both stores:
481
481
  `tests/delivery-cycle-contract.ts` and `tests/fan-out-lease-contract.ts`. A database-backed store meets four requirements; how the PostgreSQL
482
482
  store meets each is under [PostgreSQL stores](#postgresql-stores):
483
483
 
@@ -1366,7 +1366,7 @@ const host = createGovernedActionHost({
1366
1366
  ```
1367
1367
 
1368
1368
  Nothing has to be wired into Host for the secret-reference guarantee: every action declares
1369
- `admitSubmission`, which Host runs on every submission before it records anything ([Secrets and
1369
+ `admitSubmission`, which Host runs on every submission before it persists parameters ([Secrets and
1370
1370
  parameters](#secrets-and-parameters)). The releases that define and run that check are
1371
1371
  `@fabricorg/platform` 1.7.0 and `@fabricorg/platform-host` 7.3.0, and the package's peer ranges
1372
1372
  are `^1.7.0` and `^7.3.0`.
@@ -1404,7 +1404,7 @@ letter" under [Ports](#ports)).
1404
1404
  A submission refused at admission makes `submitAction` throw Host's `ActionAdmissionError` with
1405
1405
  `refusal: "refused"` and `refusalCode` `webhook_parameters_refused:<code>:<field>`
1406
1406
  (`WEBHOOK_ACTION_PARAMETER_CODES` and a declared field or `parameters`) or
1407
- `webhook_action_refused:<code>` (`WEBHOOK_ACTION_REFUSAL_CODES`); Host records nothing for it. A
1407
+ `webhook_action_refused:<code>` (`WEBHOOK_ACTION_REFUSAL_CODES`); Host records nothing for it by default. With `idempotency.recordRefusals`, a keyed definitive refusal reserves the key with fixed evidence and empty parameters. A
1408
1408
  refusal at execution fails the invocation with Host's `error` set to `webhook_action_refused:<code>`
1409
1409
  and emits no event. Neither carries a caller value or an undeclared key. `cancelledPendingIntents` is the
1410
1410
  cleanup's count, or `null` when that call threw, timed out or answered unreadably; the action
@@ -1452,11 +1452,11 @@ objects reach it; it is kept as a second line.
1452
1452
 
1453
1453
  ### Secrets and parameters
1454
1454
 
1455
- Parameters carry secret references only (decision 8). The rule is enforced before anything is
1456
- persisted, not by convention. Every action declares Platform's `admitSubmission` check, and
1455
+ Parameters carry secret references only (decision 8). The check runs before parameters are persisted. Every action declares Platform's `admitSubmission` check, and
1457
1456
  `@fabricorg/platform-host` 7.3.0 and later runs it on every submission, after authorizing the
1458
- submitter and before it writes anything for the submission: no invocation record, idempotency key,
1459
- event, policy record or error. The check reads the parameters with the package reader, which
1457
+ submitter and before it persists parameters. By default a refusal leaves no invocation record,
1458
+ idempotency key, event, policy record or error. With `idempotency.recordRefusals`, keyed definitive
1459
+ refusals instead retain a terminal `submission_refused` row with fixed evidence and empty parameters. The check reads the parameters with the package reader, which
1460
1460
  refuses undeclared keys and a `secretRef` not shaped like a reference. For the three actions that
1461
1461
  take a `secretRef` (`create_subscription`, `rotate_secret_staged`, `rotate_secret_emergency`) it
1462
1462
  then asks the application's `secretReferences.verify` with the submission's trusted tenant and
@@ -1464,8 +1464,8 @@ space. Neither step alone is enough. The shape rule refuses the forms key materi
1464
1464
  in, but it cannot tell an opaque reference from random bytes of the same shape (`x:` followed by 64
1465
1465
  hex digits passes it). The verifier confirms that the reference resolves in the tenant's own secret
1466
1466
  store, which also refuses another tenant's reference. A refusal, a verifier that throws or answers
1467
- anything but `"valid"`, and a check whose answer does not settle within Host's `admissionTimeoutMs` all leave nothing in
1468
- Host's store (tests "key material shaped like a reference …" and "a well-formed reference the
1467
+ anything but `"valid"`, and a check whose answer does not settle within Host's `admissionTimeoutMs` leave no submitted parameters in
1468
+ Host's store. Without recorded refusals they leave no row (tests "key material shaped like a reference …" and "a well-formed reference the
1469
1469
  tenant's secret store does not hold is refused at admission …").
1470
1470
 
1471
1471
  Host reads the submission once, when `submitAction` is called, and, because these actions declare
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fabricorg/webhook-delivery",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "description": "Outbound webhook subscription delivery for @fabricorg/platform-host: the fabric.webhook-delivery.v1 wire contract, persistence and egress projections, response classification, retry schedule, and the store, signer, resolver, transport, admission and authorization ports.",
5
5
  "keywords": [
6
6
  "fabric",
@@ -63,8 +63,8 @@
63
63
  "typescript": "^5.7.3",
64
64
  "vitest": "^4.1.5",
65
65
  "@fabric-platform/bundling": "0.0.0",
66
- "@fabricorg/platform": "1.12.0",
67
- "@fabricorg/platform-host": "8.2.0"
66
+ "@fabricorg/platform": "1.17.0",
67
+ "@fabricorg/platform-host": "8.9.0"
68
68
  },
69
69
  "engines": {
70
70
  "node": ">=20"