{
  "name": "ledgercovenant_decide",
  "version": "1.0.0",
  "title": "LedgerCovenant Decide",
  "description": "Test one covenant obligation for one period on an already-configured facility. Resolves which provision governed the test date, which reported figure governs when sources disagree, computes the ratio in scaled integers, and returns ACCEPT with a signed ledgered decision, or REVIEW/REFUSE with review items naming the specific artifact. Auth: InsightITS JWT, or an lcv_ API key carrying the decide scope. API reference: https://www.insightits.com/docs/ledgercovenant-api.md",
  "x-ai-agent-instructions": [
    "Call POST https://www.insightits.com/api/ledgercovenant/v1/decide with a JSON body.",
    "Use POST /v1/decide/preview first while iterating: it consumes no quota and writes nothing to the ledger.",
    "This tool does not configure a facility. Documents, defined terms, obligations, thresholds, and facts must already be recorded — the engine will not invent a threshold or a definition to keep a request moving.",
    "Never invent gate outcomes, ratios, confidence numbers, decision ids, or hashes. Relay only the fields the API returned.",
    "REVIEW and REFUSE return no decision and no signature. Do not report them as a covenant result; surface review_items, each of which names the artifact to look at.",
    "A LEGAL_AMBIGUOUS or FACT_CONFLICT refusal is the correct answer, not an error to retry around. Two provisions survived precedence, or two equally authoritative sources disagreed. Report the candidates in detail and stop.",
    "Do not resolve an ambiguity by picking a candidate yourself, and do not average conflicting figures. Both require a signed human attestation via POST /v1/review/{item_id}/resolve.",
    "knowledgeTime defaults to the end of the test period, not to now. Only pass it when deliberately asking what was known at an earlier moment.",
    "Sandbox-plan decisions carry is_development_key true. They are not regulatory artifacts and must not be presented as signed audit evidence."
  ],
  "inputSchema": {
    "type": "object",
    "required": ["facilityId", "obligationId", "testPeriod"],
    "properties": {
      "facilityId": { "type": "string", "description": "lcfac_… from POST /v1/facilities" },
      "obligationId": { "type": "string", "description": "lcobl_… from POST /v1/facilities/{id}/obligations" },
      "testPeriod": {
        "type": "string",
        "description": "Test period, e.g. 2026-Q2, 2026-06, or 2026. Normalized server-side."
      },
      "knowledgeTime": {
        "type": ["string", "null"],
        "description": "ISO 8601 transaction-time cutoff. Defaults to the end of the test period so a document filed later cannot change a historical answer."
      },
      "toleranceScaled": {
        "type": "integer",
        "default": 0,
        "description": "Scaled-integer tolerance for fact agreement. 0 means exact, which is the default on purpose."
      }
    }
  },
  "endpoint": {
    "method": "POST",
    "url": "https://www.insightits.com/api/ledgercovenant/v1/decide",
    "path": "/api/ledgercovenant/v1/decide",
    "auth": "Authorization: Bearer <InsightITS JWT>, or X-API-Key: lcv_… with the decide scope",
    "headers": { "Content-Type": "application/json", "Accept": "application/json" }
  },
  "responseFields": {
    "gate.outcome": "ACCEPT|REVIEW|REFUSE",
    "gate.reasons": "array of code/message explaining the outcome",
    "calc.outcome": "COMPLIANT|BREACH|WAIVED|NOT_APPLICABLE (absent when resolution failed)",
    "calc.computed_scaled": "scaled integer result; pair with calc.scale, never with a float",
    "calc.threshold_scaled": "the threshold in force on the test date",
    "calc.headroom_scaled": "distance to the threshold, same scale",
    "confidence.grounding_confidence_min": "0.0-1.0 across all materials",
    "confidence.grounding_confidence_wmean": "materiality-weighted mean",
    "confidence.unresolved_detail": "materials that could not be resolved, with candidates",
    "stages.legal": "governing provision plus every candidate the precedence ladder considered",
    "stages.lineage": "defined-term closure, resolution order, and any cycles",
    "decision.decision_id": "present only on ACCEPT",
    "decision.decision_payload_hash": "sha256 over the canonical payload (RFC 8785)",
    "decision.signature": "Ed25519 over the payload hash",
    "decision.is_development_key": "true on Sandbox — not a regulatory artifact",
    "decision.ledger_seq": "contiguous append-only sequence number",
    "review_items": "present on REVIEW and REFUSE; each names a specific artifact"
  },
  "reasonCodes": {
    "LEGAL_AMBIGUOUS": "Two or more provisions survived the precedence ladder. Candidates are in detail.",
    "LEGAL_MISSING_DEFINITION": "A defined term in the closure has no definition in force on the test date.",
    "LEGAL_CIRCULAR_DEFINITION": "Definitions reference each other through ordinary USES edges.",
    "FACT_CONFLICT": "Sources of equal authority report different values.",
    "FACT_MISSING": "A required fact has no assertion for the period.",
    "THRESHOLD_MISSING": "The step-down schedule has a gap on the test date.",
    "DERIVATION_CAP_UNDEFINED": "An add-back is capped but the cap basis or ceiling was never tagged.",
    "DERIVATION_NO_CONVERGENCE": "Circular caps did not settle within the declared iteration budget.",
    "BASKET_INSUFFICIENT": "The usage exceeds folded basket capacity on that date.",
    "BREACH_INVALID_TRANSITION": "That lifecycle step is not permitted from the current state.",
    "GATE_REFUSED": "The gate would not finalize. Resolve the review items.",
    "TIER_LIMIT": "Plan limit or a capability not included in the plan.",
    "QUOTA_EXCEEDED": "Monthly decision limit reached.",
    "ACCESS_DENIED_WALL": "The facility is outside the caller's deal-team scope.",
    "AUTH_KEY_SCOPE": "The API key lacks the decide scope, or the route requires a signed-in person.",
    "AUTH_KEY_FACILITY": "The API key is pinned to other facilities.",
    "AUTH_KEY_EXPIRED": "The API key has expired or been revoked."
  },
  "related": {
    "api_reference": "https://www.insightits.com/docs/ledgercovenant-api.md",
    "preview": "POST https://www.insightits.com/api/ledgercovenant/v1/decide/preview",
    "policies": "GET https://www.insightits.com/api/ledgercovenant/v1/policies",
    "derive": "POST https://www.insightits.com/api/ledgercovenant/v1/facilities/{facility_id}/derive",
    "basket_state": "GET https://www.insightits.com/api/ledgercovenant/v1/baskets/{basket_id}",
    "breach_state": "GET https://www.insightits.com/api/ledgercovenant/v1/facilities/{facility_id}/breach/{obligation_id}",
    "replay": "POST https://www.insightits.com/api/ledgercovenant/v1/decisions/{decision_id}/replay",
    "evidence_pack": "GET https://www.insightits.com/api/ledgercovenant/v1/facilities/{facility_id}/evidence-pack",
    "review_queue": "GET https://www.insightits.com/api/ledgercovenant/v1/review",
    "ledger_verify": "GET https://www.insightits.com/api/ledgercovenant/v1/ledger/verify",
    "ledger_anchors": "GET https://www.insightits.com/api/ledgercovenant/v1/ledger/anchors",
    "extractors": "GET https://www.insightits.com/api/ledgercovenant/v1/extractors",
    "extract_suggest": "POST https://www.insightits.com/api/ledgercovenant/v1/documents/{version_id}/extract/suggest",
    "dashboard": "https://www.insightits.com/dashboard.html#ledgercovenant",
    "health": "GET https://www.insightits.com/api/ledgercovenant/v1/health"
  },
  "notes": [
    "Extraction is a deterministic pattern matcher that proposes candidate spans and writes nothing; an analyst still submits what becomes evidence, and offsets are verified against the submitted text. There is no OCR and no language model in the path. Candidate confidence is the precision measured in-sample against that account's analyst tags, or 0.0 where nothing has been measured — do not present an unmeasured candidate as reliable. GET /v1/policies reports what is wired and what it was measured at.",
    "An API key can decide, replay, export evidence, and anchor a checkpoint. It can never attest, supersede a decision, move an information wall, or issue another key: an attestation is a named person taking responsibility, and no scope grants it. If a workflow needs one, stop and hand it to a person rather than looking for another route.",
    "Document text is never stored — only content hashes and the tagged spans.",
    "Corrections after a decision is signed happen by supersession, never by editing.",
    "A defined amount whose add-back caps reference the amount itself is settled by POST /v1/facilities/{id}/derive, which iterates to a least fixed point and records every pass. Do not compute such a cap yourself and do not report an unsettled figure: DERIVATION_NO_CONVERGENCE means the definition did not settle.",
    "Basket capacity has no stored balance; GET /v1/baskets/{id} folds it from events. asOf (when it happened) and knowledgeTime (when we knew) are different questions and must not be conflated.",
    "The breach lifecycle reports cure_window_expired, which is arithmetic about a date. It never declares an event of default. Do not describe an expired cure window as a default; asserting one requires a signed attestation via the transition endpoint."
  ]
}
