Skip to content

feat(addie): brand-tools MCP support for distributed brand.json (#4527)#4531

Open
bokelley wants to merge 1 commit into
mainfrom
bokelley/addie-brand-tools-4527
Open

feat(addie): brand-tools MCP support for distributed brand.json (#4527)#4531
bokelley wants to merge 1 commit into
mainfrom
bokelley/addie-brand-tools-4527

Conversation

@bokelley
Copy link
Copy Markdown
Contributor

Closes #4527.

Summary

Adds four Addie MCP tools that author and verify variant-5 Brand Canonical Documents and brand_refs[] pointer entries per the brand-protocol 3.1 spec (docs/brand-protocol/brand-json.mdx, ratified in #4505).

  • publish_brand_canonical_document — generate a variant-5 Brand Canonical Document with the brand's identity fields and validate it against the brand.json schema before returning. Hosting is left to the operator.
  • add_to_brand_refs — append a portfolio_entry pointer to a House Portfolio's brand_refs[], enforcing the Conformance section's cross-array uniqueness invariants (brand_id not in both brands[] and brand_refs[]; unique by domain and brand_id within brand_refs[]).
  • check_mutual_assertion — fetch the leaf's canonical document and its claimed house's portfolio, follow House Redirects on the house side (3-hop cap per Conformance), and classify the relationship into mutual / leaf_only / house_only / standalone / unverifiable.
  • notify_pending_verification — send the SHOULD-level notification email to the house's contact.email on leaf_only edges. Rate-limited per {leaf, house} pair at one notification per 24 hours via the new brand_assertion_notifications table. Gated behind BRAND_ASSERTION_EMAIL_ENABLED — defaults to log-only so the new send surface is opt-in.

Plumbing

  • New module server/src/addie/mcp/brand-canonical-tools.ts. server/src/addie/mcp/brand-tools.ts re-exports BRAND_CANONICAL_TOOLS + createBrandCanonicalToolHandlers so existing import sites get the full surface in one file.
  • Registered alongside the existing brand tools in three places: handler.ts (web Addie), bolt-app.ts (Slack Addie), and register-baseline-tools.ts (shared baseline).
  • New migration 478_brand_assertion_notifications.sql — table keyed on (leaf_domain, house_domain) with last_notified_at and notification_count. Insert-or-update is a single statement so concurrent notifies can't both clear the cooldown.
  • Schema validation: AJV against the source brand.json schema, with cross-file $refs (enums) preloaded synchronously at validator-compile time.

Trust-tier resolution detail

check_mutual_assertion enforces the spec's "standalone trumps third-party claim" rule by short-circuiting on house_domain absence — it never fetches the house when the leaf is silent. On the house side, it walks both house: \"<domain>\" and authoritative_location redirects up to 3 hops per Conformance.

Test plan

30 new unit tests in server/tests/unit/addie/brand-canonical-tools.test.ts. Coverage:

  • publish_brand_canonical_document validates against the real source schema (sub-brand, standalone, invalid brand_id, empty names, extra filtering, domain normalization).
  • add_to_brand_refs enforces all three uniqueness invariants from Conformance + variant-checks the house JSON + fetches when house_domain is supplied.
  • check_mutual_assertion covers all five tiers + redirect-chain following + 3-hop limit + failure modes.
  • notify_pending_verification rate-limits within 24h per {leaf, house} pair, lets a different leaf through, returns log_only when the feature flag is off (the default), and rejects invalid emails.
  • Tool surface: all 4 tools registered, handler factory wires each, JSON contract round-trips correctly.

Results: 30 passed / 30 in this test file; 3497 passed across the full npm run test:server-unit run (one pre-existing flaky LLM-routing test unrelated to this change). Typecheck clean.

Adds four Addie MCP tools that author and verify variant-5 Brand Canonical
Documents and brand_refs[] pointer entries per the brand-protocol 3.1 spec
(docs/brand-protocol/brand-json.mdx, ratified in #4505):

- publish_brand_canonical_document — generate a variant-5 doc with the
  brand's identity fields and validate it against the brand.json schema
  before returning. Hosting is left to the operator.
- add_to_brand_refs — append a portfolio_entry to a House Portfolio's
  brand_refs[], enforcing cross-array uniqueness (brand_id not in both
  brands[] and brand_refs[], unique by domain and brand_id within
  brand_refs[]).
- check_mutual_assertion — fetch the leaf and its claimed house, follow
  House Redirects on the house side (3-hop cap per Conformance), classify
  the relationship into mutual / leaf_only / house_only / standalone /
  unverifiable.
- notify_pending_verification — send the SHOULD-level email to the
  house's contact.email on leaf_only edges. Rate-limited per
  {leaf, house} pair at one notification per 24h via the new
  brand_assertion_notifications table. Gated behind
  BRAND_ASSERTION_EMAIL_ENABLED — defaults to log-only so the new send
  surface is opt-in.

Schema validation reuses the source brand.json schema with cross-file
$refs (enums) preloaded into AJV at validator-compile time.
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.

Addie brand-tools: MCP support for authoring Brand Canonical Documents + brand_refs[]

1 participant