OpenWOP openwop.dev
RFC details authors, dates, what it affects, review history
FieldValue
RFC0253
TitleOne v2 read that serves an installed pack's pack.json, so an applied workflow-chain-pack or agent-pack proposal can be byte-compared
StatusActive
Author(s)David Tufts (@davidscotttufts)
Created2026-10-29
Updated2026-10-31 — Draft → Active, comment window waived by the maintainer (user instruction 2026-10-31: "proceed", in reply to the offer to waive the window that ran to 2026-11-05). STEWARD OVERRIDE of RFC 0147 §A.6 (§A scopes the read to the caller's tenant), recorded in MAINTAINERS.md. Lands getInstalledPack, the §G descriptions, the threat-model line, v2-proposal-pack-readback (12 ids) and 0253.unadvertised-not-found; suite 2.46.39. No host advertises a pack kind in readback yet. Earlier 2026-10-31 — UQ 1–6 decided after an /architect review (maintainer-approved): private.* names only, signing refused, proposal installs only, one version, files deferred, tenant-wide. §D discloses the late-bound prompt refs; the pack threat model and the facet gain a line each; legs 0253.namespace-refused and 0253.signing-refused. Still Draft. 2026-10-29 — Draft, closing RFC 0249 gap G2 after the 2026-10-29 audit (#2056) found no v2 operation that serves an installed pack.
Affectsapi/openapi.yaml → api/v2/openapi.yaml (one operation, getInstalledPack) · spec/v2/path-manifest.json (generated) · spec/v2/facets/agents.schema.json proposals.readback (description only; the enum already admits both kinds) · schemas/v2/proposal.schema.json activation.installedArtifact (description only) · SECURITY/threat-model-node-packs.md (one line: the proposal install path) · SECURITY/invariants.yaml (proposal-inert-until-applied, proposal-no-resynthesis: a second test file) · conformance: new v2-proposal-pack-readback.test.ts · CHANGELOG · openwop-sdks (follow-up)
Compatibilityadditive
Supersedes—
Superseded by—

Summary

RFC 0249 made an applied proposal checkable: activation.installedArtifact names a v2 GET, and that read, minus the kind's host-owned fields, must be RFC 8785 (JCS) equal to the reviewed artifact. Phase 1 covered prompt-template only, because v2 has no operation that serves an installed pack. This RFC mints one: getInstalledPack, GET /installed-packs/{packName}, which serves the pack.json installed in the caller's tenant. It also states, for the two pack kinds, what a proposed artifact may contain so that a manifest-only install can be byte-compared at all. With it a host can advertise readback for workflow-chain-pack and agent-pack, and the suite can witness both RFC 0096 invariants for those kinds.

Motivation

agents.proposals.readback says workflow-chain-pack, agent-pack and automation have no read-back at v2. For a host that proposes those kinds, the two protocol-tier invariants (proposal-inert-until-applied, critical; proposal-no-resynthesis, high) bind but no outside party can check them. RFC 0249 recorded this as gap G2 and transferred it to TODO.md for an audit.

The audit (2026-10-29, #2056) found:

  • No pack read at v2. spec/v2/path-manifest.json has no operation that serves a pack. The only pack endpoints in api/openapi.yaml are the v1 test registry /v1/packs-test/..., a seam that is not in the v2 manifest.
  • getWorkflow is not a pack read. It serves one registered workflow. A chain pack is an author-time abstraction: its chains are expanded into a parent definition, and a runtime sub-chain child is registered under a host-derived id (workflow-chain-packs.md §Co-registered children). Nothing a workflow read returns is the pack's bytes.
  • getAgent is not a pack read. It returns an AgentInventoryEntry (schemas/v2/agent-inventory-response.schema.json), a host-shaped view of one agent, not the manifest.
  • An agent pack is a node pack. There is no separate agent-pack schema at v1 or v2. An agent pack is a pack.json that validates against schemas/v2/node-pack-manifest.schema.json with kind: "node" (required at v2) and a non-empty agents[], each entry an agent-manifest.schema.json (RFC 0003, Alternatives 1). A pure-agent pack sets runtime.language: "remote".
  • An agent manifest can point into a tarball. systemPromptRef, evalSuiteRef, handoff.taskSchemaRef and handoff.returnSchemaRef are tarball-relative paths. A proposal carries only artifact, a JSON object, so it has nowhere to carry those files, and a read of pack.json alone cannot show them.

spec/v2/core/conformance.md §Witness class requires a MUST whose only witness is missing to gain an observation path or be disclosed. RFC 0249 chose disclosure for these kinds in phase 1. This RFC mints the path for phase 2.

No host proposes either kind at v2 today. openwop-app advertises artifactKinds: ["prompt-template"]; the retired MyndHyve runtime advertised all four kinds with no operations. The motivation is to finish RFC 0249's design before a host proposes a pack kind, not to fix a host that does.

Proposal

§A — The operation

OperationMethod + pathScopeResponse
getInstalledPackGET /installed-packs/{packName}manifest:read200: the installed pack.json, validating against workflow-chain-pack-manifest when kind: "workflow-chain", else node-pack-manifest. 404 not_found otherwise.
  • packName is the manifest name, matching the existing pattern ^(core|vendor|community|private)\.…. It is URL-safe as written.
  • The path is unversioned and outside the registry tree. /packs/... is avoided so it cannot be read as a registry path (packs.md §The registry tree).
  • manifest:read is the scope getWorkflow already uses for reading definitions. No new scope is minted.
  • Advertisement. The operation is advertised when agents.proposals.readback contains workflow-chain-pack or agent-pack. A host that does not advertise it answers 404 not_found, as errors.md §Unadvertised operations requires.
  • Tenant scoping. The read is evaluated in the caller's tenant. A pack installed in another tenant MUST be answered exactly as a name that is not installed (404), so the operation is not an existence oracle. This is RFC 0249 §C's read-back rule, applied to a second operation.
  • One version per tenant. The read serves the version currently installed in the caller's tenant. installedArtifact.version carries the version the apply installed, so a client can tell when a later install has replaced it. The byte-match obligation (§C) holds while the installed version equals installedArtifact.version. A host that keeps several versions of one name in a tenant does not advertise readback for the kind (UQ 4, decided).
  • What it serves. A host MUST serve, through this read, every pack installed in the tenant by applyProposal. A host MAY also serve packs it installed from a registry or ships itself; this RFC places no obligation on them, and the tenant-scoping rule still applies (UQ 3, decided).
  • Visibility. A pack installed by apply is visible tenant-wide, whatever workspace the proposal's owner names; installScope has no workspace level. A host that installs packs per workspace does not advertise readback for the kind. Because the install is tenant-wide, proposals:apply (or the approval gate's quorum) for a pack kind is a tenant-level install decision (UQ 6, decided).

The response is the bare manifest, not an envelope. Install metadata (source, time, integrity) has no field in the body; both manifest schemas are closed apart from the vendor hatch, and a host MUST NOT add hatch properties the installed artifact did not carry.

§B — installedArtifact for the two kinds

On a successful apply of a workflow-chain-pack or agent-pack proposal, on a host whose readback contains that kind:

"installedArtifact": {
  "kind": "agent-pack",                  // or "workflow-chain-pack"
  "operationId": "getInstalledPack",
  "id": "private.acme.triage-agents",    // artifact.name; a host MUST NOT mint one
  "version": "1.0.0"                     // artifact.version
}

id is the artifact's own name, and version is REQUIRED for these two kinds. Both follow RFC 0249 §C, which already allows version "when the read surface is versioned".

§C — Byte-match and the host-owned fields

The host-owned field set is empty for both kinds. The body getInstalledPack returns MUST be RFC 8785 (JCS) equal to the artifact last persisted before apply, with nothing removed from either side.

The meta precedent does not carry over. prompt-template has a meta member where server-set values must live. Neither pack manifest has one: each is closed apart from the pack-authored vendor hatch (^(openwop-|x-|vendor\.)), and packs.md §The manifest schema family makes hatch values pack-authored and untrusted. A host-set value therefore has no lawful place in the body, and excluding nothing keeps the comparison exact.

The one field a host might want to own is signing. A proposal has no tarball and no detached signature, so a signing block on a proposed pack would claim registry provenance that cannot be verified. A host advertising readback for the kind MUST refuse to apply an artifact carrying signing with 422 (RFC 0249 §B: an artifact that does not validate for its kind), and MUST NOT add one at install (UQ 2, decided).

§D — What a proposed pack may contain

A manifest-only install can be byte-compared only if the manifest is the whole artifact. On a host whose readback contains the kind, at apply:

Both kinds. name MUST start with private.. A proposed pack named under core., vendor. or community. is refused: RFC 0043 §A ties those prefixes to registry verification that a draft written in a tenant has never had, and a private. name cannot collide with a later registry install (UQ 1, decided).

agent-pack. The artifact MUST validate against node-pack-manifest.schema.json with a non-empty agents[], and:

  • MUST NOT carry nodes (a non-empty nodes[] is executable code that has no tarball to come from);
  • MUST set runtime.language: "remote", as a pure-agent pack already must, and the host MUST NOT dereference runtime.entry for it;
  • every agent MUST carry an inline systemPrompt, and MUST NOT carry systemPromptRef, evalSuiteRef, handoff.taskSchemaRef or handoff.returnSchemaRef.

Late-bound prompt references (disclosed). An agent MAY carry promptLibraryRef and promptOverrides. They do not point into a tarball. They name prompt templates in the tenant's store, resolved at run time, and those templates can change after the pack is reviewed. With an inline systemPrompt a system-kind override has no effect; overrides for other kinds do. Byte-match covers the manifest, not what these references resolve to. A reviewer reads each referenced template on its own, through getPromptTemplate, which RFC 0249 already reads back.

workflow-chain-pack. The artifact MUST validate against workflow-chain-pack-manifest.schema.json. A chain manifest has no tarball-relative field, so no further restriction applies. Every node and sub-chain reference stays exact-pinned (workflow-chain-packs.md §Exact pins).

A violation is refused 422 and installs nothing; the proposal's state is unchanged.

The referenced-files decision. This RFC discloses rather than covers the tarball files. A proposed agent that needs a typed handoff or a portable eval suite cannot be proposed through a read-back-advertised kind in phase 2. handoff: {} remains valid, so a role: "skill" agent (which requires handoff) can still be proposed, with an opaque payload contract. Carrying files in a proposal is deferred to a later phase (UQ 5, decided).

§E — Install semantics

Installing behaves as the host's pack install would in the applying tenant, with the conflicts RFC 0249 §D defined for templates:

  • no pack of that name in the tenant: install;
  • a pack of that name that an earlier proposal installed, at a lower version: replace it;
  • an equal or higher installed version: 409 proposal_install_conflict, details.reason: "version-not-greater";
  • a pack of that name the host installed from a registry or ships itself: 409 proposal_install_conflict, details.reason: "read-only";
  • for agent-pack, an agentId already resolvable in the tenant from another pack: 409 proposal_install_conflict, details.reason: "read-only".

No new error code or reason value is minted. On each refusal the host installs nothing and leaves state unchanged.

§F — Inertness, observably

While a proposal of either kind is in any state other than applied, on a host whose readback contains the kind:

  • getInstalledPack for its name MUST answer 404 (when no other install of that name exists in the tenant);
  • for agent-pack, getAgent for each proposed agentId MUST answer 404, and listAgents MUST NOT list it.

After apply, the agents are resolvable only in the applying tenant: getAgent from another tenant answers as an unknown agent, which getAgent's installScope rule already requires.

§G — Where the rules live

The core budget is effectively full (36,784 / 36,800 words on 2026-10-31, check-core-budget.mjs), so, as in RFC 0249 §F, no core doc gains words. After merge at Active:

RuleOwner
§A operation, scope, advertisement, tenant scoping, what it servesthe getInstalledPack description in api/openapi.yaml (derived into api/v2/openapi.yaml)
§B id and version for pack kinds; §C empty host-owned setschemas/v2/proposal.schema.json activation.installedArtifact description
§A visibility and apply scope; §C signing refused; §D namespace, content rules and the late-binding disclosure; §E install conflicts; §F inertnessspec/v2/facets/agents.schema.json proposals.readback description (the agents family's normativeText)

SECURITY/threat-model-node-packs.md gains one line: this path installs a pack without the registry's signing or supply-chain checks, and its mitigations are review, byte-match, private.* names only, no nodes, and an inline system prompt.

packs.md and workflow-chain-packs.md are unchanged: their install, signing and pin rules bind a registry install as before, and this RFC adds a second, proposal-only install path that their rules do not describe. Whether packs.md should gain a pointer when budget allows is G3.

Examples

Positive. On a host advertising {artifactKinds:["agent-pack"], activation:"direct-rbac", clientDrafts:true, readback:["agent-pack"]}, with P a pure-agent pack private.conf.a1b2 at 1.0.0, one agent conf-a1b2 with an inline systemPrompt:

  1. POST /proposals {kind:"agent-pack", artifact:P} → 201, state: draft.
  2. GET /installed-packs/private.conf.a1b2 → 404; GET /agents/conf-a1b2 → 404.
  3. PATCH /proposals/{id} {artifact:P'} (a different systemPrompt) → 200, state: revised.
  4. POST /proposals/{id}:apply → 200, installedArtifact {kind:"agent-pack", operationId:"getInstalledPack", id:"private.conf.a1b2", version:"1.0.0"}.
  5. GET /installed-packs/private.conf.a1b2 is JCS-equal to P', and not to P.

Negative.

  • An agent-pack artifact whose agent carries systemPromptRef: "prompts/a.md" → :apply 422; GET /installed-packs/… still 404.
  • An agent-pack artifact with a non-empty nodes[] → :apply 422.
  • A chain-pack artifact carrying signing {keyId, scheme} → :apply 422.
  • An agent-pack artifact named vendor.acme.triage → :apply 422; GET /installed-packs/vendor.acme.triage still 404.
  • Tenant B: GET /installed-packs/private.conf.a1b2 → 404, the same answer as an unknown name.
  • installedArtifact {kind:"agent-pack", operationId:"getAgent", id:"conf-a1b2"} fails §B: getAgent does not serve the pack.

Compatibility

Additive (COMPATIBILITY.md §2.1, §2.4):

  • New operation. getInstalledPack is a new unversioned endpoint. A host that does not advertise readback for a pack kind serves 404, which every host already answers for an unknown path.
  • No schema shape changes. The readback items enum already lists agent-pack and workflow-chain-pack, so no enum widens. installedArtifact already has an optional version. Only descriptions change.
  • New MUSTs bind only a new advertisement. §C–§F bind a host whose readback contains a pack kind. No host advertises that today, and no committed bundle does. A host that proposes pack kinds without readback keeps today's obligations.
  • No error-code change. proposal_install_conflict and its two reason values are reused with their registered meaning (an install the target store refused). 422 is RFC 0249 §B's existing answer.
  • Response schemas. The response references the two existing manifest schemas. If the OpenAPI uses a cross-file $ref into a schema that did not have one, the suite minor bumps and the CHANGELOG names the peer (§2.1 §Cross-file $ref).

No migration is needed.

Conformance

Existing coverage.

  • v2-proposal-lifecycle.test.ts (RFC 0249) drives the prompt-template flow. Its submit-kind and unadvertised legs are kind-neutral and are not repeated.
  • workflow-chain-pack-manifest-validation.test.ts validates chain manifests server-free.
  • agentPackInstall.test.ts and agentPackExport.test.ts are major 1 only and fixture-gated (conformance-agent-pack-export). The export leg projects workspace agents back into AgentManifests; it is a v1 test fixture, not a v2 operation, and does not serve the installed pack.json.
  • No v2 scenario reads an installed pack.

New scenario v2-proposal-pack-readback.test.ts. One set of legs per kind, each gated on agents.proposals with clientDrafts: true, artifactKinds ∋ kind and readback ∋ kind; otherwise inapplicable. A harness key that is unset records blocked (the v2-auth-challenge precedent). Each run uses a fresh private.conformance.<random> name and, for agent packs, a fresh agentId. The artifacts are generated per run (freshChainPack, freshAgentPack in lib/proposal-pack-readback-witness.ts), so no fixture file is added; the bundled workflow-chain-sample.pack.json is not used because its vendor.* name and v1 engines range would break §D.

IdCaseExpect
0253.shape(server-free) an installedArtifact naming getInstalledPack with version; the two fixture artifacts validate against their manifest schemas; the negatives in §Examples fail §Dvalidate / refuse
0253.chain-draft-inertsubmit a chain pack; read itgetInstalledPack 404
0253.chain-apply-installsrevise, then applyinstalledArtifact {kind, operationId: getInstalledPack, id: name, version}
0253.chain-readback-byte-matchread the installed packJCS-equal to the revision, not to the first draft
0253.agent-draft-inertsubmit an agent pack; read itgetInstalledPack 404; getAgent 404; absent from listAgents
0253.agent-apply-installsrevise, then applyas for chains; getAgent now 200
0253.agent-readback-byte-matchread the installed packJCS-equal to the revision, not to the first draft
0253.agent-file-ref-refusedapply an agent pack whose agent carries systemPromptRef; then one with a non-empty nodes[]422 on each; getInstalledPack and getAgent still 404; state unchanged
0253.namespace-refusedapply a chain pack named vendor.<random>.chains422; getInstalledPack still 404; state unchanged
0253.signing-refusedapply a chain pack carrying signing422; getInstalledPack still 404; state unchanged
0253.install-conflictsubmit and apply a second proposal with the same name and version409 proposal_install_conflict, details.reason: version-not-greater
0253.cross-tenant-not-foundOPENWOP_TEST_TENANT_B_API_KEY reads the installed pack and agent404 on each, identical to an unknown name
0253.unadvertised-not-found(in v2-unadvertised-operation-not-found) a host whose readback lists no pack kindGET /installed-packs/{name} 404 not_found

Invariants. When the legs ship, proposal-inert-until-applied and proposal-no-resynthesis add v2-proposal-pack-readback.test.ts to tests, and their notes name the pack legs. Their witness class stays witnessable-gated. No new invariant is minted: tenant scoping and byte-match are already the two rows' and RFC 0249's rules.

Witnessing host. None today. openwop-app (tier-1) is the expected first implementer: it has a marketplace pack store, and it already serves the RFC 0249 operations. This RFC does not claim it implements anything. The legacy MyndHyve runtime is retired (2026-10-29), so Accepted evidence will be tier-1 (G1).

Falsifiability — one row per normative requirement

RequirementObservable — what an outside party seesWho can cause the conditionVerdict
§A unadvertised → 404 not_foundthe response to GET /installed-packs/{name}the suite, unaidedwitnessable-unaided
§A tenant scoping, no oracletenant B's 404 vs an unknown name's 404the suite, with two tenants' credentialswitnessable-gated
§A a proposal-installed pack is served200 on the name the apply installedthe suite (it submits and applies)witnessable-gated
§A no host-added hatch propertythe read-back body vs the artifactthe suitewitnessable-gated (via the byte-match leg)
§B id = name, version presentinstalledArtifact on the applied proposalthe suitewitnessable-gated
§C byte-match, empty host-owned setJCS equality of the read-back and the revisionthe suite (it wrote both)witnessable-gated
§C signing refused422; still 404the suitewitnessable-gated (0253.signing-refused)
§C no signing added at installthe read-back has no signingthe suitewitnessable-gated (via the byte-match leg)
§D private.* names only422; still 404the suitewitnessable-gated (0253.namespace-refused)
§D no nodes, inline prompt, no file refs422; still 404the suitewitnessable-gated
§A visibility tenant-wideanother workspace's read in the same tenantthe suite, with a second workspace's credentialswitnessable-gated in principle; no leg (no portable harness key for a second workspace)
§D runtime.entry not dereferenced—nobody outside the host: a fetch to a URL the suite does not control is not observable, and a suite-controlled URL witnesses only that host's egress policyunwitnessable — disclosed; the suite uses an unroutable entry so a host that fetches gains nothing (R3)
§E version-not-greater refused409 + reasonthe suitewitnessable-gated
§E read-only (registry or other pack) refused409 + reason: read-onlyonly when the suite knows a name or agentId the host installed itselfseam-gated in practice: no portable way to learn such a name; no leg (G4)
§F inertness, both kinds404 on getInstalledPack; 404 on getAgent; absent from listAgentsthe suitewitnessable-gated
§F installed agents tenant-scopedtenant B's getAgent 404the suite, with two tenants' credentialswitnessable-gated

Alternatives considered

  1. Do nothing; keep the disclosure. The two invariants stay unobservable for pack kinds, and the facet keeps saying so. Rejected as the end state, because a host that starts proposing agent packs (the higher-risk kind: a proposed system prompt changes model behavior) would do so with nothing checkable. Doing nothing is acceptable only while no host proposes a pack kind, which is why this is Draft rather than urgent.
  2. Per-kind reads (getInstalledChainPack, getInstalledAgentPack). Two operations with one rule. Rejected: both kinds are a pack.json keyed by name, and kind already discriminates the body. A per-kind split doubles the operation count and the advertisement logic for no difference a client can act on.
  3. Reuse getWorkflow for a single-chain pack. Rejected: a chain pack is expanded at author time; getWorkflow serves a host-derived definition (expanded, prefixed, {{params.*}} substituted), never the pack. Byte-match against it would compare different documents. It also cannot cover agent packs.
  4. Serve an AgentManifest through getAgent. Rejected: getAgent returns an inventory entry with host-shaped fields (degraded[], roster, a2aTenant), and changing its body is not additive. One agent is also not the pack the reviewer approved.
  5. An envelope {manifest, meta} with install metadata. It would give source, installedAt and integrity a home. Rejected for phase 2: RFC 0249 §C compares the body minus host-owned fields, so an envelope needs a new comparison rule ("the manifest member") rather than a host-owned field list. Kept open as UQ 3 if a general installed-pack read is wanted.
  6. A standalone facet flag (for example packs.installedRead). Rejected for now: readback already claims resolvability per kind, and its enum already admits both kinds, so a second flag would say the same thing twice. It becomes worth having only if the read serves registry installs too (UQ 3).
  7. Cover the tarball files (a files map in the artifact, or a second read for a referenced file). Rejected for phase 2: it changes what a proposal artifact is (no longer a pack.json), needs a file-level byte-match rule and a path-traversal rule for client-supplied paths. UQ 5.
  8. A pack-namespace rule for proposed packs. See UQ 1; not adopted in the Draft.

Decided questions

Decided 2026-10-31 after an /architect review, approved by the maintainer.

  1. **Namespace: private.* only.** A host advertising readback for a pack kind refuses any other name with 422 (§D). Only the prefix is required, not private.<host>.*: a client cannot know the host segment, and the suite's private.conformance.<random> names comply.
  2. signing: refused, as §C drafted. Making it host-owned needs a verifier rule for a non-registry key, which packs.md §Signing does not have. Reopen when a host wants to sign a local install.
  3. Scope of the read: proposal installs. Registry and host-shipped packs stay MAY, with no facet flag and no envelope (Alternatives 5 and 6). A general installed-pack read is a separate RFC.
  4. Versions: one per (tenant, name), no ?version=. Byte-match holds while the installed version equals installedArtifact.version (§A). A multi-version host does not advertise readback for the kind.
  5. Files: deferred to a later phase. §D discloses them, and also discloses the late-bound promptLibraryRef and promptOverrides.
  6. Workspace: tenant-wide (§A), consistent with installScope (host or tenant). A workspace-scoped host does not advertise readback for the kind, and proposals:apply for a pack kind is a tenant-level install decision.

Implementation notes (non-normative)

Order at Active.

  1. api/openapi.yaml (or the v2 seam in scripts/derive-v2-api.py, since the v1 document is frozen) gains getInstalledPack; regenerate api/v2/ and the path manifest.
  2. The three descriptions in §G.
  3. The scenario, a judge library (reuse lib/proposal-lifecycle-witness.ts where it is kind-neutral) with self-tests that fail each wrong host answer, and the invariant rows.
  4. A suite release.

Hosts. A host whose store keeps the installed pack.json verbatim serves the read from it. A host that normalizes a manifest on install (fills defaults, reorders, drops hatch properties) will fail byte-match and must keep the original bytes alongside its normalized form (R1).

SDKs. openwop-sdks needs getInstalledPack and a union response type over the two manifest types.

Acceptance criteria

  • [x] getInstalledPack in api/openapi.yaml / the derive seam and the derived api/v2/openapi.yaml, with spec/v2/path-manifest.json parity.
  • [x] The §G descriptions in proposal.schema.json and agents.schema.json. (2026-10-31, with the threat-model line.)
  • [x] v2-proposal-pack-readback.test.ts with the legs above, its judges and their self-tests; both invariants list it. (2026-10-31, suite 2.46.39. Before merge every host leg was run against a fake host: it passes a conforming one, and each of ten sabotages — a served draft, a host-added field, a re-synthesis, an accepted vendor. name, signing or file ref, an equal-version replace, a foreign 200, a listed draft agent, a minted id — fails the leg it targets.)*
  • [ ] CHANGELOG entry (done 2026-10-31); the openwop-sdks getInstalledPack method and response union are owed.
  • [ ] A host advertises readback containing at least one pack kind, and a certified major-2 bundle records that kind's 0253.* legs executed-pass (tier-1).

References

  • RFC 0249 §C, §D, gap G2: the read-back rule and the phase this RFC completes.
  • RFC 0096: the lifecycle and the two invariants.
  • RFC 0003: agent packs are node packs with agents[]; tarball-relative refs.
  • RFC 0013 / RFC 0133: chain packs, author-time expansion, co-registered children.
  • RFC 0043 §A: the namespace policy behind UQ 1.
  • spec/v2/core/packs.md (§The manifest schema family, §Signing), spec/v2/core/workflow-chain-packs.md (§Exact pins, §Co-registered children), spec/v2/core/conformance.md §Witness class, errors.md §Unadvertised operations.
  • schemas/v2/node-pack-manifest.schema.json, agent-manifest.schema.json, workflow-chain-pack-manifest.schema.json, proposal.schema.json, agent-inventory-response.schema.json.
  • openwop#2056: the 2026-10-29 audit of RFC 0249 G2 and G4.

Status history

  • 2026-10-29 — Draft.
  • 2026-10-31 — UQ 1–6 decided (/architect review, maintainer-approved); still Draft.
  • 2026-10-31 — Active (comment window waived); wire, descriptions and suite legs land in 2.46.39.

More proposals.

Edit this page on GitHub ↗