Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ jobs:
node-version: 22
cache: npm
- run: npm ci
- name: Generate exact-head dependency SBOM
run: |
mkdir -p dependency-evidence
npm sbom --sbom-format cyclonedx > dependency-evidence/policyweave-dependency-sbom.cdx.json
- run: npm run lint
- run: npm test
- run: npm run build
Expand Down Expand Up @@ -70,3 +74,10 @@ jobs:
name: policyweave-browser-evidence
path: test-results
if-no-files-found: warn
- name: Upload exact-head dependency SBOM
if: ${{ !cancelled() }}
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: policyweave-dependency-sbom
path: dependency-evidence/policyweave-dependency-sbom.cdx.json
if-no-files-found: error
1 change: 1 addition & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ PolicyWeave is a local-first privacy-policy fact-authoring workspace. It structu
- Keep persistence objects semantically named with at least two words and `snake_case` unless a framework contract requires another convention. Avoid generic named persistence objects such as a standalone `id` table/collection.
- Hosted persistence/publication must be introduced only behind explicit tenant, authorization, audit, encryption, immutable revision, and supersession contracts. CI PostgreSQL restart and dump/restore evidence lives in `db/tests/policy_revision_restore.sh` and does not enable a hosted adapter. Seed `retention_status = applies` only in the same transaction as its `retention_rule`; autocommit fails the deferred fact contract.
- GitHub Actions dependencies stay SHA pinned and checkout credentials must not persist.
- Direct npm dependencies stay pinned to their reviewed lock resolutions. Compiler and bundler packages belong in `devDependencies`, and exact-head CI publishes a CycloneDX dependency SBOM without treating license metadata as legal approval.

## Verification
The minimum exact-head gate is `npm run lint`, `npm test`, and `npm run build`, plus every live organization-required workflow, independent approval, and resolved review thread. Queued, skipped, predecessor-head, or stale results are not passing evidence.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ All notable product changes are recorded here. PolicyWeave is pre-release; entri
## Unreleased

### Added
- Executable npm manifest/lock/license contracts and an exact-head CycloneDX SBOM artifact. Every direct declaration must equal its reviewed lock resolution, the lock root must match the manifest, and every locked package must retain machine-readable license metadata.
- Deterministic local JSON draft export with a versioned `snake_case` contract, normalized operator-authored facts, explicit incomplete/review-ready state, readiness finding codes, and fail-closed rejection of service URLs containing credentials, query, or fragment components. Unresolved collection mode is serialized as `null`, not the UI empty-string sentinel, and object-URL cleanup is deferred until after download navigation starts. The browser download performs no network transfer and does not claim publication.
- PostgreSQL restart and custom-format dump/restore evidence that preserves NULL-safe complete service/collection-item values, a collecting-without-retention cross-state fixture, and independent no-collection and applies-retention facts, then re-executes no-collection plus both retention-status/rule contradictions against the restored database.
- PostgreSQL two-session concurrency evidence that observes real lock waits, rejects a collection-item writer racing with a no-collection update, and proves competing same-item UPSERTs converge to one row carrying the second writer's label, mode, and path with NULL-safe complete-value assertions and without timing-based transaction sleeps.
Expand All @@ -20,6 +21,7 @@ All notable product changes are recorded here. PolicyWeave is pre-release; entri
- Playwright/axe browser evidence harness covering desktop, tablet, and mobile rendering; horizontal overflow; keyboard activation and focus transfer; explicit no-collection progression; retention-status transitions and stale-period invalidation; effective 200% browser-zoom reflow from the desktop profile; serious/critical automated accessibility findings; real-browser JSON download events with mouse, keyboard, and touch activation; fixed filename; JSON MIME; byte-stable repeated exports; review-ready payload semantics; success and preparation/activation-error object-URL cleanup; and exact-head screenshot artifacts.

### Changed
- All direct npm packages now use exact reviewed versions. React and Lucide remain runtime dependencies; TypeScript, Vite, and the React Vite plugin are correctly classified with the test/build toolchain in `devDependencies`, and npm regenerated the lock graph so transitive development scope is accurate.
- PostgreSQL negative-path evidence now matches each expected domain error message, so an unrelated SQL or connection failure cannot masquerade as a passing invariant check.
- Repository CI now starts one digest-pinned PostgreSQL 18 service inside the existing verification job and runs the migration contract before browser evidence, avoiding a second workflow or runner while producing real database evidence.
- Repository CI now groups runs by workflow plus pull-request number or branch ref and cancels superseded heads, preventing stale queued runs from consuming runner capacity without coupling unrelated PRs or refs.
Expand Down
3 changes: 2 additions & 1 deletion docs/SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,10 @@ Protected assets include policy facts, contact details, processing descriptions,
7. Define backup/restore, incident response, access review, retention/deletion, and evidence collection before claiming SOC 2 readiness. Map hosted controls toward CSAP and SOC 2 without describing an unassessed product as certified.
8. Tests/docs use fictionalized organizations and people; real personal/institutional names are not fixtures.
9. Service URLs containing credentials, query, or fragment components are invalid and withheld from the review projection; operators must provide a credential-free HTTP(S) location whose destination can be exported without lossy rewriting.
10. Direct npm declarations use exact reviewed lock resolutions, and compiler/bundler packages are development-only. Exact-head CI emits a CycloneDX SBOM from the installed lock graph; the package-lock license inventory supports review but does not itself approve license compatibility.

## Verification
Security posture is head-specific. A successful predecessor scan, unresolved finding dismissal, or queued security workflow is not passing evidence. Merge/release decisions must reacquire the exact current head's organization-required security/SAST/review checks.
Security posture is head-specific. A successful predecessor scan, unresolved finding dismissal, or queued security workflow is not passing evidence. Merge/release decisions must reacquire the exact current head's organization-required security/SAST/review checks plus the dependency manifest contract and CycloneDX artifact. Vulnerability or license inventory is evidence for review, not a substitute for an explicit release decision.


## Local JSON export
Expand Down
2 changes: 2 additions & 0 deletions docs/TRD.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ This TRD covers the pre-release PolicyWeave browser workspace and the contracts
- `src/AuthoringFocusController.tsx` keeps explicit step navigation and review-warning jumps aligned with the newly active step by moving programmatic focus to its heading after the React update and allowing the browser to reveal that target; ordinary form controls and the dedicated preview shortcut are outside this behavior.
- The current CI contract is lint, Vitest, TypeScript/Vite build, and Playwright Chromium browser evidence plus live organization-required security/review workflows. Browser cases cover desktop/tablet/mobile rendering, keyboard-triggered focus transfer, the explicit no-collection path, retention-status transitions with stale-period invalidation, effective 200% browser-zoom reflow from the desktop layout viewport, horizontal overflow, serious/critical axe findings, real download events with mouse, keyboard, and touch activation, fixed filename, JSON MIME, byte-stable repeated exports, review-ready payload semantics, object-URL cleanup on success and simulated activation failure, contained pre-allocation failure, failure announcement, and per-project screenshots retained as an exact-head artifact.
- Muted small text uses one authored color token whose contrast is regression-tested against every current surface background at a minimum 4.5:1 ratio; browser axe remains the integration authority for rendered combinations.
- Direct npm declarations equal the exact reviewed versions resolved by `package-lock.json`. `react`, `react-dom`, and `lucide-react` are the only runtime packages; the compiler, bundler, Vite React plugin, lint, test, browser, type, and DOM harnesses are development packages. CI generates a CycloneDX 1.5 SBOM from the exact installed lock graph and retains it as a head-bound artifact; license fields are inventory evidence, not a legal compatibility decision.

## Functional contracts
1. Every PRD step must route to an editable surface; selecting a step cannot change only the rail indicator.
Expand All @@ -34,6 +35,7 @@ The separation between collection and retention follows the PIPC Standard Person
- Touched production behavior requires regression and edge-case tests first.
- Touched production functions carry descriptive JSDoc rather than relying on implicit behavior.
- Do not suppress deprecation warnings to pass CI.
- Dependency changes must update the manifest and npm-generated lock graph together, keep build-only tools out of production dependencies, retain machine-readable license inventory, and reacquire exact-head vulnerability, SBOM, and license evidence.
- Browser/accessibility validation must include keyboard/focus order, focus-target viewport visibility, WCAG 2.2 automated checks, responsive desktop/tablet/mobile interactions, and screenshot evidence before a buyer-facing accessibility claim. Deterministic jsdom focus-transition coverage is supporting evidence only and does not substitute for real-browser, zoom, screen-reader, or responsive verification.
- Hosted web endpoints, when introduced, use non-blocking/asynchronous handling and require realistic k6 tests before a p95 <=20 ms page/API claim is recorded.
- Production does not depend on synthetic demo data.
Expand Down
7 changes: 5 additions & 2 deletions docs/product-technical-gap-baseline.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ The subsequent Codex P1 review found that the validator and preview accepted que

The final URL-boundary follow-up found that WHATWG `URL.search` and `URL.hash` are empty for authored bare delimiters even though serialization retains `?` or `#`. Test-first head `0580f466837bc5b000a54e79732b08bf83a3fd2f` added both empty-delimiter cases to the existing query/hash/secret matrix; CI `34230043117` passed lint and failed in `npm test` before the source repair. Minimal child `9d92a9ea716c5427161450df34ef142caaaf64e6` checks the canonical serialization for actual delimiters, rejecting bare query/fragment markers through the one readiness/preview/export boundary. Positive edge coverage at `a6cf635fcfc082fafacff13b658108fd076fd474` separately proves encoded `%3F`/`%23` pathname data remains admissible and byte-preserved, preventing a later raw-input substring check from over-blocking legitimate path data. Exact source-fix CI `34230291396` passed 70/70 Vitest, build, PostgreSQL migration/concurrency/restart/restore, and 22 Playwright/axe cases with eight intentional project-scope skips; artifact `10057683181` is bound by digest `sha256:6d2e7fc1ddafefdbd55e9c13b716dca123ba148dc753d65efb26d1bb5e3c26f4`. This closes the reviewed delimiter bypass without widening URL parsing or adding another validator.

The dependency-governance pass found that every direct npm declaration was either `latest` or a mutable caret range and that TypeScript, Vite, and the React Vite plugin were incorrectly classified as production dependencies. Test-only head `80b69d6a640194997906ec23ca0140f28fd95908` produced exact RED CI `34244619215`: clean install and lint passed, 73 predecessor tests passed, and only the two new pin/classification contracts failed. Minimal implementation `cd9144f4a8a78427457bb58ee4b0a5f75a1ca750` pins all 21 direct packages to their existing reviewed lock resolutions, moves the three build packages to `devDependencies`, and uses npm to regenerate development-scope metadata without changing any resolved package version. A second test-only head `f6bbf9d6e5621ac26e3d1905556c192c2c8613c7` produced exact RED CI `34245711353`: 75 tests passed and only the missing CycloneDX publication contract failed. Workflow repair `a3592da89c75be87564e1d4ec8d9e685e9e3093e` generates a CycloneDX 1.5 SBOM from the exact installed lock graph and uploads it through the existing SHA-pinned artifact action. A final storage review found that placing the SBOM below `test-results` duplicated it in both browser and dependency artifacts. Test-only head `3c8ac646c7ccd0140976f3fcefc914fc4b9a7d80` produced exact RED CI `34246822467` with 75 passing tests and only the new artifact-isolation contract failing; minimal repair `00b89fb6c986b22e2453a58f4b6dc61ba7ff1dff` writes the SBOM once below `dependency-evidence` and uploads only that path as the dependency artifact. Current review follow-up independently checks runtime and development declarations, asserts both artifact destinations, and names all three runtime packages consistently. The lock/license and SBOM evidence support security and legal review but do not themselves approve dependency licenses or replace organization vulnerability gates.

## Current baseline

| Area | Evidence | Status | Commercialization gap | Owner/action | Next verification |
Expand All @@ -81,7 +83,8 @@ The final URL-boundary follow-up found that WHATWG `URL.search` and `URL.hash` a
| Policy model | ADRs, ARCHITECTURE, TRD, ADR-0003, Proposed ERD, up/down migration, schema, runtime, two-session concurrency, restart, and dump/restore contract tests | Proposed 3NF foundation; PostgreSQL 18 exact-head CI execution required; browser runtime remains memory-only | Apply/down/apply, exact negative errors, observed lock waits, conflicting-fact rejection, same-item UPSERT convergence with NULL-safe complete label/mode/path assertions, process restart, and custom-format restore with a collection/no-retention cross-state, NULL-safe complete service name/URL and item assertions, and restored no-collection plus both retention contradiction checks are implemented; authorization, audit, encryption, deletion, and production-scale contention remain unproved | Platform: retain exact-head PostgreSQL evidence, then add the hosted authorization/audit boundary while keeping the adapter disabled | Tenant authorization, immutable audit, and encryption tests |
| Publication | Readiness CTA truthfully does not pretend to publish; immutable `publication_revision` is designed | Planned | No authenticated approval, immutable publication, supersession, rollback, or public URL lifecycle | Review & Publication: implement after persistence/security entry criteria | Authorization, replay/digest, supersession tests |
| Security/privacy | `docs/SECURITY.md`; local-first runtime; SHA-pinned checkout | Baseline documented | Hosted tenant model, encryption/key handling, audit/incident/retention evidence absent | Platform/Security: threat-model hosted boundary before backend | Exact-head security tests and org scans |
| Tests | 71 unit/UI/schema/workflow regressions plus PostgreSQL runtime/concurrency/restore scripts, 23 Playwright/axe passes, ten intentional project-scope skips, real-browser interaction/download/error contracts, and a screenshot artifact contract | Improved; bounded exact-head unit/build/browser/PostgreSQL GREEN | Repository-wide 100% execution/docstring coverage is not yet evidenced | Test Engineering: measure coverage and extend realistic edge cases | Exact-head coverage + browser/database evidence |
| Dependency supply chain | Exact-pinned manifest, npm-regenerated lock graph, executable pin/scope/license contracts, and CycloneDX 1.5 CI artifact | Repaired foundation on open stack; exact-head release gate still applies | License compatibility approval and organization vulnerability verdict remain external review responsibilities | PolicyWeave owns direct dependency intent; CI/Security owners retain scanning and release gates | Exact-head clean install, 76 tests, build, SBOM artifact/digest, vulnerability checks, and explicit license review |
| Tests | 76 unit/UI/schema/workflow/dependency regressions plus PostgreSQL runtime/concurrency/restore scripts, 23 Playwright/axe passes, ten intentional project-scope skips, real-browser interaction/download/error contracts, and screenshot/SBOM artifact contracts | Improved; bounded exact-head verification required after every head movement | Repository-wide 100% execution/docstring coverage is not yet evidenced | Test Engineering: measure coverage and extend realistic edge cases | Exact-head coverage + browser/database/dependency evidence |
| Performance | Static Vite client | Unevidenced | No realistic buyer-flow browser performance baseline; no network backend exists for meaningful k6 endpoint evidence | Operability: record browser baseline now; add k6 only when hosted network surfaces exist | Real measurements before latency claims |
| CI/security merge gate | Repo CI plus active organization ruleset-required workflows; immutable Node 24-based checkout, setup/cache, and artifact-upload action releases | Live external gate; warning-free evidence is re-fetched for the exact merge candidate | Every branch movement invalidates predecessor evidence and stale approval; current hosted jobs may remain queued before runner assignment and dependency/reviewer control-plane failures can fail closed independently | Re-fetch exact-head workflows/reviews; use the central owner path for runner/dependency-review incidents rather than leaf-side churn or bypass | Terminal exact-head checks with no action-runtime deprecation warnings + independent approval + resolved threads |

Expand All @@ -96,7 +99,7 @@ The Proposed aggregate root is the minimal `policy_revision` boundary. The no-co
A publishable release requires complete fact-to-warning navigation, deterministic rendering of captured source facts, no inferred customer operational facts, truthful first-responsibility startup/progress, explicit unresolved-review blocking across the seven authoring responsibilities, an explicit no-collection path that does not infer unrelated processing facts, independent explicit retention status, immutable reviewed publication revisions, accessible responsive interaction, authoritative source/version traceability for legal rules, hosted security/privacy evidence, and exact-head CI/security/independent review. Buyer-facing wording describes assistance and reviewability, never a compliance guarantee or an internal implementation boundary.

## Active commercialization order
1. Reacquire exact-current-head CI/security/SAST/central workflow execution and independent approval; merge PR #1 only through ordinary protection.
1. Reacquire exact-current-head CI/security/SAST/central workflow execution, dependency SBOM/license evidence, and independent approval; merge PR #1 only through ordinary protection.
2. Extend the exact-head responsive/accessibility evidence with screen-reader checks, native browser-zoom automation when the harness supports it, and manual records; CSS focus contrast, logical step-focus transfer, focused-heading viewport visibility, retention transitions, effective 200% browser-zoom reflow, and current desktop/tablet/mobile screenshots are already verified.
3. Preserve exact-head PostgreSQL 18 migration, domain-error, two-session lock, restart, and dump/restore evidence, then prove tenant authorization, immutable audit, and encryption before enabling any hosted adapter.
4. Implement secure review/publication with immutable releases and explicit supersession.
Expand Down
Loading