/** * THE policy-rule landing (DES-MEM-FACETED-001 §5.2; DC-S3 probe + read-back; DC-S4a one path). * * `POST /proposals/:id/approve` (an ordinary policy proposal) and the decision landing * (`decisions/land.ts remember()`) both end here, so the probe, the read-back and the audit cannot * drift between them: * * 1. probe: a project-scoped (or superseding) rule on an engine without project rules fails loud * and writes nothing — the engine would accept the fields and drop them, landing it everywhere; * 2. upsert through the single-writer actor; * 3. read-back: the stored rule must still carry `targets.project`, the proposal ref and every * `supersedes` id; a mismatch RETIRES the just-written rule (retire, never delete) and fails loud; * 4. audit `governance.rule.upserted` with the caller's `via`. * * Failures are returned in-band (`outcome:"failed"`, the crew#388 anti-silent-loss doctrine). */ import type { CoreAdapter } from '../core/adapter.js'; import type { Actor, ConformanceRule, PolicyLandingResult, PolicyReach, SteeringType } from '../core/types.js'; import type { AuditLog } from './audit.js'; /** * Map an APPROVED policy proposal (estate `proposal.approve` → `handed_off`) into a steering * ConformanceRule (DES-MEM-FACETED-001 §5.2). A policy proposal's `kind_type` is * `policy:` and its `payload` is `{ rule, severity }`; estate writes NOTHING for it * (the AW-11 "no rules.write on estate" invariant) and hands the payload back for crew — the ONE * governed rules-write path — to land. Returns the rule to upsert plus the resolved steering type, * or a loud `error` string when the proposal cannot be shaped into a valid rule (a malformed * `kind_type` / missing `rule` / out-of-enum `severity`) — the caller reports it as a failed * landing, never a silent drop (the crew#388 anti-silent-loss doctrine). * * The rule id is DETERMINISTIC (`proposal:`) so a re-driven landing UPSERTS the same rule * (idempotent) instead of minting a duplicate; it sits OUTSIDE the reserved `PAT-/POL-` namespace, * which UI/chat/proposal-authored rules are free to do (INV-C1). The rule carries NO `effect` * (recall-only — exactly what `{rule, severity}` supports: an enforcement rule would need a * non-blank `applies_to`, which the payload does not carry, and INV-S3 fails such a rule closed). * `steering_type` is validated against the vocabulary here so the engine's INV-S1 never rejects it * as an unknown page. */ export declare function policyProposalToRule(proposalId: string, kindType: string, payload: unknown, facets: Record | undefined, scope?: { runProject?: string; reach?: PolicyReach; }): { rule: ConformanceRule; steeringType: SteeringType; reach: PolicyReach; } | { error: string; }; /** * Withdraw the rule a policy proposal landed, once the proposal is rejected. The rule lands BEFORE * estate approves the proposal, so a proposal left pending (a crash between the two, or an approve * estate did not confirm) may already have a live `proposal:` rule; rejecting the proposal must * not leave it in force. Returns `null` when nothing is live (a memory proposal, never landed, or * already retired) or the rule was retired, else the loud reason the retire failed. */ export declare function withdrawLandedRule(adapter: Pick, proposalId: string): Promise; export interface PolicyLandingDeps { adapter: Pick; audit: AuditLog; } export declare function landPolicyRule(deps: PolicyLandingDeps, built: { rule: ConformanceRule; steeringType: SteeringType; reach?: PolicyReach; }, actor: Actor, detail: { via: string; proposalId: string; } & Record): Promise; //# sourceMappingURL=policy-landing.d.ts.map