Skip to content

feat: add service inspection profile and DACS-5 reconciliation guards#25

Open
mj-deving wants to merge 7 commits into
mainfrom
mj-inspect-service-profile
Open

feat: add service inspection profile and DACS-5 reconciliation guards#25
mj-deving wants to merge 7 commits into
mainfrom
mj-inspect-service-profile

Conversation

@mj-deving

@mj-deving mj-deving commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a generic Directory service-inspection handoff for every listing and makes the bundled DACS-5 reconciliation updates explicit.

Service inspection

  • GET /api/dacs/inspect-service/{listingId}/{version}?seller=...
  • a directory-service-profile envelope containing listing identity, artifact profile, source descriptor, maturity, limitations, and links
  • a relative inspection.href affordance in listing discovery
  • an Inspect service / verifier-handoff panel on service pages
  • OpenAPI, JSON Schema, manifest, and regression coverage

The seller query is required because listing IDs are seller-scoped; missing or blank values fail closed instead of selecting the first matching catalog entry.

DACS-5 reconciliation alignment

This branch also carries two independently tested Directory correctness updates:

  • DACS-Standard #254: a shared-index phaseSummary.kind mismatch is divergence.
  • DACS-Standard #255: without an authoritative absence policy, both buyer and seller copies are required before Directory reputation attribution.

Safety and claim boundary

  • Discovery uses a relative inspection.href, not request-host-derived absolute URLs.
  • The schema uses uri-reference for the handoff.
  • The profile labels itself as a roster maturity hint, not reputation evidence and not source truth.
  • It does not change bundleCount, claim live paid history, or fetch arbitrary external sources.
  • The inspection profile is listing-level metadata, not service-specific sample execution.

Validation

Merged current Community main at 0881fe455cca8622e737307b42e71cdc67440846.

  • focused inspection/contract tests: 11/11 passed
  • full test suite: 127/127 passed
  • bun run typecheck: passed
  • bun run build: passed
  • git diff --check: passed
  • final branch review: no actionable findings

The build emits the existing local NEXT_PUBLIC_DIRECTORY_URL warning when no public origin is configured.

@mj-deving
mj-deving force-pushed the mj-inspect-service-profile branch from 266da2a to 63f23c3 Compare July 15, 2026 10:32
@mj-deving

Copy link
Copy Markdown
Contributor Author

Pushed two focused Directory hardening consumers on top of #25:

  • 1618814 pins Listing preserve-unknown verification against the DACS-Standard #259 / SIG-5 boundary: inert unknown signed fields are preserved in the hash scope, tampering/removal invalidates the signature, and unknown executable phase kinds still fail closed.
  • 634eca4 requires both buyer and seller copies before Directory reputation attribution, matching the #255 absence-evidence posture: a single valid copy is not enough to count reputation without authoritative counterparty absence.

Validation:

  • bunx tsx --test test/listing-verification.test.ts (3/3)
  • bunx tsx --test test/current-indexer.test.ts test/verification.test.ts (30/30)
  • bun run test (58/58)
  • bun run build
  • bun run typecheck
  • git diff --check

@randomblocker

Copy link
Copy Markdown
Contributor

Reviewed on current main (merged main into the branch locally — clean, auto-resolved the #31 label changes). npm run typecheck clean, 59/59 tests, npm run build passes and emits /api/dacs/inspect-service/[listingId]/[version].

The inspection profile itself — clean and honest ✅

The advertised surface is a pure catalog-data projection: no outbound fetch (no SSRF), JSON-only via catalogJson, relative inspection.href (no request-host injection), and the envelope explicitly self-labels ["roster maturity hint", "not reputation evidence", "not source truth"] with noReputationClaim/noLivePaymentClaim. The service-page panel is static React JSX (no dangerouslySetInnerHTML). It does not touch bundleCount or claim paid history. Good, careful work.

⚠️ Scope concern: this PR silently changes core reputation verification

Beyond the inspection surface, the diff also lands two DACS-5 reconciliation changes that aren't mentioned in the title or summary:

  1. currentReconciliation.tsphaseSummariesDiverge now includes kind in the compared facts (implements DACS-Standard #254, merged 2026-07-15).
  2. currentReconciliation.ts + indexer.tsrefsVerified changed from (sellerOk || buyerOk) to (sellerOk && buyerOk), requiring both copies (implements DACS-Standard #255, merged 2026-07-15).

I checked both against the merged rulings and they're correct: #254 classifies a shared-index kind mismatch as divergence, and #255 makes an unfound second copy indeterminate absent a configured absence policy — so requiring both copies is the right fail-closed behavior for a directory with no absence policy. Both are covered by explicit tests (#254 same-index phase kind mismatch must be excluded, #255 requires authoritative absence before one-copy attribution).

So the substance is sound — but a PR titled "add Directory service inspection profile" that silently alters which deals count toward reputation is exactly what the audit's step 4 warned against ("implement the standards changes as separate auditable PRs"). Even when correct, bundling spec-gated verification changes into a feature PR is how a subtle reputation regression could slip past review one day. This one didn't, because the changes happen to be right and tested.

Recommendation: the cleanest outcome is to split the #254/#255 reconciliation changes into their own PR (they stand alone and close concrete standards work), leaving this PR to the inspection profile. If you'd rather not split, at minimum re-title/expand the summary to disclose that it implements #254 and #255 — reviewers and git log shouldn't have to discover that from the diff.

Merge-readiness

Branch is BEHIND main and has no CI run yet (predates the workflow). It'll need an update-from-main to trigger typecheck · test · build before it can merge under branch protection.

Net: no correctness or security blocker; the ask is transparency/scope hygiene on the bundled verification changes.

…ofile

# Conflicts:
#	reference-implementations/dacs-directory/app/api/dacs/listings/route.ts
#	reference-implementations/dacs-directory/app/service/[seller]/[listingId]/[version]/page.tsx
#	reference-implementations/dacs-directory/src/catalog/types.ts
#	reference-implementations/dacs-directory/test/discovery-contract.test.ts
@mj-deving mj-deving changed the title feat: add Directory service inspection profile feat: add service inspection profile and DACS-5 reconciliation guards Jul 23, 2026
@mj-deving

Copy link
Copy Markdown
Contributor Author

Updated at 258ce7fe5070409f69599909213b87d05f1a8ad4.

  • merged current Community main (0881fe455cca8622e737307b42e71cdc67440846) into the existing branch and resolved the four overlapping Directory surfaces additively
  • changed the title and body to disclose the bundled #254 phase-kind divergence and #255 two-copy reputation guards explicitly
  • fixed an adjacent inspection ambiguity found during fresh review: seller is now a required, nonblank lookup key in both the route and OpenAPI contract
  • local verification: 11/11 focused tests, 127/127 full tests, typecheck, production build, and final branch review clean
  • GitHub typecheck · test · build, including browser regressions: passed

The branch is current and ready for maintainer re-review.

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