Skip to content

Roster projection collapses attesters — a second monitoring node would make the aggregate nondeterministic #52

Description

@emooreatx

Blocks a second monitoring node. From the audit in FSD/MULTI_VANTAGE.md §2 (D7) and §5 P1.

The defect

src/roster.rs keys its projection solely on attested_key_id:

let entry = by_agent.entry(row.attested_key_id.clone()).or_insert_with();
if is_composite(&dim) { entry.capacity_composite = score; }

No attesting_key_id in the key. No precedence. No timestamp comparison. Last row in DB iteration order wins, and which one that is depends on ORDER BY and paging.

Today one node emits, so nothing collides. The moment a second observer exists — which is the entire point of FSD/MULTI_VANTAGE.md — two attesters about one subject silently overwrite each other, nondeterministically. The second node would make the aggregate worse, not better.

What to use instead

Persist ships the fold we are hand-rolling a worse version of. resolve_scores:

  1. applies precedence (withdraws / recants / supersedes) per attester,
  2. takes latest-wins per attester — each observer contributes exactly one head,
  3. aggregates by polarity (signed → mean of score×confidence; boolean-via-score → min),
  4. maps to a qualitative band from the scalar, contributor count and open_contradictions — heads whose sign opposes the believed sign.

open_contradictions is disagreement-between-observers as a first-class output — precisely the signal a second vantage exists to produce, and the thing /api/v1/status/vantage currently reconstructs by hand from local SQLite rows.

Also

Nothing reads health:liveness at all. Flow A filters dimension_prefixes = ["capacity:"]. A peer's liveness rows would replicate into our corpus and be consumed by nobody.

Acceptance

  • Projection keyed on (subject, attesting_key_id); no ordering dependence.
  • resolve_scores used rather than a hand-rolled reduction, so precedence and contradiction counting come for free.
  • A consumer of health:liveness exists, and /api/v1/status/vantage can be sourced from attestations grouped by attester rather than local rows grouped by region.
  • A test with two attesters disagreeing about one subject that fails against today's code.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions