Split auto-generated principles sync MR per SSOT-owning team
## Problem
The weekly principles-sync auto-MR currently routes all affected distilled files through **one MR** (e.g. https://gitlab.com/gitlab-org/gitlab/-/merge_requests/235635 with 23 files changed). The only CODEOWNERS rule that fires on `/.ai/` points at 4 AI-tooling DRIs — so the merge can proceed with **1 approval from any of 4 people**, regardless of which domains the distilled content touched.
This is too coarse for cross-domain content. Each distilled file in `.ai/principles/distilled/<name>.md` is a domain-specific checklist derived from an SSOT doc owned by a specific team:
- `security.md` → `@gitlab-com/gl-security/appsec`
- `database-migrations.md` → `@gitlab-org/maintainers/database`
- `graphql.md` → `@gitlab-org/maintainers/rails-backend`
- `frontend-vue.md` → `@gitlab-org/maintainers/frontend`
- `qa-rspec.md` → `@abdwdd @alexpooley`
- etc. (~10–11 distinct teams across the current 23 principles)
AppSec review on the gem (see https://gitlab.com/gitlab-com/team-member-epics/access-requests/-/issues/43931) flagged this as the right thing to fix.
## Proposal
Refactor `Sync#publish` and `Sync::AutoMr#create_branch_and_mr` to **fan out by SSOT-team owner**:
- Add an `owner_team:` field per principle in `.ai/principles/manifest.yml`. Primary owner only; secondary teams go into the MR description as "request review from" mentions.
- Group affected principles by `owner_team`. For each unique team:
- Create branch `docs-sync/principles-<date>-<team-slug>` from `origin/master`.
- Write only that team's distilled files.
- Push and open one MR per team. CODEOWNERS routes the approval correctly because each MR only touches files the SSOT team owns.
- AGENTS.md, CLAUDE.md, and `.{agents,claude}/skills/gitlab-coding-principles/SKILL.md` are global (they embed the full routing table for all principles). Carve those out into a separate **tooling MR** routed to AI-tooling DRIs, since SSOT teams have no stake in their content.
- Same-day re-run idempotency: `find_open_mr_iid` becomes per-team; the script looks up each team's open MR and updates in place.
## Implementation outline
1. **Manifest schema**: add `owner_team:` per principle. Add a `team_slug:` for the branch name suffix (derived from team handle, e.g. `database` from `@gitlab-org/maintainers/database`).
2. **Sync::AutoMr#create_branch_and_mr**: replace the single-branch + single-MR flow with a per-team fan-out. Push N branches (one per affected team) plus 1 tooling branch.
3. **Sync::AutoMr#create_mr**: parameterise the title template by team. Add per-team description content (only that team's principles in the per-principle sections).
4. **Per-team idempotency**: `find_open_mr_iid` runs once per team branch. Same-day re-runs update each team's existing MR in place rather than creating duplicates.
5. **Specs**: new fixtures covering multi-team affected sets, tooling-MR separation, per-team idempotency on re-run, edge cases (only one team affected, no team-owner specified, etc.).
## Scope
This issue tracks **MR-C**, stacked on top of MR-A (https://gitlab.com/gitlab-org/gitlab/-/merge_requests/235272) and **independent of MR-B** (https://gitlab.com/gitlab-org/gitlab/-/merge_requests/235014). The CI YAML doesn't change.
## Out of scope
- Changing CODEOWNERS for the gem itself.
- Reworking how distillation triggers (still weekly schedule, still through the Duo Workflow API).
- Cross-team principles where the SSOT spans multiple owners: primary owner gets the MR; secondary teams are mentioned in description.
## Related
- AR sign-off conditions: https://gitlab.com/gitlab-com/team-member-epics/access-requests/-/issues/43931
- MR-A (gem + flow): https://gitlab.com/gitlab-org/gitlab/-/merge_requests/235272
- MR-B (CI job): https://gitlab.com/gitlab-org/gitlab/-/merge_requests/235014
- Example under-routed auto-MR: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/235635
- Parent epic: gitlab-org&21742
issue