Skip to content

Guide: publishing an authority package

Status: fixture-rehearsed. Real publishing requires a Verlag trust root, professional reviewers, and registry trust workflow that don’t exist yet (see 022 gap report items 3, 8). This guide walks the fixture lifecycle so you can design against the eventual production shape.

This guide walks the full lifecycle of an authority package as a fixture: import → candidate → review → activate → revoke. It uses the existing fixture package authority-packages/france-market-entry-projection-2026-04.json.

import { GestaltClient } from "@gestalt/sdk";
const client = new GestaltClient({
baseUrl: "http://127.0.0.1:3011",
token: "fixture-session-token",
});
const tenant = "tenant_node:rheinwerk_calibration";
const pkg = "authority_package:france_market_entry_projection_2026_04";
const imported = await client.packageImport({
tenant,
package: pkg,
publisher_signed: true,
manifest_version: "authority.package.manifest.v0.fixture",
source_hash: "sha256:fixture_source",
content_hash: "sha256:fixture_manifest",
tampered_manifest: false,
stale: false,
self_activate: false,
});
console.log(imported.outcome); // "admitted"
console.log(imported.body.candidate);

What happened:

  • The package manifest was structurally validated.
  • A candidate record was created.
  • The publisher’s signature was checked (against the fixture keyring).
  • No activation yet — that comes later.
const tampered = await client.packageImport({
...,
tampered_manifest: true,
});
// outcome: "refused"
// body.refusalReason: "authority_package_tamper_refused"
const stale = await client.packageImport({
...,
stale: true,
});
// outcome: "refused"
// body.refusalReason: "authority_package_stale"
const self = await client.packageImport({
...,
self_activate: true,
});
// outcome: "refused"
// body.refusalReason: "authority_package_self_activation_refused"

A publisher cannot activate their own package without an external reviewer. This is enforced at admission, not by social convention.

const review = await client.packageReview({
tenant,
package: pkg,
reviewer_decision: "approve", // or "refuse"
});

In production this will require:

  • a reviewer with attested professional standing for the package’s scope,
  • the reviewer’s signed review,
  • conditions (time-bound, scope-bound, with caveats).

Today the reviewer identity is implicit and the decision is a boolean.

const activation = await client.packageActivate({
tenant,
package: pkg,
publisher_signed: true,
reviewer_decision: "approve",
self_activate: false,
});
console.log(activation.outcome); // "admitted"
console.log(activation.body.decision); // "admit_fixture_only"

The package is now active in the tenant. Capabilities cited by it become valid for atom citation. In fixture onlyadmit_fixture_only is the explicit marker that this activation is not production-binding.

If you try to activate without publisher signing or reviewer approval:

const incomplete = await client.packageActivate({
...,
publisher_signed: false,
});
// outcome: "refused"
// body.refusalReason: "authority_package_activation_requirements_missing"
const status = await fetch(
"http://127.0.0.1:3011/v1/authority/packages/status",
{ headers: { authorization: "Bearer fixture-session-token" } }
).then(r => r.json());
// status.body lists packages with their lifecycle state:
// imported, candidate, reviewed, active, revoked
const revocation = await client.packageRevoke({
tenant,
package: pkg,
});

Revocation does not delete. It records a revocation lifecycle atom. Atoms previously admitted under the package remain valid for what they were admitted under, but new atoms cannot cite the revoked package.

  • Tampered manifests refuse.
  • Stale sources refuse.
  • Self-activation refuses.
  • The candidate → review → activate gate is enforced.
  • Revocation does not rewrite history.
  • It does not require a real Verlag publisher with PKI-grade signing. The publisher is implicit; the signature is fixture.
  • It does not require a real professional reviewer with attested standing. The reviewer decision is a boolean.
  • It does not bind real legal-operational reliance. Authentic activation requires the production-admission gate to land.
  • It does not surface liability terms — what relying parties may depend on, who carries liability if the package is wrong.
  • It does not connect to a registry trust workflow.

For the real production gap, see 022 gap report items 3 and 8.

You can build a publisher console against the fixture lifecycle:

  • a UI to author and submit package manifests,
  • a UI to display the candidate state and reviewer decisions,
  • a UI to surface activation receipts and revocation history.

When the Verlag pipeline lands, the Koerper rewires from the fixture publisher to the real one. The membrane shape stays.