lema · docs · api

Check

The never-reopen surface. /check-approach adjudicates one named direction against your recorded deliberation and returns a typed verdict — a recorded rejection with its cited why-not, or an honest unknown. /closed-atoms hands you the entire closed set instead, so a local guard can run on every edit without a network call.

POST

/check-approach

POST/check-approach

Check an approach

Adjudicates one named approach against your own recorded deliberation. Exactly two verdicts can fire on this surface: ruled_out — a recorded rejection governs, with the cited why-not — or no_recorded_ruling, the honest unknown. When nothing was ruled out but the record holds the reasoning, the no_recorded_ruling carries a cited why: the recorded rationale, kept distinct from a ruling.

auth · decisions:readquota · Counts as one MCP query (the ask side of the daily wallet).

Request body

approachstringrequired
The direction to check against your record.
workspace_idsstring[]
Optional workspace UUIDs to check against. Omitted, every workspace you can see.

Response

repostring
The scope label the check ran over.
approachstring
Your approach, echoed.
verdictstring
ruled_out or no_recorded_ruling — nothing else fires on this surface.
why_notstring · optional
On ruled_out only: the recorded why-not, summarized and cited. Never co-present with why.
whystring · optional
On no_recorded_ruling only, when the record holds reasoning: the recorded rationale — not a ruling, not approval.
sourcesobject[]
The citations behind the verdict: n, ref, type, text (summarized), plus optional url, binding_cosine (relevance, not confidence — measured per call), decision_id.
howobject
The forward pointer, when the record holds one: guidance and/or the sanctioned alternative, with its own citation when grounded.
notestring · optional
The honesty note telling the agent how to treat the verdict.
usage.atoms_tokensinteger
Tokens in the claims actually served.
usage.source_decisionsinteger
How many source decisions those claims cite.
usage.source_tokensinteger
Tokens in the full source documents behind them — what you did not have to load.
usage.tokens_savedinteger
source_tokens minus atoms_tokens. Conservative: only sources lema can size are counted.
usage.compression_rationumber
source_tokens over atoms_tokens, measured per call.
synthesis_tokens_in / synthesis_tokens_outinteger
The synthesis cost of this call.

Errors

  • 400approach missing, malformed workspace UUID, or an unknown JSON field.
  • 403a requested workspace exists but is not yours to see.
  • 429the daily MCP-query wallet is spent.
  • 501this deployment is not configured to answer.

Precision-safe by construction: an ungrounded match degrades to the honest no_recorded_ruling — never an ungrounded ruled_out over your record.

why_not and why are mutually exclusive: a ruled_out never carries why; a no_recorded_ruling never carries why_not.

A bare abstain returns sources: [] and the explicit note that absence is NOT approval.

decision_url is never set over a private corpus — decision_id is the stable key you keep.

$ curl https://api.lema.sh/check-approach \
  -H "Authorization: Bearer $LEMA_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"approach": "re-merge the ledger service into the monolith"}'
response shape
{
  "repo": "<the workspaces checked>",
  "approach": "re-merge the ledger service into the monolith",
  "verdict": "ruled_out",
  "why_not": "<the recorded why-not — summarized, never a verbatim quote>",
  "sources": [
    {
      "n": 1,
      "ref": "ADR-0019",
      "type": "rejected",
      "text": "<the killed option, with why it was killed>",
      "decision_id": "<stable uuid>"
    }
  ],
  "how": { "guidance": "<the sanctioned alternative, when recorded>" },
  "note": "this approach touches a recorded rejection — surface the
           why-not and its citation, do not re-propose it",
  "usage": { "atoms_tokens": …, "source_decisions": …, "source_tokens": …,
             "tokens_saved": …, "compression_ratio": … },
  "synthesis_tokens_in": …,
  "synthesis_tokens_out": …
}

GET

/closed-atoms

GET/closed-atoms

The closed set

Your org's CLOSED no-go set: every rejected alternative of an accepted, non-superseded decision, as one atom each. This is what hosted check_decided adjudicates against locally — fetch it once per session and the never-reopen guard runs without a network call per edit.

auth · decisions:readquota · Counts as one MCP query (the retrieve side of the daily wallet).

Query parameters

workspace_idsstring · repeatable or comma-joined
?workspace_ids=A&workspace_ids=B or ?workspace_ids=A,B. Absent, every workspace you can see.

Response

atomsobject[]
The closed set, newest first, capped at 500.
atoms[].idstring
The atom id.
atoms[].typestring
The claim type — rejected, for this set.
atoms[].textstring
The recorded rejection, summarized.
atoms[].refstring
The governing decision ref.
atoms[].locatorstring · optional
A finer pointer into the source.
atoms[].closedboolean
Always true here — this is the never-reopen set.
atoms[].closed_notestring
The human explanation of why the option is closed.
atoms[].match_keystring
The killed option's name — the ONLY text the guard keys on, so rationale prose can never false-fire a block.
atoms[].workspacestring · optional
Which workspace it came from.
truncatedboolean · optional
Present and true only when the 500-atom cap was hit — a partial no-go set is never silently passed off as complete.

Errors

  • 400a malformed workspace UUID.
  • 403a requested workspace exists but is not yours to see.
  • 429the daily MCP-query wallet is spent.

A caller with no workspaces gets 200 with atoms: [] — an empty record is a state, not an error.

$ curl "https://api.lema.sh/closed-atoms" \
  -H "Authorization: Bearer $LEMA_API_TOKEN"
response shape
{
  "atoms": [
    {
      "id": "<atom id>",
      "type": "rejected",
      "text": "<the recorded rejection, summarized>",
      "ref": "ADR-0019",
      "closed": true,
      "closed_note": "<why this option is closed>",
      "match_key": "<the killed option's name>",
      "workspace": "payments-api"
    }
  ]
}