Logic & Rule Compilation
Read and write an app's versioned logic manifest, compile plain-language rule cards against bound fields, and edit apps with natural-language proposals.
An app's behavior lives in its versioned content manifest — one JSON document per version carrying the mode, the logic, the input bindings, the output contract, thresholds, triggers, fallback policy, and presentation vocabulary. GET /v1/apps/:id/logic returns both sides at once: draft (the editable next version, or null) and active (the published version runs execute, or null). PUT /v1/apps/:id/logic — and its alias PATCH /v1/apps/:id — writes the whole manifest as the draft, creating version head + 1 if no draft exists yet. Drafts change nothing live until [published](app-versions).
Manifest content fields
Rules apps carry their policy as cards: each card holds the author's originalPolicy sentence plus a structured interpretation the engine executes. You rarely write interpretations by hand. Save cards with a pending_compile marker (the sentence only), then call POST /v1/apps/:id/logic/compile — the compiler grounds each pending sentence in the app's bound fields and writes executable scope/failure predicates back into the draft. A sentence that cannot be grounded stays pending, with the reason in warnings and on the card itself, so an ungrounded rule can never silently decide.
/v1/apps/:id/logic/compileBody
/v1/apps/:id/logic/fieldscurl — save a draft with a pending rule, then compile it
curl -s -X PUT https://api.talonic.com/v1/apps/$APP_ID/logic \
-H "Authorization: Bearer tlnc_your_api_key" \
-H "Content-Type: application/json" \
-d @manifest.json
# → { "version": 2, "status": "draft", "content_hash": "9df5a562cff6d2df..." }
curl -s -X POST https://api.talonic.com/v1/apps/$APP_ID/logic/compile \
-H "Authorization: Bearer tlnc_your_api_key" \
-H "Content-Type: application/json" \
-d '{"guidance": "\"billed amount\" is the total_amount field on the loads binding"}'
# → { "cards": [ ...interpretations written... ], "warnings": [] }Natural-language editing
Existing apps are edited the same way they are drafted: in language. POST /v1/apps/:id/edit-proposals takes an instruction (8–2000 chars, e.g. "Raise the quantity tolerance from 100 to 150 units") and returns typed edit ops plus a full preview of the manifest after the change, a plain-language summary, open_questions, and warnings. Nothing persists at this step. The person reviews the ops and applies them explicitly with POST /v1/apps/:id/edit-proposals/apply — a deterministic step that re-validates the ops against the live draft, saves it, and compiles the touched cards.
Edit proposal — request and response excerpt
POST /v1/apps/:id/edit-proposals
{ "instruction": "Raise the quantity tolerance from 100 to 150 units." }
{
"ops": [
{ "op": "edit_rule", "card_id": "quantity-tolerance",
"sentence": "Hold any load whose quantity exceeds 150 units." }
],
"summary": "The quantity tolerance threshold on the \"quantity-tolerance\" rule has been raised from 100 to 150 units. All other rules and settings remain unchanged.",
"open_questions": [],
"warnings": [],
"preview": { "mode": "rules", "logic": { "kind": "rules", "cards": [ ... ] }, ... }
}The op vocabulary is closed and reviewable: add_rule, edit_rule, remove_rule, pause_rule, resume_rule, set_fallback, set_adjudication, and set_mode (rules ⇄ assisted). Because apply is a separate, deterministic call taking the exact ops you accepted, an agent can propose and a human can approve — or the same caller can chain both — without an LLM ever writing directly into the draft.