Skip to documentation

Use cases by industry

Use case: plant operations

A plant runs on answers that have to be right. A supervisor chasing a shipping miss needs the real bottleneck, the current OEE by line, and the certified quality plan — not a stale runbook, and not a confident guess about when a spindle will fail. This guide builds that plant-operations assistant end to end for Ironwood Manufacturing, a precision drivetrain maker, touching the module slices: Intake to ingest the plant floor's knowledge, Atlas to map lines to their assets and products, Warrant to certify the quality program, Conduit to wire in the live MES, Lens to answer with citations, Lineage to trace any answer back to its source, and Crucible to keep it accurate as the plant changes.

One plant knowledge base, seven slices. The dashed edge is the loop that keeps it honest: a regression the golden set catches steers the next round of curation.

Follow along in the seeded workspace

Run yarn demo:seed manufacturing and this workspace appears as Ironwood Manufacturing (Discrete Mfg), pre-loaded with the plant docs, the ontology, the ironwood-mes connector, the golden set, and the plant-ops-analyst agent used throughout this guide — so every id, query slug, and question below is real and clickable. See Demo workspaces for the full catalog.

Prerequisites

  • A workspace key with kb:write, kb:read, agents:run, and runs:read, exported as $ELI_KEY. See Getting started.
  • Owner/admin on the workspace, to create the MES connector and certify the quality program.
  • The plant MES reachable read-only (the seed points ironwood-mes at a local Postgres on localhost:54329).
  • An enabled chat model, so /query can generate — otherwise 409 no-model-configured.

1 · Intake — ingest the plant floor's knowledge

The plant already knows things — they just live in scattered line runbooks, asset sheets, supplier files, and quality findings. Post them as markdown so they become searchable, citable documents. The seed loads a dozen richly cross-referenced docs; here is the plant overview going in by hand. Its storage commit precedes the graph pipeline:

POST/api/v1/documentsBearer · kb:write

Save markdown through the vault. The file, chunks, and full-text index commit before 201; embedding and graph enrichment continue as detached work, so the response contains stored-document metadata only.

Example requestbash
curl -s -X POST https://your-host/api/v1/documents \
  -H "Authorization: Bearer $ELI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "path": "plant-overview.md",
    "title": "Plant Overview",
    "content": "# Ironwood Manufacturing\n\n[[Ironwood Manufacturing]] runs three areas — [[Assembly Line 1]], [[Machining Cell B]], and [[Weld Cell C]] — building the [[Ranger Gearbox]], [[Summit Hub Assembly]], and [[Atlas Bearing Housing]]. Live [[OEE]] and downtime flow through the [[Manufacturing Execution System]]."
  }'
Responsejson
{ "docId": "01KYPLANTOVERVIEW00000000", "path": "plant-overview.md", "contentHash": "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824", "title": "Plant Overview" }

The create payload reports no entity or processing status. Detached extraction later reads the text and Atlas builds the concept graph automatically — Assembly Line 1, Fanuc M-710 Robot, Ranger Gearbox, Northgate Steel, and the rest wire themselves together. The seed posts the full set (line, asset, product, supplier, quality, and system docs) for you; the rest of this guide is identical whether you post them by hand or run yarn demo:seed manufacturing.

2 · Atlas — map lines to their assets and products

Extraction doesn't just find text — it types it. The Ironwood ontology has six entity types — ProductionLine, Asset, Product, Supplier, QualityProcess, and System — joined by relations like runs_on, located_on, supplies, and controlled_by. That is what makes retrieval structured rather than a bag of words. Pull a key entity — the line bottleneck, the Fanuc M-710 Robot — and read its place in the graph:

GET/api/v1/entities/{id}Bearer · kb:read

Read one entity with its ontology type, current authority, its typed relations, and the documents it is mentioned in — the graph neighborhood retrieval will expand into.

Example requestbash
curl -s https://your-host/api/v1/entities/01KZFANUCM710ASSET000000A \
  -H "Authorization: Bearer $ELI_KEY"
Responsejson
{
  "id": "01KZFANUCM710ASSET000000A",
  "name": "Fanuc M-710 Robot",
  "type": "Asset",
  "authority": "machine_extracted",
  "relations": [
    { "type": "located_on", "target": "Assembly Line 1", "targetType": "ProductionLine" },
    { "type": "controlled_by", "target": "Failure Mode and Effects Analysis", "targetType": "QualityProcess" }
  ],
  "mentionedIn": ["assets/fanuc-m710-robot.md", "lines/assembly-line-1.md", "quality/fmea-ranger-gearbox.md"]
}

The robot is located_on Assembly Line 1 and controlled_by the Failure Mode and Effects Analysis — where its gripper wear is a high-RPN failure mode. That neighborhood is exactly what a question about the Ranger Gearbox bottleneck needs to see. Note the authority is still machine_extracted— a starting point, not yet a source of truth. That is Warrant's job next.

3 · Warrant — certify the quality program

Some concepts an assistant should state plainly; the plant's Statistical Process Control program, owned by Aisha Kane, is one of them. In Warrant you pin its canonical definition as a reviewable change, then certify it — certified is the only tier the answer policy states without hedging:

POST/api/v1/change-requestsBearer · kb:write

Propose the canonical definition as a reviewable change rather than editing silently. Approval promotes authority to at least curated and records the reviewer on the revision.

Example requestbash
curl -s -X POST https://your-host/api/v1/change-requests \
  -H "Authorization: Bearer $ELI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "kind": "update",
    "entityId": "01KZSPCONCEPT0000000000AA",
    "payload": { "description": "Statistical Process Control: control charts on critical characteristics — bore diameter on the Haas VF-4 CNC (Machining Cell B) and assembly torque at the Fanuc M-710 Robot (Assembly Line 1). An out-of-control point stops the line until assignable cause is found." },
    "note": "Pinning the plant SPC definition owned by Aisha Kane"
  }'
Responsejson
{ "id": "01KZCR00000000000000000AA", "entityId": "01KZSPCONCEPT0000000000AA", "kind": "update", "status": "open" }
POST/api/v1/entities/{id}/certifyBearer · kb:write

Owner/admin sign-off — authority certified. Also starts the review clock: nextReviewAt lands at now + the workspace's reviewIntervalDays, so a certified quality program can't quietly go stale.

Example requestbash
curl -s -X POST https://your-host/api/v1/entities/01KZSPCONCEPT0000000000AA/certify \
  -H "Authorization: Bearer $ELI_KEY" \
  -H "Content-Type: application/json" \
  -d '{"note": "Signed off by Aisha Kane (Quality)"}'
Responsejson
{ "authority": "certified", "lifecycleStatus": "published", "version": 3, "nextReviewAt": "2027-01-18T09:10:00.000Z" }

Do the same for the source document behind the low-OEE story — verify the Machining Cell B analysis so its provenance carries a governance tier that Lineage will report:

POST/api/v1/documents/{id}/verifyBearer · kb:write

Glean-style document verification. Stamps the verification tier, the verifier, and the next re-verify date — the governance block Lineage reports and the manifest counts.

Example requestbash
curl -s -X POST https://your-host/api/v1/documents/01KYCELLB000000000000000AA/verify \
  -H "Authorization: Bearer $ELI_KEY" \
  -H "Content-Type: application/json" \
  -d '{"verification":"certified","note":"Machining Cell B low-OEE analysis reviewed with Lena Fischer"}'
Responsejson
{ "id": "01KYCELLB000000000000000AA", "verification": "certified", "verifiedAt": "2026-07-21T09:12:00.000Z", "nextVerifyAt": "2026-12-28T00:00:00.000Z" }

Certification is what earns a confident answer. With the quality docs backed, a question like "What are the top defects on the Ranger Gearbox?" clears the answer policy with verdict answer at confidence 0.72 (reason confidence_above_answer_floor) instead of hedging.

Curate in the UI too

Everything here is also a click: the Curation page shows the open change-request queue, the review-due list, and a certify button per concept. The API and the UI write the same append-only revisions — pick whichever fits the reviewer.

4 · Conduit — wire in the live MES

Documents explain the plant; the Manufacturing Execution System knows what it is doing right now. Wire the MES in as a read-only data connector so live OEE, downtime, and defects become citable, parameterized queries — capped at 200 rows and never granted write access:

POST/api/v1/connectorsBearer · kb:write

Create the read-only Postgres connector for the plant MES. The credential is stored encrypted and masked on every read; the source does nothing until a named query is run against it.

Example requestbash
curl -s -X POST https://your-host/api/v1/connectors \
  -H "Authorization: Bearer $ELI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "postgres",
    "name": "ironwood-mes",
    "config": { "host": "localhost", "port": 54329, "database": "ironwood_mes", "user": "app", "sslMode": "disable" },
    "credential": "app"
  }'
Responsejson
{ "id": "01KZMESCONN00000000000000", "type": "postgres", "name": "ironwood-mes", "status": "active", "hasCredential": true }
POST/api/v1/connectors/{id}/queries/{slug}/runBearer · kb:read

Run a named, pre-registered query by slug. The SQL is fixed by the workspace; only declared parameters are bindable — so retrieval can call oee-by-line safely, and can never issue arbitrary SQL.

Example requestbash
curl -s -X POST https://your-host/api/v1/connectors/01KZMESCONN00000000000000/queries/oee-by-line/run \
  -H "Authorization: Bearer $ELI_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
Responsejson
{
  "querySlug": "oee-by-line",
  "columns": ["line", "oee_pct", "availability_pct", "performance_pct"],
  "rows": [
    { "line": "Machining Cell B", "oee_pct": 61.4, "availability_pct": 72.5, "performance_pct": 84.8 },
    { "line": "Assembly Line 1", "oee_pct": 78.2, "availability_pct": 88.1, "performance_pct": 88.7 },
    { "line": "Weld Cell C", "oee_pct": 83.1, "availability_pct": 90.4, "performance_pct": 91.9 }
  ],
  "rowCount": 3,
  "truncated": false
}

The seed registers three queries — oee-by-line, downtime-by-line, and top-defects — and binds each to a concept: oee-by-line to the Manufacturing Execution System(labeled "Live OEE by production line"), downtime-by-line to Assembly Line 1, and top-defects to Statistical Process Control. Now the graph has both prose and a live pulse.

The model fills the parameter

The downtime-by-line binding maps its line parameter from source: model— so when a rep asks "downtime for Assembly Line 1", Lens extracts Assembly Line 1 from the question and passes it as $1 to the fixed SQL. Parameterized, not interpolated: the model chooses the value, never the query.

5 · Lens — the supervisor asks, and gets a cited answer

Now the payoff. A supervisor asks in plain language; Lens retrieves the docs, runs the bound live query, grounds the generation, and returns an answer with inline [Sn] citations, an atomic claims breakdown, and a policy decision that says how much to trust it:

POST/api/v1/queryBearer · agents:run

Run the grounded query pipeline: retrieval + entity detection + the bound live MES query + one generation + a groundedness check + the answer-policy engine. Returns a cited answer with a policy decision. The workspace comes from the key.

Example requestbash
curl -s -X POST https://your-host/api/v1/query \
  -H "Authorization: Bearer $ELI_KEY" \
  -H "Content-Type: application/json" \
  -d '{"question":"Which production line has the lowest OEE?"}'
Responsejson
{
  "answer": "Machining Cell B has the lowest OEE at 61.4% [S1] — well under the 85% plant target — driven by tool-change downtime on the Haas VF-4 CNC [S2].",
  "claims": [
    { "text": "Machining Cell B has the lowest OEE at 61.4%", "citations": ["S1"] },
    { "text": "The gap is driven by Haas VF-4 CNC tool-change downtime", "citations": ["S2"] }
  ],
  "sources": [
    { "id": "S1", "connector": "ironwood-mes", "querySlug": "oee-by-line", "label": "Live OEE by production line" },
    { "id": "S2", "docId": "01KYCELLB000000000000000AA", "docTitle": "Production Line — Machining Cell B", "docPath": "lines/machining-cell-b.md", "chunkId": "01KYCELLB000000000000000BB" }
  ],
  "entities": [ { "id": "01KZMACHCELLB0ENTITY00000", "name": "Machining Cell B", "type": "ProductionLine", "authority": "curated" } ],
  "policy": { "decision": "answer", "confidence": 0.79, "reason": "confidence_above_answer_floor" },
  "groundedness": { "verified": 2, "total": 2 },
  "model": { "chat": "claude-sonnet-4-5", "judge": "claude-haiku-4-5" }
}

The policy block is the trust signal: answer at 0.79because a live number and a certified document agree, with no conflict. Ask something the plant can't back and the policy holds the line — the pre-generation check on "When exactly will the Haas VF-4 spindle fail?" returns abstain_with_pointers at 0.13 (reason no_relevant_chunks) rather than inventing a date, exactly as the agent's system prompt demands: do not predict specific equipment-failure dates without evidence. The same pipeline is a native MCP tool, so it drops straight into a plant engineer's Claude or CMMS assistant.

6 · Lineage — trace the answer back to its source

Rosa Delgado, the plant manager, reviewing the assistant asks the fair question: where is this coming from, and can I trust it? The answer cited S2 → docId 01KYCELLB…. Pull that document's lineage and read the whole trail in one call — origin, governance, and the downstream answers it is grounding right now:

GET/api/v1/documents/{id}/lineageBearer · kb:read or runs:read

The unified per-document lineage trail: origin provenance, governance, the audit trail, derived knowledge, and downstream impact. This is how you prove an answer's pedigree end to end.

Example requestbash
curl -s https://your-host/api/v1/documents/01KYCELLB000000000000000AA/lineage \
  -H "Authorization: Bearer $ELI_KEY" | jq '{origin: .origin, verification: .governance.verification, citedBy: .downstream.citedByAnswers}'
Responsejson
{
  "origin": {
    "kind": "upload",
    "sourcePath": "lines/machining-cell-b.md",
    "ingestedAt": "2026-07-21T09:22:41.008Z"
  },
  "verification": "certified",
  "citedBy": 9
}

There it is, closed loop: the answer traces to the seeded plant doc lines/machining-cell-b.md, that document is certified (from the Warrant step), and it is currently grounding 9answers — so an edit to it has a known blast radius. Rosa didn't have to trust the model; she read the pedigree. The full trail also lists the derived concepts (Machining Cell B, Haas VF-4 CNC, Statistical Process Control) and the dependent cache entries that would invalidate if the analysis changed.

Same trail, in the document view

The workspace UI renders this exact DocumentLineage as a visual trail on the document page (via the BFF at GET /api/w/{workspaceId}/documents/{docId}/lineage), and an agent can pull it mid-run with the kb_document_lineage MCP tool. One shape, three surfaces.

7 · Crucible & Ports — lock the accuracy in and ship the agent

The plant changes every shift, and a wrong answer to a supervisor is expensive. Capture the questions people actually ask as a golden set so Crucible can prove the assistant still answers them correctly after every content change. The seed anchors items like "Which production line assembles the Ranger Gearbox?", "Who owns the SPC and FMEA quality programs?", and "Why is the Fanuc M-710 Robot the bottleneck on Assembly Line 1?" Seed a provenance qrel from the chunk that should ground the low-OEE answer:

POST/api/v1/qrelsBearer · kb:write

Author a graded relevance judgment for a golden item. source=provenance derives the highest-grade judgment from the item's anchored citation — deterministic, no judge model needed.

Example requestbash
curl -s -X POST https://your-host/api/v1/qrels \
  -H "Authorization: Bearer $ELI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "queryId": "01KZGOLDENOEE000000000000",
    "chunkId": "01KYCELLB000000000000000BB",
    "docId": "01KYCELLB000000000000000AA",
    "grade": 3,
    "source": "provenance"
  }'
Responsejson
{ "id": "01KZQREL0000000000000000A", "queryId": "01KZGOLDENOEE000000000000", "grade": 3, "source": "provenance" }

Run the Plant Ops Q&A baseline config from the evals workspace, then read the metrics for the run. Retrieval and abstention numbers are deterministic; RAGAS numbers carry the judge model that produced them:

GET/api/v1/evals/runs/{id}/metricsBearer · kb:read or runs:read

Retrieval, RAGAS, and abstention metrics for one run — overall and by facet. The ruler for 'did the assistant get worse?'

Example requestbash
curl -s https://your-host/api/v1/evals/runs/01KZRUNMFG0000000000000AA/metrics \
  -H "Authorization: Bearer $ELI_KEY"
Responsejson
{
  "runId": "01KZRUNMFG0000000000000AA",
  "n": 36,
  "retrieval": { "recallAtK": 0.77, "ndcgAt10": 0.73, "mrr": 0.81, "hitAtK": 0.94 },
  "ragas": { "faithfulness": 0.92, "responseRelevancy": 0.85, "contextPrecision": 0.68 },
  "abstention": { "truthfulness": 0.66, "abstainRate": 0.14, "aurc": 0.071 }
}

With the set green, ship it: the Plant Operations Analyst agent (slug plant-ops-analyst, dataEnabled) runs this exact pipeline — cited, and abstaining without verified backing — as a Ports deliverable. The seeded run is on record, and the plant's ambient monitors keep the loop live: an oee.below_target alert when Machining Cell B drops under 65%, and a critical spc.out_of_controlalert on the Atlas Bearing Housing bore. When a metric drops after a content change, the golden set names exactly which question regressed — that is the dashed loop in the diagram: Crucible's regressions steer the next round of Warrant curation. Compare two configs with a two-gate significance test in Measure & compare.

The leverage

Seven slices, one plant knowledge base, one audit trail. The supervisor gets a fast, cited answer that fuses a certified document with a live MES number; the plant manager can trace any answer to a certified source and see its blast radius; the policy abstains on a spindle-failure guess instead of bluffing; and the whole thing is measured, so accuracy is a number you watch rather than a hope. Swap drivetrains for any discrete line — the platform doesn't care what the plant builds, only that every answer is grounded, governed, traceable, and measured.

Keep going

Automate the deliverable side of this with Automated reports, end to end, or see the whole platform at a glance in the Capability map.