# Situational Knowledge

The knowledge system lets people and agents record **situational knowledge** — the
facts, caveats, and tips that normally live only in an operator's head ("WC-7's red
roller needs a morning kiss before a long run") — and have it resurface later for
whoever is in the same situation. It's a retrieval-augmented layer over a graph of the
tenant's real entities.

## The pieces

- **Concept** — a reusable idea the schema has no row for: a failure mode, a material, a
  technique ("Roller Jamming", "UV coating"). Concepts form a small ontology.
- **Knowledge note** — a unit of content (the knowledge itself) attached to **exactly one**
  target: a **concept** or a specific **entity** (a work center, customer, job…).
- **Edges** — `instance_of` binds an entity to a concept; concept↔concept edges relate
  concepts (`related`/`causes`/`contradicts`). Because a note on a concept is reachable
  from every entity bound to that concept, knowledge written once transfers to every
  machine (etc.) that shares the trait.

## Two independent axes on every note

- **scope** — *visibility once live*: `PERSONAL` (author only) or `TENANT` (everyone).
- **status** — *review lifecycle*: `PENDING` (proposed; hidden from retrieval until a human
  confirms) or `LIVE` (active). These are orthogonal: a note is proposed *to become visible
  at its stated scope*. Confirming a note (see below) promotes `PENDING → LIVE`.

## Capturing knowledge — the `capture_knowledge` tool

When you learn something worth keeping, call **`capture_knowledge`**. You capture a small
*subgraph* in one atomic call: optional new concepts (each with a payload-local `alias`),
the note, and any `instance_of` / concept edges. Guidance:

- **You are an agent, so propose — don't assert.** Set `status: PENDING` and
  `provenance: CHAT_DISTILLED` so a human confirms before the note surfaces.
- Set `scope: TENANT` for knowledge meant for everyone, `PERSONAL` for one user.
- Entities referenced by `instanceEdges` **must already exist** (a real work center id).
  The note's own entity target need not.
- On a problem you get field-scoped `errors` (e.g. `instanceEdges[0].entityId`) — fix and retry.

Example: an operator tells you presses jam in humidity.

```json
{
  "concepts": [{ "alias": "jam", "label": "Roller Jamming", "conceptKind": "failure-mode" }],
  "note": {
    "kind": "CONCEPT", "concept": { "alias": "jam" },
    "body": "Ink units jam when humidity is high — warm the shop before a long run.",
    "scope": "TENANT", "status": "PENDING", "provenance": "CHAT_DISTILLED"
  },
  "instanceEdges": [
    { "entityType": "workcenter", "entityId": "<press-A-uuid>", "concept": { "alias": "jam" } },
    { "entityType": "workcenter", "entityId": "<press-B-uuid>", "concept": { "alias": "jam" } }
  ]
}
```

## Confirming and retrieving

- A human (or a trusted flow) confirms a proposed note with the `confirmKnowledgeNote`
  mutation, which promotes it `PENDING → LIVE` and raises its trust weight.
- Retrieval is the `retrieveKnowledge` GraphQL query: give it the entities in context
  (`seeds`) and an optional `query`; it returns the most relevant LIVE notes in two buckets —
  `graph` (reached through the knowledge graph from the seeds) and `supporting` (semantically
  related). Use `execute_graphql_query` to call it.

See the GraphQL schema descriptions on `captureKnowledge`, `retrieveKnowledge`,
`KnowledgeNote`, `Concept`, `KnowledgeScope`, and `KnowledgeStatus` for field-level detail.