Commit graph Huginn/Cargo.lock
Author SHA1 Message Date
Meta Vens
c798345171 Cargo.lock: model-connector no longer pulls cultcache-rs (the daemon dev-dependency is gone)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 13:47:44 +01:00
Meta Vens
bd5a50e1d3 lease_client: vendor the connector lease_v2 byte goldens (ModelConnector c1802d8) and pin the kit to that merged commit
The client decodes every published refusal and the grant and encodes the request
and each message back to the same bytes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 05:41:33 +01:00
Meta Vens
056ca778d8 mind-body: tear out dollar metering; a shared tempo heartbeat; usage-only connector (WIP, tests follow)
Delete the classifier, initiative, burn, base-rate dial, shares, Envelope dollars,
persona turn max_cost, --max-budget-usd and the Self-run settle. Add tempo::tally
and tempo::pick, self-declared urgency from the reply as a Pulse, the usage line in
Persona input, and the wire-v4 connector (lease v2, usage_readout).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 05:24:54 +01:00
Meta Vens
d54ba01103 mind-self-via-lease: a Self run borrows the one Claude token from the connector over the lease socket; the child gets a cleared environment and a fresh per-spawn config; the unit's RuntimeMaxSec is the one run cap; settle is claude's last modelUsage plus the tail after it; an Expired lease withdraws its run (squash of eureka-body/mind-self-via-lease fcaf0a1..a91fc1c; Soul s1-s3)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 00:15:14 +01:00
fcaf0a1a23 mind-persona: the Persona turn organ; brake and dial before spend, typed schema reply decoded strictly, acks after posting, framed member text, campaign-checked Self-run briefs; real connector client (ModelConnector 480cf94) and RUDP chat client to the Bifrost mouth (squash of eureka-body/mind-persona onto 49bfe17, head f25decf; Soul s1, s2)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 21:03:19 +01:00
Meta Vens
35dda44001 mind-self-run: the Self-run actuator (squash of eureka-body/mind-self-run 70d0cef..654a209)
Opens claude only under an open Self run; one pure decide() owns flush, grace, headroom and escalation; process-group signals; ends on child exit or EOF. Soul s3 holds (eureka-body:verdict:cut-mind-self-run.s3).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 23:26:31 +02:00
Meta Vens
19e6c050ed mind-body: pin the library's public surface as a whole
tests/public_surface.rs reads the library source the way a consumer sees it
and compares every pub item with its signature, pub fields, derives, impl
headers and every path-looking string literal to tests/public_surface.txt.
A new pub static or pub fn under any name, a derive onto Grant, or a root
read from another path fails it. It replaces the three compile_fail
doctests that named with_root, TEST_ROOT and control_root. Dev-dependencies
syn, quote and proc-macro2, already in the graph through serde's derive.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 20:15:19 +02:00
Meta Vens
5da8b06a6d Merge remote-tracking branch 'origin/main' into eureka-body/mind-launch 2026-10-10 19:16:19 +02:00
Meta Vens
d5fddc3a58 Merge origin/main (huginn CLI) into huginn-persona-state
Resolves the eureka-state Cargo.toml comment block to main's, regenerates
Cargo.lock from main's with cargo update -w, adds the Persona and PersonaPut
arms to the CLI's unexpected-answer match and the persona field to the CLI
test MindStatus literals.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 10:15:12 +02:00
Meta Vens
b759addf3e Regenerate the response wire schema for PersonaStatus; lock serde_path_to_error
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 08:38:42 +02:00
Meta Vens
02cb3dadcd huginn CLI over HuginnClient: whoami, view, query, recipes, admit with read-back, schema
A new bin of eureka-state, crates/eureka-state/src/bin/huginn/: the agents'
shell door to the mind. Text out, typed exit codes, strict decode of
agent-written JSON (unknown key paths refused, never values), the named
campaign-state recipes, and a read-back after every committed admission.
lib.rs, main.rs and tests/mcp.rs are untouched.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 06:01:01 +02:00
Meta Vens
dbdb4e86f8 Huginn holds an instance's persona document, validated and receipted
put_persona replaces the mind's gamecult.persona_state.v0 whole through the
commit primitive: schema-valid against the published file, personaId is the
instance, canonical provenance, CAS on updatedAt, monotone updatedAt. The
document is an opaque seventeenth stored type, one per mind. Wire operations
persona_get and persona_put, MindStatus.persona, HuginnClient methods and the
eureka-state persona tools. Published wire schemas follow in the next commit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 05:30:48 +02:00
Meta Vens
cfbecd307f Cargo.lock: mind-body gains cultnet-rs, eureka-state and huginn-mind
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 20:51:20 +02:00
Meta Vens
5cccab6899 mind-body: the binary restricts its umask; the writer refuses unsafe installs
Soul s2: under a permissive umask the store was group/world-writable between
CultCache's rename and the chmod, and an fd opened there survived it. The
mind-control binary now sets umask 077 first (the library never touches the
umask). The writer refuses to write through an existing directory, lock or store
that is not root's or is group/world-writable, with the typed UnsafeStore error
naming path, mode and owner. Tests: a non-root open-for-write probe against the
real binary under umask 000; refusals for 0777/0775 directories, 0666/0664
locks and stores, and a non-root-owned directory; accepted root installs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 16:39:19 +02:00
Meta Vens
4b3e850fef mind-body: the operator's brake and burn-rate dial, the reader and the mind-control CLI
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 15:58:29 +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
2b0cd0898b huginn-mind: pin epiphany-pipeline to the per-kind key bound (leaf-key-bound)
Moves the leaf from 73edee5cdaddece8bda9c6c3271e8ddd064337f9 to the
leaf-key-bound merge commit on Epiphany main,
ef9568655e75bb6cb362a038e2739a5ac5e777ee. Cargo.lock follows with that one
line; no other lock line moves.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-01 11:40:28 +02:00
Meta Vens
9dd6d8007a Pin CultLib 8fc74c7 in every crate, and the pipeline leaf that follows it
eureka-state on Windows could not reach the daemon: the cultnet-rs RUDP
client bound 127.0.0.1, and a loopback-bound socket cannot send to
10.77.0.1 (os error 10051). CultLib 8fc74c7 binds the unspecified address
for a remote endpoint. The daemon and the client move together, because
the ack cuts between the revs changed the RUDP handshake.

epiphany-pipeline moves to Epiphany 73edee5, which pins the same CultLib,
so one cultcache-rs is in the graph and the pipeline's CultCache types
stay Huginn's.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 14:36:44 +02:00
Meta Vens
e0f07c3f53 eureka-state: the MCP server, four tools 1:1 with the wire
The eureka-state binary serves whoami, admit, view and query over stdio (rmcp
2.2.0), each one HuginnClient call. EUREKA_INSTANCE and HUGINN_ENDPOINT are
process configuration: the server fills in the instance and provenance.tool, so
input can name neither. Bad configuration never stops startup; whoami reports
it and every other tool refuses with the typed body. A mind's refusal is a
normal result; Unavailable, Rejected and Misconfigured are results with
isError. The query input schema bundles CultLib's selection schema into $defs
(vendored; a test pins it to the cultnet-rs revision).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-30 00:36:33 +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
debe7ce9e7 Move the operation envelope to huginn-mind: one spelling for client and daemon
envelope.rs (encode/decode request and response, OperationFailure,
FAILURE_SCHEMA) leaves huginn-daemon for huginn-mind, next to the wire types
it wraps. The daemon imports it and no longer re-exports it. base64 moves
with it; the daemon keeps base64 because serve.rs measures and decodes
payloads. schemars leaves the daemon, whose only user was the envelope's
OperationFailure derive. The two envelope tests run unchanged from their new
home on huginn-mind fixtures.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 23:30:21 +02:00
Meta Vens
78f8c6ee2f Cut 11a: the index write side
huginn-mind::index owns what of a document is searchable: index_text is a
pure function per kind, Mind::index_entries builds the entries with the
writing receipt's ordinal, INDEX_TEXT_VERSION says when the rule changed.

huginn-daemon::index owns the projection. A Projector reconciles the mind
against the collection at startup (the only place a point is judged
missing: set difference on point ids, rebuild when the model name, digest,
dimensions or text version differ, refuse a collection that is not this
instance's) and one worker thread embeds and upserts in batches of 32,
retrying with a 30 s to 10 min backoff. IndexSink::committed builds entries
and leaves them in an inbox; admission never waits on the embedder or on
Qdrant. Whoami reports the worker's health as IndexStatus. The Ollama and
Qdrant adapters are the only files holding HTTP or JSON (ureq 3, no TLS).
The daemon now requires --qdrant-url, --ollama-url and --embedding-model;
NoIndex leaves the binary.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 08:05:26 +02:00
Meta Vens
eb57bdba40 RS-3 2: the read side is CultNet's selection over the organ's rows
The four hand-written filters, the order and the cap are deleted:
PipelineQuery, PipelineQueryPage, QUERY_LIMIT_MAX, Reader::matches, ordered,
repo_matches. Mind::query(selection, semantic) validates through
cultnet_rs::validate, closes the values door (rows.rs refuse_values, S6),
takes the snapshot from the cursor's own asOf (an asOf beyond the head is
CursorInvalid), builds Reader::at(as_of) so every derivation runs over the
documents admitted at or before it, and evaluates through cultnet_rs::select.
The page carries matched, asOf, the next cursor, headers or whole views by
projection, and typed edges when the selection hops.

rows.rs is the organ's vocabulary: SelectionRow (a Row), Vocabulary (a
RowSet: thirteen schemas, eleven aliases, fifteen roles) and the value door.
huginn-mind links cultnet-rs at the rev the daemon pins. Selection refusals
map totally onto SelectionInvalid, CursorInvalid or Unavailable. The wire's
Query carries CultLib's selection by $ref, and both published schemas are
regenerated. The relations RS-2 unpinned are re-pinned as selections.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 05:56:37 +02:00
Meta Vens
e770fb9f21 BP-2: move Huginn to CultLib 6251cbc and the RS-L leaf 4891f2e5
One pin move: huginn-mind pins cultcache-rs at 6251cbc and the leaf at
4891f2e5; huginn-daemon pins cultnet-rs at 6251cbc. cargo tree shows one
cultcache-rs and one cultnet-rs per crate.

Adopting RS-L, which the new leaf carries:
- Campaign, cut-spec, question and ruling fixtures carry a Title; the
  question and ruling fixtures gain the new required title field.
- The epoch literals in daemon and envelope tests move v1 -> v2. A store
  written at an earlier epoch is refused at open (ForeignEpoch); no key
  migration.
- Derived stewardship, hand-off and resolution keys are now the lowercased
  OrgRepo::identity(); test key literals follow.
- The two published wire schemas are regenerated (Title, OrgRepo bound and
  description); the byte-for-byte pin test passes.

CultLib 6251cbc gives CultNetMessage::Error code and details; the four
construction sites and one pattern in huginn-daemon take None and `..`. No
behaviour change: None is skipped on the wire. mind 70 and daemon 18 pass.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 03:56:03 +02:00
Meta Vens
f7e0d020ed Move the epiphany-pipeline pin to the leaf commit carrying S5 and S8
Epiphany codex/eureka-pipeline-state b3ae787b extends the leaf's door
test with the 64-byte whole-name and per-label bounds and NUL, adds
three matching mutation entries, and corrects the entries file header
that still named the deleted repo-local harness path. One cultcache-rs
throughout: epiphany-pipeline, cultnet-rs and huginn-mind all still
resolve to CultLib a0813c6e.

Verified: cargo test --workspace (huginn-mind 65/65, huginn-daemon
20/20, eureka-state 0/0), cargo tree -i cultcache-rs shows one node.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-22 08:21:56 +02:00
Meta Vens
cc71a569dc Fourth fix batch: fill N1 in its owner, and correct two ledger claims
N1 (medium-low). Moves the epiphany-pipeline pin to the leaf's new commit
(9d3a3efd), which opens Slug::validate_slug. Huginn's own cultcache-rs pin
is untouched; cargo tree -d still carries exactly one cultcache-rs.

Mind::require_instance now validates the declared name's grammar before
comparing identity, so admission's A1 and every read refuse a bad name
identically, through one door. Mind::open and open_with validate the
declared instance before path_for ever runs, so a Slug carrying `..` and a
path separator (Soul's outer/inner probe) is refused before any store is
created, not after it has already escaped the state root.

require_grammatical_instance and its daemon-side branch in daemon.rs are
deleted: the throwaway PipelineInstance wrapper it built is no longer the
only door onto the leaf's grammar. The refusal now names the field a
caller actually held the declared name under (declared, or instance) and
the whole declared name, not the old wrapper's instance.instance field or
a single failing label.

Adds a leaf-escape regression test pinning Soul's probe and asserting no
store is created, and a fullwidth-instance test showing Admit and Query
refuse identically. Updates the cut10 grammar-fold mutant (S3wide) to the
new function shape and the affected daemon test to the new field name.

N5 and N6, prose only. The cut10 entries gain a note by S1 and S1d: neither
mutant "dies on all three" faults its shared fixture carries, contrary to
an earlier claim; S1d exempts the orphan fault by construction and is
killed by the undecodable-document block instead, the next one the test
body reaches. The cut9 header's self-contradiction at lines 18-25 is
resolved (nothing in the suite exercises the door, not "nothing reaches
it"), its self-reference now points at store.rs:18-19, and its line-1
range is corrected to V1-V24L.

All three suites rerun clean after the pin move: cut8 67/67, cut9 38/38,
cut10 65/65, every M0 green, restores hash-verified. cargo test --workspace:
huginn-mind 61/61 (was 60), huginn-daemon 18/18 (was 17).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-22 05:14:34 +02:00
Meta Vens
6b619d6bbd Serve one mind over CultNet, and no rule beside it
`huginn-daemon` becomes a library and a binary. `Daemon` holds one mind and
dispatches a `HuginnMindRequest` to the `Mind` method that answers it, with no
socket and no clock: `now` is the caller's. Every read that names an instance
is put to `Mind::require_instance` before the method runs, so ruling 14 is
checked once, by its owner, whichever side of the wire the request came from.
`IndexSink` is where Cut 11 attaches; its error is logged and the outcome is
what the mind decided.

`envelope` carries the vocabulary in CultNet's `cultnet.operation_request.v0`
and `cultnet.operation_response.v0` as base64 of named MessagePack, which is
what the C# reference and Eve's plugin ABI speak. The envelope's operation
string is checked against the decoded payload rather than trusted. A message
that does not decode is answered with a typed failure naming its code, and
reaches no mind.

`serve` binds one non-blocking socket on CultNet's operation connection id and
answers each frame on the session it arrived on. A refusal is an answer with a
`rejected` status, never a transport error. The two wire schemas go out on a
schema catalog request. A hostile datagram and a departed peer are logged and
served past. `startup` is the one place the mind opens and the socket binds,
in that order, so a mind that will not open leaves the port free.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-16 22:59:33 +02:00
Meta Vens
c4b2a0fa2e Give the mind a wire vocabulary and publish its two schemas
`huginn-mind::wire` names one request per `Mind` method plus `whoami`, and one
response per method plus the read side's refusal. The payloads are the
admission and read types unchanged, so a client speaks the organ's own
vocabulary rather than a projection of it. `operation()` and `instance()` say
what the envelope carries; `status()` derives the envelope's status from the
response, and a refusal is data in that response rather than a transport
failure.

`Mind::status` answers `whoami` from the image every time it is asked: the
instance, the schema epoch, and how many pipeline documents and receipts the
mind holds. Nothing stores a status and no configuration supplies one.

`schemas/cultnet/` publishes the JSON schema of each wire type, derived from
the type and pinned to it byte for byte by a test, so the schema catalog
cannot advertise a shape the crate does not speak.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-16 22:52:53 +02:00
Meta Vens
5ba7b0c6e5 Refuse a ref that is no ref, rather than answering over it
The pin moves to Epiphany `5cda0886`, where `PipelineRef::validate_ref` opens
the leaf's grammar to a reader. `view` and `history`'s subject scope ask it
before they look, so a ref whose kind and id disagree is refused instead of
reporting the nothing a lookup finds. `query`'s `campaign`, `cut` and `repo`
filters take a `Slug`, a `Label` and an `OrgRepo`, not refs, and are unchanged.

The refusal is `MindRefusal::Document`, the leaf's `InvalidFormat` wrapped
where the organ already wraps the leaf's four. A new variant would be a second
name for one rule, and the grammar it names lives in the leaf.

`a_ref_whose_kind_and_id_disagree_is_refused_by_both_doors` pins both doors on
a disagreeing kind and on a local no writer composes, and pins that absence is
still absence: a well-formed id of a document this mind does not hold answers
`None` and an empty history as it always did. The history test's malformed
scope asserts the refusal where it asserted an empty answer.

`V24` and `V24L` in `tools/eureka-cut9-mutations.psd1` are the validation
dropped and the validation applied at `view` alone. `V10L` leaves the suite
with its reason in the header: a subject compared by `id` alone can no longer
differ from one compared whole, since both sides' kind is now a function of
the id, so the weakening is unreachable and a mutation that cannot fail is not
a proof.

`cargo test -p huginn-mind --lib` 57 passed, 0 warnings; `cargo check
--workspace` clean; Cut 8 and Cut 9 suites green-and-killed through the
harness. The lock moves the one pin.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-16 22:41:17 +02:00
Meta Vens
3efc0dc82d Take the sequenced keys and make in force mean what it says
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>
2026-09-16 19:28:17 +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
f63c0f2d0b Add the empty Rust workspace
Three stub crates following Odin's layout: huginn-mind and eureka-state as
libraries, huginn-daemon as the binary. Edition, license and publish are
workspace-owned. .gitignore gains target/ and drops the four entries that
named build outputs no longer produced here.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-16 15:11:05 +02:00