# Current State

## Current Focus

ARR2.0 owns the deterministic XML-to-Finance path and the complete post-commit monthly publication path. The user
uploads XML once. After an accepted Finance commit, a dedicated worker consumes the durable outbox event, derives the
month and “更新至” watermark from committed `ARRIVAL` facts, publishes a validated workbook, and records a durable
download identity.

The company-channel detail generator now separates generation permission from calendar completeness: a current-month
or historical C/O period can be generated from the current committed Finance snapshot, while future report months stay
blocked. A not-yet-ended period keeps its fixed C/O cutoff and must be rerun after later source facts arrive if the final
workbook needs those facts. Duplicate publication of the same semantic snapshot is idempotent: the first validated
archive/result pair remains authoritative even if a retry rebuilds different XLSX bytes.

Monthly and company-channel XLSX generation is now Web/container deployable with Python/openpyxl only. The monthly
builder preserves sheet/header/row/formula/semantic validation, including `=R[row]*C[row]*G[row]`; the company builder
preserves its no-formula contract. Both publishers upload new workbook and `result.json` objects through the existing
immutable OSS adapter, while download routing retains controlled-local compatibility for historical records and keeps
`.web-jobs` queue state local.

## Daily Interaction Correction On 2026-08-11

- The local source now treats Daily Report rows as informational table rows rather than hidden log controls. It removes
  row click and Enter/Space activation, `role=button`, `tabindex`, selected-row decoration and pointer styling. The
  explicit needs-review button still focuses the manual-price panel, report downloads remain links, and only the
  top-right `任务日志` link opens the trace dialog.
- JavaScript syntax, all 81 `test_arr_web*.py` regressions and an isolated browser interaction check pass. The browser
  proved an ordinary `0805.XML` row leaves the dialog closed, the `待人工处理` control focuses a populated review panel,
  and the header utility opens the dialog; there were no console errors. This source change has not been pushed or
  deployed to `8.138.234.141:8765`, so the reported production behavior remains until a controlled release.

## Implemented Locally On 2026-08-11

- Implemented Booking parser 2.1.0 exact-header compatibility for the user-confirmed July legacy and August bilingual
  source templates. Readable approved header labels are normalized once and then compared as complete cells; the
  parser does not use substring, fuzzy, month, filename or worksheet-name matching. Existing aliases, 20-row header
  scan, duplicate-header failure and one-file/full-replacement activation semantics remain unchanged.
- Added parser/coordinator/i18n regressions. Four supplied workbooks now parse only their intended source sheets with
  the expected 79/111/16 (Lian Tai July), 67/100/16 (Lian Tai August), 235/447/432 (QBD July) and 104/218/212 (QBD
  August) rows/items/pending counts; two Daily/channel output workbooks remain rejected. No workbook, OSS object,
  draft, Booking batch, Finance fact or runtime process was changed. Deployment and a controlled post-restart
  read-only replay remain pending; QBD pending items are existing room-type review work, not a header failure.

## Diagnosed On 2026-08-11

- The reported company-channel Booking Excel parse failure occurs before object storage and draft persistence; a
  read-only database snapshot shows no new draft/artifact/batch and accepted batch 7 `july-test.xlsx` remains current.
  Exact parser replay isolates two cases: generated Daily/channel report workbooks are correctly rejected as the wrong
  input type, while current Lian Tai/QBD raw workbooks expose a parser compatibility defect because bilingual
  `Tour Code / 主团号` and hotel-detail headers do not equal the narrow exact alias allowlist. Replacing only those two
  headers in memory makes both raw workbooks parse, with original files and all business state unchanged. At diagnosis,
  the controlled alias expansion plus regression fixtures remained unimplemented. The user has now explicitly confirmed that both
  supplied formats must be supported. An exact three-alias process-memory probe recognizes only the intended sheet in
  each file: Lian Tai yields 67 rows/100 items/16 pending, while QBD 2026-08-06 yields 104 rows/218 items/212 pending;
  Daily/channel output workbooks remain rejected. This parser-only plan needs no migration or upload-page redesign, but
  the existing one-file/full-replacement activation model still cannot append two separately uploaded files.
- The exact desktop `0806.XML` deterministically fails processor 4.0.0 before any row or price processing with
  `XML_PARSE_ERROR` at line 1872, column 0. A `TRACE_TEXT` value contains one CESU-8 surrogate pair representing
  `U+1F389` even though the document declares UTF-8; the file is structurally closed and not truncated. This error is
  outside the pure-`PRICE_UNMATCHED` review boundary, so a formal failure with no manual-price panel is correct. The
  public deployment health endpoint remains 200. The source must be re-exported as valid UTF-8 and uploaded as a new
  task; no source, runtime, database, Finance, object-store or event state was changed during diagnosis.

## Artifact Conversion On 2026-08-11

- The user-supplied `8.6 修正.XML` was an XLSX package mislabeled with an XML extension. Its 181-row first sheet
  contains the flattened Opera fields needed by the ARR parser. A separate UTF-8 `RES_DETAIL` XML was reconstructed
  from those rows and passed strict XML/UTF-8 checks plus processor 4.0.0: 115 retained rows, 37 rate-code exclusions,
  29 duplicates and zero price-unmatched/review rows. The original workbook and malformed XML remain unchanged; no
  upload, Finance, database, object-store or event state was changed.

## Runtime Recovery On 2026-08-06

- Restored the local ARR login page after a reported opening failure. No Web process was listening and the retained
  Keychain-backed 8766 launcher still passed two removed Node/artifact-tool flags. Removed only those obsolete flags,
  then started one detached `arr2-web-8766` Screen session. `/healthz` returns 200 and root redirects to login with no
  browser console error. No login, upload, database, Finance or object-store mutation was performed. The existing
  reboot-persistent supervision follow-up remains open.

## Deployed And Accepted On 2026-08-06

- Reconciled the live migration-016 function/comment semantics without rerunning 016, created a privacy-minimized
  pre-017 checkpoint, and ran a transaction-only up/down probe. The first probe exposed a real legacy
  `artifact_callback`/`direct_mcp` run-constraint drift and rolled back cleanly; corrected 017 preserves that contract.
  Formally applied migration 017 SHA-256 `22a0578e…67b5b` under an advisory lock with all original business table counts
  unchanged. The guarded down migration SHA-256 is `9e85af0c…29101`.
- Closed incomplete runs 61–63 through the normal repository failure transition as
  `REVIEW_SCHEMA_MIGRATION_MISSING`, retaining all three source artifacts and adding only failure-audit events. The
  first post-migration upload, run 64, then exposed a 16-value/15-placeholder delivery INSERT bug and closed safely as
  `DATABASE_WRITE_FAILED`; the placeholder and a focused regression were corrected.
- Restarted Web as PID 24225 with all six authenticated readiness flags true. A subsequent exact-hash `0805.XML`
  upload is now run 65 / open review case `dailyreview-878e45ae132b73c131560299b3b2dcb3`: the live page shows the two
  expected Lian Tai keys and candidate prices at `0 / 2`, while confirmation remains disabled. PostgreSQL has one open
  revision-0 case, two unset items and one required event, with no daily XLSX, manual manifest, Finance version, run
  outbox or new monthly event. Historical daily version 28 remains rejected and unchanged. Finance-priced finalization
  is the remaining authorized business step.
- Subsequent employee interactions created two independent frozen cases: run 66 stores GRP1/LBLT as `2300/0`, and
  latest run 67 stores `200/0`. Both stopped safely as retryable `generation_failed` with no Finance version or run
  outbox event. Diagnosis found two finalization defects: the live artifact-kind constraint omitted
  `manual_override_json`, and the Finance-version INSERT had 21 placeholders for 20 values. Migration 018
  (`5600d825…cd00`) was rollback-probed and formally applied as the additive artifact-kind correction; the surplus SQL
  placeholder was removed. A real PostgreSQL outer-transaction review-to-Finance slice now reaches one active version,
  one manual row and one commit event before rolling back to zero residue.
- Web is now PID 26286 with all six readiness flags true. The review UI/API displays and accepts only non-negative
  integers while preserving exact `.00` database/manifest normalization. At the finalization-repair handoff, run 67
  was revision 2 `generation_failed`, read back as `200` and `0`, and had not been retried by that repair; run 66 held a
  different frozen GRP1 value. That checkpoint is historical and the later browser-visible state is recorded below.
  Historical version 28 remained rejected and unchanged at the repair checkpoint.
- The manual-review UI follow-up is runtime-active without a Web restart because static files are read on each request.
  `待人工处理` plus progress are one operation button that focuses/scrolls the price panel without opening the task
  log; retryable cases omit the removed frozen-list sentence; finalization projects `日报生成中`; and the complete
  review panel/dialog/error surface follows the Chinese/English/Thai selector. Authenticated read-only browser QA
  verified both a retryable and an editable case. During that QA, history had advanced outside this task: jobs
  `arrjob-e36d8c4c133b48dbb81a57a002e41d76` and `arrjob-cce736734c5e4731b733f03c4a9a3b76` displayed succeeded, while
  `arrjob-d3bbbb435cae4559b5f69cb7ea331cee` and `arrjob-dddc27119bea43b19588c78eac087763` still displayed needs-review.
  This UI task issued no price save, finalize/retry/cancel submission or upload, so it does not attribute those external
  lifecycle changes to itself.

## Diagnosed On 2026-08-06

- Diagnosed the user's fresh post-v4 `0805.XML` upload read-only. The page shows `请求未完成`, while PostgreSQL has
  three new v4 run/attempt shells (61–63 / 53–55) stuck `running`, three exact 948,683-byte source artifacts, no
  delivery, Finance version or outbox event. Live database effects match 016 but migration 017 is absent: review tables
  do not exist and lifecycle checks permit only success/failed. An isolated same-hash v4 replay plus independent
  validation succeeds as `review_required` with exactly `LIAN TAI / LBLT / 0` and `LIAN TAI / GRP1 / 1150`. The Web
  transaction therefore fails on the missing review table and its best-effort closure fails at the same dependency.
  No live migration, cleanup, re-upload, review edit or business write was performed.
- Diagnosed deployed daily job `arrjob-f1cd01f5fddd458cbdafada0ec7dd14d` read-only. A local XML with the exact logged
  948,683-byte/SHA-256 identity reproduces the processor-3.0.0 failure: Lian Tai `LBLT + 0` and `GRP1 + 1150` are absent
  from the frozen price reference. All 151 `validation_failed` outcomes are `BATCH_NOT_VALIDATED` fallout; they are not
  separate source-field errors. Finance version 28 remains rejected, and no price, code, server, database or job state
  was changed. Finance must approve the missing totals or an explicit zero-night rule before rebuild, exact replay and a
  fresh upload.

## Implemented Locally On 2026-08-06

- Added the v4 `PRICE_UNMATCHED`-only manual-price-review path for the active fixed-processor/artifact-callback flow.
  A pure missing-price result records an audited, privacy-minimized `awaiting_review` case and returns `needs_review`
  without a daily XLSX, Finance version, rejected version, failure outbox or monthly event. Mixed errors remain failures.
- Authenticated/CSRF review APIs and the Daily Report panel page grouped keys, candidate fixed prices, aggregate impact
  and revision-locked non-negative integer prices (including `0`), then normalize exact `.00` storage/manifest values. Finalization freezes canonical provenance, rematerializes
  the registered source XML and independently replays before its one atomic Finance/outbox commit. Infrastructure
  retries retain the manifest; deterministic final errors close the review/run.
- Migrations 017/018 and their guarded down migrations, v4 processor package/schema, trace v4 and package checksum parity were
  locally verified. After the navigation/progress/localization follow-up, the dependency-complete `.venv` suite passes
  393 tests with three intentional private-fixture skips; direct-MCP remains an explicit v3 no-review compatibility
  projection. The controlled rollout and later browser-visible user activity supply live review/success state, while
  this follow-up itself remains UI-only and produced no Finance or monthly mutation.

## Completed On 2026-08-04

- Repaired deployment availability for monthly and company report artifacts. Removed the monthly Node/private-package
  runtime path and the stale Node builders/package manifests, added Python/openpyxl monthly validation, and added
  shared OSS publication/read routing with hash/size/MIME rechecks. Migration 016 allows OSS monthly artifact
  identities while preserving historical local rows. Local fake-object-store, builder, publisher, download-router and
  migration tests pass; the development machine has no Docker, so CentOS image/Compose acceptance is explicitly handed
  to the operator. No live report or business data was changed.
- Fixed the reported `MONTHLY_REPORT_OUTPUT_VALIDATION_FAILED` false negative for the 2026-08-03 440-row monthly
  workbook. `_validate_workbook` now scans read-only sheets sequentially with `iter_rows` and compares Excel-decimal
  readback values within `0.000001`; sheet order, headers, dimensions, semantic identity, formula count and exact
  `=R[row]*C[row]*G[row]` formulas remain strict. A 440-row/five-sheet decimal regression and the 18-case monthly
  builder/publishing/worker/service/repository suite pass. The dead/pending outbox events were not modified.

## Completed On 2026-08-03

- Removed the private npm dependency from the company-channel report deployment path after CentOS Docker build failed
  with `@oai/artifact-tool` 404. The company workbook builder now uses Python/openpyxl inside Web, keeps formula-injection
  text escaping, produces no preview PNGs, and validates regenerated workbooks after saving. `compose.yaml` starts Web
  with `--enable-company-reports`; HTTP/IP test overrides must keep that flag while omitting `--secure-cookies`.
  Focused company-report and deployment-entrypoint tests pass 19/19. No database migration or live server deployment was
  performed from this workstation.
- Made the mobile H5 dashboard publicly readable without weakening the desktop/operator boundary. Anonymous users can
  load `/h5`, its H5 assets and purpose-built `/api/public/h5/months` plus `/api/public/h5/analytics` aggregate routes;
  the public projection omits source hashes and operational metadata. Generic analytics, legacy H5 APIs, desktop pages,
  detailed health, jobs/traces, downloads and all write paths remain authenticated. H5 keeps optional authenticated
  logout, uses no-detail `/healthz` for its connection indicator, and 71 `test_arr_web*` tests plus syntax checks pass.
  No live service restart or public deployment was performed.
- Clarified ARR trace semantics for internet-facing deployment. `artifact_callback` traces now expose additive
  `execution_scope=arr_runtime`, `processor_mode=fixed_processor` and `remote_dispatch=none`; legacy `direct_mcp`
  traces identify remote Agent/MCP delivery. User-visible messages no longer call ARR output “本地处理”, and the
  queued downstream message explicitly says Finance database commit is complete while the outbox waits for its
  consumer. Persisted `local-...` delivery keys and existing trace fields remain unchanged. Trace/Web tests (27) plus
  Python/JavaScript syntax and diff checks pass; no live task or business data was mutated.
- Performed a read-only live diagnosis after a user reported that Daily Report uploaded but monthly did not update.
  Daily run 39 is accepted and Finance version 14 is active with 111 retained rows for 2026-08-01; its
  `arr.daily_version_committed` outbox event was initially pending with zero attempts. The dedicated worker was then
  started in detached Screen, consumed the backlog through event 20, and published active August V01 (`更新至
  2026-08-01`, 111 rows); July V05 (`更新至 2026-07-27`, 987 rows) also became active while older July V04 was
  superseded. The registered XLSX/result pair exists and the Web health endpoint remains ready. The worker is running
  for this session, but reboot-persistent supervision is still open; no re-upload or source-code change was made.
- Performed a second read-only BI freshness diagnosis after August publication advanced. Active August V02 is now
  `更新至 2026-08-02` with 268 rows, and a fresh repeatable-read analytics query returns the same watermark and
  `updated_at=2026-08-03 14:21:29 +08`. An already-open BI page can still show 8.1 because `app.js` loads analytics
  only at boot, first BI entry or month change; the monthly page's four-second poll does not refresh BI. This is a
  frontend freshness bug, not a monthly worker/database publication failure. No code or business data changed.
- Implemented BI freshness detection for desktop and public H5. While visible, each surface checks its lightweight
  month metadata endpoint every five seconds and reloads full analytics only when the selected month's `updated_at`
  changes or the selected month changes. Polling pauses while hidden, resumes with an immediate check, preserves the
  last good snapshot during transient failures, and keeps the existing four-second monthly-history polling separate.
  Static BI/Web tests pass 5/5 and 19/19; both JavaScript syntax checks and `git diff --check` pass. No API, report or
  business data behavior changed.
- Fixed company-report duplicate publication. A retry now validates the existing archive/result pair against the
  deterministic reservation and builder `semantic_sha256`, verifies the archive hash against the result JSON, and
  reuses the first successful artifact metadata instead of comparing the new XLSX binary SHA. Partial, corrupt or
  semantically conflicting pairs fail closed; an existing `current` file is not overwritten, while a missing one can be
  repaired from the authoritative archive. First-publication rollback behavior and monthly publication code are
  unchanged. Publisher tests pass 6/6, company-report tests pass 32 with five optional ArtifactTool skips, Web
  company/trace tests pass 13/13 and Python compilation is clean. No live report rerun or business-data mutation was
  performed; the historical 2026-07 `11-20` retry remains to be rerun as a separate acceptance action.
- Added Booking Excel to company-report traceability. New report jobs persist a safe source summary captured server-side
  at submission (batch id, filename, activation time and counts); the company page now shows the active source, job
  detail shows the submission-time source, and history adds a source column. Re-uploading the same active workbook is
  treated as an informational refresh that keeps the existing source and report history; it does not re-extract or
  auto-generate a report. Historical jobs without source metadata remain readable and show that the source was not
  recorded. Full discovery passes 360 tests with 10 optional skips; no live upload, activation, report generation or
  service restart was performed because the available browser session was unauthenticated.
- A read-only live follow-up found accepted Booking Excel batch 7 active with 72 rows and no review draft. The latest
  August `01-10` jobs contain `source: null` and all five company results fail at `publish` with
  `COMPANY_REPORT_PUBLISH_FAILED` after building row counts. The port-8766 Web process predates both source-traceability
  and current duplicate-publication handling, so a controlled Web restart followed by one authorized rerun is required;
  no restart or backfill was performed.
- Clarified company-report source and publication status copy for operators. The job panel now says `本次任务使用的
  Excel`; missing metadata says `未记录，无法确认使用了哪份 Excel` and explains that the filename/batch were not saved.
  `COMPANY_REPORT_PUBLISH_FAILED` now says the data reached publication but the official Excel was not saved, and
  explicitly distinguishes that error from successful reuse of a complete identical version. Focused Web/company and
  publisher tests plus JavaScript syntax checks pass. Existing `source: null` jobs remain untraceable and no live
  restart, report rerun or business-data mutation was performed.
- Removed the redundant Booking Excel provenance card from company-report job details and the provenance column from
  generation history. The upload/review current-source panel and server-side job `source` metadata remain intact for
  operation and audit. Web/company regression passes 29 tests, JavaScript syntax and runtime-reference checks pass,
  and no report or business data changed.
- After the operator-reported 8766 restart and another `2026-08/01-10` attempt, job
  `253ce23dc7544d34a6e0fb9405ac4d9a` again built all five row sets (`54/18/7/1/15`) but failed at `publish`; the prior
  `c5358fa293184f5f9bad85178afada22` succeeded with the same counts and complete artifacts. Read-only process evidence
  still shows PID `11176` started on 2026-08-02 12:20, before the current duplicate-publication source change, so the
  effective 8766 listener was not replaced. Publish copy was simplified to direct restart-and-retry instructions; no
  report, database or output mutation was performed by this recheck.
- The operator's latest `2026-08/01-10` retry, job `087dceca79e64bebb719ad06e7813465`, finished at 15:29 +08 with the
  same five row counts and the same publish-only failures. At 15:37 +08, TCP 8766 was still owned by PID 11176 under
  the 2026-08-02 Screen session; the launcher preflight is ready, but the listener still predates the current publisher
  and job-source modules. The earlier successful five archive/result pairs and current downloads all remain
  SHA-256-consistent, and six focused publisher tests pass. No restart, rerun, file repair or business-data write was
  performed; exact listener replacement remains the required operational fix.
- With explicit operator confirmation, the exact stale PID 11176 was stopped and replaced by PID 54127 at 15:46:29
  +08 through the existing launcher. One authorized job `05cc547d62854df281b0c9cac60e6f6d` then succeeded at 15:48:37
  +08 for all five companies with row counts `54/18/7/1/15`; the new job recorded active Booking batch 7 source
  metadata, reused the same version numbers/artifact descriptors as `c5358fa...`, and all five authenticated HTTP
  downloads returned 200 with matching archive/current/result hashes. The prior files were not overwritten, the
  temporary session was logged out, and no Booking/Finance source or fact mutation occurred.
- Confirmed the source contracts for repeated Booking/report workflows: byte-identical activated Excel uploads reuse the
  activated source; same rows with different XLSX bytes create a new reviewable source; unchanged report snapshots
  reuse their complete publication pair; changed Finance or Booking version pins create a new report version; and an
  activated subset changes Booking detail coverage without deleting the Finance fact rows. Focused source/publisher/
  integration checks pass 14 tests with two optional ArtifactTool skips. The controlled 8766 replacement and one live
  5/5 rerun now pass; reboot-persistent supervision remains a separate deployment gap.
- Confirmed a separate operator-visibility gap: the publisher reuses the archive/result pair internally, but neither
  `PublicationOutcome`, `CompanyRunResult` nor the public company-job projection exposes a reuse disposition or prior file
  identity. A successful retry therefore looks like a normal new successful job with a download link; no code change was
  made in this read-only check.

## Completed On 2026-08-02

- Restored cross-month history visibility for Daily Report, monthly processing and company-channel generation history.
  Each list now has an independent previous/month/next/`本月` navigator and defaults to its latest non-empty month using
  authenticated read-only `GET /api/history-months`. Counts and empty states name the active month and can jump to the
  latest month with records. Company `生成月份` is now visibly labeled and independent from history `查看月份`; monthly
  polling follows the viewing month without changing generation contracts. A guarded live read returns July counts of
  30 daily and four monthly records, while company state retains four July jobs. The full 356-test suite passes with 10
  skips, and isolated Chinese/English/Thai browser QA at 1440/900/390 pixels found no page overflow. Port 8766 was
  restarted under detached Screen and is `ready`; no upload, report generation, source activation or business-data write
  occurred.

## Completed On 2026-07-31

- Refined the Channel BI utility surface in preserve mode: removed the visible BI panel heading and ready-state
  `数据库已连接` copy while retaining the navigation label, browser metadata and semantic status dot. Compressed the
  month selector to a compact control on desktop/H5, and changed task-log/logout utilities from button chrome to
  low-emphasis accessible links without changing their behavior. JavaScript syntax plus focused BI, daily visual,
  task-log and auth tests pass; no API or business data changed.
- Tightened the Channel BI panel's top rhythm after the heading removal: the desktop panel now starts 20px higher
  relative to the shared 38px page padding, while the responsive desktop shell keeps a 10px mobile-only adjustment.
  The four-tab bar, panel content and BI data behavior are unchanged; focused Web regression remains green.
- Refined the Channel BI presentation and data-range contract. Removed the BI-only CHANNEL PERFORMANCE, snapshot
  watermark copy and visible TOTAL PRICE labels on desktop and H5, and added a localized 数据范围 line below the
  company-sales title. The read-only analytics payload now supplies the minimum and maximum ARRIVAL coverage dates
  from one repeatable-read current-version snapshot; no Finance/report business data changed. JavaScript syntax and
  focused analytics/Web/UI tests pass.
- Implemented the ARR Web Chinese/English/Thai presentation layer. Desktop, H5 and login now share `arr_web/static/i18n.js` with locale selectors, localStorage/cookie preference, `html.lang`, dynamic prompt/API-error translation, Bangkok/Gregorian/Latin-digit date/number formatting and locale-aware duration/money display. The runtime preserves original source strings so switching back to Chinese is safe. `ARR Report`, operational proper nouns, business/API behavior and XLSX/monthly/company report output contracts remain unchanged. Scoped Web regression passed 61/61; full discovery still has only the pre-existing environment errors for missing `httpx`/unavailable OSS client.
- Rotated both ARR Web operator credential values in separate macOS Keychain items without recording either value in
  source, launcher arguments, logs or project memory. The exact port-8766 listener was stopped by controlled SIGINT and replaced at
  15:30 +08 under one detached `arr2-web-8766` Screen session. Live acceptance rejects the prior pair, accepts the new
  pair, verifies hardened cookie/session/CSRF/logout, desktop/H5, anonymous route boundaries, all six detailed readiness
  flags and loopback/LAN health. Two read-only snapshots stayed at 30 daily jobs, 4 monthly versions and 4 company jobs;
  the newest business records predate the restart, so no business write occurred. Nine focused auth/deployment tests and
  credential-literal scans of the workspace, launcher, state logs and process list pass. The requested password still
  matches the username, so the distinct high-entropy password follow-up remains open.
- Simplified the three company-channel generation cards by removing the visible `第一期`/`第二期`/`第三期`
  labels and making the C/O ranges the primary card values: `C/O:01-10`, `C/O:11-20` and a month-aware final range
  (`C/O:21-30` for 30-day months or `C/O:21-31` for 31-day months).
  Completion-state chips (`周期未结束` / `周期已结束`) and Bangkok completion times remain, while the underlying period
  keys and generation payload are unchanged. An incomplete period is now still generatable; future months remain blocked.
  JavaScript/HTML checks, 28 focused Web/company tests, 348-test discovery and isolated 1280x720/390x844 browser QA
  pass with no overflow or page-console warnings. The shared port-8766 service was restarted at 14:36:45 +08 and
  its `/healthz` endpoint returns `ready`.
- Simplified company report results for end users: duplicate review problems are collapsed by type/code/period so a
  repeated `同房型存在不同静态价格，需人工复核` item appears once per company and period. Replaced the internal
  `版本`/`version_no` display with `生成时间`, using the completed job time and falling back to its created time;
  API version metadata remains intact. JavaScript/HTML checks, 28 focused Web/company tests and targeted deduplication
  execution pass.
- Rebuilt the company-channel report setup as a dense four-card desktop row: `上传 Excel 报表` followed by the first,
  second and third C/O periods. At that point the `报表月份` picker was a compact visually unlabeled control in the large
  setup card's upper-right corner; the 2026-08-02 history repair later labeled it `生成月份` and moved history filtering
  to its own control. All period CTAs read `生成` with responsive card-sized widths. Replaced the
  browser-native generation confirm with an in-page accessible dialog showing month/period context; cancel, backdrop
  and Escape dismiss without submitting, while explicit confirmation preserves the existing payload, generation polling
  and business behavior. JavaScript/HTML checks, 28 focused Web/company tests, 348-test discovery and isolated
  1280x720/390x844 browser QA pass with no overflow or console warnings; the shared port-8766 service was restarted at
  14:36:45 +08 and its `/healthz` endpoint returns `ready`.
- Rebalanced the company-channel setup surface for the current Finance workflow. The fixed five-company scope now sits
  beside `公司渠道明细` as pale helper text, the Excel upload action is bounded to a 760px desktop rail and remains
  full-width/single-column on mobile, and `刷新任务` exposes a read-only scope tooltip. The generation month remains the
  C/O report-month selector for period completeness and the generation payload; its former history-filter role was
  removed by the 2026-08-02 cross-month history repair. No report,
  upload or database behavior changed. JavaScript/HTML checks, 28 focused Web/company tests, 348-test discovery and
  isolated 1280x720/390x844 browser QA pass with no overflow or console warnings. Port 8766 was not mutated by QA.
- Compressed the daily overview row to a compact equal-height desktop treatment. The upload card now uses a horizontal
  icon-and-copy dropzone, reduced heading/footer spacing and smaller controls, while the three KPI cards stretch to the
  same row height. Mobile upload layout remains unchanged. JavaScript syntax and 20 focused Web/static/trace tests pass;
  no upload, API or processing behavior changed.
- Refined the company-channel generation controls for dense Finance use. The three period CTAs are now compact
  104–124px actions centered inside each card, while `提取并核对` uses the same 42px button family and is centered
  inside the upload action column on desktop and mobile. Labels remain single-line, upload/report behavior is
  unchanged, 28 focused Web/company tests and the 348-test discovery pass, and the restarted port-8766 service is
  healthy at 13:37:49 +08.
- Restored equal card heights across the daily overview row. The ARR.XML upload panel and the three KPI cards now
  stretch to the same grid-row height, with KPI content centered inside each card; mobile stacking remains unchanged.
  JavaScript syntax and 20 focused Web/static/trace tests pass; no upload, API or processing behavior changed.
- Reverted the KPI width shrink after clarification. The three daily cards now retain their original grid-column widths,
  while their height is content-sized and vertically centered in the upload module's shared desktop row. JavaScript
  syntax and 20 focused Web/static/trace tests pass; no upload, API or processing behavior changed.
- Centered the shortened daily KPI cards within the upload module's shared desktop grid row, preserving their widths,
  270px height and mobile content-sized fallback. JavaScript syntax and 20 focused Web/static/trace tests pass; no
  upload, API or processing behavior changed.
- Tightened the three daily KPI cards so they no longer inherit the upload panel's full grid-row height. The desktop
  cards keep their existing widths and data hierarchy, use a compact 270px height with smaller decorative rings, and
  return to content-sized cards on narrow screens. JavaScript syntax and 20 focused Web/static/trace tests pass; no
  upload, API or processing behavior changed.
- Recomposed the daily overview into one desktop row containing the ARR.XML upload station plus the ARRIVAL DATE,
  processing-duration and NO. OF ROOM cards. Removed the duplicate top `Daily Report` heading and `THIS MONTH` eyebrow,
  renamed the daily-history heading to `Daily Report`, and kept the upload request, inline progress estimate and
  on-demand task-log behavior unchanged. JavaScript syntax and 20 focused Web/static/trace tests pass; no API or
  processing behavior changed.
- Updated the daily XML upload surface so submitting ARR.XML stays on the daily page instead of opening the task-log
  dialog automatically. The upload card now shows a compact stage-based estimate for upload, fixed processing,
  validation and database commit, finalizing at 100% on success and retaining an inline error state on failure. The
  header task-log button remains the sole on-demand trace entry; the later 2026-08-11 interaction correction removed
  daily-history row log activation. JavaScript syntax and the original 15 focused Web/static/trace tests passed; no API
  or processing behavior changed.
- Simplified the desktop monthly page into a single six-column download table. The redundant standard-monthly heading,
  `VERSION HISTORY`/version-record copy, visible monthly `版本` column and C/O-period footer note are removed; the
  navigation label is now `月报`; the list is identified by a compact `月报处理` heading. The visible `更新至` cell reads the explicit `max_arrival_date` API field, which is
  backed by the published run's `as_of_date` (the maximum included `ARRIVAL`) while retaining the legacy field and
  version ordering for compatibility. The remaining panel uses a compact live-status toolbar and responsive table
  spacing; focused Web/schema/task-log tests and JavaScript/Python syntax checks pass. No report or business data changed.
- Froze the Markdown-backed July company-channel baseline before any Booking Excel activation. The read-only,
  non-publishing package binds the exact `RES_COMMENT_TYPE_OF_ROOM.md` hash to accepted Booking batch 1, five pinned
  Finance daily versions, processor 1.2.0/rule identity and five generated XLSX files. All 314 output rows independently
  match the Markdown-derived Booking Room expectation; 27 are filled and 287 are correctly blank. The builder reopened
  and exact-value checked every workbook, rendered all 15 sheets, and the retained SHA-256 inventory verifies every
  package file. One reviewing Excel draft remained separate; the current Booking pointer and room-item counts were
  unchanged.
- Refined the Booking record-extraction review surface for dense operator work. The page now renders 50 records at a
  time, supports individual and all-visible selection, and deletes 1-50 unique selected records through one bounded
  atomic backend operation. Single and batch delete share a count-aware in-page dialog; cancel, backdrop and explicit
  Escape handling never submit and restore focus. The separate accepted-source status/summary is removed; the open
  review now identifies its own extraction records with the validated uploaded workbook filename directly below
  `Booking记录提取`, wrapping fully on narrow screens. The requested review/upload helper copy is removed. Isolated authenticated browser QA covered one/two/50-row
  selection plus 390×844 layout without calling delete; the full suite passes 346 tests with 10 expected optional skips.
- Implemented the deterministic Booking Excel extraction program requested for raw Tour Code/`โรงแรม` workbooks.
  It applies physically-last-row replacement/cancellation, splits bracketed room items, normalizes agreed TWN/DBL
  variants, preserves quantities on unknown labels, and routes unknown/unbracketed room names to editable/deletable
  pending records. The supplied workbook replays to 26 Tour Codes, 37 items and 7 pending items; `LLT260715AC` becomes
  `TWN/12 + DBL/9`, while `LT260715LD` becomes `U-TWN/17 + pending/2`. Durable review/activation, paged desktop UI and
  bounded GET/POST/PATCH/DELETE transport are present. A real-PostgreSQL transaction probe created a two-item draft,
  corrected its pending item, atomically activated one three-room source row and then rolled the outer transaction back;
  source batch 1, zero drafts and zero synthetic artifacts were restored. No persistent Booking/report business write
  was performed.
- Confirmed end-to-end readiness boundaries. The company-channel processor already reads current Booking views at report
  generation; a live read-only July snapshot produced valid 5/5 results from 417 Finance facts and 27 matched Booking
  Group Codes, with missing/unmatched Booking Room blank. The expanded Booking/company/real-XLSX suite passed 55/55.
  The controlled real-PostgreSQL draft/edit/activation path passed inside an outer rollback. July `21-month-end` does not open until
  2026-08-01 00:00 Bangkok, and a shared-database test workbook must be a deliberate complete replacement.
- Audited Booking parser 2.0's human-review requirements across the live schema, current source and active Web process.
  During the audit, concurrent work applied migrations 014/015: the live database now has a current-source pointer plus
  empty draft/item tables supporting basic confirmed/pending/deleted latest-state editing. It still lacks actor, reason
  and revision history. Its earlier GET/POST-only transport finding was subsequently repaired with PATCH/DELETE handlers
  and real socket coverage; real PostgreSQL write/rollback acceptance now passes. The audit itself made no persistent
  database/runtime/business-data mutation.
- Completed a privacy-minimized, read-only Booking dimension/database audit. `Group Code + room type + quantity` is the
  sufficient normalized allocation model for current data, whose nonblank codes do not cross stay/company/channel;
  missing/unmatched enrichment is blank as designed. Its initial parser/importer snapshot was superseded by the dedicated
  manual-review audit above; migrations 014/015 are formally applied and the transaction boundary is verified, while the
  first operator-authorized real workbook activation remains incomplete.
  No business data changed by this audit.
- Reduced the ARR login gateway to one clear brand statement and one form. The old workflow marketing copy, numbered
  steps, repeated welcome/access copy and help/footer disclaimers are removed; the remaining field labels are
  `username` and `password`. Existing password visibility, loading/error, safe-return and authentication behavior is
  unchanged. Thirty-three focused Web/auth/UI tests pass, and live 390x844 plus 1280x720 checks show no horizontal
  overflow or browser warnings/errors.

## Completed On 2026-07-30

- Added application-owned Finance login across desktop, H5, APIs, uploads, traces and downloads. Runtime credentials are
  required, login attempts are bounded, random server-side sessions retain hardened cookies/CSRF, logout revokes the
  session, and only login assets plus no-detail `/healthz` remain anonymous. Caddy now owns HTTPS only.
- Added a responsive ARR login gateway and desktop/H5 logout/session-expiry behavior. The live source passed wrong and
  correct login, password visibility, safe `/`/`/h5` return, both logout paths, zero-console-error checks and
  375/768/1024/1440 no-overflow verification.
- Added and applied additive migration 013. New uploads store the validated browser XML basename on
  `ingestion.processing_runs`, while private source artifacts and processor input remain canonical `source.xml`.
  Daily history and task trace read only the new provenance; pre-013 rows render `—`.
- Added and applied additive migration 012. The `reporting` schema stores monthly versions, Finance daily-version
  lineage, channel row-count manifests and two artifact references without duplicating business/guest rows.
- Replaced in-memory monthly identities with database IDs, sequential versions, canonical snapshot hashes, atomic
  activation/supersession, persisted failures and idempotent published-snapshot replay.
- Made the report's `as_of_date` equal the greatest `ARRIVAL` actually included in its snapshot. XML filenames and the
  wall clock are ignored.
- Added a standalone `monthly_reports.worker` process with leases, `FOR UPDATE SKIP LOCKED`, expired-lease reclaim,
  bounded retry/backoff and dead-letter behavior.
- Made outbox acknowledgement conditional on a registered active/superseded report and both workbook/result artifacts.
- Replaced the synthetic monthly list and unavailable download resolver with `reporting.monthly_runs` reads and
  confined path/size/SHA-256 checked downloads.
- Removed month/cutoff/manual-generation controls from the primary page. The guarded POST route remains only as a
  controlled recovery surface when explicitly enabled.
- Changed every XLSX data-row `TOTAL PRICE` cell to the exact row-relative `=R[row]*C[row]*G[row]` formula and validates
  the complete formula matrix again after reopening the workbook.
- Removed the monthly refresh control. The visible monthly tab now performs one non-overlapping list read every four
  seconds, stops while hidden/inactive, reloads immediately when restored, and preserves the last good list during a
  transient background failure.
- The desktop and H5 headers use the plain `ARR Report` identity with no decorative icon. The daily content heading is
  `Daily Report`; the duplicated daily/monthly explanatory copy has been removed without changing automatic publishing.
- The desktop header utility formerly labeled `手机看板` is now `任务日志` and opens the existing black task console in
  a native modal. The console no longer occupies the daily-processing layout, and the 2026-08-11 interaction correction
  makes this header utility its only opener; upload completion and Daily rows do not open it. `/h5` remains available
  by direct URL. Both history and trace SQL are explicitly limited to `pipeline_type = 'opera_daily'`, so this is a
  one-daily-job processing trace rather than a global server, monthly-run or company-report log.
- Refined the daily desktop surface after visual review. `ARR Report` remains the dominant workspace title while
  `Daily Report` is smaller; `任务日志` is a compact outlined button at the adjacent status-label size; the upload
  station is centered and responsive; decorative `01 / UPLOAD` and `本月留痕` labels are gone; and `开始处理` is a
  compact right-aligned action. No upload, API, route or trace behavior changed.
- Daily, monthly and selected-month company histories use 50 records per page. Each footer shows the exact monthly
  total, current visible range, page number and previous/next controls; counts and rows are read from one database
  snapshot or coordinator lock. Channel BI remains an aggregate view rather than a paginated detail list.

## Live Acceptance

- Five `arr.daily_version_committed` events have produced July publications: one is the earlier database acceptance
  fixture `mvp-v1-fixture-20260727`; four are real 07-20/07-21/07-22/07-23 uploads.
- Report ID 4/version 4 is active for 2026-07 with `as_of_date=2026-07-27`, 417 rows and six channels; V03/V02/V01 are
  superseded. Its persisted date equals max current `ARRIVAL` structurally, but that maximum comes from the fixture.
- The superseded V03 workbook has 308 authorized `TOTAL PRICE` formulas and zero mismatches. Its 40,635 bytes and SHA-256
  `494fb78283f68cb7bffce2501b3531613c494d148a56a7ccc8d2aabe46b1e29c` match the registered artifact.
- Earlier browser/access-log verification showed V03/V02/V01 downloads and repeated monthly API reads at the
  four-second cadence. The current API now lists V04 active above those versions; ARR2 Web remains green and the worker
  remains separate.
- ARR2 Web is active on all local interfaces at port 8766 under detached Screen session `arr2-web-8766`. The current
  trusted-Wi-Fi entry is `http://192.168.3.103:8766/`; anonymous root redirects to login and `/login` plus `/healthz`
  return HTTP 200. The current process restarted at 2026-07-31 19:27:42 +08 to load the Web i18n static resources
  after the source implementation; it loads the Booking bulk-review
  composition; the public health check returns `ready`.
  Authenticated acceptance reports database, processing, monthly reports, downloads, company reports and company-source
  upload ready. At the earlier 11:30 acceptance the draft endpoint returned no open draft; this later UI task did not
  authenticate against, inspect or mutate the shared draft contents. Anonymous PATCH/DELETE reach the application auth gate and return JSON
  401 rather than transport-level 501. Migrations 014/015 are live and the current pointer selects batch 1; no persistent
  Booking write was performed. Legacy port 8765 remains closed; the mode-0700 launcher keeps secrets outside the repository.
- The active ARR2 analytics API on port 8766 returns 417 rooms because the known one-row fixture remains current.
- Live pagination acceptance on port 8766 currently reports 30 daily jobs, 4 monthly versions and 4 company jobs. All
  three render page 1/1 with correct disabled boundary controls; a 390-pixel viewport has no horizontal overflow.
- Migration 013 is live in `booking_test`: 25 total processing runs, zero falsely backfilled upload filenames and a
  validated constraint. A rolled-back Unicode-basename probe proved history/trace return the upload name while the
  artifact remains `source.xml`.
- The pre-012 privacy-minimized metadata checkpoint is
  `runtime/backups/booking_test_pre_012_20260730T151922+0800/manifest.json`, SHA-256
  `230206eb074fd5877132744eb592b3dc6cd6638d12a3dd4d71a8101a9bd2998e`.

## Active Data-Quality Incident

- The company-report cutoff-10 and cutoff-20 Web jobs both completed 5/5 with valid zero-row workbooks because every
  current supported-company fact has C/O in the 21-to-month-end period. Processor 1.2.0 implements the final
  user-confirmed fallback: no Group Code leaves both `RES_COMMENT`/`Booking Room` blank; a present Group Code that
  cannot resolve in Booking remains visible while only `Booking Room` is blank. A repeatable-read July 31 preview is
  now valid 5/5: LianTai 138 rows/122 blank Booking Rooms, QBD 139/128, DY-AI-Easy-KB 1/1, FengRun 33/33 and HanaTour
  3/3. No report or business-data mutation was performed. The active port-8766 runtime now loads the current processor
  and reports company-report readiness true; one controlled 5/5 Web job remains a separate acceptance action, with a
  post-completion rerun recommended if later source facts should be reflected.
- Finance current version 2 is `synthetic.xml` from provider `local_fixture`; it adds 1 room, 3 room-nights, 5,400
  revenue and a synthetic room type to Channel BI and all July monthly publications.
- V01's legitimate operational source is exactly 119 rows with `ARRIVAL=2026-07-21`; its persisted lineage and
  hash-matched workbook also contain the one-row 07-27 fixture, which is why the stored report says 120 rows and
  `as_of_date=2026-07-27`. This is contaminated content, not a metadata-only date error.
- Excluding the fixture leaves the verified four-day business total of 416 rows/rooms, 853 room-nights and 1,451,350
  revenue through ARRIVAL 2026-07-23. Hash matching and isolated replay prove the accepted file mapping is
  07-20=100, 07-21=119, 07-22=88 and 07-23=109; the user's total was right but the 07-20/07-22 labels were reversed.
- No database repair was performed during diagnosis. The fixture should be retired from the current projection without
  deleting immutable history, followed by a clean July republication and live API verification.
- Channel BI now checks the selected month's `updated_at` every five seconds while visible, so an already-open view
  reloads its aggregate data after a new Finance version is published. The historical 308/417 observation above is
  retained as evidence of the earlier stale-view behavior, separate from the one-row fixture contamination.
- The BI `公司数` card actually counts worksheet channels; LianTai GROUP/FIT are separate, so six channel keys can still
  correspond to five top-level companies.

## Verification Status

- The 2026-07-31 Web i18n implementation passed JavaScript syntax checks, a DOM/runtime locale smoke (Chinese → English → Thai → Chinese), and 61 focused ARR Web tests. A full 298-test discovery was attempted; eight import/runtime errors are environment-only (`httpx` absent and OSS client unavailable), with no i18n-related failure.
- Migration 012 passed transaction-only up/down probes, including a synthetic active publication followed by rollback.
- The 38-test monthly/migration/Web regression set passed, including real XLSX build/reopen checks.
- A clean full-suite rerun with the optional ARR1 compatibility dependency installed passed 291 tests in 108.2 seconds
  with 7 explained environment/fixture skips and no failures or errors.
- The automatic-list follow-up passed 18 focused Web/schema tests, JavaScript syntax checking and a clean 291-test full
  discovery in 110.8 seconds with the same 7 explained environment/fixture skips.
- The post-update BI diagnosis passed 24 focused analytics/contracts/Web tests and reconciled both live Web APIs against
  a repeatable-read, read-only database snapshot.
- Hash-matched local source inspection and isolated deterministic replay reproduced `0720.XML=100` and `0722.XML=88`;
  the 07-23 accepted run was traced to its 16:12:27 commit and 109 retained rooms.
- The final scoped company/Booking/report suite ran 32 tests successfully with three expected private-fixture skips; it
  included real XLSX export, value verification after reopen, rendering and the dedicated no-Group-Code path. Four Web
  company-task coordinator tests also passed.
- The 50-row pagination follow-up passed JavaScript syntax, 29 focused Web/repository tests and the complete 305-test
  discovery with 10 existing environment-dependent skips. Live desktop and 390-pixel checks confirmed all three
  totals/ranges and boundary-button states.
- The upload-filename change passed 69 focused tests, JavaScript/Python syntax checks and a clean 312-test full
  discovery in 99.280 seconds with 10 environment/fixture skips.
- The application-login change passed a 33-test focused auth/Web/company/deployment set after final compatibility edits,
  JavaScript/Python syntax checks, Ruby static Compose parsing and the clean 317-test full discovery in 97.311 seconds
  with 10 environment/fixture skips. Docker is not installed locally, so live `docker compose config` was not claimed.
- The expanded absent-or-unmatched company-report fallback passed a 37-test
  company/Booking/real-XLSX/Web-coordinator suite with three expected private-fixture skips and no failures; the current
  controlled July 31 projection previewed valid 5/5. A separate non-publishing real-data vertical slice built, reopened,
  value-checked and rendered all five actual workbooks in a temporary directory.
- The daily visual-polish follow-up passed JavaScript syntax and 33 authenticated Web/auth/daily-visual/task-log tests.
  Live 375/768/1024/1440 checks confirmed the corrected title hierarchy, centered upload geometry, compact actions,
  task-log dialog focus restoration, zero horizontal overflow and zero browser warnings/errors.
- Live login activation passed anonymous root/API rejection, exact credential login, hardened cookie/session/CSRF,
  authenticated desktop/H5/history reads, all five readiness flags, logout revocation and loopback/LAN health. Read-only
  totals at initial activation were 24 daily jobs, 4 monthly versions and 3 company jobs; no upload, report job or worker
  was started.
- The 2026-07-31 credential rotation passes prior-pair rejection, new-pair login, hardened cookie/session/CSRF, logout
  revocation, desktop/H5 and all six current detailed readiness flags. Two read-only snapshots remained 30 daily jobs,
  4 monthly versions and 4 company jobs, with their latest creation times before the 15:30 restart. No upload, report
  generation, Booking activation or monthly worker action occurred.
- Booking extraction runtime acceptance passed authenticated health/source-draft reads, clean logout, anonymous
  PATCH/DELETE application routing and direct read-only repository access. At that probe all relevant readiness flags
  were true, source batch 1 remained current and no draft existed. A later operator upload created one reviewing draft;
  the Markdown baseline freeze proved it remained isolated and did not change batch 1. A 2026-07-31 14:14 +08 live
  read-only recheck found no reviewing draft and still found Markdown batch 1 current with 867 rows, six worksheets and
  348 Group Codes, so the draft blocker is currently clear without any Booking source switch.
- The same live recheck found that the current July company-report projection has advanced beyond the frozen
  five-version baseline: 986 supported-company Finance facts now all have C/O dates from July 21 through July 30.
  Read-only processor 1.2.0 output remains valid 5/5 with 598 rows, 224 filled Booking Rooms and 374 blanks. The earlier
 314-row package remains correct for its pinned snapshot; it is not the expected row count for this later live
  projection. The first two July periods can now be generated from the current snapshot before their calendar
  completion; any later Finance facts within the fixed C/O ranges require a rerun.
- Final post-change discovery ran 343 tests in 102.451 seconds: all passed, with 10 explained optional
  renderer/private-fixture skips. JavaScript syntax, Python compilation, supplied-workbook replay and the 17 focused
  parser/review/coordinator/router/socket tests are also green.
- Booking review persistence passed a real-PostgreSQL transaction-only vertical slice: draft creation exposed two items
  with one pending, edit confirmed the pending item, activation produced one source row with quantity three, and the outer
  rollback restored batch 1 with no synthetic draft, source or artifact residue.
- A 2026-08-03 diagnosis reproduced the 2026-07 `11-20` company-report retry failure: all five companies failed at
  `publish` after an earlier same-period success because repeated XLSX builds had identical semantic SHA-256 values but
  different binary SHA-256 values. Publisher idempotency now reuses a complete matching archive/result pair and fails
  closed on partial or conflicting state; the historical retry still needs a deliberate live rerun.
- Isolated authenticated browser checks covered the upload-first desktop flow, editable review table, fixed-company text
  and responsive 375/390-pixel layouts with no horizontal overflow or console errors.

## Remaining Deployment Work

- Perform the first operator-authorized real workbook upload/review/activation, then run one controlled five-company
  report and verify all five downloads. The database transaction boundary is accepted, but this task intentionally did not
  replace the current business Booking source. Because activation replaces the whole source, supply a complete workbook
  and restoration plan.
- Decide whether Booking confirmation is a simple single-operator correction loop or an auditable approval workflow;
  add actor/reason/revision history and stronger declarative DB transitions if audit-grade confirmation is required.
- Upload one controlled raw Tour Code/`โรงแรม` workbook, review/activate it, confirm
  replacement semantics and run one controlled company report. A period may be generated before its Bangkok completion
  boundary, but rerun it after completion if the source snapshot changes; the currently open July periods contain zero
  rows and cannot prove populated Booking Room. Before real use, confirm whether 23 fixture Group Codes shared by
  `DY-AI-Easy-KB` and `LIANTAI-FIT` are intentionally additive; the current view merges them globally.
- The prior 8766 outage and credential gate are resolved. The current Web process is a detached local Screen session,
  not a reboot-persistent service; `/Users/chillishark/.local/bin/arr2-web-8766 --check` validates its private route and
  Keychain inputs without printing them before a controlled restart.
- Live authentication/readiness and one controlled 5/5 company-report job with all five downloads are accepted. One
  no-PII XML upload should still confirm migration-013 filename provenance after restart; the Web/worker sessions remain
  detached and are not reboot-persistent.
- The latest operator-selected Web credentials were rotated on 2026-07-31, but the password still matches the username.
  Rotate it again to a distinct high-entropy value in Keychain, followed by one controlled Web restart.
- The workstation runs Web and worker as separate processes. The checked-in Compose image supports both report paths
  through Python/openpyxl; the worker still needs the existing database/OSS secrets and may use `/app/outputs` only for
  staging and local `.web-jobs` state. A formally controlled no-PII CentOS Docker acceptance run remains appropriate.
- ARR2.0 now has Git metadata; `main` tracks `origin/main`. Runtime credential values remain outside Git and project
  files.

## Last Updated

2026-08-04
