Skip to main content

Fidelity, validity, negative knowledge and continuity

The quickstart and scenarios pages cover goal/state/next_action/evidence/rejected/constraints/open_questions and Contact Cards. A capsule can optionally carry four more things — Critical Context Units, validity conditions, negative knowledge items, and a parent capsule declaration. This page explains what each one honestly claims, and — just as importantly — what it does not claim. Every command on this page was run against v0.0.0 before this page was written; see Runnable scenarios below to reproduce them yourself.

This is a hypothesis, not a proven result

Same standing note as the overview and scenarios: none of what follows is a measured claim about how much time or rediscovery it actually saves. It is the mechanism; whether it helps is still being measured.

Critical Context Fidelity — a rendering claim, not a comprehension claim​

A Critical Context Unit is a sender-marked pointer naming one field (or one list item) the sender needs a recipient to preserve — capture's critical key, up to ten per capsule. ophiuchus inspect/receive --with codex assess each one and print a verdict:

  • preserved — this consumer's rendering carries the pointed-at field through.
  • unsupported — either this build's schema does not recognise the kind the unit points at, or this consumer path does not render that field.
  • unknown — no consumer path has been evaluated yet (the sender-side preview always shows this, because the recipient's own adapter decides on receive).
  • degraded — defined for a future consumer path that truncates or partially renders a field. Not reachable today: neither the Codex adapter nor the sender-side preview partially renders anything — each field is carried through whole or not at all.

Read this exactly as literally as it's stated:

This reports only what Ophiuchus serialized and rendered through its supported consumer adapter contract. It is not evidence that any model read, understood, remembered or obeyed this context.

A preserved verdict means the text reached the page Codex would read. It is not evidence Codex (or any model) read it, understood it, remembered it a turn later, or acted on it. Nothing in this build measures comprehension — only whether the byte-for-byte content of the field survived the trip from capsule to rendered Markdown.

Context Validity vs. TTL — two different systems, not one​

These are easy to conflate and answer different questions:

  • TTL (expires_at, --delete-after-read) obsoletes the whole capsule at a fixed wall-clock instant, regardless of content. It is a relay-enforced lifecycle mechanism — see the quickstart's TTL note.
  • A validity condition says one specific assumption inside the capsule was only ever asserted to hold under a stated condition, while the rest of the handoff may still be perfectly usable. The capsule can be well within its TTL and still have a declared assumption that no longer holds.

A sender declares conditions, never a verdict — capture's validity key, up to ten per capsule, three kinds:

  • git_paths — a list of relative path globs unchanged since a base_commit (defaulting to the capsule's own grounding commit). The only kind this build can actually verify, because git is the one system Ophiuchus is already allowed to interrogate locally.
  • time_window — valid only while evaluated before a declared not_after deadline.
  • declared_scope — free text naming what the handoff applies to (e.g. "the auth module"). Always evaluates as unverifiable — this is a sender declaration, displayed as one, never independently checked or trust-scored.

Whether a condition still holds is computed fresh, on whichever machine evaluates it (inspect or receive --with codex) — never written into the capsule, never carried from the sender's machine. A verdict about someone else's environment, computed anywhere but the reading machine at read time, is stale the instant conditions there change.

Per-condition verdicts:

  • valid — the declared condition currently holds on this checkout.
  • stale — every declared path changed (for git_paths), or the deadline has passed (for time_window).
  • partially_stale — some but not all declared paths changed (git_paths only).
  • unverifiable — declared_scope always; or a git_paths/time_window condition this machine could not evaluate (grounding commit absent, no declared paths evaluated, unrecognised kind).

The aggregate across required conditions is the worst-of, with one deliberate judgement call: a stale condition mixed with an unverifiable one still aggregates to partially_stale, not unverifiable — once something is known-bad, the aggregate stays loud about the known-bad part rather than letting an unrelated "could not check" quietly outrank it. A receive --with codex on a capsule whose declared conditions have moved prints exactly this on stderr:

warning: CONTEXT VALIDITY — partially_stale (2 required condition(s) not
valid; ids: `vc-window, vc-scope`). Validity compares the sender's declared
conditions against this machine's checkout only. It is not a trust,
authority or correctness judgement, and it verifies no system outside this
repository.

That limitation note is the whole point: validity says something about this machine's checkout, never about trust, authority, or correctness in any broader sense.

Circinus boundary​

Validity is deliberately not the thing Circinus answers. Ophiuchus's own product framing draws this line explicitly:

Ophiuchus: How does useful context move? Circinus: Where did information come from, what authority did it have, and what may it influence?

Context may cross a boundary. Authority must not cross it implicitly.

declared_scope is never trust-scored, and a valid verdict is never a statement about provenance or authority — it is a statement about whether a declared git path changed or a declared deadline passed, nothing more. See docs/product/north-star.md's "Circinus boundary" section in the repository for the full reasoning.

Negative knowledge lifecycle — a record, not authoritative policy​

capture's existing rejected field (plain text) is untouched. A capsule can additionally carry negative_knowledge: a structured record of one approach tried and ruled out, up to ten per capsule, each with a hypothesis, a why_invalid, and a state:

  • rejected (default) — a live rejection.
  • superseded / revalidated — retired: a later item or a later capsule has moved past this one.

An item's computed standing is:

  • still_applicable — every validity condition the item's applies_while references currently reads valid.
  • revalidation_required — at least one referenced condition reads stale or partially_stale. This is the one standing that fires a notice — "something concrete was observed to have changed since this rejection was written."
  • applicability_unknown — no applicability was recorded, a referenced condition is unverifiable, or the state isn't one this build recognises. This is deliberately not the same as revalidation_required: "I couldn't check" is not "something changed."
  • retired — state is superseded or revalidated, unconditionally.

Negative knowledge answers "what has this sender already tried and ruled out," referenced against the capsule's own validity conditions by condition_id — it is not a second validity system. And it is explicitly not authoritative policy: Ophiuchus never verifies that a rejection was correct, and it never forbids retrying an approach. A recipient with new evidence may always retry, regardless of what standing a negative knowledge item shows. retry_if is free prose the sender wrote about when a retry might be worth revisiting — it is rendered as data and is never parsed or evaluated by any code in this repository, now or planned.

Parent/delta continuity — one declared predecessor, a bounded local diff​

A capsule may declare parent_capsule_id (capture --parent <id>) — the one predecessor handoff it continues from. ophiuchus inspect on a capsule that declares a parent walks the local .ophiuchus/ sibling files (bounded, at most ten hops) and computes a delta against the immediate parent, when its body is still available:

  • inherited / added / dropped — id-set differences for critical/validity/negative_knowledge between parent and child.
  • carried_over / added / absent_here — counts only, never text, for the four bare-text fields (evidence/rejected/constraints/ open_questions). Ophiuchus genuinely cannot tell "this open question was resolved" from "dropped" from "reworded" for a field with no stable per-item id — the counts-only shape is what keeps the report honest about that limit rather than implying a judgement it can't make.
  • resolved — a child CriticalUnit.supersedes pointer that names a unit_id actually present in the parent's critical units.
  • A negative knowledge item's state transition between parent and child (e.g. rejected → revalidated).

This is deliberately not Team Context or shared memory — the anti-goal this repository's own guardrails name most explicitly. A few structural facts that keep it that way:

  • Single parent, never a list. One predecessor, not a DAG to merge.
  • No persistent lineage graph, no index, no cache. Every walk reads the ancestor files fresh from disk; nothing is stored beyond the one ContinuityReport the caller receives and discards.
  • The relay never learns any of this. ophiuchus.lineage never contacts a relay; the chain is walked entirely over local files.
  • Bounded depth. At most ten hops; a longer chain reports as bounded, not as an error.

This compares this capsule against an ancestor handoff that happens to still be on this machine. It is not a record of the full history of this work, and an ancestor that is gone is reported as gone, never reconstructed.

Benchmark evidence vs. a model's own self-report​

The repository also ships an internal continuation benchmark (continuation_benchmark/, evaluation tooling only — never shipped in the wheel, never wired into the ophiuchus CLI). Its runner ships exactly one executor today, oracle, and its own report schema refuses to build unless its first disclaimer line is present, verbatim:

Executor 'oracle' replays each benchmark case's own committed ground truth. These numbers measure whether the scoring pipeline is correct, deterministic and reproducible — they are NOT evidence that any model, agent, or Ophiuchus Context Capsule achieved this continuation correctness. No live recipient session was run, and results are identical across every arm by construction, so no comparison between arms can be read from this report.

This matters here because it is the same underlying discipline as FIDELITY_LIMIT_NOTE above, applied one level up: a number produced by replaying committed ground truth, or a "preserved" verdict produced by checking whether text reached a rendering, is not a model's own claim about what it understood — it is Ophiuchus checking its own mechanics. Where the benchmark's Critical Context Preservation Rate and Stale Context Misuse Rate are scored from executor-declared evidence rather than from ophiuchus.capsule.fidelity/validity directly, its own schema quotes FIDELITY_LIMIT_NOTE verbatim to say so.

Separately, and more fundamentally: nothing on this page, and nothing the benchmark corpus measures, is evidence toward Ophiuchus's actual falsification question. The benchmark measures North-Star metrics 1–5 (correctness, rediscovery avoided, repeated-rejected-hypotheses avoided, TTUC, efficiency) against a committed synthetic corpus, using this repository's own scoring pipeline. It is not, and cannot become, external validation:

HORO-207's falsification measurement requires a real external evaluator running the comparison independently, and it measures North-Star metrics 6–7 (voluntary reuse, willingness to pay) — nothing this module touches.

No number derived from anything on this page may be reported as market or product validation.

Current support boundary — one real pipeline, not a matrix​

There is exactly one real adapter pipeline in this repository: ClaudeCodeProducer (producer only) → CodexConsumer (consumer only). There is no reverse path, no second consumer, and — despite how "Claude vs. Codex" sounds — no tools-by-tools matrix. The four semantic tracks documented above (fidelity, validity, negative knowledge, continuity) are rows; a small, fixed support-level taxonomy is the only other axis. Three cells of that matrix are named gaps rather than fabricated passes — FidelityResult.DEGRADED, the fidelity rule for "a field this consumer's schema knows but doesn't render" (unreachable because the Codex adapter's supported-field set is exactly this build's full field set), and a degraded/partial negative knowledge standing (ADR-0017 states this has no standing by design). Recipient-aware compilation — tailoring what a capsule emphasizes per recipient role or tool — is a real idea this project has evaluated and explicitly not shipped: today's benchmark executor is arm-invariant by construction (it replays committed ground truth identically regardless of which comparison arm asked for it), so there is no live-agent signal yet to justify building one. See docs/adapter-conformance-matrix.md and docs/adr/0022-recipient-aware-context-not-yet.md in the repository for the full record.

Explicit non-goals​

None of the above is, or is a step toward:

  • shared memory or a permanent team knowledge base,
  • owner/routing discovery ("who should get this"),
  • cross-capsule orchestration, or
  • trust/authority scoring of any declared condition.

These are this project's own named anti-goals, not an incidental omission — see docs/product/north-star.md's "Explicit anti-goals" and "Four Jobs" sections in the repository for the full framing. A preserved/valid/ still_applicable/resolved verdict is a fact about one capsule's mechanics, checked on one machine, never a claim about ownership, authority, team memory, or comprehension.

Runnable scenarios​

See Scenarios D–F for three end-to-end, copy-pasteable scenarios exercising fidelity, validity and continuity against the real CLI.

The Workflow Handoff Bridge — publishing a verified handoff (ADR-0025)​

Everything above this section is about moving a capsule between two Ophiuchus sessions. ophiuchus publish (v0.0.4) is a different, later step: it materializes a verified handoff where a team already works — a GitHub issue, a Jira ticket, a ClickUp task, a Slack message, a Teams channel message. See Scenario G for the runnable commands and the capability matrix; this section explains the concepts those commands rest on.

RECORD vs. DISCUSS are different artifacts, not one "send text" method. compose_record produces a durable, management-friendly view (title, goal, current state, evidence, rejected hypotheses, constraints, requested next action) for destinations that function as a system of record: GitHub, Jira, ClickUp. compose_discuss produces a shorter, conversation-friendly view (summary, why discussion is needed, evidence trimmed harder than RECORD's, requested discussion) for destinations that function as a conversation: Slack, Teams. An earlier design that flattened both into one send(text) method was considered and rejected (ADR-0025) precisely because the two profiles have different required fields and different update semantics — create-or-append for RECORD, create-or-reply-in-thread for DISCUSS. Neither view embeds a capsule's fidelity-critical fields raw; each is represented (a pointer, via the same assess_fidelity verdict machinery the Current support boundary section above describes), never silently dropped and never silently assumed preserved.

Preview is mandatory before publish, by construction, not by convention. ophiuchus publish ... --preview composes the view and renders it, and returns before any provider is looked up, any credential is read, or any network-capable client is constructed — the same scope-exclusion pattern send --preview already uses elsewhere in this CLI. This is not merely a documented best practice: the preview code path in ophiuchus publish cannot reach a provider lookup even if you wanted it to, because the branch returns first. A real publish without first previewing is allowed by the CLI (there is no flag that enforces the sequencing), but every example this project documents shows --preview first, because a provider write is a real, less-reversible external side effect — unlike a relay send, there is no corresponding delete-before-expiry operation for most of these providers.

Credential setup is provider-specific and always an environment variable, never a CLI flag. Each provider adapter reads its own OPHIUCHUS_<PROVIDER>_* variable(s) eagerly when the provider is constructed — e.g. OPHIUCHUS_GITHUB_TOKEN, OPHIUCHUS_JIRA_BASE_URL / OPHIUCHUS_JIRA_EMAIL / OPHIUCHUS_JIRA_API_TOKEN, OPHIUCHUS_CLICKUP_API_TOKEN, OPHIUCHUS_SLACK_BOT_TOKEN, OPHIUCHUS_TEAMS_ACCESS_TOKEN — never from a command-line flag, the same "a long-lived credential does not belong in shell history" reasoning this project already applies to database_url. DestinationCapability.credential_requirement is the authoritative, provider-declared statement of exactly what that credential needs to be able to do; see Scenario G's capability matrix for each provider's current value.

Retry, ambiguity, and idempotency. No provider shipped in this campaign confirms a native idempotency key for external writes (IdempotencyMode.NATIVE) — every one is CLIENT_MANAGED except Teams, which is honestly UNKNOWN (it implements no duplicate-write mitigation of its own beyond never retrying internally, and this build has not confirmed whether Microsoft Graph's channel-message endpoint is itself idempotent). idempotency_key is derived once, by the composer, as sha256(capsule_id + provider + destination_target + operation), and a CLIENT_MANAGED provider's caller is expected to persist (idempotency_key -> external_reference) before the external call and check it first on retry — the Delivery Receipt sidecar below is where that pair lives. The resulting PublicationOutcome/DeliveryReceipt status is one of three truthful values, never a fourth invented one: published (the provider confirmed the write), ambiguous (the call may have committed before a timeout or disconnect — this is reported instead of a false failed, because reporting definite failure here could contradict what the provider's own state already holds), or failed (a real, definitive rejection or error observed before any provider-side commit could plausibly have happened). An ambiguous outcome is never silently collapsed into either of the other two.

Delivery Receipt vs. ophiuchus history. ophiuchus history (described earlier on this page and in Scenarios) only ever knows about this machine's own relay send/receive calls — it has no field for an external provider reference and was never extended to have one, because its one-row-per-capsule shape cannot host N external deliveries for one capsule. Publishing instead writes to a separate, additive sidecar: one row per publication, carrying provider, operation, external_reference, status, idempotency_key, and a safe destination_alias label — never a provider access token, never the full published body, never a Contact Card value, and never the Context body as a second permanent copy. The two stores answer different questions and neither substitutes for the other.

Lifecycle asymmetry. Deleting a local Ophiuchus Context/history entry does not delete the external GitHub issue, Jira ticket, ClickUp task, Slack message, or Teams message it produced. A Delivery Receipt row for a deleted capsule becomes an orphaned-but-truthful record of "this was published" — that is correct, not a bug: the external artifact's own lifecycle is owned by its provider, never by Ophiuchus (ADR-0025 §6).

Explicit non-goals​

The Workflow Handoff Bridge extends Job 4 (durable record) and adds a bounded DISCUSS-publication capability — it does not turn Ophiuchus into a different product. None of the following is, or is a step toward:

  • bidirectional sync with any destination,
  • polling a destination's state back into Ophiuchus,
  • webhook ingestion from any destination,
  • automatic provider reconciliation,
  • treating any destination (GitHub, Jira, ClickUp, Slack, or Teams) as a canonical Context store,
  • Slack/Teams inbox or chat-client behavior — Ophiuchus posts a message or a reply; it never reads a channel back,
  • owner/channel-discovery intelligence,
  • persistent provider sync of any kind,
  • a universal-parity fiction across providers — the capability matrix in Scenario G is the honest record of what each adapter can and cannot do,
  • mass or implicit mention — mention_support is inert_only for every provider shipped in this campaign, by binding default, until a future ticket explicitly authorizes ACTIVE for one destination with its own security review.

These are the same binding non-goals ADR-0025 §7 names, restated here because this page is where a reader learns the mechanism, not just the command.