# Thought (JOE) — the simplest, testable “world model” primitive

A **Thought** is an auditable reasoning artifact that can be created by a **human** or by an **agent/LLM**.

It exists to make reasoning **inspectable**, **editable**, and **reusable** inside JOE — not as hidden prompt text.

---

## The 3 Thought Types (keep it small)

We use only three types to avoid field creep and ontology soup.

### 1) Hypothesis
A claim that should be **vetted**.

- Purpose: capture a learning/insight that may influence decisions.
- **Requires:** `because[]` (at least one receipt)
- Usually: short statement, has a certainty score.
- Lifecycle: typically starts `proposed`, becomes `accepted` after review.

Example:
> “Client likely has insomnia driven by anxiety.”

### 2) Synthesis
A longer summary that **compresses** multiple objects into one coherent statement.

- Purpose: summarize/synthesize a set of objects (intake, results, notes, conditions, etc.).
- **Requires:** `about[]` (what is being summarized)
- `because[]` is optional (nice-to-have but not required).
- Lifecycle: can be draft/accepted depending on workflow.

Example:
> “Across intake + last 2 sessions, the pattern is late-night rumination, inconsistent schedule, and poor sleep onset.”

### 3) Link
A binary relationship claim: **A relates to B** in a specific way.

- Purpose: encode an explicit relationship between two things.
- **Requires:** endpoints A and B, a `relationship_type`, and `because[]`.
- Also typically includes a short `rationale`.

Example:
> “Recommendation magnesium is included in the protocol because insomnia + sleep latency + guideline resource.”

---

## Two concepts that prevent confusion

### About vs Because
These answer different questions:

- `about[]` = **What this thought concerns**
  - Used for synthesis (“I’m summarizing these objects”)
  - Can also attach a thought to a single object or to an itemtype/schema.

- `because[]` = **Why we believe the thought**
  - The receipts/evidence trail for hypotheses and links.
  - Each entry can include a `role` (why this supporting item matters) and a note.

### Binary link + multi-cause proof
We keep Link thoughts **binary** (A ↔ B) for clarity and reviewability.

Multi-cause reasoning (condition + client fact + resource + result) belongs in `because[]`.

This makes links:
- easy to query,
- easy to audit,
- easy to approve/reject individually.

---

## Minimal field shape (conceptual)

All Thoughts share:
- `thought_type` (hypothesis | synthesis | link)
- `statement` (human-readable)
- `certainty` (0–1)
- `author` / `created_by` (human or agent id/name)
- `status` (draft | proposed | accepted | rejected | superseded)
- `about[]` (object or itemtype/schema the thought is about)
- `lineage` (ai_response_id, timestamps, reviewer fields)

Link thoughts additionally use:
- `a: { itemtype, id }`
- `b: { itemtype, id }`
- `relationship_type` (enumerated verb)
- `rationale` (one sentence)
- `because[]` (receipts)

---

## Why this works as “world model” scaffolding

- Thoughts are stored as objects → **persistent**, **inspectable**, **permissionable**.
- Pipeline steps can include Thoughts as context blocks → the agent gets a **structured mental state**.
- AI can propose new Thoughts → they land as `proposed` and require review → no silent “AI truth creep”.
- Accepted Thoughts improve future runs measurably (you can test that).

---

## MVP testing approach

1) **Manual Thoughts**  
Create a few hypotheses, syntheses, and links. Verify they’re easy to read/edit/filter.

2) **Pipeline compile**  
Make a pipeline that selects:
- overarching Thoughts (vision/constraints) by tags,
- protocol-scoped Thoughts by `scope_id`,
- tool-thoughts (rules/examples/functions) as context blocks.

Compile should be deterministic.

3) **Agent config + run**  
Agent config references pipeline + ai_prompt template. Run produces an `ai_response`.

4) **Thought generation**  
LLM outputs `proposed_thoughts[]` (JSON contract). Save as `proposed` and review into `accepted`.

---

## Practical protocol example (clean and auditable)

Thought (Link):
- A = recommendation “Magnesium glycinate”
- B = protocol “Sleep protocol”
- relationship_type = included_in
- rationale = “Included to support sleep onset.”
- because[] = condition insomnia + result sleep latency + resource guideline

This single link can be accepted/rejected, and the receipts explain why.

---

If you want to extend later:
- Add app-scoped relationship types via a small config schema/dataset.
- Add an `ai_rule` schema only if you truly need conditional logic beyond binary links.
