Skip to content

Guide: standing and mandates

Status: capability-state mix. Standing claim, evaluate, grant, and revoke walk end-to-end as fixture / staging-durable records. Mandate delegate and revoke are fixture-rehearsed. Real Verlag-issued authority package validation and real registered-office data are not yet substantive — see 022 gap report items 3, 7, 9.

This guide walks how an actor (a human, an AI, a system process) gets the right to act on behalf of a company in a specific office — and how that right is delegated, scoped, and revoked.

Authority in Gestalt has two layers:

  • Standing — the legal/operational basis for an actor to hold an office (Geschäftsführer, Prokurist, Bookkeeper, Auditor). Standing is granted citing real-world evidence (Handelsregister entry, appointment letter, board resolution) and is the durable thing an audit references.
  • Mandate — a delegated, revocable scope of power within an existing standing. A Geschäftsführer can delegate “approve invoices up to €10,000” to a clerk for a quarter. The clerk operates with a mandate, not with full standing.

Standing answers “is this person allowed to be the one acting here?” Mandate answers “and what specifically may they do?” A third layer — presence — binds a sensitive operation to a human’s authenticated, in-person attestation. Standing and mandate are persistent; presence is per-act. See human-auth-flows.md and auth-and-sessions.md.

  1. client.standingClaim — actor (or an existing officer on their behalf) claims an office.
  2. client.standingEvaluate — Gestalt evaluates the claim against the supplied evidence and the active authority package.
  3. client.standingGrant — once evaluation is satisfied, an existing officer (or the Verlag for the bootstrap case) grants the standing.
  4. client.mandateDelegate — the standing-holder delegates a scoped subset of their power.
  5. (Operate.)
  6. client.mandateRevoke / client.standingRevoke — wind down.
const tenant = "tenant_node:rheinwerk_calibration";
const claim = await client.standingClaim({
tenant,
actor: "human_person:anna",
company: "company_geist:rheinwerk_calibration",
office: "geschaeftsfuehrer",
evidence: [
"evidence_bundle:rheinwerk_handelsregister_anna",
"evidence_bundle:rheinwerk_appointment_letter_anna",
],
human_presence_receipt: "human_presence_receipt:fixture_private_presence",
create_standing_from_presence: false,
fixture: true,
});
console.log(claim.body.standingClaim);
// "standing_claim:rheinwerk_anna_geschaeftsfuehrer"

create_standing_from_presence: false is asserted explicitly. Even though the call carries a presence receipt (which is required for the claim to bind to an authenticated human), the presence receipt does not itself create standing. Setting it to true would refuse with a structured reason — phishing a passkey ceremony cannot promote an attacker to a Geschäftsführer.

const evaluation = await client.standingEvaluate({
tenant,
standing_claim: claim.body.standingClaim,
evidence: [
"evidence_bundle:rheinwerk_handelsregister_anna",
"evidence_bundle:rheinwerk_appointment_letter_anna",
],
human_presence_receipt: "human_presence_receipt:fixture_private_presence",
fixture: true,
});
console.log(evaluation.body.evaluationOutcome);
// "satisfied" | "missing_evidence" | "refused"

Evaluation runs the supplied evidence against the active authority package’s expectations for the office. The result is itself an admitted record — a future audit can reread why the standing was considered satisfied.

If the evaluation is missing_evidence, the body lists which evidence kinds were expected and missing. The Koerper should surface this as a “to do” list rather than a blocking error.

const grant = await client.standingGrant({
tenant,
standing_claim: claim.body.standingClaim,
standing_evaluation: evaluation.body.standingEvaluation,
actor: "human_person:anna",
company: "company_geist:rheinwerk_calibration",
office: "geschaeftsfuehrer",
powers: ["sign_invoices", "approve_period_close", "delegate_mandate"],
human_presence_receipt: "human_presence_receipt:fixture_private_presence",
fixture: true,
});
console.log(grant.body.standing);
// "standing:rheinwerk_anna_geschaeftsfuehrer"

The powers list is enumerated explicitly. The active authority package constrains which power strings are admissible for which office; passing a power the office cannot hold refuses with standing_grant_power_not_allowed.

Without standing_evaluation, the grant refuses with standing_grant_evaluation_missing. This is the load-bearing refusal — granting standing without evaluation would let a Koerper claim authority by assertion.

const mandate = await client.mandateDelegate({
tenant,
principal: "human_person:anna",
delegate: "human_person:bookkeeper_max",
source_standing: grant.body.standing,
act_scope: ["sign_invoices_up_to_eur_10000"],
readable_lens: ["lens:invoice_admin", "lens:payment_observation"],
human_presence_receipt: "human_presence_receipt:fixture_private_presence",
fixture: true,
});

The mandate carries act_scope (what verbs the delegate may invoke), readable_lens (what projections they may see), a citation back to source_standing (so revoking the source standing automatically invalidates derivative mandates), and a fresh presence receipt from the principal (delegation is itself sensitive). Without source_standing, the delegation refuses — a delegate without a principal has nothing to inherit.

The delegate operates against the membrane citing the mandate. Domain operations consult the mandate’s act_scope to decide whether the delegate is in scope; out-of-scope verbs refuse with mandate_act_scope_exceeded. See german-invoice-payment-advisor.md for what the operate stage looks like end-to-end.

When a delegate’s term ends, or when a standing holder leaves the company:

await client.mandateRevoke({
tenant,
mandate: mandate.body.mandate,
reason: "delegate_term_ended_2026q2",
enforce_runtime_overlay: true,
fixture: true,
});
await client.standingRevoke({
tenant,
standing: grant.body.standing,
reason: "officer_resignation_filed_2026_06_30",
enforce_runtime_overlay: true,
fixture: true,
});

enforce_runtime_overlay: true tells the runtime to immediately reject any in-flight operation citing the revoked standing or mandate. Without the overlay, the revocation is recorded but the runtime keeps honoring the binding until normal expiry — useful for staged removal, dangerous in production.

Revoking a standing implicitly invalidates any mandate derived from it. A Koerper showing the revocation should also surface the list of derivative mandates that just became invalid.

Sensitive operations require not just standing or mandate, but fresh presence on top. The presence-approval endpoint binds a presence receipt to a specific actor + vessel pair:

const approval = await client.m13PresenceApproval({
tenant,
actor: "human_person:anna",
vessel: "vessel:fixture_sdk",
human_presence_receipt: "human_presence_receipt:fixture_private_presence",
create_standing_from_presence: false,
});
console.log(approval.body.sensitiveApprovalSatisfied); // true
console.log(approval.body.standingCreated); // false

This is what gates an effect intent’s “send invoice email” or a high-value refund: the standing says the actor may, the presence says they are here right now. Both must hold.

create_standing_from_presence: true refuses with m13_human_presence_cannot_create_standing — the constitutional separation between presence and standing.

A Koerper that walks this flow should be ready to render:

  • standing_grant_evaluation_missing — grant invoked without evaluation first. Surface an “evaluate first” CTA.
  • standing_grant_power_not_allowed — requested power string the active authority package doesn’t permit for the office. Surface the package’s allowed powers.
  • mandate_act_scope_exceeded — a domain operation tried to run under a mandate that doesn’t cover the verb. Surface the mandate’s actual scope.
  • m13_human_presence_cannot_create_standing — back-door attempt. Surface the constitutional invariant: presence is per-act, standing is granted.
  • Expired delegation — a domain operation cited a mandate whose principal-side standing was revoked. Surface “delegation invalidated by source revocation” and prompt re-delegation.
  • Authority is two-layered (standing + mandate) and each layer is itself a citable record.
  • Presence and standing are separated by construction. An attacker who phishes a passkey cannot upgrade themselves to an officer.
  • Revocation has both a recorded-intent and a runtime-overlay posture; the latter is what actually halts in-flight operations.
  • Real Verlag-issued authority package validation. The active package today is fixture data; powers and offices are hard-coded. A real Verlag signing chain that issues authority packages cryptographically is not yet in place — see 022 item 3.
  • Real registered-office data. companyBootstrap accepts hashed legal name and register number, but the Handelsregister connector that would verify those is fixture data. See 022 item 7.
  • Real cross-tenant standing. Standing today binds an actor to a company within one tenant. Cross-tenant scenarios (an advisor with standing at multiple client tenants) are roadmapped.