Skip to content

API: Observability, tenant, commits, M7, refusals

Capability state: mixed. See per-operation labels in reference/capability-state.md.

This page covers the foundational and inspection-only endpoints: observability probes, tenant context (including tenant onboarding and company bootstrap), recent commits, M7 durable state inspection, and refusal-code introspection.

These are unauthenticated and exist for ops and CI.

GET /health
state: staging-durable

Returns 200 if the runtime is healthy.

GET /ready
state: staging-durable

Returns 200 if the runtime is ready to accept work.

GET /version
state: staging-durable

Returns the runtime version and the membrane contract version.

GET /metrics
state: staging-durable

Returns runtime metrics in a fixture-shaped surface today; production metrics surface format will be documented when the runtime metrics contract stabilizes.

Terminal window
curl -s http://127.0.0.1:3011/health
curl -s http://127.0.0.1:3011/ready
curl -s http://127.0.0.1:3011/version
curl -s http://127.0.0.1:3011/metrics

Inspect own tenant / session boundary.

GET /v1/tenant/self
state: shape-only
sdk_role: inspect own tenant/session boundary
request_record: CloudTenantSelfRequest
responses: tenant_context | receipt
{
"operation": "tenant.self",
"outcome": "verified",
"body": {
"tenant": "tenant_node:rheinwerk_calibration",
"productionAdmission": false
},
"receipt": {...}
}

Today, the only tenant is tenant_node:rheinwerk_calibration. Tenant onboarding has no membrane endpoint yet (see 022 gap report item 7).

const tenant = await client.tenantSelf();

Record minimized tenant onboarding candidate with optional key custody reference and no raw customer payload storage.

POST /v1/tenants/create
state: staging-durable
sdk_role: record minimized tenant onboarding candidate with optional key custody reference and no raw customer payload storage
request_record: CloudTenantCreateRequest
responses: tenant_onboarding | refusal | receipt
interface TenantCreateRequest {
tenant?: GestaltRef;
requested_tenant?: GestaltRef; // must start with "tenant_node:"
host?: string; // unique per tenant
company?: GestaltRef;
parent?: GestaltRef;
authority_epoch?: GestaltRef;
home_reality?: GestaltRef;
signing_key?: GestaltRef;
encryption_key?: GestaltRef;
auth_policy?: string; // e.g. "fixture_session_only"
key_custody_attestation?: GestaltRef;
fixture?: boolean; // must be true
contains_customer_data?: boolean; // refused if true
raw_customer_payload?: unknown; // refused if present
}
{
"operation": "tenant.create",
"outcome": "admitted",
"body": {
"tenant": "tenant_node:...",
"host": "...",
"company": "company_geist:...",
"status": "candidate",
"tenant_key_custody": "referenced_not_provisioned",
"tenant_key_custody_bound": true,
"durable_state": {...},
"raw_customer_data_stored": false,
"production_admission": false
},
"receipt": {...}
}

tenant_key_custody is one of:

  • referenced_not_provisioned — a key_custody_attestation ref was supplied (the tenant points at a key custody record but the membrane does not provision keys here).
  • not_provisioned — no attestation ref supplied.

Refusal codes: tenant_onboarding_raw_payload_refused, tenant_onboarding_invalid_tenant_ref, tenant_onboarding_existing_tenant_refused, tenant_onboarding_host_conflict.

const created = await client.tenantCreate({
tenant: "tenant_node:rheinwerk_calibration",
requested_tenant: "tenant_node:m21_koerper_fixture",
host: "m21-koerper.fixture.local",
company: "company_geist:m21_koerper_fixture",
parent: "tenant_node:rheinwerk_calibration",
authority_epoch: "authority_epoch:fixture",
home_reality: "reality:fixture",
auth_policy: "fixture_session_only",
fixture: true,
});

Record minimized company bootstrap hashes and verification evidence without raw register payload storage.

POST /v1/companies/bootstrap
state: staging-durable
sdk_role: record minimized company bootstrap hashes and verification evidence without raw register payload storage
request_record: CloudCompanyBootstrapRequest
responses: company_bootstrap | refusal | receipt
interface CompanyBootstrapRequest {
tenant?: GestaltRef;
tenant_onboarding?: GestaltRef;
company?: GestaltRef;
legal_name?: string;
legal_name_hash?: string; // computed from legal_name if absent
legal_form?: string; // e.g. "DE_GmbH"
jurisdiction?: string; // e.g. "DE"
register_number_hash?: string;
verification_evidence?: GestaltRef[];
fixture?: boolean; // must be true
contains_customer_data?: boolean; // refused if true
raw_register_payload?: unknown; // refused if present
}
{
"operation": "company.bootstrap",
"outcome": "admitted",
"body": {
"company": "company_geist:...",
"jurisdiction": "DE",
"status": "bootstrapped_fixture",
"durable_state": {...},
"raw_customer_data_stored": false,
"raw_register_payload_stored": false,
"raw_legal_name_stored": false,
"production_admission": false
},
"receipt": {...}
}

The membrane stores only the legal name hash, the register number hash, and the citation list. Raw register payloads and the original legal_name are not persisted.

Refusal codes: company_bootstrap_raw_register_payload_refused.

const bootstrapped = await client.companyBootstrap({
tenant: "tenant_node:rheinwerk_calibration",
tenant_onboarding: "tenant_node:m21_koerper_fixture",
company: "company_geist:m21_koerper_fixture",
legal_name: "M21 Koerper Fixture GmbH",
legal_form: "DE_GmbH",
jurisdiction: "DE",
register_number_hash: "sha256:m21_fixture_register_hash",
verification_evidence: ["evidence_bundle:fixture_advisor"],
fixture: true,
});

Inspect recent durable signed atom commits through the authorized tenant membrane.

GET /v1/commits/recent
state: staging-durable
sdk_role: inspect recent durable signed atom commits through authorized tenant membrane
request_record: CloudRecentCommitsRequest
responses: commits | receipt
{
"operation": "commit.recent",
"outcome": "verified",
"body": {
"commits": [...],
"durable": true
},
"receipt": {...}
}

durable: true indicates the commit journal is operating against a durable store (recent commit 9d3570e). In purely in-memory fixture mode, durable: false.

const recent = await client.recentCommits();

Inspect tenant-scoped durable M7 object counts without raw database access.

GET /v1/m7/state
state: staging-durable
sdk_role: inspect tenant-scoped durable M7 object counts without raw database access
request_record: CloudM7StateRequest
responses: durable_counts | receipt
{
"operation": "m7.state",
"outcome": "verified",
"body": {
"remoteDurable": true,
"rawDbExposed": false,
"productionAdmission": false,
"counts": {
"atoms": 0,
"evidenceBundles": 0,
"passkeyBindings": 0,
"sessionLifecycles": 0,
"...": 0
}
},
"receipt": {...}
}

rawDbExposed: false is asserted: the membrane never exposes raw database access, even for inspection.

const state = await client.m7State();

Inspect stable machine-readable refusal taxonomy.

GET /v1/refusals/codes
state: shape-only
sdk_role: inspect stable machine-readable refusal taxonomy
request_record: CloudRefusalCodesRequest
responses: codes | receipt
{
"operation": "refusal.codes",
"outcome": "verified",
"body": {
"codes": [
"required_evidence_missing",
"authority_package_stale",
"...": "..."
]
},
"receipt": {...}
}

The taxonomy is currently shape-only; codes are scattered as string literals across cloud handler code. A durable taxonomy is a roadmap item.

See reference/refusal-codes.md for the documented set.

Inspect the developer refusal registry. Each entry carries category metadata, the guard rule that emits the code, the privacy posture, and the live runtime taxonomy attached to it.

GET /v1/refusals/registry
state: shape-only
sdk_role: inspect the developer refusal registry
request_record: (empty body)
responses: registry | receipt
{
"operation": "refusal.registry",
"outcome": "verified",
"body": {
"entries": [
{
"code": "required_evidence_missing",
"category": "evidence",
"guard_rule": "...",
"privacy_posture": "...",
"runtime_taxonomy": ["..."]
}
]
},
"receipt": {...}
}
const registry = await client.refusalRegistry();

Return the embedded gestalt-cloud-membrane.v0 contract document. Useful for client-side introspection (matching SDK request shapes against the live contract version, generating documentation, or validating that a runtime is the expected version).

GET /v1/membrane/contract
state: shape-only
sdk_role: not yet wrapped — call directly when introspecting the contract
request_record: (empty body)
responses: contract_document | receipt

The endpoint takes no body. No bearer token is required.

The full membrane contract JSON document is returned as the response body. See contracts/gestalt-cloud-membrane.v0.json for the canonical shape.

Terminal window
curl -s http://127.0.0.1:3011/v1/membrane/contract | jq '.version'
# "0.0.1-fixture"