@openwop/spec-artifacts 2.42.9 → 2.43.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/CORPUS-STAMP.json +55 -54
- package/api/seams-v2.yaml +57 -1
- package/api/v2/asyncapi.yaml +1 -1
- package/api/v2/openapi.yaml +5 -4
- package/package.json +1 -1
- package/schemas/audit-verify-result.schema.json +40 -8
- package/schemas/v2/audit-verify-result.schema.json +106 -10
- package/schemas/v2/capabilities.schema.json +96 -0
- package/schemas/v2/error-envelope.schema.json +3 -1
- package/schemas/v2/registry-version-manifest.schema.json +2 -2
- package/schemas/v2/run-event-payloads.schema.json +2 -1
- package/schemas/v2/suspend-request.schema.json +2 -2
- package/spec/v1/core-standard-manifest.json +2 -2
- package/spec/v1/gaps.json +323 -0
- package/spec/v2/core/capabilities.md +6 -2
- package/spec/v2/core/conformance.md +1 -1
- package/spec/v2/core/connection-packs.md +1 -1
- package/spec/v2/core/conversation.md +1 -1
- package/spec/v2/core/errors.md +5 -4
- package/spec/v2/core/events.md +1 -1
- package/spec/v2/core/form-content-packs.md +1 -1
- package/spec/v2/core/idempotency.md +1 -1
- package/spec/v2/core/identity.md +1 -1
- package/spec/v2/core/interop.md +1 -1
- package/spec/v2/core/interrupt.md +21 -7
- package/spec/v2/core/node-pack-runtimes.md +1 -1
- package/spec/v2/core/oauth.md +1 -1
- package/spec/v2/core/overview.md +1 -1
- package/spec/v2/core/packs.md +12 -5
- package/spec/v2/core/persistence.md +1 -1
- package/spec/v2/core/portability.md +1 -1
- package/spec/v2/core/replay.md +1 -1
- package/spec/v2/core/runs.md +1 -1
- package/spec/v2/core/security-defaults.md +13 -2
- package/spec/v2/core/tool-catalog.md +1 -1
- package/spec/v2/core/versioning.md +1 -1
- package/spec/v2/core/webhooks.md +1 -1
- package/spec/v2/core/workflow-chain-packs.md +1 -1
- package/spec/v2/corrections.json +18 -1
- package/spec/v2/declaration.json +39 -14
- package/spec/v2/errors.json +11 -1
- package/spec/v2/ext/brand/README.md +1 -1
- package/spec/v2/ext/chat/README.md +3 -3
- package/spec/v2/ext/coordination/README.md +1 -1
- package/spec/v2/ext/dataIntegration/README.md +2 -2
- package/spec/v2/ext/entities/README.md +2 -2
- package/spec/v2/ext/kanban/README.md +3 -3
- package/spec/v2/ext/knowledge/README.md +3 -3
- package/spec/v2/ext/messaging/README.md +1 -1
- package/spec/v2/ext/restTransport/README.md +2 -2
- package/spec/v2/ext/webResearch/README.md +3 -3
- package/spec/v2/facets/auditLogIntegrity.schema.json +30 -0
- package/spec/v2/release.json +2 -2
- package/spec/v2/surface-baseline.json +50 -2
package/spec/v2/core/interop.md
CHANGED
|
@@ -162,4 +162,4 @@ A receiver prefers the in-message value, ignores a malformed one, and MUST NOT d
|
|
|
162
162
|
|
|
163
163
|
`SECURITY/threat-model-interop.md` is the threat model for this document; its invariants are rows of `SECURITY/invariants.yaml`. Peer identity and authorization at the boundary are governed by security-defaults.md; a peer MUST NOT gain authority the caller's Subject does not hold.
|
|
164
164
|
|
|
165
|
-
*Sources:
|
|
165
|
+
*Sources: RFCs 0175, 0198, 0207, 0208, 0211, 0214.*
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
## Why this exists
|
|
7
7
|
|
|
8
|
-
`interrupt` is
|
|
8
|
+
`interrupt` is how a run waits for something outside itself: a decision, an answer, an event, a conversation turn. Every kind shares one payload shape, event pair, resolve contract and token scheme, so a client that resolves an approval can resolve anything.
|
|
9
9
|
|
|
10
10
|
## Payload
|
|
11
11
|
|
|
@@ -35,14 +35,17 @@ Per-kind rules:
|
|
|
35
35
|
|
|
36
36
|
### Re-entry and resume values
|
|
37
37
|
|
|
38
|
-
`key` is the deterministic re-entry key.
|
|
38
|
+
`key` is the deterministic re-entry key of one invocation. A host MUST derive it from at least the run, the node and the node's visit index: the number of that node's interrupts in this run whose resolution was consumed before this execution began. Its spelling is host-defined.
|
|
39
39
|
|
|
40
|
+
- A replay or recovery of the same execution MUST re-derive the same key.
|
|
41
|
+
- A later execution of the node, reached over an edge, MUST derive a different key, MUST raise a new `interrupt.requested`, and MUST NOT return an earlier visit's `resumeValue`.
|
|
42
|
+
- Two interrupts raised in one execution MUST have distinct keys.
|
|
40
43
|
- A host MUST invoke an interrupt with key `K` at most once for the lifetime of the run.
|
|
41
44
|
- On recovery the engine MUST consult the event log, find the prior `interrupt.resolved`, and return the persisted `resumeValue` without emitting a second `interrupt.requested`.
|
|
42
45
|
- An in-memory cache MAY serve in-process replays but MUST NOT replace the event log for cross-process replays.
|
|
43
46
|
- A host MUST validate the resume value against `resumeSchema` when one is declared, and MUST refuse a failing value with `400 validation_error`.
|
|
44
47
|
|
|
45
|
-
`timeoutMs`, when set, is the interrupt's own deadline.
|
|
48
|
+
`timeoutMs`, when set, is the interrupt's own deadline. What an approval gate does when it elapses is §Rejection.
|
|
46
49
|
|
|
47
50
|
## Events
|
|
48
51
|
|
|
@@ -51,7 +54,7 @@ Every kind uses two registered types ([events.md](events.md)):
|
|
|
51
54
|
- `interrupt.requested` — the payload is the `InterruptPayload` verbatim.
|
|
52
55
|
- `interrupt.resolved` — the closed payload is `interruptResolved`. Resolving an approval-kind interrupt MUST record the applied `action` there, with the field §Approval requires.
|
|
53
56
|
|
|
54
|
-
The kind-specific `approval.*` and `clarification.*` types remain registered. Their payload definitions in `schemas/v2/run-event-payloads.schema.json` are `$ref` aliases of `interruptRequested` and `interruptResolved
|
|
57
|
+
The kind-specific `approval.*` and `clarification.*` types remain registered. Their payload definitions in `schemas/v2/run-event-payloads.schema.json` are `$ref` aliases of `interruptRequested` and `interruptResolved`. A host emitting `interrupt.requested` SHOULD also emit the kind-specific type until its consumers migrate.
|
|
55
58
|
|
|
56
59
|
Both events are durable and appear in the `updates` and `debug` stream modes. While suspended, `RunSnapshot.currentNodeId` names the node and `status` is `waiting-approval`, `waiting-input` or `waiting-external`.
|
|
57
60
|
|
|
@@ -113,9 +116,20 @@ The token grammar and the `interrupt.tokenAlgs[]` / `kid` check are [identity.md
|
|
|
113
116
|
- `requiredApprovals` sets the quorum (default 1). `rejectionPolicy` is `single-veto` (default) or `majority`.
|
|
114
117
|
- When `overrideBypassesQuorum` is `true`, a configured override principal MAY release the gate alone; otherwise its vote counts once.
|
|
115
118
|
|
|
119
|
+
### Rejection
|
|
120
|
+
|
|
121
|
+
A `reject` exits the suspend. The host MUST record `action: "reject"` and `decision: "rejected"` on `interrupt.resolved`, and SHOULD also emit `approval.rejected`. The resume value returns to the raising node (§Re-entry and resume values).
|
|
122
|
+
|
|
123
|
+
- A node that does not turn the rejection into an output MUST fail with `approval_rejected` and `retryable: false` on the `node.failed` error, and MUST NOT be retried.
|
|
124
|
+
- A rejected gate is a failed source. It MUST NOT satisfy an `all_success`, `any_success` or `none_failed` edge. The run continues past it only over an edge whose `triggerRule` admits a failed source (`all_complete` or `any_failed`).
|
|
125
|
+
- When no such edge exists, the run MUST terminate `failed` with `run.failed.error.code` `approval_rejected` and `failedNodeId` naming the gate.
|
|
126
|
+
- The gate resolves rejected on one eligible `reject` under `single-veto`, or when rejects exceed half of `requiredApprovals` under `majority`. A vote that does not decide the gate MUST NOT emit `interrupt.resolved`.
|
|
127
|
+
- When a non-zero `timeoutMs` elapses with no resolution, the host MUST resolve the gate rejected, recording `action: "timeout"`, `decision: "rejected"` and `reason: "timeout"`, whatever `onTimeout` holds, and MUST apply the rules above. A timeout MUST NOT grant a gate. A host MUST treat `onTimeout: "approve"` as `reject` and SHOULD NOT emit it. `escalate` MAY notify a host-defined target but MUST NOT extend or grant the gate. A host MUST NOT accept `timeout` on a resume request.
|
|
128
|
+
- On replay the failure MUST be derived from the recorded `interrupt.resolved`, never re-decided.
|
|
129
|
+
|
|
116
130
|
## Approver enforcement
|
|
117
131
|
|
|
118
|
-
|
|
132
|
+
The facet `spec/v2/facets/interrupt.schema.json` carries `tokenAlgs[]` (REQUIRED) and `refKinds[]` ⊆ `principal`, `group`, `role`.
|
|
119
133
|
|
|
120
134
|
- **`approversList`** (explicit principals) binds everywhere: a host advertising `interrupt` MUST refuse a resolver not in the list.
|
|
121
135
|
- **`approverGroupRefs`** binds only where `refKinds` includes `group`: the host MUST surface the field unchanged and MUST resolve and enforce its members as eligible approvers.
|
|
@@ -125,10 +139,10 @@ Enforcement is an obligation of the fields, not a discovery flag. The facet `spe
|
|
|
125
139
|
|
|
126
140
|
Eligibility binds every writer of the suspension record, not every route. A host whose durable store is writable by a principal other than the engine MUST enforce the same eligibility at the store, or MUST NOT expose the record to that principal for write.
|
|
127
141
|
|
|
128
|
-
Refs are opaque to the engine; the host resolves them
|
|
142
|
+
Refs are opaque to the engine; the host resolves them. Membership MUST be resolved at decision time and MUST NOT be re-resolved during replay or `forkRun`: the recorded eligibility decision is fixed history ([replay.md](replay.md)).
|
|
129
143
|
|
|
130
144
|
## During the v1 overlap
|
|
131
145
|
|
|
132
146
|
The v1 interrupt-token drain is [identity.md](identity.md) §4.
|
|
133
147
|
|
|
134
|
-
*Sources:
|
|
148
|
+
*Sources: RFCs 0170, 0171, 0173, 0187, 0196, 0223.*
|
|
@@ -31,4 +31,4 @@ It has no `packages[]`, `headers`, `variables` or `_meta`, so it carries no inst
|
|
|
31
31
|
- A host SHOULD NOT treat `name` as a verified identity: an inline record carries no proof of namespace ownership.
|
|
32
32
|
- A host that authenticates to the server does so through the node's `requiredCredentials` or `auth`.
|
|
33
33
|
|
|
34
|
-
*Sources:
|
|
34
|
+
*Sources: RFCs 0008, 0203.*
|
package/spec/v2/core/oauth.md
CHANGED
|
@@ -63,4 +63,4 @@ Then:
|
|
|
63
63
|
- `declined` fails the node with `connector_auth_declined`.
|
|
64
64
|
- A host that binds a node to one credential reference (for example, a connection) reads "resolves" as that reference resolving with the node's scopes, carries it as `credentialRef`, and still completes `connectUrl` only for the initiating Subject.
|
|
65
65
|
|
|
66
|
-
*Sources:
|
|
66
|
+
*Sources: RFCs 0046, 0047, 0199.*
|
package/spec/v2/core/overview.md
CHANGED
|
@@ -96,4 +96,4 @@ These rules bind any public conformance statement:
|
|
|
96
96
|
|
|
97
97
|
Every MUST, SHOULD, and MAY in `core/` is a requirement with an id in `requirements.json` and a `witness` from `witnessable-unaided | witnessable-gated | seam-gated | claims-check | negative-existence`. A seam-gated MUST is governed by [`conformance.md`](conformance.md) §"Witness class".
|
|
98
98
|
|
|
99
|
-
*Sources:
|
|
99
|
+
*Sources: RFCs 0155, 0167, 0168, 0169, 0171, 0174, 0190, 0197.*
|
package/spec/v2/core/packs.md
CHANGED
|
@@ -26,12 +26,12 @@ Each conjunct keeps its own refusal code. A mechanical ceiling bump is not a ver
|
|
|
26
26
|
|
|
27
27
|
## The `packs` capability
|
|
28
28
|
|
|
29
|
-
A host advertises `packs` when it serves the registry surface above
|
|
29
|
+
A host advertises `packs` when it serves the registry surface above:
|
|
30
30
|
|
|
31
31
|
- A host MUST NOT advertise `packs` unless it resolves pack references through a registry reachable from its discovery document.
|
|
32
|
-
- A client MUST treat an absent record as "
|
|
32
|
+
- A client MUST treat an absent record as "no registry resolution", not as an unknown. It says nothing about pack validation or execution, which `sandbox` and §"The engine range" bind.
|
|
33
33
|
|
|
34
|
-
`testMode` is DEPRECATED and MUST NOT be relied on by a client (
|
|
34
|
+
`testMode` is DEPRECATED and MUST NOT be relied on by a client (§"During the v1 overlap"). A host mounting a test catalog SHOULD advertise the seams profile instead, and MUST NOT treat `testMode` as a second way to claim one.
|
|
35
35
|
|
|
36
36
|
## The registry tree
|
|
37
37
|
|
|
@@ -90,9 +90,16 @@ The same block applies to a **bare manifest** — the `pack.json` inside the tar
|
|
|
90
90
|
- A verifier MUST verify the signature against the issuing registry's key for `keyId`, and MUST check the pack name against that key's `permittedNamespaces`.
|
|
91
91
|
- A signature over tarball bytes is not a v2 signature; such a pack MUST be re-signed, not relabeled.
|
|
92
92
|
|
|
93
|
+
Only a `signingKeys[]` entry whose `status` is `active` MAY sign a new publication. A key MUST stay listed while a served version names it, and a verifier MUST NOT refuse a version because its key is not `active`.
|
|
94
|
+
|
|
93
95
|
## Version manifests
|
|
94
96
|
|
|
95
|
-
`kind` is REQUIRED on every version manifest and every bare manifest.
|
|
97
|
+
`kind` is REQUIRED on every version manifest and every bare manifest. Lifecycle flags sit outside the signature; changing one republishes the version manifest.
|
|
98
|
+
|
|
99
|
+
- `versionDeprecated: true`: still served; a consumer MAY refuse to install it.
|
|
100
|
+
- `yanked: true`: its manifest, tarball and signature stay served, and the pack index MUST NOT name it `latest` while an unyanked version exists. A range MUST skip it; a pin MAY resolve it. Advisory-listed versions MUST be yanked.
|
|
101
|
+
|
|
102
|
+
A registry MUST refuse a submission that breaks these rules or republishes a version, with `pack_integrity_failure`, `pack_validation_failed`, `pack_signature_invalid`, `pack_engine_unsupported`, `pack_peer_dependency_undefined` or `version_conflict`.
|
|
96
103
|
|
|
97
104
|
## The registry's own schemas
|
|
98
105
|
|
|
@@ -111,4 +118,4 @@ A registry MUST validate submissions against vendored copies of these schemas pi
|
|
|
111
118
|
- The v1 registry tree is frozen through the overlap, behind the v2 tree.
|
|
112
119
|
- `testMode` advertises the v1 `/v1/packs-test/*` mirror, a conformance seam ([conformance.md §"The seams profile"](conformance.md)). It remains advertisable through the overlap and is removed at 3.0.
|
|
113
120
|
|
|
114
|
-
*Sources:
|
|
121
|
+
*Sources: RFCs 0177, 0212, 0222.*
|
|
@@ -143,4 +143,4 @@ A host MAY claim a qualification rung (`durable-single-instance`, `durable-multi
|
|
|
143
143
|
|
|
144
144
|
See also: [overview.md](overview.md), [events.md](events.md), [replay.md](replay.md), [identity.md](identity.md), [webhooks.md](webhooks.md).
|
|
145
145
|
|
|
146
|
-
*Sources:
|
|
146
|
+
*Sources: RFCs 0041, 0158, 0170, 0171, 0172, 0176, 0180, 0185, 0186, 0187.*
|
|
@@ -41,4 +41,4 @@ An applied import emits `import.applied` (`schemas/v2/run-event-payloads.schema.
|
|
|
41
41
|
|
|
42
42
|
No protocol path is defined for export or import: a host serves them on routes of its own. A host-private migration from an anonymous sandbox into a signed-in tenant fits this contract, because its response is a subset of the import outcome.
|
|
43
43
|
|
|
44
|
-
*Sources:
|
|
44
|
+
*Sources: RFCs 0043, 0096, 0098.*
|
package/spec/v2/core/replay.md
CHANGED
|
@@ -132,4 +132,4 @@ A host advertising `replay` MUST document retention for source snapshots, source
|
|
|
132
132
|
|
|
133
133
|
See also: events.md, runs.md, persistence.md, security-defaults.md.
|
|
134
134
|
|
|
135
|
-
*Sources:
|
|
135
|
+
*Sources: RFCs 0036, 0039, 0041, 0057, 0104, 0111, 0140, 0173, 0176, 0194.*
|
package/spec/v2/core/runs.md
CHANGED
|
@@ -264,4 +264,4 @@ A host that does not advertise `dataResidency` MAY ignore or reject a `residency
|
|
|
264
264
|
|
|
265
265
|
A non-terminal run inherited from v1 continues, or is cancelled `v1_pin_unsupported`, per [persistence.md](persistence.md) §"Runs pinned to v1".
|
|
266
266
|
|
|
267
|
-
*Sources:
|
|
267
|
+
*Sources: RFCs 0170, 0171, 0176, 0182.*
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Security Defaults
|
|
2
2
|
|
|
3
3
|
> **Status: Stable.**
|
|
4
|
-
> **Normative home:** `sandbox`, `compensation`, `purposePropagation`.
|
|
4
|
+
> **Normative home:** `sandbox`, `compensation`, `purposePropagation`, `auditLogIntegrity`.
|
|
5
5
|
|
|
6
6
|
## Why this exists
|
|
7
7
|
|
|
@@ -28,6 +28,7 @@ A security-load-bearing behavior is an obligation of the surface that needs it.
|
|
|
28
28
|
| `idempotency` | Layer-2 effect identity (§Layer-2 effect identity) | witnessable-gated (fixture provider) | `logical-effect-id-retry-stable` |
|
|
29
29
|
| an `oauth2` or `oidc` lane | protected-resource metadata and challenges ([identity.md §2.5](identity.md)) | witnessable-gated | `auth-challenge-no-oracle` |
|
|
30
30
|
| any outbound request | no inbound credential on an onward hop (§Onward hops) | seam-gated | `inbound-credential-no-passthrough` |
|
|
31
|
+
| `auditLogIntegrity` | a chained, checkpointed, verifiable audit log (§Audit-log integrity) | witnessable-gated | `audit-checkpoint-signed-over-root` |
|
|
31
32
|
|
|
32
33
|
### Auth lanes
|
|
33
34
|
|
|
@@ -91,6 +92,16 @@ One credential is not inbound in this sense: an A2A push-config credential (`aut
|
|
|
91
92
|
|
|
92
93
|
A host advertising `purposePropagation` MUST re-emit a `permittedPurposes` label it received (A2A `metadata.openwop.permittedPurposes`, `TriggerEvent.permittedPurposes`) on every onward hop of the same data, narrowing and never widening, and MUST treat `[]` as no onward use. `purposePropagation.propagatesOnward` is `false` only on a host with no onward hop. The family advertises propagation, not enforcement.
|
|
93
94
|
|
|
95
|
+
### Audit-log integrity
|
|
96
|
+
|
|
97
|
+
A host advertising `auditLogIntegrity` MUST keep an audit log a privileged insider cannot silently rewrite. It:
|
|
98
|
+
|
|
99
|
+
- MUST keep the log append-only, each entry carrying `prevHash`, the lowercase-hex SHA-256 of the prior entry's canonical JSON ([conformance.md §Canonical JSON](conformance.md)), `null` for the first;
|
|
100
|
+
- MUST sign a checkpoint anchoring at most `checkpointIntervalEntries` entries, and anchor an entry within `checkpointIntervalSeconds` of its append. The range, leaves, root and signature are [RFC 0218 §A](https://github.com/openwop/openwop/blob/main/RFCS/0218-audit-checkpoint-preimage.md); the signature is Ed25519 (`checkpointSignatureAlgorithm`) under `checkpointPublicKey`, a key used for no other surface;
|
|
101
|
+
- MUST serve `GET /audit/verify` (scope `audit:read`), answering `schemas/v2/audit-verify-result.schema.json` with every checkpoint whose `atSequence` is in the range, ascending, and the anomalies of [RFC 0218 §C](https://github.com/openwop/openwop/blob/main/RFCS/0218-audit-checkpoint-preimage.md). A host that does not advertise the family MAY omit the operation.
|
|
102
|
+
|
|
103
|
+
The `audit-log-integrity` and `audit-checkpoint-signature` scenarios witness the verify body, each signature, and the cadence. The root is not witnessable from outside, because entries are not on the wire; tamper detection is a host-internal test.
|
|
104
|
+
|
|
94
105
|
## Relaxations
|
|
95
106
|
|
|
96
107
|
A relaxation, where one is legitimate — a development deployment, a single-tenant appliance — is an operator setting, never a discovery field. Every relaxation a host runs under MUST be recorded in its certification bundle as `host.relaxations[]` (`schemas/v2/certification-bundle.schema.json`): `{ obligation, durability, reason }`, `durability ∈ session | deployment | persisted`.
|
|
@@ -131,4 +142,4 @@ Rows `C6.1`–`C6.9` are `spec/v1/migrations.json` entries.
|
|
|
131
142
|
|
|
132
143
|
See also: identity.md, replay.md, webhooks.md, capabilities.md, conformance.md.
|
|
133
144
|
|
|
134
|
-
*Sources:
|
|
145
|
+
*Sources: RFCs 0150, 0163, 0164, 0170, 0173, 0214, 0218, 0224.*
|
|
@@ -42,4 +42,4 @@ A host advertising `toolCatalog.compactView` MUST answer `?view=compact` on both
|
|
|
42
42
|
|
|
43
43
|
A host advertising `toolCatalog.sessionLifecycle` MAY bracket calls with content-free `tool.session.opened` and `tool.session.closed`; a consumer MUST tolerate their absence.
|
|
44
44
|
|
|
45
|
-
*Sources:
|
|
45
|
+
*Sources: RFCs 0078, 0112, 0204.*
|
|
@@ -192,4 +192,4 @@ Every vendor namespace — capability records ([capabilities.md](capabilities.md
|
|
|
192
192
|
|
|
193
193
|
Rows `C5.1`–`C5.9` are `spec/v1/migrations.json` entries (`C5.2` is owned by `events.md`). The persisted-data disposition for each is `not-persisted`, except `C5.1` (legacy-stamped) and `C5.7` (never-upgraded).
|
|
194
194
|
|
|
195
|
-
*Sources:
|
|
195
|
+
*Sources: RFCs 0167, 0168, 0172, 0176, 0179, 0181, 0193, 0219.*
|
package/spec/v2/core/webhooks.md
CHANGED
|
@@ -124,4 +124,4 @@ At delivery time a host MUST re-resolve the hostname, validate every resolved ad
|
|
|
124
124
|
|
|
125
125
|
See also: events.md, replay.md, persistence.md, security-defaults.md.
|
|
126
126
|
|
|
127
|
-
*Sources:
|
|
127
|
+
*Sources: RFCs 0053, 0165, 0171, 0173, 0176, 0188, 0196, 0201, 0215, 0217.*
|
|
@@ -36,4 +36,4 @@ Fragment edges carry the same `condition` and `triggerRule` shapes as a top-leve
|
|
|
36
36
|
|
|
37
37
|
A host MUST carry both fields through expansion verbatim and MUST honor them on expanded edges as on authored ones. [form-content-packs.md](form-content-packs.md) reuses this operator set for field visibility.
|
|
38
38
|
|
|
39
|
-
*Sources:
|
|
39
|
+
*Sources: RFCs 0133, 0177.*
|
package/spec/v2/corrections.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "./corrections.schema.json",
|
|
3
3
|
"$comment": "RFC 0197 §A.4 — v2 Class-3 corrections. Seeded with P3 only. The 2.8.2 removal of `workflowChainPacks.deferredParameters` and `.hostExpansionSeam` (P1) is deliberately NOT seeded: a committed bundle carried `deferredParameters` and then failed `capabilities-root-closed`, so the row would fail R3 — which is the point. P1 is recorded as the motivating defect in COMPATIBILITY.md §3a, not laundered into this register.",
|
|
4
4
|
"version": 1,
|
|
5
|
-
"updated": "2026-09-
|
|
5
|
+
"updated": "2026-09-28",
|
|
6
6
|
"rows": [
|
|
7
7
|
{
|
|
8
8
|
"id": "openwop.correction.v2.1",
|
|
@@ -43,6 +43,23 @@
|
|
|
43
43
|
"manifestsScanned": 156,
|
|
44
44
|
"note": "The prior shape is any string; the corrected shape is the axis-1 `<major>.<minor>` grammar that spec/v2/core/versioning.md §1.5 and the v2-min-client-version scenario already required of an advertised value. Bundle leg: all 8 committed evidence/v2-host-bundles/*.json advertise minClientVersion, and every value conforms (seven \"1.0\", MyndHyve \"0.1\"), so 0 carry a value the pattern rejects. The one \"0.1.0\" in the corpus is a major-1 witness under evidence/rfc-witnesses/, not a v2 bundle. Registry leg: minClientVersion is a discovery field, not a manifest field; 0 of 156 pack.json documents on openwop-registry origin/main (c15d3d6) carry it. The schema added a pattern only, so no property, type or required entry moved and check-v2-surface-monotone sees no change."
|
|
45
45
|
}
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"id": "openwop.correction.v2.3",
|
|
49
|
+
"date": "2026-09-28",
|
|
50
|
+
"class": "w3c-class-3",
|
|
51
|
+
"rfc": "0218",
|
|
52
|
+
"pointers": [
|
|
53
|
+
"schemas/v2/audit-verify-result.schema.json#/chainValid",
|
|
54
|
+
"schemas/v2/audit-verify-result.schema.json#/anomalies"
|
|
55
|
+
],
|
|
56
|
+
"compatibilityEntry": "an audit anomaly's shape, and `chainValid` as the aggregate verdict",
|
|
57
|
+
"priorShapeCensus": {
|
|
58
|
+
"bundles": 0,
|
|
59
|
+
"manifests": 0,
|
|
60
|
+
"manifestsScanned": 157,
|
|
61
|
+
"note": "The prior shape is a verify result with `chainValid: true` beside a non-empty `anomalies`, or `chainValid: false` beside an empty one; the corrected shape is the root if/then/else RFC 0218 §C.4 adds, which the schema's `chainValid` and `anomalies` descriptions already required. Bundle leg: none of the 9 committed evidence/v2-host-bundles/*.json carries a `GET /audit/verify` body (no `chainValid` member anywhere). Registry leg: a verify result is not a manifest field; 0 of 157 pack.json documents on openwop-registry origin/main (4c5de1f) carry `chainValid`. The Anomaly members RFC 0218 §C adds are OPTIONAL additions that check-v2-surface-monotone reports as additive."
|
|
62
|
+
}
|
|
46
63
|
}
|
|
47
64
|
]
|
|
48
65
|
}
|
package/spec/v2/declaration.json
CHANGED
|
@@ -1621,6 +1621,31 @@
|
|
|
1621
1621
|
"owningRfc": "0154",
|
|
1622
1622
|
"facetsFrom": "spec/v2/facets/auth.schema.json"
|
|
1623
1623
|
},
|
|
1624
|
+
{
|
|
1625
|
+
"key": "auditLogIntegrity",
|
|
1626
|
+
"kind": "family",
|
|
1627
|
+
"normativeText": [
|
|
1628
|
+
"spec/v2/core/security-defaults.md"
|
|
1629
|
+
],
|
|
1630
|
+
"anchor": "core",
|
|
1631
|
+
"section": "core/capabilities.md#auditLogIntegrity",
|
|
1632
|
+
"peerDependencyId": "auditLogIntegrity",
|
|
1633
|
+
"witness": "witnessable-gated",
|
|
1634
|
+
"maturity": {
|
|
1635
|
+
"technical": "experimental",
|
|
1636
|
+
"adoption": "none"
|
|
1637
|
+
},
|
|
1638
|
+
"facets": [
|
|
1639
|
+
"checkpointSignatureAlgorithm",
|
|
1640
|
+
"checkpointPublicKey",
|
|
1641
|
+
"checkpointIntervalEntries",
|
|
1642
|
+
"checkpointIntervalSeconds"
|
|
1643
|
+
],
|
|
1644
|
+
"floorScenarios": [],
|
|
1645
|
+
"requirementIds": [],
|
|
1646
|
+
"owningRfc": "0224",
|
|
1647
|
+
"facetsFrom": "spec/v2/facets/auditLogIntegrity.schema.json"
|
|
1648
|
+
},
|
|
1624
1649
|
{
|
|
1625
1650
|
"key": "i18n",
|
|
1626
1651
|
"kind": "family",
|
|
@@ -1737,7 +1762,7 @@
|
|
|
1737
1762
|
"extensionName": "rest-transport",
|
|
1738
1763
|
"witness": "witnessable-gated",
|
|
1739
1764
|
"maturity": {
|
|
1740
|
-
"technical": "
|
|
1765
|
+
"technical": "stable",
|
|
1741
1766
|
"adoption": "single-witness"
|
|
1742
1767
|
},
|
|
1743
1768
|
"facets": [
|
|
@@ -1779,7 +1804,7 @@
|
|
|
1779
1804
|
"witness": "claims-check",
|
|
1780
1805
|
"maturity": {
|
|
1781
1806
|
"technical": "experimental",
|
|
1782
|
-
"adoption": "
|
|
1807
|
+
"adoption": "none"
|
|
1783
1808
|
},
|
|
1784
1809
|
"facets": [],
|
|
1785
1810
|
"floorScenarios": [],
|
|
@@ -1814,8 +1839,8 @@
|
|
|
1814
1839
|
"extensionName": "chat",
|
|
1815
1840
|
"witness": "claims-check",
|
|
1816
1841
|
"maturity": {
|
|
1817
|
-
"technical": "
|
|
1818
|
-
"adoption": "
|
|
1842
|
+
"technical": "stable",
|
|
1843
|
+
"adoption": "multi-witness"
|
|
1819
1844
|
},
|
|
1820
1845
|
"facets": [],
|
|
1821
1846
|
"floorScenarios": [],
|
|
@@ -1833,7 +1858,7 @@
|
|
|
1833
1858
|
"witness": "claims-check",
|
|
1834
1859
|
"maturity": {
|
|
1835
1860
|
"technical": "experimental",
|
|
1836
|
-
"adoption": "
|
|
1861
|
+
"adoption": "none"
|
|
1837
1862
|
},
|
|
1838
1863
|
"facets": [],
|
|
1839
1864
|
"floorScenarios": [],
|
|
@@ -1850,7 +1875,7 @@
|
|
|
1850
1875
|
"extensionName": "data-integration",
|
|
1851
1876
|
"witness": "claims-check",
|
|
1852
1877
|
"maturity": {
|
|
1853
|
-
"technical": "
|
|
1878
|
+
"technical": "stable",
|
|
1854
1879
|
"adoption": "single-witness"
|
|
1855
1880
|
},
|
|
1856
1881
|
"facets": [],
|
|
@@ -1868,7 +1893,7 @@
|
|
|
1868
1893
|
"extensionName": "entities",
|
|
1869
1894
|
"witness": "claims-check",
|
|
1870
1895
|
"maturity": {
|
|
1871
|
-
"technical": "
|
|
1896
|
+
"technical": "stable",
|
|
1872
1897
|
"adoption": "single-witness"
|
|
1873
1898
|
},
|
|
1874
1899
|
"facets": [],
|
|
@@ -1886,8 +1911,8 @@
|
|
|
1886
1911
|
"extensionName": "kanban",
|
|
1887
1912
|
"witness": "claims-check",
|
|
1888
1913
|
"maturity": {
|
|
1889
|
-
"technical": "
|
|
1890
|
-
"adoption": "
|
|
1914
|
+
"technical": "stable",
|
|
1915
|
+
"adoption": "multi-witness"
|
|
1891
1916
|
},
|
|
1892
1917
|
"facets": [],
|
|
1893
1918
|
"floorScenarios": [],
|
|
@@ -1904,8 +1929,8 @@
|
|
|
1904
1929
|
"extensionName": "knowledge",
|
|
1905
1930
|
"witness": "claims-check",
|
|
1906
1931
|
"maturity": {
|
|
1907
|
-
"technical": "
|
|
1908
|
-
"adoption": "
|
|
1932
|
+
"technical": "stable",
|
|
1933
|
+
"adoption": "multi-witness"
|
|
1909
1934
|
},
|
|
1910
1935
|
"facets": [],
|
|
1911
1936
|
"floorScenarios": [],
|
|
@@ -1941,7 +1966,7 @@
|
|
|
1941
1966
|
"witness": "claims-check",
|
|
1942
1967
|
"maturity": {
|
|
1943
1968
|
"technical": "experimental",
|
|
1944
|
-
"adoption": "
|
|
1969
|
+
"adoption": "none"
|
|
1945
1970
|
},
|
|
1946
1971
|
"facets": [],
|
|
1947
1972
|
"floorScenarios": [],
|
|
@@ -1958,8 +1983,8 @@
|
|
|
1958
1983
|
"extensionName": "web-research",
|
|
1959
1984
|
"witness": "claims-check",
|
|
1960
1985
|
"maturity": {
|
|
1961
|
-
"technical": "
|
|
1962
|
-
"adoption": "
|
|
1986
|
+
"technical": "stable",
|
|
1987
|
+
"adoption": "multi-witness"
|
|
1963
1988
|
},
|
|
1964
1989
|
"facets": [],
|
|
1965
1990
|
"floorScenarios": [],
|
package/spec/v2/errors.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://openwop.dev/spec/v2/errors.schema.json",
|
|
3
3
|
"$comment": "RFC 0171 §B.1 — the error registry: one row per code {code, meaning?, httpStatus, retriable, details, since, deprecated?}. schemas/v2/error-envelope.schema.json is GENERATED from it (scripts/generate-error-envelope.mjs). Retry timing lives in Retry-After only (§B.2). statusSource records whether the status was stated in v1 prose, a v1 convention, or decided here. details is null until a code's details schema is registered (a null row means details is an open object for that code — closure over details is the RFC 0171 Phase 3 follow-up G-row).",
|
|
4
4
|
"version": "2.0",
|
|
5
|
-
"updated": "2026-09-
|
|
5
|
+
"updated": "2026-09-28",
|
|
6
6
|
"vendorCodePattern": "^(?!openwop\\.)[a-z][a-z0-9]*(-[a-z0-9]+)*\\.[a-z][a-z0-9_]*$",
|
|
7
7
|
"rows": [
|
|
8
8
|
{
|
|
@@ -839,6 +839,16 @@
|
|
|
839
839
|
"since": "2.0",
|
|
840
840
|
"source": "spec/v2/core/errors.md §The envelope — a request body whose Content-Type the host does not accept (RFC 9110 §15.5.16); registered 2026-09-05 because both production hosts had to invent it"
|
|
841
841
|
},
|
|
842
|
+
{
|
|
843
|
+
"code": "approval_rejected",
|
|
844
|
+
"meaning": "An approval gate resolved rejected (a decision, a quorum or a timeout) and no edge routed the failure, so the node and the run failed.",
|
|
845
|
+
"httpStatus": 422,
|
|
846
|
+
"statusSource": "v2 decision",
|
|
847
|
+
"retriable": false,
|
|
848
|
+
"details": null,
|
|
849
|
+
"since": "2.43",
|
|
850
|
+
"source": "RFC 0223; spec/v2/core/interrupt.md §Rejection"
|
|
851
|
+
},
|
|
842
852
|
{
|
|
843
853
|
"code": "capability_not_provided",
|
|
844
854
|
"meaning": "The host does not provide a capability the request or pack requires.",
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
| --- | --- |
|
|
9
9
|
| **witness:** | `claims-check` |
|
|
10
10
|
| **technical:** | `experimental` |
|
|
11
|
-
| **adoption:** | `
|
|
11
|
+
| **adoption:** | `none` |
|
|
12
12
|
| **peer-dependency id** | `brand` |
|
|
13
13
|
| **advertised as** | `extensions.<org>.brand` |
|
|
14
14
|
| **declared facets** | none defined |
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
# `chat` extension
|
|
2
2
|
|
|
3
|
-
> **Status:
|
|
3
|
+
> **Status: Stable.**
|
|
4
4
|
|
|
5
5
|
`chat` names a host service that posts messages and cards into a host-established chat session. It is a discovery-only reservation: v2 defines no portable operations or payload contract for it.
|
|
6
6
|
|
|
7
7
|
| Field | Value |
|
|
8
8
|
| --- | --- |
|
|
9
9
|
| **witness:** | `claims-check` |
|
|
10
|
-
| **technical:** | `
|
|
11
|
-
| **adoption:** | `
|
|
10
|
+
| **technical:** | `stable` |
|
|
11
|
+
| **adoption:** | `multi-witness` |
|
|
12
12
|
| **peer-dependency id** | `chat` |
|
|
13
13
|
| **advertised as** | `extensions.<org>.chat` |
|
|
14
14
|
| **declared facets** | none defined |
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
| --- | --- |
|
|
9
9
|
| **witness:** | `claims-check` |
|
|
10
10
|
| **technical:** | `experimental` |
|
|
11
|
-
| **adoption:** | `
|
|
11
|
+
| **adoption:** | `none` |
|
|
12
12
|
| **peer-dependency id** | `coordination` |
|
|
13
13
|
| **advertised as** | `extensions.<org>.coordination` |
|
|
14
14
|
| **declared facets** | none defined |
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
# `dataIntegration` extension
|
|
2
2
|
|
|
3
|
-
> **Status:
|
|
3
|
+
> **Status: Stable.**
|
|
4
4
|
|
|
5
5
|
`dataIntegration` names typed data-source operations: fetches from configured external sources, transforms and run-scoped variables. It is a discovery-only reservation: v2 defines no portable operations or payload contract for it.
|
|
6
6
|
|
|
7
7
|
| Field | Value |
|
|
8
8
|
| --- | --- |
|
|
9
9
|
| **witness:** | `claims-check` |
|
|
10
|
-
| **technical:** | `
|
|
10
|
+
| **technical:** | `stable` |
|
|
11
11
|
| **adoption:** | `single-witness` |
|
|
12
12
|
| **peer-dependency id** | `dataIntegration` |
|
|
13
13
|
| **advertised as** | `extensions.<org>.data-integration` |
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
# `entities` extension
|
|
2
2
|
|
|
3
|
-
> **Status:
|
|
3
|
+
> **Status: Stable.**
|
|
4
4
|
|
|
5
5
|
`entities` names generic entity CRUD over projects and workspace assets. It is a discovery-only reservation: v2 defines no portable operations or payload contract for it.
|
|
6
6
|
|
|
7
7
|
| Field | Value |
|
|
8
8
|
| --- | --- |
|
|
9
9
|
| **witness:** | `claims-check` |
|
|
10
|
-
| **technical:** | `
|
|
10
|
+
| **technical:** | `stable` |
|
|
11
11
|
| **adoption:** | `single-witness` |
|
|
12
12
|
| **peer-dependency id** | `entities` |
|
|
13
13
|
| **advertised as** | `extensions.<org>.entities` |
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
# `kanban` extension
|
|
2
2
|
|
|
3
|
-
> **Status:
|
|
3
|
+
> **Status: Stable.**
|
|
4
4
|
|
|
5
5
|
`kanban` names board, task, timeline and automation operations. It is a discovery-only reservation: v2 defines no portable operations or payload contract for it.
|
|
6
6
|
|
|
7
7
|
| Field | Value |
|
|
8
8
|
| --- | --- |
|
|
9
9
|
| **witness:** | `claims-check` |
|
|
10
|
-
| **technical:** | `
|
|
11
|
-
| **adoption:** | `
|
|
10
|
+
| **technical:** | `stable` |
|
|
11
|
+
| **adoption:** | `multi-witness` |
|
|
12
12
|
| **peer-dependency id** | `kanban` |
|
|
13
13
|
| **advertised as** | `extensions.<org>.kanban` |
|
|
14
14
|
| **declared facets** | none defined |
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
# `knowledge` extension
|
|
2
2
|
|
|
3
|
-
> **Status:
|
|
3
|
+
> **Status: Stable.**
|
|
4
4
|
|
|
5
5
|
`knowledge` names knowledge-base retrieval through the host's RAG pipeline. It is a discovery-only reservation: v2 defines no portable operations or payload contract for it.
|
|
6
6
|
|
|
7
7
|
| Field | Value |
|
|
8
8
|
| --- | --- |
|
|
9
9
|
| **witness:** | `claims-check` |
|
|
10
|
-
| **technical:** | `
|
|
11
|
-
| **adoption:** | `
|
|
10
|
+
| **technical:** | `stable` |
|
|
11
|
+
| **adoption:** | `multi-witness` |
|
|
12
12
|
| **peer-dependency id** | `knowledge` |
|
|
13
13
|
| **advertised as** | `extensions.<org>.knowledge` |
|
|
14
14
|
| **declared facets** | none defined |
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
| --- | --- |
|
|
9
9
|
| **witness:** | `claims-check` |
|
|
10
10
|
| **technical:** | `experimental` |
|
|
11
|
-
| **adoption:** | `
|
|
11
|
+
| **adoption:** | `none` |
|
|
12
12
|
| **peer-dependency id** | `messaging` |
|
|
13
13
|
| **advertised as** | `extensions.<org>.messaging` |
|
|
14
14
|
| **declared facets** | none defined |
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
# `restTransport` extension
|
|
2
2
|
|
|
3
|
-
> **Status:
|
|
3
|
+
> **Status: Stable.**
|
|
4
4
|
|
|
5
5
|
`restTransport` names conditional GET and response compression on run reads. The run-snapshot rules are in [`runs.md`](../../core/runs.md) §"Caching and encoding". This page defines the claim and what advertising it adds to those rules.
|
|
6
6
|
|
|
7
7
|
| Field | Value |
|
|
8
8
|
| --- | --- |
|
|
9
9
|
| **witness:** | `witnessable-gated` |
|
|
10
|
-
| **technical:** | `
|
|
10
|
+
| **technical:** | `stable` |
|
|
11
11
|
| **adoption:** | `single-witness` |
|
|
12
12
|
| **peer-dependency id** | `restTransport` |
|
|
13
13
|
| **advertised as** | `extensions.<org>.rest-transport` |
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
# `webResearch` extension
|
|
2
2
|
|
|
3
|
-
> **Status:
|
|
3
|
+
> **Status: Stable.**
|
|
4
4
|
|
|
5
5
|
`webResearch` names search, fetch and research orchestration through the host's search adapter. It is a discovery-only reservation: v2 defines no portable operations or payload contract for it.
|
|
6
6
|
|
|
7
7
|
| Field | Value |
|
|
8
8
|
| --- | --- |
|
|
9
9
|
| **witness:** | `claims-check` |
|
|
10
|
-
| **technical:** | `
|
|
11
|
-
| **adoption:** | `
|
|
10
|
+
| **technical:** | `stable` |
|
|
11
|
+
| **adoption:** | `multi-witness` |
|
|
12
12
|
| **peer-dependency id** | `webResearch` |
|
|
13
13
|
| **advertised as** | `extensions.<org>.web-research` |
|
|
14
14
|
| **declared facets** | none defined |
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$comment": "RFC 0224 §A — the audit-log-integrity family's facets: the checkpoint signing key and algorithm a verifier needs, and the checkpoint cadence the host declares. The record's presence claims the hash chain, so the earlier major's `hashChain: true` has no seat.",
|
|
3
|
+
"properties": {
|
|
4
|
+
"checkpointSignatureAlgorithm": {
|
|
5
|
+
"const": "ed25519",
|
|
6
|
+
"description": "The checkpoint signature algorithm. Ed25519 over the 32 bytes `merkleRoot` hex-decodes to (RFC 0218 §A.4)."
|
|
7
|
+
},
|
|
8
|
+
"checkpointPublicKey": {
|
|
9
|
+
"type": "string",
|
|
10
|
+
"pattern": "^MCowBQYDK2VwAyEA[A-Za-z0-9+/]{43}=$",
|
|
11
|
+
"description": "The audit-signing public key: base64 (RFC 4648 §4, padded) of its DER SubjectPublicKeyInfo, 44 bytes for Ed25519. Every checkpoint `GET /audit/verify` returns MUST verify under it."
|
|
12
|
+
},
|
|
13
|
+
"checkpointIntervalEntries": {
|
|
14
|
+
"type": "integer",
|
|
15
|
+
"minimum": 1,
|
|
16
|
+
"description": "The most entries a checkpoint anchors: consecutive checkpoints' atSequence, and the first checkpoint's atSequence from 0, differ by at most this."
|
|
17
|
+
},
|
|
18
|
+
"checkpointIntervalSeconds": {
|
|
19
|
+
"type": "integer",
|
|
20
|
+
"minimum": 1,
|
|
21
|
+
"description": "The longest an appended entry waits before a checkpoint anchors it."
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"required": [
|
|
25
|
+
"checkpointSignatureAlgorithm",
|
|
26
|
+
"checkpointPublicKey",
|
|
27
|
+
"checkpointIntervalEntries",
|
|
28
|
+
"checkpointIntervalSeconds"
|
|
29
|
+
]
|
|
30
|
+
}
|