diff --git a/docs/architecture/agentvault-negotiation-protocol.md b/docs/architecture/agentvault-negotiation-protocol.md
new file mode 100644
index 0000000..25f1ef0
--- /dev/null
+++ b/docs/architecture/agentvault-negotiation-protocol.md
@@ -0,0 +1,369 @@
+# AgentVault Negotiation Protocol
+
+> Status: Draft protocol sketch
+> Related: [protocol-spec.md](../protocol-spec.md), [precontract-negotiation-notes.md](precontract-negotiation-notes.md), [ifc-reintegration-proposal.md](ifc-reintegration-proposal.md)
+
+## 1. North Star
+
+AgentVault should allow delegated agents to negotiate bespoke bounded-computation agreements without allowing freeform contract generation.
+
+The intended middle ground is:
+
+- most sessions use standard named offers from the registry
+- advanced sessions negotiate bespoke agreements by composing admitted artefacts
+- execution always happens through a rigid, verifiable contract derived from that agreement
+
+The key distinction is between two layers:
+
+- **agreement layer** — negotiable, structured, and expressive within bounds
+- **execution layer** — content-addressed, machine-verifiable, and relay-admissible
+
+Agents do not invent raw execution contracts. They negotiate a bounded computation agreement and deterministically compile it into an execution contract.
+
+This split is also an evolution boundary. Negotiation semantics can change over time without changing the execution contract format, as long as compilation still produces the same relay-verifiable contract shape. The same boundary runs the other direction: execution assurance can evolve, for example from relay-asserted to TEE-attested, without changing the shape of agreement negotiation.
+
+## 2. Negotiation Threat Model
+
+Negotiation is not a benign coordination helper. It is an information channel and must be treated as such.
+
+The main risk is that agents can learn about each other from:
+
+- proposal choices
+- counterproposal choices
+- reject reasons
+- convergence failure
+- timing and number of rounds
+
+So the system must decide what trust boundary applies during negotiation.
+
+### 2.1 Default assumption
+
+The safest default model is:
+
+- negotiation messages are not treated as disclosure-free
+- negotiation reveals some bounded metadata about acceptable computation shapes
+- private substantive facts must not be exchanged during negotiation
+
+This means negotiation should be understood as a tightly constrained metadata exchange, not as a private pre-session conversation.
+
+### 2.2 Stronger future model
+
+A stronger model may later place negotiation inside a relay- or enclave-mediated trust boundary so that proposal contents are not directly revealed agent-to-agent.
+
+That is not assumed by this sketch.
+
+For now, the protocol should be designed conservatively for the direct-exchange case.
+
+There are at least two future variants:
+
+- **trusted relay mediation**
+ - the relay can observe negotiation contents and mediate convergence, but the counterparties do not see each proposal directly
+- **TEE-mediated negotiation**
+ - negotiation contents are hidden from both counterparties and the relay operator, subject to the enclave trust model
+
+Both variants would materially reduce direct agent-to-agent leakage, but they also introduce stronger trust assumptions than the current sketch.
+
+### 2.3 Design consequence
+
+Because negotiation is itself a side channel:
+
+- message types must be fixed and small
+- reason codes must be coarse and finite
+- round count must be bounded and explicit
+- the protocol should minimize repeated exploratory bargaining
+
+## 3. Agreement Object
+
+The agreement object is the main object of negotiation. It describes what bounded computation should be run, not arbitrary runtime behavior.
+
+### 3.1 Agreement fields
+
+An initial agreement object should contain:
+
+- `topic_code`
+- `signal_family`
+- `acceptable_schema_refs`
+ - must all be compatible with the chosen `signal_family`
+- `required_policy_refs`
+- `acceptable_profile_refs`
+- `acceptable_program_refs` or a deterministic derivation rule
+- `bounded_parameters`
+- `preference_order`
+- `related_session_context` (optional)
+
+### 3.2 Field intent
+
+- `topic_code`
+ - real-world coordination domain
+ - examples: `salary_alignment`, `meeting_scheduling`, `project_scope`
+
+- `signal_family`
+ - semantic class of the bounded result
+ - examples: `overlap_signal`, `feasibility_signal`, `mediation_triage`
+
+- `acceptable_schema_refs`
+ - one or more admitted schema identifiers or hashes compatible with the chosen signal family
+
+- `required_policy_refs`
+ - policy bundles that must apply to any acceptable agreement
+
+- `acceptable_profile_refs`
+ - acceptable reasoning/model profile artefacts
+
+- `acceptable_program_refs`
+ - admitted prompt/program artefacts, unless program choice is fully derived from the other fields
+
+- `bounded_parameters`
+ - tightly limited negotiable parameters, such as:
+ - entropy tier
+ - timing class
+ - allowed follow-up scope
+
+- `preference_order`
+ - ranked ordering over acceptable choices, so negotiation can converge without prose
+
+- `related_session_context`
+ - optional prior receipt/session/topic references when negotiation is not starting from zero
+
+### 3.3 Hard constraints and ranked preferences
+
+The agreement object should distinguish between:
+
+- hard constraints
+- ranked preferences
+
+Hard constraints define what is acceptable at all.
+
+Ranked preferences define how to choose among mutually acceptable options.
+
+For example, an agent may require:
+
+- `strict_privacy_mode`
+- one of `[overlap_signal_v1, overlap_signal_v2]`
+
+And prefer:
+
+- `balanced_reasoning` before `fast_low_compute`
+- `overlap_signal_v2` before `overlap_signal_v1`
+
+This is more precise than loose "preferred" semantics and gives convergence logic a deterministic basis.
+
+### 3.4 Compatibility validation
+
+The agreement layer should reject incoherent combinations early.
+
+At minimum:
+
+- every `acceptable_schema_ref` must be admitted for the selected `signal_family`
+- every `acceptable_program_ref` must be compatible with the selected schema and policy set
+- bounded parameters must be valid for the selected signal family and schema
+
+The preferred way to enforce this is through registry-declared compatibility mappings rather than late compilation failure.
+
+## 4. Negotiation Message Types
+
+Negotiation should use a small typed protocol, not free-text bargaining.
+
+The initial message set should be:
+
+- `PROPOSE_AGREEMENT`
+- `COUNTER_AGREEMENT`
+- `ACCEPT_AGREEMENT`
+- `REJECT_AGREEMENT`
+
+Every negotiation envelope should also include:
+
+- `negotiation_id`
+- `round_index`
+- `round_budget`
+
+`round_budget` should be an explicit protocol parameter visible to both sides at negotiation start. A small default such as 3 rounds is likely sufficient for most flows.
+
+### 4.1 PROPOSE_AGREEMENT
+
+Sent when one side proposes an initial agreement object.
+
+Fields:
+
+- `negotiation_id`
+- `proposal_id`
+- `round_index`
+- `round_budget`
+- `agreement`
+- `sender`
+- `created_at`
+
+### 4.2 COUNTER_AGREEMENT
+
+Sent when the counterparty can accept the general direction but needs different admissible choices.
+
+Fields:
+
+- `negotiation_id`
+- `proposal_id`
+- `counterproposal_id`
+- `round_index`
+- `round_budget`
+- `agreement`
+- `reason_codes`
+- `sender`
+- `created_at`
+
+`reason_codes` should be structured and finite, for example:
+
+- `INCOMPATIBLE_TERMS`
+- `NO_ACCEPTABLE_AGREEMENT`
+- `ROUND_BUDGET_EXHAUSTED`
+
+Reason codes should stay as coarse as the convergence goal allows. They are useful for convergence, but they are also part of the negotiation side channel.
+
+There is a real tradeoff:
+
+- **coarser codes** leak less but make convergence harder
+- **finer codes** help convergence but reveal more about posture and acceptable terms
+
+The initial protocol should make this tradeoff explicit. One plausible first model is:
+
+- agent-visible codes remain coarse
+- more specific failure details are visible only to the relay or audit log
+
+### 4.3 ACCEPT_AGREEMENT
+
+Sent when one side accepts a fully resolved agreement object.
+
+Fields:
+
+- `negotiation_id`
+- `proposal_id`
+- `round_index`
+- `round_budget`
+- `resolved_agreement`
+- `resolved_agreement_hash`
+- `sender`
+- `created_at`
+
+Acceptance must bind a single resolved choice for each execution-relevant dimension. It must not bind only a still-ambiguous set of acceptable options.
+
+### 4.4 REJECT_AGREEMENT
+
+Sent when no acceptable convergence exists.
+
+Fields:
+
+- `negotiation_id`
+- `proposal_id`
+- `round_index`
+- `round_budget`
+- `reason_codes`
+- `sender`
+- `created_at`
+
+The reject path should explain failure in structured coarse terms rather than natural language.
+
+## 5. Compilation Rule to Execution Contract
+
+Once both sides accept the same resolved agreement object, AgentVault compiles it deterministically into an execution contract.
+
+The compilation rule should:
+
+1. resolve the selected schema ref to one concrete schema artefact
+2. resolve the selected policy refs to one concrete policy set
+3. resolve the selected profile ref
+4. resolve or derive one concrete program ref
+5. resolve bounded parameters into final concrete values
+6. synthesize one canonical execution contract
+7. compute the resulting contract hash
+
+The execution contract should then bind the relay-relevant artefacts, such as:
+
+- `schema_hash`
+- `policy_hash`
+- `profile_hash`
+- `program_hash`
+- concrete bounded parameter values
+
+This compilation must be deterministic. Two agents holding the same accepted agreement must derive the same execution contract bytes and the same contract hash.
+
+### 5.1 Standard offers
+
+Standard offers should be immutable, content-addressed agreement artefacts in the registry.
+
+For example:
+
+- `salary_overlap_offer`
+- `compatibility_check_offer`
+- `mediation_triage_offer`
+
+Using a standard offer should still produce an agreement object. The difference is only that the object is largely pre-filled rather than negotiated from scratch.
+
+Referencing a standard offer should be unambiguous and versioned, for example via an offer ref or offer hash.
+
+## 6. Constraints on the Negotiation Process
+
+The negotiation protocol itself must be bounded, not just the artefacts.
+
+Initial constraints should include:
+
+- a fixed message grammar
+- no free-text semantic bargaining
+- an explicit small round budget
+- explicit reject and counterproposal reason codes
+- no exchange of private substantive facts during negotiation
+- no unregistered schemas, policies, profiles, or programs
+
+Negotiation is for formal parameter convergence, not for moving the real coordination problem outside the vault.
+
+## 7. Worked Examples
+
+### 7.1 Salary alignment
+
+Two agents want to determine whether acceptable compensation ranges overlap.
+
+Agreement shape:
+
+- `topic_code = salary_alignment`
+- `signal_family = overlap_signal`
+- `acceptable_schema_refs = [overlap_signal_v1, overlap_signal_v2]`
+- `required_policy_refs = [corporate_confidentiality]`
+- `acceptable_profile_refs = [balanced_reasoning, conservative_reasoning]`
+
+If both sides converge on `overlap_signal_v1 + corporate_confidentiality + balanced_reasoning`, the system compiles a concrete execution contract and runs the vault session.
+
+### 7.2 Ambiguous mediation / compatibility case
+
+Two agents know they need bounded help on a sensitive coordination problem, but do not initially agree whether the right signal is compatibility assessment or mediation triage.
+
+Agreement shape:
+
+- `topic_code = project_scope`
+- `signal_family = [compatibility_signal, mediation_triage]`
+- `acceptable_schema_refs = [...]`
+- `required_policy_refs = [strict_privacy_mode]`
+
+The negotiation protocol can narrow this to one admissible signal family and one compatible schema without forcing both sides to guess a brittle top-level `purpose_code` upfront.
+
+### 7.3 Failure at round limit
+
+Two agents negotiate under `round_budget = 3` and fail to converge on a mutually acceptable resolved agreement.
+
+The protocol terminates with `REJECT_AGREEMENT` and coarse structured reasons such as:
+
+- `NO_COMMON_SCHEMA`
+- `POLICY_TOO_WEAK`
+
+The system should report the failure to the principal in a way that does not reveal more than the negotiated protocol already exposed. In the initial model, a safe default is:
+
+- "No acceptable bounded agreement was reached."
+
+Richer reporting can be added later, but it should be treated as another disclosure surface.
+
+## 8. Direction
+
+The intended direction is:
+
+- keep standard offers as the default product path
+- allow richer structured negotiation when standard offers do not fit
+- treat `purpose_code` as a coarse derived label or family tag, not the deepest semantic primitive
+- keep the registry as the innovation surface for new capabilities
+
+This note is a protocol sketch, not yet a normative specification. Its role is to define the target shape of agreement negotiation before individual fields and wire formats are frozen.
diff --git a/docs/architecture/ifc-reintegration-proposal.md b/docs/architecture/ifc-reintegration-proposal.md
new file mode 100644
index 0000000..9b41811
--- /dev/null
+++ b/docs/architecture/ifc-reintegration-proposal.md
@@ -0,0 +1,299 @@
+# IFC Reintegration Proposal
+
+> Status: Draft architecture note
+> Related: [protocol-spec.md](../protocol-spec.md), [a2a-integration-spec.md](a2a-integration-spec.md), [precontract-negotiation-notes.md](precontract-negotiation-notes.md), `vfc/packages/ifc-engine`, `vfc/packages/message-envelope`
+
+## 1. Role of IFC in the Modern Stack
+
+This note proposes how to reintegrate IFC into the current AgentVault architecture without blurring its role with AFAL or vault execution.
+
+The intended layering is:
+
+- **A2A** — optional transport and interoperability carrier
+- **AFAL** — admission and session formation
+- **Vault contract** — bounded computation
+- **IFC** — bounded communication and context-flow control outside sessions
+
+The key correction is that IFC should no longer be treated as an old experimental subsystem or an optional wrapper around a few messages. It should be the default policy membrane for out-of-vault agent communication.
+
+That gives the system two complementary controls:
+
+- **bounded computation** inside a vault session
+- **bounded communication** outside a vault session
+
+This restores a clean architecture. Without IFC, AgentVault risks having a highly disciplined in-vault path and a comparatively ungoverned out-of-vault path.
+
+### 1.1 Distinct responsibilities
+
+AFAL and IFC should remain separate:
+
+- **AFAL asks:** should these agents open a bounded session, and under what agreement?
+- **IFC asks:** may this concrete message flow between these agents outside a session, and if so under what constraints?
+
+The vault contract then governs the actual execution once a session exists.
+
+### 1.2 IFC as a membrane, not message decoration
+
+An IFC envelope is not just a safer message wrapper. It is a signed, policy-evaluable claim about permissible information flow.
+
+That claim binds:
+
+- sender and recipient
+- message payload
+- IFC label
+- policy hash
+- label receipt
+- optional grant context
+
+The receiver does not merely "read metadata." The receiver evaluates the flow mechanically and obtains one of a small number of outcomes.
+
+### 1.3 Where IFC applies
+
+IFC should sit laterally to vault sessions rather than strictly before or after them.
+
+Valid paths include:
+
+- `IFC message`
+- `IFC -> Escalate -> AFAL -> Vault`
+- `Vault -> receipt/grant -> IFC follow-up`
+
+This means IFC can govern:
+
+- pre-session low-risk coordination
+- inter-session follow-up
+- post-session acknowledgements, logistics, and controlled artifact transfer
+
+It should not be used as a replacement for bounded vault computation.
+
+### 1.4 Non-IFC messages
+
+If IFC is the default membrane, the architecture needs an explicit rule for plain out-of-vault messages that are not IFC-wrapped.
+
+The long-term target should be:
+
+- production: blocked by default unless sent via an explicitly non-sensitive channel policy
+- development: optional bypass for iteration
+
+The important thing is to make this policy explicit. Otherwise "default membrane" degrades into "membrane for only the flows we remembered to wrap."
+
+## 2. Modern IFC Envelope and Policy Model
+
+The existing IFC machinery in `vfc` remains strong in concept:
+
+- signed message envelopes
+- label algebra over confidentiality, integrity, and boundedness
+- label receipts and policy hashes
+- capability grants
+- HIDE semantics
+
+What needs updating is the semantic surface. The old IFC policy model still reflects earlier purpose buckets such as `MEDIATION` and `NEGOTIATION`. Current AgentVault has moved toward more explicit contract fields and richer session semantics, so IFC should do the same.
+
+### 2.1 Envelope model
+
+Keep the existing cryptographic envelope model, but modernize the policy inputs around it.
+
+Recommended message fields:
+
+- `message_id`
+- `sender`
+- `recipient`
+- `payload`
+- `label`
+- `ifc_policy_hash`
+- `label_receipt`
+- `message_class`
+- `topic_code`
+- `session_relation`
+- `related_session_id` (optional)
+- `related_receipt_id` (optional)
+- `grant_id` (optional)
+
+### 2.2 Message classification
+
+`message_class` should be functional, not contextual. Context belongs in `session_relation`.
+
+Recommended initial `message_class` values:
+
+- `LOGISTICS`
+- `CONSENT`
+- `REFERENCE`
+- `ARTIFACT_TRANSFER`
+- `CLARIFICATION`
+- `ESCALATION_TRIGGER`
+
+Recommended initial `session_relation` values:
+
+- `PRE_SESSION`
+- `POST_SESSION`
+- `STANDALONE`
+
+This separation makes policy evaluation cleaner than using relational labels like `FOLLOW_UP` or `SESSION_ADJACENT` inside `message_class`.
+
+### 2.3 Policy inputs
+
+The IFC policy engine should evaluate at least:
+
+- label confidentiality / integrity / boundedness
+- `message_class`
+- `topic_code`
+- `session_relation`
+- current context label
+- grant scope and expiry, if a grant is present
+- operator-selected policy bundle
+
+Policy outputs remain:
+
+- `Allow`
+- `Hide`
+- `Escalate`
+- `Block`
+
+Interpretation:
+
+- **Allow** — deliver into active agent context
+- **Hide** — quarantine as a hidden variable; do not deliver into active reasoning context
+- **Escalate** — this message should be converted into session formation
+- **Block** — reject outright
+
+### 2.4 HIDE semantics
+
+HIDE is worth preserving. It is one of the strongest ideas in the original IFC design because it gives a third path between permissive delivery and simple rejection.
+
+However, the design constraint needs to be explicit:
+
+**HIDE must not become silent semantic smuggling.**
+
+Hidden material must remain quarantined strongly enough that it cannot influence active reasoning except through:
+
+- explicit bounded inspection, or
+- explicit escalation into a more appropriate protocol path
+
+In practice, HIDE should remain mostly an internal control primitive, not a user-facing concept that leaks into most product surfaces.
+
+### 2.5 Escalation as a proto-agreement seed
+
+`Escalate` should not be a vague recommendation. It should return a structured seed that AFAL can consume.
+
+Recommended shape:
+
+- `recommended_topic_code`
+- `recommended_signal_family`
+- `recommended_policy_constraints`
+- `reason_code`
+- `source_message_id`
+- `grant_context`
+
+This keeps the system from falling back into prose at the exact moment a message becomes too sensitive for out-of-vault handling.
+
+### 2.6 Grants
+
+Capability grants should become the main authorization primitive for non-session flows.
+
+Conceptually:
+
+- **contracts** authorize bounded computation
+- **grants** authorize bounded communication
+
+A grant should be narrowly scoped and short-lived. Recommended fields:
+
+- issuer
+- audience
+- allowed `topic_code` or topic family
+- allowed `message_class` set
+- label ceiling
+- optional related session or receipt provenance
+- expiry
+- use count
+
+Bias strongly toward provenance-bound grants tied to an existing session or receipt. Avoid broad standing authority, which would recreate ambient trust through accumulated permissions.
+
+## 3. First Implementation Slice
+
+The first reintegration slice should be deliberately narrow. The goal is to prove the membrane concept in a place where IFC is obviously useful, not to revive the entire historical IFC surface at once.
+
+### 3.1 Scope
+
+Implement IFC as the default path for:
+
+- post-session follow-up
+- scheduling / logistics tied to an existing session or receipt
+- grant issuance and grant consumption for those flows
+
+Include an escalation stub in the API shape, but do not require a full end-to-end `Escalate -> AFAL -> Vault` path in the first slice.
+
+### 3.2 Why start here
+
+This is the easiest place for IFC to be clearly valuable:
+
+- there is already provenance from the prior session
+- the topic context is already bounded
+- the communication need is real but smaller than reopening a vault
+- grants can be minted naturally from a completed session or receipt
+
+This avoids speculative "general safe agent chat" and keeps the first slice grounded.
+
+### 3.3 Initial flow
+
+Recommended first flow:
+
+1. Two agents complete a vault session and receive a receipt.
+2. One side mints a narrow capability grant for approved follow-up or logistics.
+3. Subsequent out-of-vault messages are sent as IFC envelopes referencing the related receipt or session.
+4. The receiver evaluates each message and gets `Allow`, `Hide`, `Escalate`, or `Block`.
+5. If `Escalate` occurs, the system returns a structured escalation seed that can later feed AFAL session formation.
+
+### 3.4 Candidate use cases
+
+Good first-slice use cases:
+
+- "I acknowledge receipt of the bounded result."
+- "Here are three candidate times for the follow-up."
+- "I consent to the next bounded step."
+- "Here is a pointer to the artifact we agreed to exchange."
+
+Bad first-slice use cases:
+
+- substantive compatibility or mediation reasoning
+- open-ended bargaining
+- any communication that is effectively trying to continue the vault session in prose
+
+Those should either block or escalate.
+
+### 3.5 Minimal product and protocol requirements
+
+The first slice should add:
+
+- an architecture note defining IFC's modern role
+- a minimal message envelope profile for post-session and logistics messages
+- grant issuance and verification for those messages
+- a clear policy for plain non-IFC messages in the selected surfaces
+- logging / receipts sufficient to debug `Allow` / `Hide` / `Escalate` / `Block`
+
+It should not yet add:
+
+- broad pre-session IFC chat
+- free-form negotiation inside IFC
+- a full replacement for AFAL or vault session semantics
+
+## 4. Open Design Questions
+
+The following questions remain, but they do not block the first slice:
+
+- Should some very low-risk channels auto-wrap plain messages into a lowest-tier IFC envelope, or should all production flows require explicit IFC wrapping?
+- What exact `topic_code` ontology should IFC use when no active session exists?
+- Should grants be minted only by completed receipts, or also by explicit user/operator action?
+- How much of HIDE should be surfaced in developer tooling versus kept entirely internal?
+- When escalation is wired end-to-end, should AFAL treat the escalation seed as a proposal hint or as a more formal proto-agreement object?
+
+## 5. Recommendation
+
+Reintegrate IFC as the default out-of-vault communication membrane, but do so through a narrow, session-adjacent first slice.
+
+The architectural target is:
+
+- **AFAL** for session admission
+- **Vault contracts** for bounded computation
+- **IFC** for bounded communication and context-flow control outside sessions
+- **A2A** as an optional carrier for either AFAL or IFC payloads
+
+This restores IFC as a structurally necessary part of the system rather than a dormant historical subsystem.
diff --git a/docs/architecture/negotiation-fixtures.md b/docs/architecture/negotiation-fixtures.md
new file mode 100644
index 0000000..da2bb95
--- /dev/null
+++ b/docs/architecture/negotiation-fixtures.md
@@ -0,0 +1,98 @@
+# Negotiation Fixtures
+
+> Status: Draft fixture note
+> Related: [agentvault-negotiation-protocol.md](agentvault-negotiation-protocol.md), [negotiation-wire-format.md](negotiation-wire-format.md)
+
+## 1. Purpose
+
+This note records three lightweight negotiation fixtures that can later become protocol vectors or tests.
+
+## 2. Fixture A: Convergent Salary Alignment
+
+### Initial proposal
+
+- `topic_code = salary_alignment`
+- `signal_family = overlap_signal`
+- `acceptable_schema_refs = [overlap_signal_v1, overlap_signal_v2]`
+- `required_policy_refs = [corporate_confidentiality]`
+- `acceptable_profile_refs = [balanced_reasoning, conservative_reasoning]`
+- `round_budget = 3`
+
+### Counterproposal
+
+Counterparty narrows to:
+
+- `acceptable_schema_refs = [overlap_signal_v1]`
+- `acceptable_profile_refs = [balanced_reasoning]`
+
+### Acceptance
+
+Resolved agreement:
+
+- `schema_ref = overlap_signal_v1`
+- `policy_refs = [corporate_confidentiality]`
+- `profile_ref = balanced_reasoning`
+- `program_ref = overlap_estimator_v2`
+
+Expected result:
+
+- agreement accepted within round budget
+- deterministic execution contract compiled
+
+## 3. Fixture B: Incompatible Terms
+
+### Initial proposal
+
+- `topic_code = project_scope`
+- `signal_family = mediation_triage`
+- `required_policy_refs = [strict_privacy_mode]`
+- `round_budget = 3`
+
+### Counterparty response
+
+Counterparty can only accept:
+
+- `signal_family = compatibility_signal`
+- `required_policy_refs = [corporate_confidentiality]`
+
+### Expected result
+
+- no resolved agreement
+- protocol terminates with `REJECT_AGREEMENT`
+- agent-visible reason codes remain coarse, for example:
+ - `INCOMPATIBLE_TERMS`
+
+## 4. Fixture C: Round Budget Exhausted
+
+### Initial proposal
+
+- `topic_code = relationship_future`
+- `signal_family = compatibility_signal`
+- `acceptable_schema_refs = [compatibility_signal_v1, compatibility_signal_v2]`
+- `round_budget = 3`
+
+### Negotiation path
+
+1. proposal sent
+2. counterproposal sent
+3. second counterproposal still does not converge on one resolved agreement
+
+### Expected result
+
+- negotiation halts when `round_index == round_budget`
+- protocol terminates with `REJECT_AGREEMENT`
+- principal-visible outcome can safely be:
+ - "No acceptable bounded agreement was reached."
+
+## 5. Direction
+
+These fixtures are intentionally simple.
+
+Their role is to pressure-test:
+
+- agreement object shape
+- resolved acceptance semantics
+- coarse reject behavior
+- explicit round-budget behavior
+
+Once the wire format and registry artefacts stabilize, these can become concrete JSON test vectors.
diff --git a/docs/architecture/negotiation-registry-artefacts.md b/docs/architecture/negotiation-registry-artefacts.md
new file mode 100644
index 0000000..cb4eac2
--- /dev/null
+++ b/docs/architecture/negotiation-registry-artefacts.md
@@ -0,0 +1,155 @@
+# Negotiation Registry Artefacts
+
+> Status: Draft architecture note
+> Related: [agentvault-negotiation-protocol.md](agentvault-negotiation-protocol.md), [protocol-spec.md](../protocol-spec.md)
+
+## 1. Purpose
+
+This note sketches the registry artefacts needed to support structured bounded-computation negotiation in AgentVault.
+
+It is intentionally lightweight. The goal is to define the shape of the artefacts and their compatibility links before governance and wire formats are frozen.
+
+## 2. Artefact Types
+
+The minimum negotiation registry should contain four artefact types:
+
+- `signal_family`
+- `schema`
+- `policy_bundle`
+- `standard_offer`
+
+Model profiles and prompt/program artefacts already exist conceptually in the system and can be referenced directly by negotiation.
+
+## 3. Signal Family Artefact
+
+A `signal_family` defines the semantic class of bounded result the session is meant to produce.
+
+Suggested fields:
+
+- `signal_family_id`
+- `version`
+- `semantic_intent`
+- `admitted_schema_refs`
+- `admitted_program_refs`
+- `bounded_parameter_kinds`
+
+Example families:
+
+- `overlap_signal`
+- `compatibility_signal`
+- `mediation_triage`
+- `feasibility_signal`
+
+### 3.1 Role
+
+`signal_family` is the semantic anchor of negotiation.
+
+It answers:
+
+- what kind of bounded computation is this?
+- how should the output be interpreted?
+- which schemas and programs are even valid choices?
+
+## 4. Schema Artefact
+
+A `schema` defines one concrete bounded realization of a signal family.
+
+Suggested fields:
+
+- `schema_id`
+- `version`
+- `schema_hash`
+- `signal_family_id`
+- `json_schema`
+- `entropy_class`
+- `output_notes`
+
+### 4.1 Role
+
+The schema fixes:
+
+- output structure
+- output field set
+- boundedness / entropy shape
+- machine validation surface
+
+Each schema should belong to exactly one signal family.
+
+## 5. Policy Bundle Artefact
+
+A `policy_bundle` defines execution and disclosure constraints relevant to negotiation and execution.
+
+Suggested fields:
+
+- `policy_bundle_id`
+- `version`
+- `policy_hash`
+- `policy_scope`
+- `constraints`
+- `compatible_signal_families` (optional)
+
+Example bundles:
+
+- `corporate_confidentiality`
+- `strict_privacy_mode`
+- `relationship_sensitive_mode`
+
+## 6. Standard Offer Artefact
+
+A `standard_offer` is a content-addressed pre-composed agreement template.
+
+Suggested fields:
+
+- `offer_id`
+- `version`
+- `offer_hash`
+- `topic_code`
+- `signal_family`
+- `default_schema_ref`
+- `required_policy_refs`
+- `acceptable_profile_refs`
+- `program_ref` or derivation rule
+- `default_bounded_parameters`
+
+### 6.1 Role
+
+A standard offer gives agents a simple default path.
+
+Most sessions should start from a standard offer and only fall back to richer negotiation when the standard offer does not fit.
+
+## 7. Compatibility Rules
+
+Compatibility should be declared in the registry, not inferred ad hoc at runtime.
+
+Minimum compatibility rules:
+
+- a `signal_family` declares its admitted schemas
+- a `signal_family` declares its admitted programs, unless programs are fully derived
+- a `schema` belongs to exactly one `signal_family`
+- a `standard_offer` references only compatible artefacts
+- bounded parameter kinds must be admitted by the selected `signal_family`
+
+This allows incoherent combinations to fail early, before execution contract compilation.
+
+## 8. Governance Surface
+
+These compatibility mappings are also a governance surface.
+
+Adding a new schema to a signal family or a new standard offer to the registry changes what negotiations can successfully produce.
+
+This note does not define governance policy, but the system will eventually need a clear ownership and review model for:
+
+- who may define new signal families
+- who may attach schemas/programs/policies to them
+- how compatibility mappings are versioned and reviewed
+
+## 9. Direction
+
+The intended shape is:
+
+- signal families define semantic classes
+- schemas define concrete bounded realizations
+- policy bundles define execution constraints
+- standard offers define default pre-composed agreement templates
+
+These artefacts should all be content-addressed or otherwise unambiguously versioned, so that negotiation and execution remain machine-verifiable.
diff --git a/docs/architecture/negotiation-wire-format.md b/docs/architecture/negotiation-wire-format.md
new file mode 100644
index 0000000..646a229
--- /dev/null
+++ b/docs/architecture/negotiation-wire-format.md
@@ -0,0 +1,146 @@
+# Negotiation Wire Format
+
+> Status: Draft wire-format sketch
+> Related: [agentvault-negotiation-protocol.md](agentvault-negotiation-protocol.md), [negotiation-registry-artefacts.md](negotiation-registry-artefacts.md)
+
+## 1. Purpose
+
+This note sketches an initial JSON wire format for structured bounded-computation negotiation in AgentVault.
+
+It is intentionally draft and should not yet be treated as normative.
+
+## 2. Envelope Shape
+
+Every negotiation message should share a common envelope:
+
+```json
+{
+ "version": "AV-NEGOTIATE-V1",
+ "negotiation_id": "uuid",
+ "message_type": "PROPOSE_AGREEMENT",
+ "proposal_id": "uuid",
+ "round_index": 1,
+ "round_budget": 3,
+ "sender": "alice",
+ "created_at": "2026-03-11T16:00:00Z",
+ "body": {}
+}
+```
+
+Common fields:
+
+- `version`
+- `negotiation_id`
+- `message_type`
+- `proposal_id`
+- `round_index`
+- `round_budget`
+- `sender`
+- `created_at`
+- `body`
+
+## 3. Agreement Shape
+
+The draft agreement object should look like:
+
+```json
+{
+ "topic_code": "salary_alignment",
+ "signal_family": "overlap_signal",
+ "acceptable_schema_refs": [
+ "schema:overlap_signal_v1",
+ "schema:overlap_signal_v2"
+ ],
+ "required_policy_refs": [
+ "policy:corporate_confidentiality"
+ ],
+ "acceptable_profile_refs": [
+ "profile:balanced_reasoning",
+ "profile:conservative_reasoning"
+ ],
+ "acceptable_program_refs": [
+ "program:overlap_estimator_v2"
+ ],
+ "bounded_parameters": {
+ "entropy_tier": ["E8", "E12"]
+ },
+ "preference_order": {
+ "schema_refs": [
+ "schema:overlap_signal_v2",
+ "schema:overlap_signal_v1"
+ ],
+ "profile_refs": [
+ "profile:balanced_reasoning",
+ "profile:conservative_reasoning"
+ ]
+ }
+}
+```
+
+## 4. Message Bodies
+
+### 4.1 PROPOSE_AGREEMENT
+
+```json
+{
+ "agreement": { "...": "..." }
+}
+```
+
+### 4.2 COUNTER_AGREEMENT
+
+```json
+{
+ "agreement": { "...": "..." },
+ "reason_codes": ["INCOMPATIBLE_TERMS"]
+}
+```
+
+The initial wire format should bias toward coarse agent-visible reason codes.
+
+More specific diagnostics can be relay-visible without being counterpart-visible.
+
+### 4.3 ACCEPT_AGREEMENT
+
+```json
+{
+ "resolved_agreement": {
+ "topic_code": "salary_alignment",
+ "signal_family": "overlap_signal",
+ "schema_ref": "schema:overlap_signal_v1",
+ "policy_refs": ["policy:corporate_confidentiality"],
+ "profile_ref": "profile:balanced_reasoning",
+ "program_ref": "program:overlap_estimator_v2",
+ "bounded_parameters": {
+ "entropy_tier": "E8"
+ }
+ },
+ "resolved_agreement_hash": "64hex"
+}
+```
+
+`resolved_agreement` must contain one concrete selection for every execution-relevant dimension.
+
+### 4.4 REJECT_AGREEMENT
+
+```json
+{
+ "reason_codes": ["NO_ACCEPTABLE_AGREEMENT"]
+}
+```
+
+## 5. Direction
+
+This format is intended to stay:
+
+- small
+- typed
+- deterministic
+- compatible with future signing and hashing rules
+
+The next stage would be to freeze:
+
+- exact field requirements
+- canonicalization rules
+- signature rules
+- the allowed reason code set
diff --git a/packages/agentvault-demo-ui/public/app.js b/packages/agentvault-demo-ui/public/app.js
index d585ff3..7d03312 100644
--- a/packages/agentvault-demo-ui/public/app.js
+++ b/packages/agentvault-demo-ui/public/app.js
@@ -17,6 +17,7 @@
stopBtn: $('stop-btn'),
resetBtn: $('reset-btn'),
newRunBtn: $('new-run-btn'),
+ replayLink: $('replay-link'),
statusChip: $('status-chip'),
statusText: $('status-text'),
// Chat panels
@@ -64,6 +65,7 @@
var totalEvents = 0;
var reconnectNotice = null;
var terminalAgents = {};
+ var suppressSseReconnectWarning = false;
// ── Init vault card manager ────────────────────────────────
VaultCardManager.init(els.vaultEvents);
@@ -385,18 +387,34 @@
}
// ── SSE ────────────────────────────────────────────────────
+ function closeLiveEventStream() {
+ suppressSseReconnectWarning = true;
+ if (eventSource) {
+ eventSource.close();
+ eventSource = null;
+ }
+ }
+
function connectSSE() {
if (eventSource) eventSource.close();
+ suppressSseReconnectWarning = false;
eventSource = new EventSource('/api/events');
eventSource.onmessage = function (e) {
try { handleEvent(JSON.parse(e.data)); }
catch (err) { console.error('SSE parse error:', err); }
};
eventSource.onerror = function () {
+ if (suppressSseReconnectWarning) return;
console.warn('SSE reconnecting...');
};
}
+ if (els.replayLink) {
+ els.replayLink.addEventListener('click', closeLiveEventStream);
+ }
+ window.addEventListener('pagehide', closeLiveEventStream);
+ window.addEventListener('beforeunload', closeLiveEventStream);
+
// ── Status polling ─────────────────────────────────────────
async function pollStatus() {
try {
diff --git a/packages/agentvault-demo-ui/public/index.html b/packages/agentvault-demo-ui/public/index.html
index 446a7ac..520cca9 100644
--- a/packages/agentvault-demo-ui/public/index.html
+++ b/packages/agentvault-demo-ui/public/index.html
@@ -8,7 +8,7 @@
-
+