docs/backend-migration/plans/2026-04-24-snake-case-wire-realignment-plan.md
Team mode — coordinator + parallel teammates. Smaller scope than builtin-skill pilot: undo H1's directional mistake + flip the frontend's camelCase wire fields, no new features.
Companion specs:
aionui-backend/docs/backend-migration/specs/2026-04-24-snake-case-wire-realignment-design.md— authoritative contractAionUi/docs/backend-migration/specs/2026-04-24-snake-case-wire-realignment-design.md— frontend changes
Goal: Realign the builtin-skill pilot's wire surface with the
project-wide snake_case convention (origin/main dae96f8). Remove 21
rename_all = "camelCase" from skill.rs; flip 18+ backend tests; flip
5 frontend field-naming sites + their Vitest; rerun Playwright.
Team size: 1 coordinator + 3 role-teammates (backend-dev, frontend-dev, e2e-tester). No backend-tester / frontend-tester — scope is mechanical naming flips, devs self-test.
| Branch | Repo | Base | Owner(s) |
|---|---|---|---|
feat/backend-migration-coordinator | AionUi | (existing) | coordinator |
feat/backend-migration-builtin-skills | AionUi | current tip (has merge 259505156) | frontend-dev, e2e-tester |
feat/builtin-skills | aionui-backend | current tip (has merge 0fbccd6) | backend-dev |
No new branches — extend existing ones.
T0 (coordinator setup)
│
▼
T1 (backend-dev: remove rename_all=camelCase from skill.rs, flip 18+ tests,
verify skills_builtin_e2e + assistants_e2e green, cargo build to
refresh symlink)
│
▼
T2 (frontend-dev: flip 5 field-naming sites in ipcBridge + AcpSkillManager +
initAgent + GeminiAgentManager + ConversationServiceImpl, update Vitest
mocks, tsc+lint clean)
│
▼
T3 (e2e-tester: rerun Playwright 8 scenarios against the realigned pair,
audit any payload assertions for camelCase residue, flip if found)
│
▼
T4 (coordinator closure: merge, module log, handoff)
Critical path: T0 → T1 → T2 → T3 → T4. T2 STRICTLY depends on T1 (sending snake_case body before backend accepts it → 400 everywhere).
Owner: coordinator.
feat/backend-migration-coordinator; push.aionui-snake-case-realign.No new feature branches needed; teammates work on the existing branches.
Owner: backend-dev. Branch: feat/builtin-skills (aionui-backend).
Working dir: /Users/zhoukai/Documents/github/aionui-backend
TaskList, TaskGet taskId=<T1>, TaskUpdate in_progress owner=backend-devcd /Users/zhoukai/Documents/github/aionui-backend && git checkout feat/builtin-skills && git pull --ff-onlygrep -c 'rename_all = "camelCase"' crates/aionui-api-types/src/skill.rs → should report 21#[serde(rename_all = "camelCase")] from crates/aionui-api-types/src/skill.rs. Mechanical.grep -c 'rename_all = "camelCase"' crates/aionui-api-types/src/skill.rs → 0file_name now reject fileName; rename guards accordingly (test_read_builtin_resource_request etc.)test_materialize_response_serializes_camel → test_materialize_response_serializes_snake and flip assertion from json["dirPath"] to json["dir_path"]test_skill_list_item_deserializes_camel_case — rename and flip similarlygrep -E '"(conversationId|enabledSkills|dirPath|relativeLocation|isCustom|fileName)":' crates/aionui-app/tests/skills_builtin_e2e.rs → any hit must flip to snake_casegrep -E '(\.conversationId|\.enabledSkills|\.dirPath|\.relativeLocation|\.isCustom)' crates/aionui-app/tests/skills_builtin_e2e.rs → Rust-side struct access uses field names (unchanged by rename_all removal, field names were always snake_case in Rust). No change needed.cargo fmt --all -- --check cleancargo test -p aionui-api-types — 18+ flipped tests pass; whole crate 451+ passingcargo test --test skills_builtin_e2e 14/14 greencargo test --test assistants_e2e 44/44 greencargo clippy --workspace -- -D warnings — pre-existing red elsewhere is fine; no new warnings from skill.rs changescargo build --release
TMP=$(mktemp -d)
target/release/aionui-backend --local --port 25908 --data-dir "$TMP/data" &
# Should now return 200
curl -s -X POST http://127.0.0.1:25908/api/skills/builtin-skill \
-H 'Content-Type: application/json' -d '{"file_name":"auto-inject/cron/SKILL.md"}' | head -c 100
# Should now return 400
curl -s -X POST http://127.0.0.1:25908/api/skills/builtin-skill \
-H 'Content-Type: application/json' -d '{"fileName":"auto-inject/cron/SKILL.md"}'
# Same for materialize
curl -s -X POST http://127.0.0.1:25908/api/skills/materialize-for-agent \
-H 'Content-Type: application/json' -d '{"conversation_id":"probe","enabled_skills":[]}'
# Response check
curl -s http://127.0.0.1:25908/api/skills | python3 -c "import json,sys; r=json.load(sys.stdin)['data'][0]; print(sorted(r.keys()))"
# Expected: ['description', 'is_custom', 'location', 'name', 'relative_location', 'source']
git add -Afix(skill): revert H1 — realign skill.rs wire format to project-wide snake_case convention (dae96f8)git pushcargo build (debug) to refresh ~/.cargo/bin/aionui-backendOwner: frontend-dev. Branch: feat/backend-migration-builtin-skills (AionUi). Depends on: T1.
Working dir: /Users/zhoukai/Documents/github/AionUi
git pull origin feat/backend-migration-builtin-skillscd /Users/zhoukai/Documents/github/aionui-backend && git pull && cargo build (refresh symlink) In src/common/adapter/ipcBridge.ts:
listAvailableSkills response row fields: relativeLocation → relative_location, isCustom → is_custommaterializeSkillsForAgent request body: conversationId → conversation_id, enabledSkills → enabled_skillsmaterializeSkillsForAgent response: dirPath → dir_path readBuiltinRule and readBuiltinSkill: already use file_name, leave alone.
src/process/task/AcpSkillManager.ts:
SkillDefinition type and any interface that carries relativeLocation / isCustom — rename fieldsskill.relativeLocation → skill.relative_location, skill.isCustom → skill.is_custom{ file_name: skill.location } — leave alone (already correct)src/process/utils/initAgent.ts — call site that invokes materializeSkillsForAgent:
const { dir_path: dirPath } = await ipcBridge.fs.materializeSkillsForAgent.invoke({
conversation_id: conversationId,
enabled_skills: enabledSkills,
});
src/process/task/GeminiAgentManager.ts — if any explicit object key used for the invoke payload (not just variable shorthand), flip.src/process/services/conversation/ConversationServiceImpl.ts — cleanup call, same audit.tests/unit/acpSkillManager.test.ts:
listBuiltinAutoSkills.invoke response items — keep location (it's already lowercase, no change)listAvailableSkills.invoke response items — use snake_case keys (relative_location, is_custom)skill.relative_location / skill.is_custom access sitestests/unit/initAgent.materialize.test.ts:
materializeSkillsForAgent.invoke return value: { dir_path: '/tmp/x' }{ conversation_id: ..., enabled_skills: ... }grep -nE "(relativeLocation|isCustom|dirPath|conversationId|enabledSkills)" src/ --include='*.ts' --include='*.tsx' | grep -v __tests__ | grep -v '\.test\.'
conversationId / enabledSkills camelCase survivals in places where they're NOT wire-body (e.g. internal TS parameter names, loop variables — fine). Wire-body usages flipped.bunx tsc --noEmit cleanbun run lint --quiet — baseline unchangedbun run test --run tests/unit/acpSkillManager.test.ts tests/unit/initAgent.materialize.test.ts — greenbun run test --run — baseline unchanged (no NEW failures vs current)git add -Arefactor(skill): flip pilot-new field names to snake_case to match backend realignmentgit pushOwner: e2e-tester. Branch: feat/backend-migration-builtin-skills. Depends on: T2.
git pull~/.cargo/bin/aionui-backend target freshness: stat -Lf "%Sm" ~/.cargo/bin/aionui-backend — must reflect T1's buildbunx electron-vite build — refresh renderer bundlegrep -nE "(relativeLocation|isCustom|dirPath|conversationId|enabledSkills)" tests/e2e/features/builtin-skill-migration/ — any hit inside response/request body assertions must flip to snake_case.conversationId at the TypeScript level are fine (URL path is a string, not a body field).bun run test:e2e tests/e2e/features/builtin-skill-migration/docs/backend-migration/e2e-reports/2026-04-23-builtin-skill-migration.md with a "Run 3 — post-realign" section documenting the flip and the 8/8 result.Owner: coordinator. Depends on: T3.
/api/skills/builtin-auto and /api/skills/builtin-skill with snake_case bodies work end-to-end.docs/backend-migration/handoffs/coordinator-snake-case-realignment-2026-04-24.md.modules/skill-library.md with "Snake-Case Realignment 2026-04-24" section. Record the H1 mis-direction as a lesson.No PRs per user convention.
grep -c 'rename_all = "camelCase"' aionui-backend/crates/aionui-api-types/src/skill.rs returns 0file_name / conversation_id / enabled_skills all accepted (200); camelCase variants rejected (400)GET /api/skills response row keys: ['description', 'is_custom', 'location', 'name', 'relative_location', 'source']