Skip to content

fix(dacs-directory): harden strict bundle verification#15

Open
cX3po wants to merge 2 commits into
mainfrom
cx3po/dacs-directory-strict-verifier
Open

fix(dacs-directory): harden strict bundle verification#15
cX3po wants to merge 2 commits into
mainfrom
cx3po/dacs-directory-strict-verifier

Conversation

@cX3po

@cX3po cX3po commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Submission checklist

  • Placed in reference-implementations/.
  • README states what the directory is and its DACS surface.
  • Conformance status is declared honestly as exercises-spec.
  • Documented setup and run instructions are unchanged.
  • Covered by the repository MIT license.
  • No secrets or private endpoints added.

What & why

Hardens the DACS directory’s strict deal verifier so signed artifacts count only when signer coverage, registered-copy identity, positional references, graph closure, and job/party bindings all agree. It also makes the browser verdict honest when cryptography is internally consistent but the copy has no registered address-role binding.

Changes

  • Enforces one shared current-bundle signer policy: unique buyer/seller roles, distinct Demos signing identities, correct anchor signer for single-party aborts, and full party coverage otherwise.
  • Binds legacy signatures to their declared Ed25519 algorithm/container and rejects ambiguous listing signature containers.
  • Requires exact positional ref kind/id/hash, agreement/evidence job and party binding, phase closure, cross-job rejection, and consistent transitive hashes.
  • Resolves and verifies rating, attestation, delivery, and supplementary evidence bindings; unsupported amendment paths fail closed.
  • Binds the browser’s unhashed anchoredByRole plus buyer/seller claims to the registered copy. Unregistered but internally consistent bundles show a neutral limited state, not a verified result.
  • Adds adversarial regression coverage for signer aliasing, malformed signature containers, ref substitution, graph escape, rating-role mismatch, and registered-copy spoofing.

Compatibility boundaries

The pinned legacy SDK cannot resolve/report non-empty ratings or amendments, so those legacy cases fail closed. Its strict helper still requires a phase attestationRef; the current-profile graph honors the current contract’s optionality.

Integration note

This branch was built and reviewed from main at 07a008a in parallel with #14. The branches overlap in the indexer/evidence-graph tests; if #14 lands first, this branch will be rebased, conflicts resolved, and all validation repeated before merge.

Validation

  • npm test — 37/37 pass
  • npm run typecheck — pass
  • npm run build — pass
  • Formal Sonnet + Opus Gate 2 review — approved with notes
  • Independent adversarial, compatibility, and strict-verifier reviews — approved; no high- or medium-severity findings remain
  • Phil-Sim — pass

Take or leave as useful.

@mj-deving

Copy link
Copy Markdown
Contributor

One verifier edge case looks worth fixing before this lands.

Finding: buildCurrentEvidenceGraph() now builds verifiedPhaseRefs from artifacts whose kind is only evidence or verify-result:

  • reference-implementations/dacs-directory/src/catalog/evidenceGraph.ts around the new verifiedPhaseRefs check

But top-level vetRecords are resolved earlier from raw.vetRecords as kind composite, and DACS-5 defines vetRecords: AttestationRef[] as composite verification records while making the top-level vetRecords[] / settlementEvidence[] arrays the authoritative attestation set (spec/DACS-5-VERIFY.md §10.4, vetRecords, settlementEvidence, and per-phase attestationRef text).

Why it matters: a normal vetted bundle whose vet phase phaseSummary[].attestationRef points at its already-verified composite vet record will now fail with phase attestation reference is outside the verified graph, even though that composite was already hash/signature/job verified through vetRecords[].

Suggested fix: include verified composite artifacts in verifiedPhaseRefs, or compare phase refs against all verified top-level phase-capable refs. I would also add a regression where phaseSummary[vet-credentials].attestationRef equals vetRecords[0].

Other local validation on head 78899aaaecb6f42ee949f28421edbb911f9febeb was good:

  • bun run test -> 37/37 pass
  • bun run typecheck -> pass
  • bun run build -> pass, with only the expected local NEXT_PUBLIC_DIRECTORY_URL warning

@cX3po

cX3po commented Jul 13, 2026

Copy link
Copy Markdown
Contributor Author

Good catch — fixed in ec82fb2. verifiedPhaseRefs now includes verified composite artifacts, so a vet phase whose attestationRef points at its already hash/signature/job-verified composite vet record resolves inside the graph instead of false-rejecting. Added the regression you suggested (phaseSummary[vet-credentials].attestationRef === vetRecords[0] must verify) — it fails against the pre-fix filter and passes after. Suite 38/38, typecheck + build green. The widening admits only verified composites (bundle-membership-, jobId-, and signature-bound), so no fail-open. Thanks for the careful read.

@mj-deving mj-deving left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified the ec82fb2 fix for my earlier finding.

The important path is now covered: verifiedPhaseRefs includes verified composite artifacts, and the new regression exercises a bundle whose phase attestationRef points at vetRecords[0].

Local validation on the PR head:

  • bun run setup
  • bun run test -> 38 passed
  • bun run typecheck
  • git diff --check origin/main...HEAD

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.

2 participants