Files
set50-system/docs/engineering-log/2026-08-23-integrity-hardening.md
2026-08-23 14:58:15 +07:00

3.0 KiB

2026-08-23 — snapshot integrity hardening

Plan status

  • Root-cause fix for fail-open point-in-time metadata: complete.
  • Raw payload and normalized snapshot binding: complete.
  • Manifest/source metadata cross-checks: complete.
  • Cached research report revalidation: complete.
  • Trusted host/signing boundary: documented as local-only; multi-user deployment deferred.

Changed files

  • backend/app/vintages.py — canonical normalized hash, raw payload verification, manifest/source cross-checks, timezone-equivalent revision handling.
  • backend/app/prices.py — canonical normalized hash, strict boolean point-in-time metadata, raw/manifest/source cross-checks.
  • backend/app/research.py — validate selected snapshots before cached report lookup and derive the price gate from the verified snapshot source.
  • backend/app/__init__.py — price health validates the latest snapshot before reporting availability.
  • backend/tests/test_vintages.py — normalized payload tamper regression.
  • backend/tests/test_research.py — manifest tamper and cached-ready replay regressions.

Root cause

The previous implementation trusted manifest metadata too early. A truthy string such as "false" could pass a boolean gate, and a ready report could be returned from cache before current snapshot bytes were revalidated. The previous vintage loader also checked identity but not raw/normalized content against the manifest.

Fix

All new persisted snapshots carry:

normalized_hash_algorithm: sha256-json-canonical-v1
normalized_snapshot_hash: SHA-256(sorted-key compact UTF-8 JSON, excluding only the hash field)
raw_payload_hash: SHA-256(raw provider payload)

Loads now verify raw files, normalized content, manifest metadata, strict boolean types, and snapshot identity before the research runner can return a cached result or run an event study.

Live evidence

BOT source restarted and replayable=true.
Price snapshot re-collected under the new schema; 9 symbols; point_in_time=false.
GET /api/v1/prices/health → HTTP 200, available=true, revised_vendor_history.
POST /api/v1/research/tourism/run → HTTP 200, blocked 1/12 releases.

Verification

PYTHONPATH=backend .venv/bin/python -W error -m unittest discover -s backend/tests -v
Ran 57 tests ... OK

npm run build
Vite build completed successfully.

npm audit --omit=dev --audit-level=high
found 0 vulnerabilities

python -m compileall -q backend
python /tmp/set50_platform_security_scan.py → {}
git diff --check

Boundary

Content hashes are a local artifact/corruption control. They are not a signature against a hostile operator who can rewrite the application, manifests, raw files and runtime environment. Add a trusted deployment signing key before multi-user or hostile-host deployment.

Independent review

passed: true
security_concerns: []
logic_errors: []

Non-blocking backlog: retain the canonicalization/hash-version contract, keep crash/partial-write coverage, and introduce signed manifests when the deployment threat model expands.