`query.rs` is the read side, over a `&Mind<S>` with no store file, no daemon and no index. A `PipelineDocumentView` is four fields: the id, because a `PipelineDocument` does not carry its key and a client must never derive one; the document; the facts of its admission; and its status. The facts come from the commit receipts and from their `writes` alone, so a document a later batch cited as a strong read keeps the receipt that wrote it, and `admitted_at` is that receipt's `committed_at` -- the `now` admission was passed -- never the store's `stored_at`. A pipeline document the image holds and no receipt wrote is an integrity fault and refuses; the store has one writer and the receipt is its proof. Status is derived per call through `docs::Docs`, the same owner the admission rules ask, so a withdrawn resolution reopens its subject for a reader exactly when it reopens it for a rule. `closing_resolution` is `in_force_unless`'s own body asked for the resolution rather than the bool, so there is no second derivation to drift. Four reads: `view` by id, `query` over the filters (root, repo, cut, kinds, in force, faculty, an admission window), `open_items` for one campaign's unanswered questions, standing findings, follow-ups, unreported specs and unjudged reports, and `history` for every resolution a subject ever had or every assignment of a repo to this mind, withdrawn ones included with their reasons. A query is ordered by `(admitted_at, id)`, capped at 200, and carries `matched`, the count before the cap, so a truncation is never a short page that reads like the whole answer. `semantic` is accepted by the type and refused typed until Cut 11 owns the index; no substring filter lives here to become a second answer to "the text of a document". `cargo test -p huginn-mind --lib`: 56 passed, 0 failed, 0 warnings (46 + the ten tests). `cargo check --workspace` clean. No dependency, no target, no kind, no schema, no epoch; `Cargo.toml` and `Cargo.lock` untouched. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
67 lines
3.1 KiB
Markdown
67 lines
3.1 KiB
Markdown
# Huginn
|
|
|
|
Huginn is the GameCult memory organ. It owns each agent instance's mind as
|
|
typed state: what an instance remembers, which of that memory is admitted to
|
|
steer its next action, and the provenance of every admitted claim.
|
|
|
|
Upstream: `https://github.com/GameCult/Huginn.git`
|
|
|
|
## Authority
|
|
|
|
- An instance owns its mind; Huginn owns the state. Huginn is the single
|
|
writer of an instance's memory documents. No other service, script, or agent
|
|
writes them.
|
|
- Memory documents are CultCache state. `huginn-mind`, the one live crate,
|
|
persists them through CultLib's Rust CultCache into a redb store at
|
|
`<state_root>/minds/<instance>/mind.redb`. Publishing them over CultNet is
|
|
`huginn-daemon`'s, and that crate is a stub: nothing here publishes yet.
|
|
- Retrieval is to depend on Qdrant directly, refusing loudly when Qdrant is
|
|
unreachable rather than falling back to a second store or a second writer.
|
|
No crate opens that connection yet.
|
|
- Mind state is not version-controlled. It lives in Huginn's store, not in
|
|
any repository.
|
|
|
|
Generic `.cc` inspection is not Huginn's job. CultCache Studio inspects and
|
|
edits `.cc` state. Huginn reads and writes minds.
|
|
|
|
## Layout
|
|
|
|
A Cargo workspace of three crates:
|
|
|
|
- `crates/huginn-mind`: storage, identity, admission, and queries and derived
|
|
status over memory documents.
|
|
- `crates/huginn-daemon`: a stub. It will carry the CultNet surface and serve
|
|
loop; today it holds neither.
|
|
- `crates/eureka-state`: a stub. It will carry typed state for the Eureka
|
|
pipeline; today it holds none.
|
|
|
|
`huginn-mind` is live: it opens one instance's store (an owned redb CultCache
|
|
at `<state_root>/minds/<instance>/mind.redb`, locked for the mind's lifetime),
|
|
and refuses a store whose `instance` document names another instance, whose
|
|
epoch record is foreign, or whose types are not a mind's. It admits batches
|
|
of pipeline documents through one commit path: the leaf's bounds, formats and
|
|
keys, then the organ's cross-document rules (references, in-force status,
|
|
the resolution matrix, derived resolutions and stewardships), then one
|
|
compare-and-swap that lands the batch whole with a receipt naming the exact
|
|
bytes it read and wrote. An exact replay answers with the stored receipt.
|
|
It reads them back the same way: a document with the facts of its admission
|
|
joined from that receipt and its status derived at read time, typed queries
|
|
over one mind, a campaign's open work, and a subject's or a repo's history.
|
|
Status is never stored, and the views derive it through the same rules
|
|
admission does. Document shape and keys come from `epiphany-pipeline`; the
|
|
store is CultLib's Rust CultCache.
|
|
`huginn-daemon` and `eureka-state` are stubs; the
|
|
campaign's cut map in `Epiphany/notes/eureka-pipeline-state-cut.md` owns what
|
|
each crate must do next.
|
|
|
|
```powershell
|
|
cargo check --workspace
|
|
```
|
|
|
|
## Persona
|
|
|
|
Huginn's legacy repo Persona lives under `.voidbot/`. Its `state/huginn.cc`
|
|
holds legacy `void.*` documents and its `voice/identity.json` names the
|
|
Persona. The two disagree about jurisdiction; that migration belongs to the
|
|
portable-Persona work, not to this workspace, and nothing here reads or writes
|
|
`.voidbot/`.
|