No description
  • Rust 98.4%
  • C++ 1.2%
  • Python 0.4%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Meta Vens 056db28792 RS fix batch: read-side density, the smallest seal, R5's two shapes, stale prose
F1: AdmissionIndex::build now calls receipt::head before copying any
ordinal, so query and view refuse a receipt chain that is not exactly
{1..=N} (duplicate, gap, zero, or above-N) instead of trusting a stored
ordinal unchecked. New test query::tests::query_and_view_refuse_a_receipt_chain_that_is_not_dense
pins it behaviourally: it plants each broken chain directly (bypassing
admission) and asserts query and view both refuse. The schema's ordinal
gets minimum: 1 (was 0), matched by #[schemars(range(min = 1))] on
AdmissionFacts::ordinal. head's doc now says AdmissionIndex::build asks
it too.

F2: Mind::open_with is renamed to an internal open_checked, and a
test-only Mind::open_with is gated behind cfg(test) or the test-support
feature, exactly like store_path_for. Production reaches open_checked
only through Mind::open, which takes the store's per-path lock first.
mind::tests::a_mind_has_one_owner_at_a_time (pre-existing) still pins
that a second Mind::open on the same path is refused. The full store
seal against a second in-process owner over an arbitrary MindStore stays
a recorded follow-up. lib.rs's crate doc now names Mind::open as the
owner of "may this store be this instance's mind".

F3: R5 is not binary. Two loosenings are pinned as R5b and R5c in
mind.rs, with behavioural fixtures: a foreign type with no epoch record
at all still refuses MissingIdentity, not ForeignStore (R5b); an epoch
record at the current key with a foreign value, beside a foreign type,
still refuses ForeignEpoch, not ForeignStore (R5c).

F5: gate step numbering in mind.rs's doc comment and its test comments
now read 2 (epoch), 3 (type), matching the code's actual order. docs.rs
no longer credits resolutions_of/assignments_of with reading history,
which RS-2 deleted. The two-door test in query.rs is renamed from
a_ref_whose_kind_and_id_disagree_is_refused_by_both_doors to
..._by_view, since view is the only door left.

Per the operator's ruling retiring the anchor-based mutation harness,
this batch carries no .psd1 changes; the cut9/cut10/readside mutation
files have uncommitted edits from the earlier pass (stale references to
the old test names, and R3L's target) left for a later pass to fold in
or drop.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-22 18:34:47 +02:00
.voidbot Document Huginn repo swarm wiring 2026-06-21 15:51:46 +01:00
crates RS fix batch: read-side density, the smallest seal, R5's two shapes, stale prose 2026-09-22 18:34:47 +02:00
schemas/cultnet RS fix batch: read-side density, the smallest seal, R5's two shapes, stale prose 2026-09-22 18:34:47 +02:00
tools Cut RS-1: the receipt ordinal, receipt v2, and the epoch-first opener 2026-09-22 11:56:04 +02:00
.gitignore Add the empty Rust workspace 2026-09-16 15:11:05 +02:00
AGENTS.md Describe the daemon that exists instead of the stub that does not 2026-09-16 23:00:28 +02:00
Cargo.lock Move the epiphany-pipeline pin to the leaf commit carrying S5 and S8 2026-09-22 08:21:56 +02:00
Cargo.toml Add the empty Rust workspace 2026-09-16 15:11:05 +02:00
README.md Cut RS-2: delete open_items, history, and the admission window 2026-09-22 09:51:32 +02:00

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 persists them through CultLib's Rust CultCache into a redb store at <state_root>/minds/<instance>/mind.redb. huginn-daemon serves one such mind over CultNet RUDP: admission and the read side ride cultnet.operation_request.v0 and cultnet.operation_response.v0, and the two wire schemas answer a schema catalog request.
  • 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: the CultNet surface. The socket, the sessions, the process and the operation envelope, and no rule.
  • 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, and typed queries over one mind. 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 opens one mind, binds one UDP socket in that order, and answers every frame on the session it arrived on: one operation per Mind method plus whoami, whose payload is the mind's own types as named MessagePack. A refusal is an answer with a rejected status, never a transport error; an envelope that does not decode is answered with a typed failure and reaches no mind. The two schemas it publishes live in schemas/cultnet/ and are pinned to their derivation by a test. There is no index yet.

eureka-state is a stub; the campaign's cut map in Epiphany/notes/eureka-pipeline-state-cut.md owns what each crate must do next.

cargo check --workspace
cargo run -p huginn-daemon -- --state-root <abs> --instance <slug> --bind 127.0.0.1:17872

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/.