Commit graph Huginn/AGENTS.md
Author SHA1 Message Date
Meta Vens
78773a2a13 Docs: eureka-state's huginn binary is the agents' CLI
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 06:01:01 +02:00
Meta Vens
09e1b9792b Relicense the workspace AGPL-3.0-only, own the CultLib rev once, index every schema
Add the AGPL-3.0 text as LICENSE and set the workspace license to
AGPL-3.0-only (rulings license-split, leaf-relicensed-agpl); the leaf's
provenance (Epiphany ef956865, PolyForm Noncommercial, relicensed by its sole
copyright holder 2026-10-09) is recorded in its Cargo.toml and README.

One [workspace.dependencies] entry per CultLib crate now owns the revision;
the crates inherit it. index.json lists Huginn's two wire schemas too, and the
catalogue test drops its huginn. prefix exclusion: every schema file is listed.
README and AGENTS stop naming Epiphany notes as the owner of the cut.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 15:15:10 +02:00
Meta Vens
c46b0ec183 Rename the pipeline leaf to eureka-pipeline and take it as a path dependency
Package and lib become eureka-pipeline / eureka_pipeline; the crate joins the
workspace; huginn-mind's git dependency on GameCult/Epiphany is replaced by
the path, and Cargo.lock is regenerated (the Epiphany source entry is gone).
Every epiphany_pipeline mention in huginn-mind, huginn-daemon and eureka-state
is renamed. The schema-publication test reads ../../schemas/cultnet. The
leaf's license-file key (../LICENSE, which Huginn has no file for) is dropped.
Type ids, the epoch and every schema_id string are untouched. Schemas README
and the pipeline section of schemas/cultnet/README.md are rewritten for the
new home; README and AGENTS no longer say the leaf is pinned by git. New test:
the catalogue lists exactly the schema files beside it.

Not yet built or tested; verification follows on Yggdrasil.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 14:09:16 +02:00
Meta Vens
272dc09800 Add the eureka-state client core: HuginnClient::call
One call carries one HuginnMindRequest to a daemon over CultNet RUDP on the
operation connection and returns the mind's own HuginnMindResponse. Each call
is its own session and nothing survives it. A Deferred answer is fetched on
that session through cultnet-rs's fetch_content, capped at huginn-mind's
MAX_DEFERRED_BODY_BYTES, and decoded, so a caller never sees the deferral.
Refusals are answers. ClientError::Unavailable is the only error and names the
endpoint. The client opens no store and admits nothing.

Tests run a real daemon in-process on a loopback port over a temporary mind,
plus scripted servers for the failures a daemon cannot be made to produce.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 23:41:25 +02:00
Meta Vens
a235304ae5 Describe the daemon that exists instead of the stub that does not
`huginn-daemon` serves a mind, so the README and AGENTS say what it serves,
over which envelope, in which order it starts, and where its two published
schemas live. `eureka-state` is the remaining stub. The command block gains
the daemon's own invocation.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-16 23:00:28 +02:00
Meta Vens
49cc6e3e62 Read a mind: views, queries, open items and history
`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>
2026-09-16 21:22:41 +02:00
Meta Vens
1cfa81d571 Close the epoch record, the minted leaf refusal and the nested resolution
Soul's Cut 8 pass found three rules the code only half held and one
document that promised more than the crate does.

The opener's step 3 said "exactly one epoch record at the current epoch"
and checked neither the count nor the key: a record keyed anything at all
was read as the epoch record, and a second one was never looked at, so a
current record beside a foreign one passed or refused on nothing but the
order the store returned them in. Step 3 now counts before it reads,
refuses a record under any key but the epoch, and names the defect in
`found`: the stored epoch, the offending key, or the count.

The campaign row minted `PipelineRefusal::FieldBound` for an empty
`repos`. The organ does not get to invent the leaf's refusals; an empty
`repos` is admission's own rule and is now `MindRefusal::EmptyRepos`.

The matrix admitted `Withdrawn` on a resolution, which made a subject
resolvable twice over: withdraw the resolution and the subject is open
again. A subject resolves at most once, and a resolution is not itself a
subject, so `resolution` joins `campaign`, `cut_report`, `verdict`,
`instance` and `hand_off` as not resolvable. The key grammar still spells
a resolution of a resolution; admission refuses it here. Self's default
ruling on Q17, standing until the operator rules.

`README.md` and `AGENTS.md` claimed CultNet publication and a Qdrant
connection in the present tense and called the store `.cc`. The daemon is
a stub, nothing connects to Qdrant, and the live crate writes
`mind.redb`. They say so now.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-16 17:53:08 +02:00
Meta Vens
946758f666 Open a mind fail-closed over an owned redb store
Cut 8, Huginn half, commit 1 of 4: the store port, the opener and the
identity rules. `huginn-mind` gains its dependencies (`cultcache-rs` at
Epiphany's pin `a0813c6`, `epiphany-pipeline` at `a65c6420`, the Epiphany
half of this cut), `store.rs` with the one narrow `MindStore` trait that
injects compare-and-swap, `mind.rs` with `Mind::open` and `open_with`, and
`refusal.rs` with the organ's refusal vocabulary.

The opener refuses in order and attaches nothing until every gate passes:
a foreign type, a foreign epoch, a missing identity, an identity naming
another instance. The path under the state root is derived from the slug;
the `instance` document is the authority, so a store copied into another
instance's directory is refused. The owned store's exclusive lock is the
single-writer mechanism: a second `Mind::open` of the same path is
`MindAlreadyOwned`.

The receipt type and the two provenance shapes (`Faculty`,
`PipelineProvenance`) land here rather than in the later commits because
the opener registers the receipt's type id, and their only consumer is the
receipt; the commit primitive itself is the next commit. `MindRefusal`
carries a serde remote definition of the leaf's `PipelineRefusal`, which
derives neither `Serialize` nor `JsonSchema` at the pinned rev; it is
compiled against the leaf's type so a leaf change breaks the build rather
than drifting.

`Cargo.lock` is regenerated and gains 90 packages. The map predicted a
CRLF-to-LF rewrite of the whole file; the file was already LF in the index
and stays LF, so the diff is additions only.

README and AGENTS now say `huginn-mind` is live and the other two crates
are stubs.

Builds: `cargo check -p huginn-mind --lib --tests` and `cargo test -p
huginn-mind --lib` (4 tests) pass. This commit carries dead-code warnings
on the store and cache accessors and the refusing test store; commits 2 and
3 consume them.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-16 17:04:23 +02:00
Meta Vens
4094e689c6 Say in AGENTS that the crates are stubs
README carried the caveat that every crate is an empty stub filled by a
named Eureka cut; AGENTS described ownership, admission, CultNet
publication and a Qdrant dependency in the present tense. Add the same
caveat to the Body section and name Studio as the .cc inspection owner
in one sentence instead of a list of things Huginn does not do.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-16 15:25:29 +02:00
Meta Vens
e20c786c96 Describe Huginn as the memory organ
README and AGENTS now state what Huginn is: the single writer of each
instance's mind as typed CultCache state, published over CultNet, depending
on Qdrant directly and refusing loudly without it. Generic .cc inspection is
CultCache Studio's. The docs name the Rust workspace, the F: drive body, and
the cut map that owns what each crate does next.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-16 15:12:18 +02:00
Meta Vens
afee1a262f Document Huginn repo swarm wiring 2026-06-21 15:51:46 +01:00