- Rust 98.4%
- C++ 1.2%
- Python 0.4%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
The pin moves to Epiphany `d5a36c2a`, where a resolution's key ends in its per-subject sequence and a stewardship's in its per-(instance, repo) one. Two fields arrive with it, so `stewardship` and `resolution` in the fixtures set `sequence: 1` and `stewardship_n`/`resolution_n` say otherwise when a test needs a second record. Every literal key that gained `.n1` moved with it, `id_of` included. The rules the sequence was for: - `in_force` is recursive. A document is in force when no resolution that is itself in force names it, so a withdrawn resolution stops closing its subject. The old one-level version counted a withdrawal as if it still stood, which is half of why a reopened subject could not be resolved again. - The other half was A10. `refuse_collisions` no longer has a `Resolution` arm: a resolution key is not one-per-subject any more, so a collision on it means what it means for every other kind, and whether a subject is closed is A8's question. - A8 asks it, for both sequenced kinds, in the same two steps. The sequence is the writer's and must be the previous plus one over image and batch, counting every record of that scope but this document -- `ResolutionOutOfSequence`, `StewardshipOutOfSequence`. Then no record of that scope may still be in force -- `AlreadyResolved`, `AlreadyStewarded`. With both, at most one stewardship of a repo stands on a mind, which is what `stewardship_of` has been assuming. - Q19 A is enforced rather than described: a resolution whose subject is a resolution of a resolution is `IncompatibleResolution`. A withdrawal cannot be withdrawn; a closure is reinstated by resolving the subject again. - `derive` sets a sequence on each write it makes, from the same image the rule reads. Two existing tests move with the rules. `subject_resolves_at_most_once` is now `a_subject_with_a_resolution_in_force_refuses_another` and separates the two refusals. The hand-off test's last case used to be an A4 collision between a batch's own stewardship and the derived one; the derived write now takes the sequence after the batch's, so there is nothing left to collide and the batch is refused as out of sequence instead. 31 tests, 0 warnings; `cargo check --workspace` clean. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
| .voidbot | ||
| crates | ||
| tools | ||
| .gitignore | ||
| AGENTS.md | ||
| Cargo.lock | ||
| Cargo.toml | ||
| README.md | ||
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 ishuginn-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, and admission of memory documents.crates/huginn-daemon: the CultNet surface and serve loop.crates/eureka-state: typed state for the Eureka pipeline.
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.
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.
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/.