IngaDB 0.1 · Product documentation
IngaDB/DocumentationAPI v1
Browse documentation
EXAMPLES

IngaDB in practice, from five perspectives.

The same causal store looks different depending on where you stand. This page walks a fictional packaging line, packaging-line, through five roles. Every code block assumes the state built in the quickstart and runs as written.

Guide + hands-onAPI v1ingactl
How to read this page

Each scenario stands alone — start from the role closest to yours. Scenario 3, turning a pile of incident reports into evidence, is the longest and covers the full collaboration with an AI agent.

Why some commands are curl and some are ingactl

IngaDB has two entrances. /db/v1 is the versioned HTTP contract — the surface SDKs and custom integrations target — and scenarios 1–2 deliberately show it as raw curl. ingactl drives the full /api surface (reads and writes alike) through a catalog synced from the instance — the operating surface for people and agents, used in scenarios 3–6. Both act on the same store.

1. The reliability engineer — a tree as data, not a drawing

You have: a fault tree on a whiteboard.
You get: a typed topology you can search, diff, and audit.

Write events and gates as typed data. Topology replacement is atomic, so readers never see a half-written graph.

terminalbash
curl -s -X PUT "localhost:9876/db/v1/graphs/$GID/topology" \
  -H "X-Org-Id: $ORG" -H 'content-type: application/json' -d '{
  "events": [
    {"id":"E_BEARING","label":"bearing wear","component":"conveyor","failure_mode":"wear"},
    {"id":"E_SEAL","label":"seal leak","component":"pump","failure_mode":"seal_leak"}
  ],
  "gates": [
    {"id":"G_TOP","label":"line stops","type":"OR","inputs":["E_BEARING","E_SEAL"]}
  ]
}'

curl -s -X POST "localhost:9876/db/v1/graphs/$GID/views/analysis" \
  -H "X-Org-Id: $ORG" -d '{}' \
  | jq '{p_top: .analysis.gate_quantities.G_TOP, rev: .analysis.graph_revision}'

This is where the difference from a drawing tool begins: the tree is queryable, every change lands as a revision, and each computed result carries the revision it was computed from.

2. The equipment designer — describe the mechanism once

You have: knowledge of how the equipment fails.
You get: a tree compiled on demand for any hazard.

Instead of drawing one tree per hazard, record failure modes, propagation, and redundancy once — and compile the tree a hazard implies whenever you need it.

terminalbash
curl -s -X POST localhost:9876/api/mechanism -H "X-Org-Id: $ORG" -d '{
  "source": "manual",
  "facts": [
    {"component":"pump","fact_type":"failure_mode","subject":"pump","object":"seal_leak","params":{}},
    {"component":"line","fact_type":"propagates_to","subject":"pump","object":"line",
     "params":{"class":"omission","rule":"or"}},
    {"component":"pump_house","fact_type":"redundancy","subject":"pumps","object":"pump",
     "params":{"k":1,"n":2}}
  ]
}'

curl -s -X POST "localhost:9876/db/v1/graphs/$GID/compile" -H "X-Org-Id: $ORG" \
  -d '{"component":"line","class":"omission"}' \
  | jq '{top_gate_id, written, cut_branches: (.cut_branches|length)}'

written is always false: the compile returns the tree those facts imply and changes nothing. cut_branches lists every branch the compiler stopped — mechanism graphs contain feedback loops a fault tree cannot hold — each with its reason. Want a second pump? Add one redundancy fact and recompile.

What comes back is the generated tree itself. A real response, excerpted with unedited values, annotated:

compile response (real, excerpted)json
{
  "written": false,                          ← ①
  "top_gate_id": "G_LINE_OMISSION",
  "nodes": [
    { "id": "E_CONVEYOR_BEARING_WEAR", … },
    { "id": "G_PUMPS_OMISSION",
      "label": "pumps fails (2 of 2)",       ← ②
      "properties": { "gate_type": "AND" } },
    …
  ],
  "provenance": [
    { "gate_id": "G_LINE_OMISSION",
      "rule": "or",
      "from_facts": [
        "propagates_to(conveyor -> line)",   ← ③
        "redundancy(pump_house, pumps)" ] } ],
  "cut_branches": []                         ← ④
}
  1. ① Read-only generation — nothing was written
  2. ② The redundancy fact (k=1, n=2) became an AND gate
  3. ③ The mechanism facts behind each gate
  4. ④ Cut branches — zero for this model; each would carry its reason

3. The maintenance team with an AI agent — turning report piles into evidence

You have: years of incident reports.
You get: evidence records with sources attached, and probabilities derived from real history.

Probabilities come from evidence — and most of that evidence sleeps inside reports like these (a Japanese-language plant, as many of our users run):

incident-reports.txttext
【報告書 26-041】5/12 夜勤
充填ライン3号機、段取り替え後の立ち上げ中に停止。調査の結果、
供給ポンプ P-101 のメカニカルシールから微量の漏れを確認。
シール交換で復旧。停止時間 45 分。
(Line 3 stopped during startup; slight leak found at the mechanical
seal of feed pump P-101. Seal replaced. 45 min downtime.)

【報告書 26-055】6/3 日勤
3号機のポンプでまた圧力低下。前回と同じ箇所からの漏れ。
(Pressure drop again at the Line-3 pump. Leak at the same spot.)

【報告書 26-072】7/18 夜勤
コンベア C-3 の軸受から異音。摩耗の初期兆候あり。経過観察。
(Abnormal noise from conveyor C-3 bearing. Early signs of wear.)

Turning that prose into typed records is exactly what coding agents such as Claude Code or Codex are good at. Start by handing the agent the output of ingactl skill — an operating guide generated from the instance's own catalog, so it never drifts from the routes the server actually serves.

terminalbash
ingactl sync
ingactl skill   # prints the discover → contract → dry-run → execute guide

Three instructions matter when prompting the agent: close the vocabulary (only the types IngaDB accepts are valid candidates), require verbatim source quotes, and build the alias table first — in these reports, 「供給ポンプ P-101」 and 「3号機のポンプ」 are the same pump. The agent's proposal comes back as candidate JSON:

candidates.jsonjson
{
  "aliases": [
    {"component": "pump",
     "mentions": ["供給ポンプ P-101", "3号機のポンプ"]}
  ],
  "incidents": [
    {"id": "INC-26-041", "event_id": "E_SEAL",
     "component": "pump", "failure_mode": "seal_leak",
     "occurred_at": "2026-05-12", "confidence": "high",
     "source_span": "供給ポンプ P-101 のメカニカルシールから微量の漏れを確認"},
    {"id": "INC-26-055", "event_id": "E_SEAL",
     "component": "pump", "failure_mode": "seal_leak",
     "occurred_at": "2026-06-03", "confidence": "high",
     "source_span": "3号機のポンプでまた圧力低下。前回と同じ箇所からの漏れ"},
    {"id": "INC-26-072", "event_id": "E_BEARING",
     "component": "conveyor", "failure_mode": "wear",
     "occurred_at": "2026-07-18", "confidence": "medium",
     "source_span": "コンベア C-3 の軸受から異音。…摩耗の初期兆候あり"}
  ]
}

source_span is a verbatim quote. A reviewer only has to match candidates against the reports — and a judgment call like marking 26-072 medium (early signs, not a failure) is visible at a glance and easy to debate.

Only approved candidates are written — and the write is a catalog route too. Routes marked mutate ask for confirmation before executing, and --project injects the project id into the route's declared slot. Incidents attach to tree events — hand-written or compiled — by component and failure_mode.

terminalbash
cat > approved-incidents.json <<'EOF'
{"incidents": [
  {"component": "pump", "failure_mode": "seal_leak",
   "symptom": "seal leak, 45 min stop (report 26-041)"},
  {"component": "pump", "failure_mode": "seal_leak",
   "symptom": "pressure drop, same leak point (report 26-055)"},
  {"component": "conveyor", "failure_mode": "wear",
   "symptom": "bearing noise, early wear signs (report 26-072)"}
]}
EOF

ingactl api call data/incidents/append \
  --project 'packaging-line' --file approved-incidents.json \
  --dry-run   # preview the resolved request without sending

ingactl api call data/incidents/append \
  --project 'packaging-line' --file approved-incidents.json

Then let the agent verify its own work — the retrieval routes are read-only, so it can call them freely:

terminalbash
ingactl api call data/event-evidence \
  --project 'packaging-line' --param node_id=E_SEAL -o json
ingactl api call data/analysis --project 'packaging-line' -o json
This placement runs in production

Our own failure-knowledge platform, Causation, structures trouble reports and maintenance records with AI and quantifies countermeasure effects with a calculation engine — running on the same causal engine as IngaDB, with exactly this scenario's division of labor: AI extracts, people approve, a deterministic engine computes.

Keep the division of labor explicit

Extraction is probabilistic, so the agent's output is a proposal. A person approves; IngaDB validates and computes deterministically. Give the agent wide read access and restrict writes to approved records — then every probability remains traceable back to its source sentence.

4. The operations lead — no stale numbers in the meeting

You have: a weekly risk review.
You get: freshness, plus the exact reason anything went stale.

terminalbash
ingactl api call data/analysis --project 'packaging-line' -o json
# → the computed view, with staleness and exact changes_since deltas

curl -s "localhost:9876/db/v1/graphs/$GID/deltas?from=0" \
  -H "X-Org-Id: $ORG" | jq '.deltas[] | {revision, kind}'

"Three new evidence records since last week, topology unchanged, here is the recomputed probability" — the opening line of the weekly review becomes one sentence.

5. The decision maker — compare countermeasures without writing

You have: a proposal to invest in upgraded seals.
You get: top-event probability before and after — with the stored data untouched.

terminalbash
# Evaluate the model under the projected post-upgrade value (never persisted)
ingactl api call pipeline/what-if \
  --project 'packaging-line' \
  --set 'overrides=[{"target_id":"E_SEAL","value":0.005}]' -o json

What-if results are never persisted, and each names the revision it was evaluated against. What goes into the proposal document is those two numbers and their base revision.

6. The AI agent — answers with a basis, or no answer

You have: the question "what is the biggest driver of line stops?"
You get: a deterministically computed, revision-stamped answer.

terminalbash
# 1. Find the subject
ingactl api call data/tree/search \
  --project 'packaging-line' --param query=seal -o json

# 2. Walk the causal path to the top event
ingactl api call data/causal-path \
  --project 'packaging-line' --param node_id=E_SEAL -o json

# 3. Answer "biggest driver" with importance measures
ingactl api call data/importance \
  --project 'packaging-line' --param node_id=E_SEAL -o json

Every answer carries the revision it was computed from, so the agent can reply in a verifiable form: "as of revision 42, seal leak has the highest Fussell-Vesely importance."

Where to go next