# Passenger roster header aliases and content diagnosis ## Scope and gate - Feature task on `main`, sole worktree `/Users/andy/IdeaProjects/LWLT-AIBOT`, base `0282c30a2aa66435a193b96b17c0022420d881b3`. Main thread only. - Existing dispatch/readiness changes are the completed previous task in this conversation; preserve them. `.idea/` and existing ignored residue are unrelated and preserved. No other worktree or overlapping edits in the roster normalizer/tests. Overlap: Clear. - User authorizes compatibility for two observed header aliases and read-only validation of the supplied workbook contents. No source workbook edits, ERP import/access, task submission, deployment, restart or external sending. - Own roster normalizer, roster regression tests and this task record. No canonical memory or extension changes. ## Evidence and plan - Supplied XLS matches the reported attachment: 48128 bytes, SHA-256 `c11d17fd13607afc9c8a52bf2716a5e900a3a387137f88ba314e8dcf15e3d76d`. - Existing local conversion succeeds. Actual normalizer reproduces `roster_workbook_header_not_found`: `Sheet1!H2` is 出生地点 and `K2` is 有效期至. Other ten required fields are recognized, no duplicate semantic headers. - Add only the two approved exact aliases, preserve semantic uniqueness and fixed canonical output. Validate both aliases and duplicate/conflicting headers with synthetic records. - Run full local normalization/content inspection on the original file, report remaining content problems without inventing passenger facts. Keep passenger values out of tests, task records and logs. - Run required repository/type/control-plane/legacy/build checks; record results and any pre-existing check failures. ## Results - Normalizer `v1.5.1` accepts exact aliases 出生地点 → 出生地 and 有效期至 → 有效期. All 12 semantic source fields remain required and unique; canonical TSV remains the same 13 columns. Added synthetic equality and canonical/alias duplicate rejection coverage. No content normalization or ERP execution behavior was changed. - Original workbook passed conversion and complete normalization without editing it: header row 2, data rows 3–22, 20 passengers, unique sequential indices 1–20. All 60 date cells and all canonical text/identifier projections were independently compared with the converted sheet; zero mismatches. Source hash remained unchanged. - Names, English names, gender, birthplace, passport numbers, issue location, three date fields and remarks are populated for all 20 passengers. Phone is populated for 11; nine blank phones remain blank under existing rules. Merged remarks correctly project to their constituent passenger rows. No imported-field formulas need compatibility; the ordinary age column remains ignored. - Exactly one leader marker has both name and phone. Both independent and shared-child Program parser routes passed with synthetic local-only lookup context, 20 rows and leader_contact. These calls only validated content/operation contracts; no task, database, ERP or external call was made. No additional content compatibility is needed for this file. - Focused workbook tests 14/14; full control-plane 241/241 and legacy 402/402 (643 total); type check and build PASS. Repository checks 10/10 in a byte-verified isolated copy excluding secrets and pre-existing `.idea`/residue. Two legacy HTTP tests initially failed only because sandbox loopback listening was denied; approved loopback rerun passed all 402. Original unrelated files preserved. - Main-thread final read-only review PASS. No subagents, source workbook edits, live ERP import, service restart, deployment, commit or push. This compatibility is server-side; the extension release is unaffected. Existing `npm run dev` process needs a user-authorized restart to load the new source. - [Read-only evidence summary](../../../archive/evidence/2026-09-15/roster-header-aliases-01a0858b/README.md). ## Promotion candidates - Document accepted source aliases in canonical roster guidance after integration if needed; canonical ERP fields remain unchanged.