Skip to content

feat(covenant): typed relations + the answer path — the symmetry breach closed#12

Merged
NetworkTheoryAppliedResearchInstitute merged 4 commits into
mainfrom
feat/covenant-relations
Jul 13, 2026
Merged

feat(covenant): typed relations + the answer path — the symmetry breach closed#12
NetworkTheoryAppliedResearchInstitute merged 4 commits into
mainfrom
feat/covenant-relations

Conversation

@NetworkTheoryAppliedResearchInstitute

Copy link
Copy Markdown
Contributor

Transplant of local 2bb081d onto the stack (temp-file debris stripped). Typed relations (trade / adjudication-conduct / verdict-satisfaction) live in the signed bytes with per-relation standing — no cross-relation pool is expressible. Every rating is answerable by the rated party, adjudicator included; annotation never erasure.

Stacked on #11; merge after it.

…fold

Executes the Merkle-now decision (Jodson, 2026-07-12), the stack plan's
highest-rework item, inside the only cheap window it will ever have: no
durable logs, no external consumers, no live witnesses.

- Head is now the RFC-6962 Merkle tree head over leaf IDs (leaves keep
  drops/leaf/v0; interior nodes carry drops/node/v1 — the 0x00/0x01
  discipline in canon-domain form, so leaves never replay as nodes).
- Inclusion proofs are audit paths: ~log2(size) hashes however large the
  log grows. This is the open-problem-8 floor made real — an entry-level
  phone verifies its covenant in a million-entry log with ~20 hashes.
- Consistency proofs are RFC-6962 subproofs; Log.ProveConsistency serves
  the witness's extension evidence, and Witness.Countersign consumes the
  proof instead of raw leaves.
- LogID moves to its own drops/logid/v1 tag (the chain-fold arity is gone);
  checkpoint and witness payloads bump to v1. Entry/leaf/content stay v0 —
  byte-identical derivations keep their tags.
- Exhaustive property suite: every leaf of every tree size to 33, every
  consistency pair to 33, tamper/truncation/padding/replay rejection, and
  the Log-level tie-in over a real appended log.

The un-checkpointed-order residual is unchanged (exactly CT's), and the
witness amnesia residual is unchanged; neither is papered over.

Signed-off-by: Jodson Graves <info@ntari.org>
…ber witnesses

The Part-IV plumbing, built as code with every stand-in labeled:

- Lifecycle log: a second per-operator Merkle log (domain-disjoint from the
  dialog log at every derivation) whose leaves are claim transitions —
  file -> adjudicate -> resolve -> seal, monotonic per claim, filed-first,
  seal-only-after-resolve (a clock never force-seals; dwell is a readable
  fact, never a verdict). Checkpointed and countersigned by the same
  witness machinery via the new VerifyAs/CountersignAs generic bindings.
- Filing intake: FilingCommitment (hash, type, timestamp, exchange ref —
  PII discipline at its hardest) + FilingReceipt, the witness's ONE write.
  Receipts carry an explicit independence label: the consumer API's
  in-process intake is operator-run and says so (independent=false), the
  stand-in until real intake witnesses run.
- Consumer API: dispute filing now lodges the commitment at the intake
  BEFORE the registry acts (the operator-absent-at-birth ordering, kept in
  miniature); every dispute transition appends to the lifecycle log; new
  surfaces for lifecycle checkpoints/claims, drops inclusion proofs
  (member-verifiable offline, ~log2(n) hashes), and the consistency proofs
  witnesses need.
- internal/relay: the witness relay — caches, relays, serves, fans out
  filings; decides nothing (which witnesses count, which checkpoint is
  official, and settlement all stay with readers); bypassable by design
  and tested as such.
- internal/witnesskit + cmd/witnessd: membership-as-witnessing (the
  problem-8 lever). Any member runs a witness: poll, verify (log identity
  re-derived, never taken on the relay's word), countersign, host the one
  filing write. cmd/witness-relay is the thin relay shell.
- Hermetic federation test: two member witnesses federate over the relay,
  the stand-in label DROPS, a forked checkpoint gathers no honest
  countersignature (refused by witnesses, not the relay), and filing
  fan-out yields two verifying, operator-independent receipts.

Named residuals, unchanged and unhidden: witness amnesia (restart =
trust-on-first-checkpoint), single-operator in-process intake labeling,
and no adjudicator key in cloudyd (no ruling transitions producible).

Signed-off-by: Jodson Graves <info@ntari.org>
…ch closed

The two demands the stack plan holds the covenant layer to, in code:

- Relations. Every assessment now carries one of three typed relations —
  trade, adjudication-conduct, verdict-satisfaction — INSIDE its signed
  bytes (domain bumped to cloudy/covenant/assessment/v1; a trade verdict
  can never replay as a conduct verdict). Standing is typed all the way
  down: per-relation distributions with NO cross-relation pool anywhere on
  the type — collapsing relations is the forbidden average committed
  across relations, and the shape now makes it inexpressible. Anchoring
  routes by relation: trade anchors on the sealed exchange as before; the
  adjudication relations anchor on REAL claim participation (Anchors gains
  Adjudicated), so the governance-relevant stream cannot be inflated by
  members who never touched a claim.
- Answers. Every claim is answerable: the rated party — the adjudicating
  operator included, which is the one place the architecture named the
  symmetry broken — attaches a signed, hash-only annotation to any
  assessment about them. One answer per assessment; the assessment is
  never edited, hidden, or diluted (tests pin the harm count unchanged
  beside its answer). The operator registers as a member of its own
  platform at construction (single participant identity), making it
  rateable and answerable through the same public surface as everyone.

API: assessments carry relation and return their ID; answers POST/GET at
/api/v1/assessments/{id}/answer(s); standing serves the three typed
relation views and nothing pooled. End-to-end test drives the loop the
architecture demanded: real claim -> conduct No Trust on the operator ->
operator's answer -> harm visible in its own stream, stranger's conduct
rating refused.

Note for review: dispute Withdrawal currently resolves the claim in the
lifecycle log; adjudication-conduct remains rateable while a claim dwells
(non-response is conduct), which is deliberate.

Signed-off-by: Jodson Graves <info@ntari.org>
Signed-off-by: Jodson Graves <info@ntari.org>

# Conflicts:
#	internal/consumerapi/api_slice2_test.go
#	internal/consumerapi/disputes.go
#	internal/consumerapi/server.go
@NetworkTheoryAppliedResearchInstitute
NetworkTheoryAppliedResearchInstitute merged commit ceafc4d into main Jul 13, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant