fix(api): AIN-183 P0-3 follow-up · tenant_handle suffix swap + tulkas sanitize#49
Merged
hizrianraz merged 1 commit intoMay 19, 2026
Conversation
…al-agent sanitize
Two issues surfaced after migration 0018 deployed:
1. Founder tenant lost bare 'ainfera-ai'. The 0018 backfill found two
prod tenants owning agents with owner_handle='hizrianraz' — first-by-id
kept bare 'ainfera-ai' (dormant artifact), second (active founder
tenant, owns Varda/Yavanna) got conflict suffix 'ainfera-ai-280f44'.
Marketing widget filters on bare 'ainfera-ai/varda' and finds zero
events.
2. Internal-agent name on tenant_handle. 0018 MIN(owner_handle) set one
tenant's handle to 'tulkas' (it owns the internal red-team agent
sacrificial-001 registered under owner_handle='tulkas'). The string
is now visible on /v1/audit/public — leak the AuditTicker allowlist
masks on marketing but the raw API still exposes.
## Phases (idempotent)
1. Free bare 'ainfera-ai': non-founder squatter renamed to
'inactive-<id-slice>'.
2. Promote: suffixed founder tenant (LIKE 'ainfera-ai-%' AND owns
hizrianraz-handle agent) renamed to bare 'ainfera-ai'. Limit 1 with
stable ORDER BY id in the sub-select.
3. Sanitize: any tenant whose tenant_handle ∈ {manwe, namo, aule, tulkas}
renamed to 'internal-<id-slice>'. Varda + Yavanna excluded — they're
public agents and their tenant_handles are intentionally surfaceable.
4. Invariants:
- If any founder agent exists, founder tenant must be on bare
'ainfera-ai'. (Fresh CI DB with zero agents skips this check.)
- No internal-fleet name may remain on tenant_handle.
Both raise RuntimeError on violation.
## Downgrade
Reconstructing the original conflict-suffix slice is impossible without
a backup. Downgrade is a no-op — restore from snapshot if rollback is
needed.
Closes: AIN-183 P0-3 follow-up (suffix swap + tulkas sanitization)
Discipline: #3 (internal agent name off tenant_handle), #11
|
You have used all Bugbot PR reviews included in your free trial for your GitHub account on this workspace. To continue using Bugbot reviews, enable Bugbot for your team in the Cursor dashboard. |
AIN-183 🟠 All-repos audit sweep — 14 repos × spec-vs-built + Discipline #3/#4/#11/#17 verification
Severity: 🟠 HIGH — comprehensive repo-level Discipline #1 + #17 auditFiled 2026-05-18 PM after AIN-153 + AIN-158 spec-vs-built audit revealed Aule shipping less than spec'd then marking parents Done. Pattern requires systematic verification across ALL 14 repos in the Founder directive: "Hard revert to In Progress and force the missing work. Also check all repos." ScopeFor each of the 14 repos in
14 repos to auditProduction-facing (Phase 1, urgent)
Agent-implementation (Phase 2)
Customer + tooling (Phase 3)
Audit deliverable per repoFor each repo, Aule produces a comment on this ticket with: ## Repo: ainfera-ai/<name>
### Spec match
- Stated purpose: <from README>
- Actual state: <from main branch traversal>
- Drift: <none / specifics>
### Recent Done tickets touching this repo
- AIN-XYZ — claimed: "..." → actual state: ✅ matches / ⚠️ partial / ❌ missing
### Production-vs-main drift
- Last deploy SHA: <sha>
- main HEAD: <sha>
- Drift: <none / files differ / etc>
### Grep results
- Founder PII: <count> matches → <files>
- Internal agent names in public: <count> matches → <files>
### Lock compliance
- D7-D37 references: <count>
- Discipline #6 corollary violations: <count>
### Recommendation
- ✅ Clean / ⚠️ Cleanup needed / 🔴 Active violation
### Tickets to file
- <list of child tickets needed if cleanup work surfaces>Audit commands Aule runs per repocd ~/code/ainfera-ai/<repo>
git pull origin main
# Discipline #3 grep
rg -i "hizrian|izzy|raz|fibromyalgia|adhd|snowboard|julius baer|sommelier" \
--type-not lock \
--type-not log \
-l
# Internal agent naming in public surfaces
rg -i "manwe|yavanna|namo|aule|tulkas" \
src/ app/ public/ docs/ README.md \
--type-not lock \
-l
# Discipline #4 author override check (last 50 commits)
git log -50 --pretty=format:'%h %an <%ae>' | rg -v "Aule <aule@" | head -20
# Production-vs-main drift (for deployed repos)
gh api repos/ainfera-ai/<repo>/deployments --jq '.[0:3] | .[].sha'
# Compare against `git rev-parse main`
# Spec vs files
ls -la docs/
cat README.md | head -30Acceptance gates
Out of scope
Connection
Founder authorizationPer "Hard revert to In Progress and force the missing work. Also check all repos" (2026-05-18 session 3.5 PM). |
3 tasks
hizrianraz
added a commit
that referenced
this pull request
May 23, 2026
…ce (#69) Final piece of the cross-repo AAMC retirement (paired with sdk #11+#12, mcp-server #12, ainfera-os #49, routing #2). Removes references to "AAMC voter" / "voter pool" / "Council" in code comments + display names + the (now-defunct) invariant test file. Changes: - adapters/openai.py: comment reframe — "AAMC voter pool" → "canonical routing backends". - adapters/upstream_aliases.py: same. - orm.py: drop the `aamc_voter` flag field-comment reference (the field itself stays — was repurposed as a generic catalog-eligibility flag; just rename the rationale in the comment). - routers/stats.py: leaderboard endpoint comment reframe. - services/response_normalizer.py: comment cleanup. - services/routing.py: comment cleanup. - scripts/seed_dev.py: display names reframed ("GPT-5.5 Pro (AAMC voter)" → "GPT-5.5 Pro"). - tests/integration/test_aamc_invariants.py → renamed to test_routing_backends_invariants.py. Test logic unchanged — it enforces the canonical 5-backend lock (Opus, GPT-5.5, Gemini, Grok, Mistral-Large), reframed away from the retired AAMC framing. No runtime behavior change. Pure vocabulary cleanup. Per Ontology v1.2 amendment (2026-05-22) which retired ATS/AAMC and folded their semantics into Routing (`q_empirical` for trust; `M_allowed` for eligibility veto). Ontology v1.3 (2026-05-23) further made Mithril the canonical product the doctrine leads with. Co-authored-by: Claude <noreply@anthropic.com>
3 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two issues surfaced after PR #47 (migration 0018) deployed to prod:
1. Founder tenant lost bare 'ainfera-ai' to a dormant duplicate
The 0018 backfill found two prod tenants owning agents with `owner_handle='hizrianraz'`. The first-by-id (dormant artifact, likely an early signup) kept bare `ainfera-ai`. The second — the active founder tenant that owns Varda + Yavanna — got the conflict suffix `ainfera-ai-280f44`. Marketing widget filters on bare `ainfera-ai/varda` and currently finds zero events.
2. Internal-agent name on tenant_handle
The 0018 MIN(owner_handle) backfill set one tenant's `tenant_handle` to literally `tulkas` — the tenant owning the internal red-team agent `sacrificial-001` (registered under `owner_handle='tulkas'`). The string is now visible on the raw `/v1/audit/public` endpoint. The AuditTicker allowlist on marketing masks it from the UI, but the raw API still exposes it.
Migration 20260519_0019
Four phases, all idempotent:
Both invariants raise on violation, aborting the migration.
Test plan
Downgrade
Reconstructing the original conflict-suffix slice from 0018 is impossible without a backup. Downgrade is a no-op — restore from snapshot if rollback is needed.
Closes: AIN-183 P0-3 follow-up
Discipline: #3 (internal-agent name off tenant_handle), #11