M003 — A session is a durable envelope, and knowledge is compiled from what is already canonical
A worker with no conversation history can answer what happened, why, what was decided, which evidence supports it, where the canonical source lives, and what to do next — from records and a derived index, with git still the authority over both.
ACTIVE 8 of 16 issues done · this is the active milestone
- ready
- 2
- blocked
- 6
- active
- 0
- verify
- 0
- done
- 8
- cancelled
- 0
Problem
Continuity today is task-shaped. A task record says what one piece of work is, and checkpoints, handovers, decisions and questions hang off it. Nothing represents the execution episode itself — the worker sat down, touched three tasks, recorded two decisions, closed one issue, and stopped — so the causal question a later worker actually asks is unanswerable from the records: which work happened together, in what order, against which commits, and what did it decide. The second gap is retrieval. `search` is a literal scan over six operational record kinds, which is right for those files and blind to everything else: the claims matrix, the milestone and issue contracts, the policy, the profiles, the prompts and the documents already carry explicit, machine-readable relationships — claim to implementation to test, issue to milestone to dependency, evidence to issue — and no command can traverse one of them. A worker therefore reconstructs both from a conversation, which is the thing that does not survive.
Outcome
A worker with no conversation history can answer what happened, why, what was decided, which evidence supports it, where the canonical source lives, and what to do next — from records and a derived index, with git still the authority over both.
Current state
There is no session concept: `.majordomus/state/` holds task, checkpoint, handover, decision, question and ledger, and the ledger is the only thing that knows two records were written by the same episode, which it knows only by adjacency in time. There is no index of any kind; docs/CONTINUITY.md states that as a deliberate choice for the record corpus and says nothing about the rest of the repository. docs/DESIGN.md's Clean Extraction Boundary excludes graph semantics absolutely, which forbids even a provenance graph derived from this repository's own files.
Desired state
A session lifecycle exists with one active session per worktree and immutable closed records that reference authoritative records rather than copying them, and whose whole reference envelope is derived from the ledger instead of accumulated by hand. A knowledge compiler discovers curated sources through git, extracts nodes with identities that survive a rebuild, records edges only where an explicit relationship was observed, keeps a content-hash manifest that makes a no-op sync cheap, and answers read-only queries without mutating anything. `context` can select a bounded slice of it. Both are declared doctrines with validators that doctor and watch dispatch, and the boundary between shared and operational knowledge is a tested property rather than a convention.
Scope
- lib
- bin/majordomus
- share/standard/majordomus/
- share/allow
- share/skeleton
- docs
- test/cases
- .majordomus/policy.yaml
- .majordomus/project
Out of scope
- Any database, embedding, vector store, or similarity ranking
- Any model invocation, network call, or generated summary
- A second mutable narrative store that copies decisions, questions or checkpoint bodies
- Publishing operational records to the website
- Renderer-specific knowledge output for any particular note-taking application
- Inferring a relationship from prose that does not state it explicitly
Acceptance criteria
- A session opens, closes, and its closed record is immutable, temporally ordered, and interpretable against current git through the existing divergence vocabulary
- A closed session names the tasks, issues, checkpoints, handovers, decisions and questions of its episode by reference, and copies none of their bodies
- Knowledge discovery is driven by git rather than by a filesystem walk, and an untracked file is not a source
- A node identity survives a rebuild, and editing one source changes only the nodes derived from it
- Every edge carries the file it was observed in; an edge without provenance is a validation failure
- A second sync with no source change reports no work and is measurably cheaper than a cold one
- Every read-only knowledge and session command leaves `git status` byte-identical
- Shared and operational knowledge are separable, and a test proves the shared projection contains no operational record
- `context` can carry a bounded knowledge section that is dropped before any immutable fact and is named under EXCLUDED when it is
- Each new guarantee is a declared doctrine with a validator that doctor and watch dispatch, a claim, and a behavioural case
- docs/CONTINUITY.md and docs/DESIGN.md state the new architecture precisely instead of contradicting it
Validation
- bash test/run.sh
- bin/majordomus doctor
- bin/majordomus watch
- bin/majordomus plan validate
- shellcheck -x -s bash bin/majordomus lib/*.sh
Evidence required
- session_lifecycle
- session_immutability
- knowledge_determinism
- knowledge_idempotence
- provenance_required
- readonly_proven
- privacy_boundary
- context_bounded
- doctrines_wired
- dogfood_loop
Risks
- A knowledge index is a second thing that can be believed. Every mitigation is the same one: the index is a pointer, it carries the source path and hash of what it points at, and it is reported stale rather than silently rebuilt by a query.
- A curated source list is a place where something can be forgotten. The alternative — indexing everything git tracks — imports generated files, vendored trees and site output, and was rejected; the cost is that adding a canonical file kind is an explicit edit, and the validator names a declared source class whose discovery returns nothing.
- Deriving a session's references from the ledger makes the ledger load-bearing for a second thing. It is already append-only, machine-written and validated by majordomus.ledger-integrity, and the alternative — accumulating references into a mutable session file on every command — puts a write on the hot path of every other command and creates the second store this milestone exists to avoid.
- The Clean Extraction Boundary currently forbids graph semantics without qualification. Narrowing it is a deliberate change to a published boundary, and it must be narrowed precisely — a generic provenance graph over this repository's own artifacts — or it stops being a boundary.
Issues
Each one is an execution contract with its own acceptance criteria, validation command and required evidence. The wave column is the layer of the dependency graph it sits in.
| issue | status | wave | depends on | title |
|---|---|---|---|---|
| I0801 | DONE | 0 | — | Narrow the Clean Extraction Boundary and record what was adopted |
| I0802 | DONE | 0 | — | Specify the session record before writing one |
| I0803 | DONE | 1 | I0802 | Open a session and report its status |
| I0804 | DONE | 2 | I0803 | Close a session into an envelope derived from the ledger |
| I0805 | DONE | 3 | I0804 | Read sessions back with a divergence label |
| I0806 | READY | 4 | I0805 | Make the session rules doctrines, with retention and archiving |
| I0807 | DONE | 1 | I0801 | Discover knowledge sources from git, not from the filesystem |
| I0808 | DONE | 2 | I0807 | Extract nodes with identities that survive a rebuild |
| I0809 | DONE | 3 | I0808 | Record only edges that a file states, each with where it was observed |
| I0810 | READY | 4 | I0809 | A content-hash manifest that makes a second sync cheap |
| I0811 | BLOCKED | 5 | I0810 | Read-only knowledge lookup with an ordering that can be explained |
| I0812 | BLOCKED | 6 | I0811 | Validate the graph, and let doctor and watch ask the same validator |
| I0813 | BLOCKED | 7 | I0806, I0812 | A closed session becomes a node that points at its episode |
| I0814 | BLOCKED | 6 | I0811 | Give the worker a bounded slice of knowledge, not the knowledge base |
| I0815 | BLOCKED | 8 | I0813, I0814 | Say what is now true in the claims, the documentation and the worker instructions |
| I0816 | BLOCKED | 9 | I0815 | Prove the loop on a real issue, without a transcript |
The graph
flowchart LR
I0801["I0801<br/>Narrow the Clean Extraction Boundary and record what was adopted"]:::done
I0802["I0802<br/>Specify the session record before writing one"]:::done
I0803["I0803<br/>Open a session and report its status"]:::done
I0804["I0804<br/>Close a session into an envelope derived from the ledger"]:::done
I0805["I0805<br/>Read sessions back with a divergence label"]:::done
I0806["I0806<br/>Make the session rules doctrines, with retention and archiving"]:::ready
I0807["I0807<br/>Discover knowledge sources from git, not from the filesystem"]:::done
I0808["I0808<br/>Extract nodes with identities that survive a rebuild"]:::done
I0809["I0809<br/>Record only edges that a file states, each with where it was observed"]:::done
I0810["I0810<br/>A content-hash manifest that makes a second sync cheap"]:::ready
I0811["I0811<br/>Read-only knowledge lookup with an ordering that can be explained"]:::blocked
I0812["I0812<br/>Validate the graph, and let doctor and watch ask the same validator"]:::blocked
I0813["I0813<br/>A closed session becomes a node that points at its episode"]:::blocked
I0814["I0814<br/>Give the worker a bounded slice of knowledge, not the knowledge base"]:::blocked
I0815["I0815<br/>Say what is now true in the claims, the documentation and the worker instructions"]:::blocked
I0816["I0816<br/>Prove the loop on a real issue, without a transcript"]:::blocked
I0801 --> I0807
I0802 --> I0803
I0803 --> I0804
I0804 --> I0805
I0805 --> I0806
I0806 --> I0813
I0807 --> I0808
I0808 --> I0809
I0809 --> I0810
I0810 --> I0811
I0811 --> I0812
I0811 --> I0814
I0812 --> I0813
I0813 --> I0815
I0814 --> I0815
I0815 --> I0816
classDef done stroke:#16a34a,fill:#052e16,stroke-width:2px
classDef active stroke:#2563eb,fill:#eff6ff,stroke-width:2px
classDef verify stroke:#7c3aed,fill:#f5f3ff,stroke-width:2px
classDef ready stroke:#0891b2,fill:#ecfeff,stroke-width:2px
classDef blocked stroke:#b45309,fill:#fffbeb,stroke-width:2px
classDef cancelled stroke:#6b7280,fill:#f9fafb,stroke-width:2pxCanonical record: .ai/repo/project/milestones/M003.yaml. Read it back with majordomus plan show M003.