Skip to content

chore(db): renumber 433_catalog_adagents → 434 to break dup deadlock#3256

Merged
bokelley merged 1 commit into
mainfrom
bokelley/fix-433-dup
Apr 26, 2026
Merged

chore(db): renumber 433_catalog_adagents → 434 to break dup deadlock#3256
bokelley merged 1 commit into
mainfrom
bokelley/fix-433-dup

Conversation

@bokelley

Copy link
Copy Markdown
Contributor

Summary

PRs #3235 (auto-provision verified-domain) and #3244 (catalog UNION reader) both landed migration 433_*.sql simultaneously. This breaks the filename validator in migrate.ts at boot, and the "No duplicate migration numbers" CI check fires on every open PR.

This is a one-file rename: 433_catalog_adagents_lookup_index.sql434_catalog_adagents_lookup_index.sql. Standard "last in, last numbered" convention — the catalog migration from PR #3244 landed second.

No SQL change, no code references either filename (migrations are loaded by directory scan), so this is a pure file rename.

Why this needs its own PR

The duplicate-migration check unions PR-branch + main file lists, then looks for duplicate number prefixes. Even if a feature PR renamed the migration on its branch, the union would still contain both 433_* files (because main has them both). The fix can only land via a PR that ends with main itself having no duplicate. Hence this single-purpose change.

Verification

  • npx tsx server/src/db/migrate.ts --validate → applies cleanly: 432_publishers_overlay → 433_auto_provision_verified_domain → 434_catalog_adagents_lookup_index.
  • No grep hits for either filename outside server/src/db/migrations/.
  • Pre-commit (test:unit + dynamic-imports + typecheck) green.

Impact

Unblocks every open PR currently failing on:

  • No duplicate migration numbers
  • Built migrations against Postgres

🤖 Generated with Claude Code

PRs #3235 (auto-provision verified-domain) and #3244 (catalog UNION reader)
both landed `433_*.sql` simultaneously. The filename validator in
`migrate.ts` rejects duplicate version prefixes at boot, and the
"No duplicate migration numbers" CI check fires on every open PR's union
view of (PR + main) since the duplicate is on main itself. Every open PR
is currently blocked at both gates.

Renaming the second-landed of the two — `433_catalog_adagents_lookup_index.sql`
from PR #3244 — to `434_*`. Standard "last in, last numbered" convention.
No SQL change, no code references either filename (migrations are loaded
by directory scan), so this is a pure rename.

Verified locally: 432 → 433 (auto_provision) → 434 (catalog_adagents)
applies cleanly with no errors.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@bokelley bokelley merged commit f638d0e into main Apr 26, 2026
12 of 13 checks passed
@bokelley bokelley deleted the bokelley/fix-433-dup branch April 26, 2026 14:00
bokelley added a commit that referenced this pull request Apr 26, 2026
…up at 434 (#3259)

PRs #3256 and #3257 both attempted to fix the original 433 collision
from #3235/#3244 in parallel from different conductor workspaces:

- #3257 (merged 13:56 UTC) renamed auto_provision: 433 → 434
- #3256 (merged 14:00 UTC) renamed catalog: 433 → 434

Net result: now 434_auto_provision and 434_catalog both exist on main.
Migration runner throws again, every PR's dup-check fails again.

Restore catalog to 433. Auto_provision stays at 434. Envs that
deployed between #3257 and #3256 would have recorded:
  schema_migrations: (433, catalog), (434, auto_provision)
This commit aligns disk back to that state — no mismatch, no
re-application.

CI's "No duplicate migration numbers" check on this PR will fail
because the union of (PR files: 433_catalog) and (main files:
434_catalog, 434_auto_provision) still shows a 434 dup. Must be
admin-merged. After this lands, every other PR's check should clear.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Apr 26, 2026
PR #3256 (catalog 433 → 434) and #3257 (auto_provision 433 → 434) both
landed within minutes of each other. Both renamed their respective 433
to 434, recreating the duplicate at the new number.

Renumbering catalog to 435 — auto_provision landed first per git log
order (#3257 merged 09:56 vs #3256 at 10:00 UTC), so it keeps 434.
Local migrate confirms 432 → 434 → 435 applies cleanly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Apr 26, 2026
…ol reference (#3249)

* feat(addie): self-knowledge docs — audience pages + auto-generated tool reference

Addie has been fabricating capability answers ("does AAO support X?", "how do
I do Y in the dashboard?", "what flag does claude mcp add take?") because
there is no canonical "what can Addie / what can the AAO site do" reference
for her to search_docs against. This PR builds that reference.

Three audience-specific pages under docs/aao/:
- users.mdx — member-facing (sign in, certification, perspectives, listings)
- org-admins.mdx — org-admin-facing (tier, billing, brand.json, agents)
- aao-admins.mdx — internal staff (escalation triage, editorial, system
  settings); noindex: true so it stays out of public search engines but
  remains in Addie's filesystem-indexed corpus

One auto-generated reference page:
- addie-tools.mdx — every registered Addie tool (224 across 14 capability
  sets + 18 always-available + 2 always-available-admin + 40 ungrouped).
  Generated from the source of truth — server/src/addie/tool-sets.ts plus
  the AddieTool[] exports in server/src/addie/mcp/*.ts — using the
  TypeScript Compiler API for AST extraction (no module-load side effects,
  no DB needed at build time)

Tooling:
- scripts/build-addie-tool-reference.ts — the generator. Walks every
  *-tools.ts file plus knowledge-search.ts and docs-search.ts, parses
  AddieTool literal definitions out of *_TOOLS array exports, and renders
  grouped MDX. Includes --check mode for CI.
- npm run build:addie-tools — regenerate
- npm run test:addie-tools — parity check, fails if the page is stale

This solves the problem the OAuth escalation surfaced (Addie fabricates
when she has no source of truth to consult). search_docs already indexes
docs/ filesystem-wide, so these pages are searchable immediately by Addie
without any further wiring.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(addie-tools): escape MDX-hostile characters in tool-reference output

Pre-push lint caught literal '<!-- STATUS: <code> -->' fragments inside two
brand-domain tool descriptions, plus '< 30 days' / '< 90 days' less-than
operators in two others — MDX 3 reads any of these as malformed JSX.

Generator now HTML-escapes all '<' to '&lt;' in tool descriptions. Tool
descriptions are LLM-facing prose; they don't legitimately contain JSX or
HTML tags, so escaping unconditionally is safe and renders identically.
The MDX comment marker on line 6 was already corrected to {/* */} form.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* refactor(addie): remove rules-content duplicated by docs/aao/, fix anon deflect

The self-knowledge work introduced docs/aao/ as the authoritative source for
"what can Addie / what can the AAO site do" questions. This removes the
hardcoded rules content that's now duplicated in those pages, replaces it
with one search-first rule, and fixes a separate bug that was making Addie
deflect on tools she actually has.

knowledge.md (-56 lines):
- Removed "## Membership Tiers and Certification Access" — tier table, seat
  types, what each tier adds, certification access rules, and the full Q&A
  block. All content lives verbatim in docs/aao/org-admins.mdx and
  docs/aao/users.mdx. Replaced with a 3-line pointer + the proration
  exception (which is the one piece of policy worth keeping in-prompt).

behaviors.md (-76 lines):
- Removed "## Adagents Validation" — covered by validate_adagents tool
  description in docs/aao/addie-tools.mdx + org-admins.mdx setup section.
- Trimmed "## Publisher and Agent Setup, Testing, and Compliance" 26 lines
  → 4 — kept the diagnostic-tool-list rule, removed the duplicated setup
  chain (which is in org-admins.mdx).
- Removed "## Working Groups" — covered by the member tool set in
  addie-tools.mdx.
- Removed "## Billing & Subscription Management" — single sentence pointing
  at get_billing_portal, covered by the tool description.
- Removed "## Member Profile Management" — covered by tool descriptions.
- Removed "## Perspectives Browser" — covered by list_perspectives tool
  description + users.mdx.
- Trimmed "## Account Linking" — kept the 2-line "thanks for linking"
  acknowledgment behavior; removed the get_account_link tool walkthrough.
- Added "## Capability Questions: Search docs/aao/ First" — the single
  rule that replaces all of the above. Tells Addie: search before answering
  capability questions, don't invent if you don't find.

behaviors.md "## Anonymous Tier Awareness":
- Rewrote the rule to lead with what tools anonymous users DO have rather
  than what they don't, fixing the deflection-bias the older language was
  encouraging.

member-context.ts (the source of the bug):
- The anonymous user-context block was telling Haiku "You do NOT have
  documentation search or protocol research tools" — flatly wrong, since
  search_docs / get_doc / search_repos / search_resources / get_recent_news
  are all in ANONYMOUS_SAFE_KNOWLEDGE_TOOLS and registered globally for
  anonymous chat. This was the load-bearing line behind the geo_proximity
  refusal observed empirically against prod. Replaced with an accurate
  enumeration of what's available + a "do not refuse before trying" rule.

redteam-scenarios.ts (+8 scenarios, aao-self-knowledge category):
- aao-cert-1: Does Explorer unlock Tier 2/3 certification?
- aao-tier-1: Difference between Explorer and Professional?
- aao-upgrade-1: Upgrade proration mid-period?
- aao-listing-1: Diagnose adagents.json properties not appearing
- aao-tools-1: What tools for member profile management?
- aao-perspective-1: How do I publish a perspective?
- aao-anon-1: Search the docs for "geo_proximity" (was the bug)
- aao-fabricate-1: Can you delete my AAO account? (must refuse, not invent)

Local verification (docker compose stack with this branch's rules):
- All 8 new aao-self-knowledge scenarios pass (8/8).
- 12 existing-suite failures are pre-existing baseline issues in unrelated
  categories (governance, openrtb, privacy, accountability, gaps) — they're
  about banned ritual phrases and length-cap on short questions, neither
  of which this commit touches. None of the failed scenarios test removed-
  rule territory.

Net: ~130 lines removed from Addie's prompt per turn; capability questions
now route through docs/aao/ instead of hardcoded duplicate text.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(ci): unblock TypeScript Build, check-seo, CodeQL on PR #3249

Three CI checks failed on the previous push:

1. **TypeScript Build** — `redteam-checks.test.ts` had a hardcoded
   `expect(RED_TEAM_SCENARIOS.length).toBe(25)` assertion that broke when
   I added the 8 aao-self-knowledge scenarios (33 total). Switched to
   `toBeGreaterThanOrEqual(25)` so the suite can grow without churning
   the test on every addition. The category-coverage assertions stay
   exact-match — those are the structural guarantee.

2. **check-seo** — All four `docs/aao/*.mdx` pages were missing the
   required `"og:title"` frontmatter field, and the SEO checker also
   requires the value to start with "AdCP". Added properly-formatted
   `og:title` to users/org-admins/aao-admins/addie-tools (the autogen
   script now emits it too).

3. **CodeQL high-severity alert** — `js/incomplete-multi-character-sanitization`
   on the dead `escapeMdxCell` function I wrote and never called.
   Removed it; the actual escaping logic is in `indentDescription` and
   handles only the `<` characters that show up in production tool
   descriptions.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(db): renumber 433 → 434 to break duplicate-migration deadlock on main

PRs #3235 (auto-provision verified-domain) and #3244 (catalog UNION reader)
both landed migration 433_*.sql simultaneously, blocking every open PR
at the "No duplicate migration numbers" and "Built migrations against
Postgres" CI checks.

Renaming the second-landed of the two — 433_catalog_adagents_lookup_index.sql
from PR #3244 — to 434_. Standard convention is "last in, last numbered."

Verified locally: migrations apply cleanly in order (432 → 433 → 434).
No code references either filename — migrations are loaded by directory
scan, not by name — so this is a pure file rename with no follow-on
changes needed.

Out of scope for this PR (addie self-knowledge), but it's the only path
to getting any open PR through CI right now. Filing here rather than
opening a separate one-line PR for speed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(db): bump catalog 434 → 435 — crossed paths with #3257 rename

PR #3256 (catalog 433 → 434) and #3257 (auto_provision 433 → 434) both
landed within minutes of each other. Both renamed their respective 433
to 434, recreating the duplicate at the new number.

Renumbering catalog to 435 — auto_provision landed first per git log
order (#3257 merged 09:56 vs #3256 at 10:00 UTC), so it keeps 434.
Local migrate confirms 432 → 434 → 435 applies cleanly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(db): re-sync migrations with main — catalog stays at 433

Main settled the migration race via #3259, which restored
433_catalog_adagents_lookup_index.sql to its original number after the
two-cycle dup at 434. My speculative 435 rename here is now wrong —
syncing with main's resolved state (433 = catalog, 434 = auto_provision).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Apr 26, 2026
… 438 (#3302)

PRs #3294 (addie_prompt_telemetry) and #3295 (org_membership_provisioning)
both landed migration 436_*.sql simultaneously, blocking every open PR
at the duplicate-migration CI check (same pattern as #3256 / #3259 fixed
the dual-433 dup last week).

Renaming the second-landed of the two — #3295's
436_organization_membership_provisioning_source.sql — to 438 because
437 is also taken by an unrelated 437_auto_provision_digest_sent_at.sql
migration that landed in the same window.

Pure rename — no SQL change. Migrations are loaded by directory scan,
not by name reference.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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