feat: add public h5 dashboard and publish traceability
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
# Evidence Topic: 2026-07 company-report retry publication failure
|
||||
|
||||
## Metadata
|
||||
|
||||
- Date: 2026-08-03
|
||||
- Status: Implemented; live historical rerun pending
|
||||
- Scope: 2026-07 company-channel report, C/O `11-20`, local Web job `60bcda9c8dae49758fb69dc47e0ff9e7`
|
||||
- Confidence: Fact for recorded job/build observations; inference for the exact publisher guard
|
||||
- Source: job JSON, prior successful job JSON, read-only controlled PostgreSQL snapshot, source-code inspection and temporary-directory double-build probe
|
||||
- Last verified: 2026-08-03
|
||||
- Stale trigger: changes to the company XLSX builder, artifact identity, reservation-version derivation or publisher idempotency
|
||||
|
||||
## Question
|
||||
|
||||
Why did the Web show `正式表格发布失败` for 2026-07?
|
||||
|
||||
## Evidence
|
||||
|
||||
- The failed job is for report month `2026-07`, period `11-20`, and as-of date `2026-07-20`. All five companies failed at stage `publish` with `COMPANY_REPORT_PUBLISH_FAILED`; there are no record IDs and no source/Booking/business validation errors.
|
||||
- The immediately preceding job for the same month and period succeeded for all five companies and created archive versions. The failure is therefore a retry of an already published semantic snapshot, not a first-build data failure.
|
||||
- `company_reports.repository.PostgresReportRepository.reserve_report()` derives the version directory from a deterministic semantic identity containing the company, period, as-of date, processor/rule/schema versions, daily-version pins and Booking-version pins. The retry therefore targets the same archive version path.
|
||||
- A read-only double-build probe loaded the current controlled July snapshot and built each of the five valid `11-20` workbooks twice in separate temporary directories. For every company, the two binary SHA-256 values differed while the builder's `semantic_sha256` was identical.
|
||||
- `AtomicReportPublisher._install_once()` rejects an existing archive path when its binary SHA-256 differs from the newly built file, raising `COMPANY_REPORT_PUBLISH_FAILED`. The result JSON also embeds the binary SHA-256, so allowing only the archive copy would still leave the same retry-identity conflict at result validation.
|
||||
- No database write, report rerun or output repair was performed during this diagnosis.
|
||||
|
||||
## Implemented Fix
|
||||
|
||||
- `AtomicReportPublisher` now checks for an existing archive/result pair before creating legacy/current side effects. A
|
||||
retry is reusable only when both files are regular files, the result JSON matches the deterministic report identity and
|
||||
current semantic SHA, and the archive's actual SHA-256 matches the result JSON's stored artifact SHA.
|
||||
- A matching retry returns the existing archive/result metadata and activates the repository without copying the new
|
||||
XLSX bytes. An existing current file is left untouched; a missing current file is repaired from the existing archive.
|
||||
- Partial, corrupt, hash-inconsistent or semantically conflicting publication state fails closed with
|
||||
`PUBLISH_FAILED`. First publication and activation-failure rollback paths remain covered.
|
||||
- Regression coverage passed for same-semantic/different-binary retry, semantic mismatch, partial publication and
|
||||
corrupted archive. The real ArtifactTool integration regression is present but was skipped locally because the
|
||||
optional `@oai/artifact-tool` dependency is unavailable.
|
||||
- No live report rerun, output repair or business-data mutation was performed after the code change.
|
||||
|
||||
## Conclusion
|
||||
|
||||
The 2026-07 `11-20` failure was caused by a non-byte-deterministic XLSX build colliding with the publisher's deterministic archive/version identity on retry. The workbook contents were semantically the same, but changing XLSX bytes made the immutable archive and result identity appear conflicting. The existing successful 11-20 artifacts remain valid; the failed retry did not replace them. The publisher now handles this case idempotently by reusing that stable identity.
|
||||
|
||||
## Fix direction
|
||||
|
||||
The publisher-side idempotency fix is implemented and is the active remedy: reuse/validate the existing artifact by semantic identity and preserve one stable binary artifact identity. Making the XLSX builder byte-deterministic remains an optional future optimization, not a prerequisite for retry success. The historical job still needs a deliberate live rerun to verify the deployed path.
|
||||
Reference in New Issue
Block a user