Story 011: Corpus answers the fish-water question¶
Status: Hard-MVP blocker
Summary¶
As a node operator, I want one node to ask a bounded biological question and two other nodes to contribute through a bounded reasoning market and, in the post-MVP profile, let selected model-backed participants deliberate through a shared Room so the requester can stop the process once the answer is satisfactory.
The concrete question is:
Do fish drink water?
Node A is the requester. Node B and node C are Corpus-capable providers. Node B also hosts the Seed Directory and an offer-catalog profile with a biology taxonomy. The story uses Corpus as the topic-routed reasoning layer over the existing question, service-offer, procurement, and room primitives.
Actors¶
- Node A asks the question, creates the Corpus query, aggregates bids, selects
a provider, and may close the round as
requester-satisfied. In the Agent profile it also runs the Room-attested chair Agent. - Node B publishes a
corpus.provideroffer for the biology taxonomy, runs the Seed Directory role in the profile, and is selected as the expert. In the Agent profile it participates through a Room-attested participant Agent. - Node C publishes a second
corpus.provideroffer for the same taxonomy and remains a competing bidder; selection does not ambiently enroll it in the A↔B deliberation.
Flow¶
- Node B exposes a remote offer catalog and Seed Directory profile.
- Node B and node C publish
corpus.provideroffers with the samecorpus/taxonomy-digestandcorpus/topics. - Node A creates a
corpus-reasoning-query.v1around aquestion-envelope.v1whose text isDo fish drink water?. - The query carries a Room collaboration reference; the acceptance pack uses the daemon-owned bounded WSS carrier and retains the Matrix room id only as future transport intent.
- Node B and node C produce
corpus-reasoning-bid.v1responses. - Node A builds a requester-owned bid-state read model and selects the cheapest valid accepted bid.
- In the Agent profile, B's admitted participant Agent invokes Inquirium and
proposes an inert, content-addressed reasoning turn through the explicit
corpus.room.turneffect and human-in-loop gate. - A consumes the Room event through Interaction Broker, runs its admitted chair Agent, and accepts the terminal product as an unpublished Corpus answer draft.
- Once the answer is satisfactory, node A can stop the round by marking it
requester-satisfied; publication remains a separate Corpus-owned transition.
The intended answer distinguishes freshwater and saltwater fish: freshwater fish gain water osmotically and mostly do not need to drink, while many marine fish drink seawater and excrete salts.
MVP Boundary¶
This story is part of the hard-MVP story set and blocks MVP readiness until the local acceptance pack can complete the documented three-node Corpus query/bid/select/close path. The MVP blocker is the bounded Corpus procurement round itself; a real Matrix homeserver-backed live collaboration transport is a post-MVP extension as long as the query and answer path preserve the Matrix room id as protocol intent.
Story 012 is the gated follow-on profile that composes this Agent-deliberation topology with a chair-owned, read-only Workbench terminal view. It is not part of Story 011 completion; its composed three-node process runner and cross-process evidence are now executable.
Acceptance Pack¶
The initial operator-facing pack lives in:
node/tools/acceptance/story-011-corpus-fish/
The executable pack is a multi-address single-host profile. A/B/C bind to
127.0.0.1, 127.0.0.2, and 127.0.0.3; peer certificates bind the exact
address in their IP SAN, and Node B's Seed Directory binds to B's address. This
proves distinct TCP/WSS process endpoints and node-specific addressing, but not
separate hosts, public reachability, NAT traversal, independent failure domains,
or production federation-relay deployment. On macOS the shared acceptance helper
adds the explicit .2 and .3 aliases; runners validate them and never invoke
privileged setup implicitly.
For unattended execution, the pack exposes an explicit
single-address-single-host profile. It binds all three daemons to
127.0.0.1, isolates them by port, and records the lower evidence strength in
the result. It is never an automatic fallback and does not prove
address-distinct routing.
It renders three local daemon profiles, imports Corpus-capable offers for B and
C, creates the A-side query, asks B and C for provider bids, registers those bids
on A, selects the cheapest valid bid, and verifies that A can stop the round as
requester-satisfied.
The managed smoke uses the same federation-root trust seam as runtime
consumers: after first boot it reads real node IDs, creates B/C provider
participants, rewrites the signed runtime federation-root.v1 with Node B's
official Seed Directory endorsement and B/C participant attestation roots,
restarts all daemons, asserts Node A's active /v1/seed-directory trust view,
and only then issues/publishes provider capability passports.
The pack does not start a real Matrix homeserver. It exercises the bounded WSS
Room carrier. Its Agent-deliberation profile proves a selected B participant
Agent, an A chair Agent, a host-owned room-event Interaction Broker watch,
human-approved turn dispatch, metadata-only durable watch replay, restart-safe
Agent bindings, mismatched participant refusal, stale cursor refusal after
Room-source restart, exact accepted-draft replay after restart, and absence of
ambient answer publication. A homeserver-backed transport fixture can be layered
onto the same Room contract later.
Done When¶
- The local three-node acceptance pack initializes all profiles with valid daemon configuration.
- The managed smoke starts A, B, and C and completes the Corpus query/bid/select path.
- The managed smoke refreshes the signed runtime federation root after first
boot and proves that Node A sees Node B as an active
federation-endorsedSeed Directory source before provider passport discovery. - B is selected when it offers the lower valid price.
- A closes the round with
round/status = requester-satisfied. - The query and answer path preserve the Room and future Matrix transport intent, while the exercised carrier is stated explicitly.
- The Agent profile admits only signed, fresh, exact Room evidence; B's turn is inert until human-approved effect dispatch, and A observes it through the host-owned broker.
- B is the selected expert, C remains a competing bidder, and neither raw model adapters nor unselected providers gain Room authority.
- Restart recovers the A/B Agent bindings and completed chair outcome; stale Room cursors fail closed and exact effect replay does not duplicate publication.
- Agent output remains an inert draft until a separate Corpus-owned acceptance or publication transition.