feat: ship production local assurance viewer in core

This commit is contained in:
thanhnv
2026-07-28 23:09:22 +07:00
parent 3cc897c5bb
commit 9c9efb1043
21 changed files with 2544 additions and 136 deletions
@@ -0,0 +1,99 @@
# CASAN Core Local Assurance Viewer
## Product decision
A project that installs only CASAN Core can inspect production-quality visual
reports. Platform is not a prerequisite for basic visibility.
Core owns the single-project review loop:
- latest assurance receipt and run history;
- interactive H1→H7 evidence spine;
- H6 runtime, reliability, token/cost coverage, freshness and findings;
- loading, empty, error, legacy and partial-telemetry states;
- self-contained HTML and machine-auditable JSON export on demand.
Platform remains the centralized operations layer: multi-project fleet views,
organization RBAC, shared approval queues, remote ingestion, governed settings
and managed retention.
## Lifecycle
```text
Prompt finishes
└─ hook writes canonical trace/events/H6 + latest-run receipt
└─ no server, no HTML export, no second model call
Developer runs `casan view`
└─ Core starts or reuses a loopback viewer
├─ reads bounded evidence projections
├─ opens latest/specified trace
└─ generates HTML/JSON only when Export is selected
```
Do not run `casan report export` after every prompt. Export is an independent
review artifact, not the evidence source of truth.
## Commands
```bash
casan report latest
casan view [trace-id] [--no-open]
casan report export [trace-id] --format html|json [-o path]
casan report export --h6 --format html|json [-o path]
casan dashboard start [--port 0]
casan dashboard open
casan dashboard status
casan dashboard stop
```
When Platform code is installed, `casan dashboard` manages the centralized
Control Plane. `casan view` remains the predictable Core single-project viewer.
## Runtime and packaging contract
- Python standard library only; no Node/npm or network dependency.
- Static HTML/CSS/JS ships inside `casan-core`.
- System fonts only; no CDN, analytics or external asset requests.
- Managed and vendored Core use the same runtime allowlist.
- Runtime tests and source-only tooling do not cross the release boundary.
- Evidence remains under the project's `.specify/` tree.
## Security model
- binds only to `127.0.0.1` on an ephemeral port by default;
- rejects non-loopback clients and non-loopback `Host` headers;
- requires a high-entropy session token for every API/export request;
- stores viewer state as `0600` on POSIX and under the project ACL on Windows;
- exposes GET-only evidence APIs; mutation verbs return `405`;
- sends CSP, `no-store`, `nosniff`, frame denial and no-referrer headers;
- validates trace/project filters and never resolves a request path as a file;
- bounds source reads, record counts and response size;
- rotates the non-evidence request log at 1 MiB and never logs the session token;
- redacts prompt bodies, credentials, tool input/output and authorization data;
- keeps missing token/cost values `null`, never fabricated as zero.
The UI shell itself is non-sensitive and may load without a token. All project
metadata, evidence and exports require the session token.
## Production acceptance gate
The Core viewer is releasable only when all of these pass:
1. unit contracts for empty, legacy, partial, certified and unsafe-input states;
2. clean-project test from the built `casan-core` tarball;
3. no `packages/casan-control-panel`, `package.json` or Node dependency in Core;
4. unauthorized API, mutation and Host-header checks fail closed;
5. run/H6 HTML and JSON export work offline;
6. browser validation covers the report hierarchy, interaction and responsive
navigation;
7. existing harness, DevKit installation and packaging suites remain green.
## Maturity statement
This viewer improves evidence usability; it does not grant CASAN Maturity L4.
Maturity is assessed from real operational evidence, ownership, controls and
repeatability. The interface must show the recorded maturity status and must
not infer a level from the installed edition.