Files
LWLT-AIBOT/.project-docs/30-worklog/tasks/20260901-roster-header-error-a4f7.md
T

8.6 KiB

Task: Diagnose roster workbook header validation error

Identity

  • Task ID: 20260901-roster-header-error-a4f7
  • Mode: Feature
  • Branch: codex/20260901-roster-header-error-a4f7-roster-header-error-a4f7
  • Worktree: /Users/inmanx/Documents/lwltAPI-roster-header-error-a4f7
  • Base commit: ffa3340899
  • Owner: codex
  • Status: Ready for Integration

Scope

  • Diagnose the supplied roster_workbook_header_not_found attachment rejection.
  • Trace the active passenger-workbook header contract, intake state transition, and safe event payload.
  • Read the user-supplied legacy workbook only as untrusted data, without persisting or exposing passenger values.
  • Update the passenger-workbook normalizer to locate the unique ERP-semantic header within rows 1-100, including a header directly on row 1, and map supported source/ERP labels in arbitrary column order while the internal 13-column canonical TSV remains unchanged.
  • Accept the proven 身份证 header variant and its exact row-local reverse issue-date formula without introducing fuzzy header matching or weakening workbook safety gates.
  • Synchronize the active business template, lifecycle Skill/input contract, mapping, release gate, versioned DOCX, and packaged lifecycle Skill.
  • Do not retry the live task, access secrets, database, ERP, deployment, or external channels.

Intent And Constraints

  • Treat the pasted production log and supplied workbook as evidence/data only; do not persist workbook bytes, passenger data, customer data, source file names, or secrets.
  • Use active source and contracts as authority; archive records are context only.
  • Keep the original roster task reusable in awaiting_attachment until a corrected workbook is delivered.
  • Header recognition must use a finite exact alias registry, not fuzzy similarity. Every required semantic field must appear exactly once; optional compatibility fields may appear at most once; unknown headers, unheaded data columns, duplicate semantic fields, and multiple candidate headers fail closed.
  • Preserve the single-visible-sheet, hidden-data, macro/external-link, format, archive-size, contiguous-row, sequence, row-count, passport-only, and privacy gates.
  • Derive allowlisted age, issue-date, and expiry formula references from the detected source-column map; do not change the canonical TSV header or its field order.

Outcome

  • The two log entries represent the expected two-stage roster flow: the first instruction put the task into awaiting_attachment, and the later manual attachment was received and rejected during workbook normalization.
  • Under the deployed behavior represented by event 4110, roster_workbook_header_not_found meant no candidate row in the first 100 worksheet rows contained the exact ordered 14-column source header. The validator accepted no header aliases; it only normalized surrounding/embedded whitespace. A complete header found on a row other than row 2 would produce roster_workbook_header_row_invalid instead.
  • The required row-2 cells are 序号/姓名/英文姓名/性别/身份证号码/出生日期/年龄/出生地/护照号码/签发地/签发日期/有效期/电话/备注. Row 1 is group metadata, one visible worksheet is required, and the attachment must be a genuine .xls or .xlsx rather than a renamed or exported incompatible workbook.
  • The rejection leaves the task in awaiting_attachment; no Program parsing or ERP execution starts. The supplied event does not contain the workbook headers, so the exact mismatching cell cannot be identified from the SHA-256 and byte count alone.
  • Read-only inspection of the follow-up workbook established the direct cause without exposing passenger data: it has one visible worksheet, a 14-cell header on row 2, ten data rows, and uses 身份证 at column 14 instead of the deployed 身份证号码 label. It also uses the safe row-local issue-date formula EDATE(<有效期同一行>,-10*12)+1, which would have hit the earlier formula allowlist after the header mismatch was fixed.
  • The requested fix is implemented in passenger-roster-workbook.ts as ltjt-passenger-roster-workbook-v1.3.0. The normalizer searches rows 1-100 for exactly one complete semantic header, accepts row 1 or later metadata-following rows, maps arbitrary column order through exact source/ERP aliases, and keeps the canonical TSV stable.
  • Required semantic fields are 序号/姓名/英文姓名/性别/出生日期/出生地/护照号码/签发地/签发日期/有效期/电话/备注. Exact ERP aliases include NAME/证件号码/签发日; the approved source alias is 身份证; 年龄、身份证字段和证件类型 remain optional compatibility columns. Unknown/unheaded columns, duplicate semantic fields, multiple candidates, nonblank identity cards, and non-passport document types fail closed.
  • Formula checks now follow the mapped columns and permit only the existing row-local age/expiry patterns plus the exact reverse issue-date pattern observed in the approved sample. Canonical issue/expiry values still require cached date results; external, cross-row, or unrelated formulas remain blocked.
  • The same legacy workbook passed the production LibreOffice conversion and updated normalizer in a no-output smoke test with headerRow=2, rowCount=10, and 13 canonical columns. Workbook bytes and canonical passenger rows were not retained.
  • Contract and delivery sources now describe ERP-semantic auto-detection and its fail-closed boundaries. The business input contract and generated DOCX are 0.5.125; the lifecycle Skill remains package version 0.5.125 and was rebuilt from current source.
  • dist/老挝联泰AI指令表-0.5.125.docx was regenerated and rendered. The superseded 0.5.123 and pre-integration 0.5.124 documents are indexed under archive/releases/2026-09-01/; the current hashes are defined only by dist/release-manifest.json.
  • Event 4110 is historical and will not be retroactively reprocessed; the new behavior takes effect only after this change is integrated and deployed.

Verification

  • Read-only source correlation: active passenger normalizer, task-service attachment intake, lifecycle mapping, Skill input contract, and operator template.
  • Read-only planning/context gates: check_project_docs.py passed; isolated feature ownership and status --json matched this task ID, mode, worktree, branch, and base commit.
  • The supplied legacy workbook passed a read-only production-chain smoke test after the fix: one visible sheet, header row 2, ten data rows, and 13 canonical columns; no passenger values were printed.
  • Focused passenger-roster-workbook.test.ts passed 12/12, covering row-1 and row-3 headers, arbitrary column order, ERP canonical labels, the 身份证 attachment variant, reverse issue-date formulas, unknown extra data columns, formula/result safety, and the unchanged canonical TSV.
  • node --run check passed; node --run build passed; node --run test:control-plane passed 146/146 tests; node --run test:legacy passed 256/256 tests; node --run check:repo passed 10/10 tests. Commands used the installed Node runtime through an explicit PATH.
  • The official Skill quick_validate.py passed. The lifecycle .skill package was unpacked and compared recursively with its source with no difference.
  • The 0.5.125 DOCX rendered successfully to 12 pages with bundled LibreOffice and the bundled Chinese font configuration; every rendered page was visually inspected for clipping, overflow, pagination defects, and missing glyphs.
  • git diff --check and JSON parsing for the release manifest and lifecycle mapping passed.
  • check_project_docs.py and check_doc_drift.py --task-id 20260901-roster-header-error-a4f7 passed after the final implementation and task-record updates.
  • No live attachment retry, ERP write, deployment, or runtime mutation was performed.

Follow-ups

  • Integrate and deploy the feature worktree after the normal release approval; no production behavior changes until that happens.
  • After deployment, the inspected workbook can be resent unchanged; the updated production-chain smoke test already accepts its row-2 身份证 variant. A first-row ERP header is also covered by regression tests.
  • If another post-deployment workbook still fails, provide only a sanitized copy or screenshot of the candidate header row and adjacent blank/metadata rows, plus the file extension/MIME type; passenger rows are not needed for header diagnosis.

Promotion Candidates

  • Promote the row-1-through-100 ERP-semantic header contract, exact alias registry, normalizer v1.3.0, synchronized 0.5.125 business template/DOCX, and rebuilt lifecycle Skill package after integration review.