Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ All notable product changes are recorded here. PolicyWeave is pre-release; entri
- Collection-path editing remains in the collection step while processing-purpose editing stays in its dedicated purpose step.
- Review preview applies the same whitespace-normalized purpose-completeness contract as the blocking review rule.
- Step-rail, previous/next, and review-warning navigation now transfers programmatic focus to the newly active step heading; ordinary form controls and the dedicated preview shortcut are excluded from that transfer.
- Review-warning navigation now lets the browser scroll the focused owner heading into view; the previous `preventScroll` option could leave that heading hundreds of pixels above the desktop or mobile viewport.
- The publication-area CTA describes a readiness check and directs the operator to responsible review rather than exposing internal implementation boundaries.
- Unshipped JSON export is visibly disabled as `준비 중`, the redundant no-op `검토본 생성` control was removed, and the document title is non-interactive status text.
- Authored generic and custom-checkbox keyboard focus outlines now use the high-contrast `--green` token; a CSS regression test computes and enforces at least 3:1 contrast against white instead of relying on a low-contrast focus color.
Expand All @@ -45,7 +46,7 @@ All notable product changes are recorded here. PolicyWeave is pre-release; entri

### Not yet shipped
- Authoritative legal-rule snapshots that can determine legal sufficiency beyond product-defined fact completeness.
- Full browser-matrix/accessibility evidence and screenshot verification beyond CSS focus contrast and deterministic step-focus transition tests.
- Manual zoom and screen-reader evidence beyond the automated desktop/tablet/mobile Chromium accessibility and focus checks.
- Durable versioned policy persistence and audit history.
- Authenticated immutable publication revisions and public URL lifecycle.
- Hosted tenant/security/operability evidence and endpoint load testing.
6 changes: 3 additions & 3 deletions docs/TRD.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ This TRD covers the pre-release PolicyWeave browser workspace and the contracts
- Structured authoring state is in browser memory; no production database or backend exists.
- `src/policy.ts` owns deterministic review logic for collection selection/no-collection attestation/mode/purpose/path and the non-collection authoring-completeness findings for service identity, explicit retention status/period, transfer statuses/details, and privacy contact.
- `src/App.tsx` provides the seven-step authoring flow, review navigation, explicit collection/retention/transfer-status capture, stale dependent-fact invalidation, and deterministic preview projection.
- `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; ordinary form controls and the dedicated preview shortcut are outside this behavior.
- `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, horizontal overflow, serious/critical axe findings, 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.

Expand All @@ -23,7 +23,7 @@ This TRD covers the pre-release PolicyWeave browser workspace and the contracts
8. Blank/whitespace authoring facts are normalized as unresolved where that fact is required by the explicit governing status.
9. Disabling a collection item invalidates dependent collection-mode, processing-purpose, and collection-path evidence; re-enabling requires renewed confirmation.
10. Every blocking finding links to the responsible editing step.
11. Explicit step navigation through the rail, previous/next controls, or a blocking-finding action transfers focus to the newly active step heading after that surface renders. This logical focus-order contract must not steal focus from ordinary editing controls or the dedicated preview shortcut.
11. Explicit step navigation through the rail, previous/next controls, or a blocking-finding action transfers focus to the newly active step heading after that surface renders. The focused heading must remain fully inside the current viewport; navigation must not suppress the browser scroll needed to reveal it. This contract must not steal focus from ordinary editing controls or the dedicated preview shortcut.
12. Preview text is derived from current structured facts, including independent collection and retention statuses; it does not become an independently editable authority.
13. UI copy distinguishes a review draft from legal advice, certification, or a compliance guarantee.

Expand All @@ -33,7 +33,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.
- Browser/accessibility validation must include keyboard/focus order, 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 focus-not-obscured, zoom, screen-reader, or responsive verification.
- 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
8 changes: 5 additions & 3 deletions docs/product-technical-gap-baseline.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,19 +38,21 @@ The browser-evidence slice adds a bounded Playwright/axe harness to the existing

Exact-head CI `34073373104` then supplied the missing real-browser evidence. Dependency installation, lint, 45 tests, production build, Chromium installation, all three keyboard/no-collection cases, and artifact upload succeeded; the three viewport accessibility cases consistently failed on the same muted token. Axe measured `#6d756f` at 4.17–4.45:1 against the authored rail, conditional-field, and metadata backgrounds. A RED stylesheet contract reproduces those exact background combinations and requires 4.5:1; the single shared token is darkened to `#656d67`, whose weakest current authored pairing is above the threshold. This is a bounded text-contrast repair, not a claim of WCAG conformance, and remains pending an exact-head browser rerun.

The focus-not-obscured slice preserved the reviewed PR #1 head and stacked a browser contract above it. Its first hosted RED (`34079868713`) exposed an ambiguous test locator rather than product behavior, so the locator was narrowed to the specific service-name finding without changing production. The corrected exact-head RED (`34080045989`) then proved the product defect: keyboard activation focused the correct owner heading but left it at `y=-656` on desktop and `y=-581` on mobile; tablet passed and the matrix finished 7/9. `AuthoringFocusController` no longer suppresses focus scrolling, allowing the browser to reveal the focused heading. This is bounded responsive focus-target evidence; zoom and screen-reader evidence remain open, and GREEN requires a fresh exact-head hosted rerun.
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved

## Current baseline

| Area | Evidence | Status | Commercialization gap | Owner/action | Next verification |
| --- | --- | --- | --- | --- | --- |
| Guided authoring | PRD, ADR-0002, seven routed editors, first-responsibility startup, `getReview`, explicit retention `getDraftReview`, no-collection/transfer states | Repaired foundation | Fresh state no longer skips or falsely completes step 1; collection, retention, transfer and other responsibilities fail closed independently; collection-path evidence remains unstructured free text and legal sufficiency is deliberately separate | Policy Fact Authoring: preserve deterministic completeness and independent authority; add structured path-evidence types only when a real integration/use case proves the need | Exact-head unit/UI edge tests, then browser E2E |
| Customer-fact authority | Zero-inferred startup facts; truthful initial rail state; explicit no-collection; independent explicit retention status; explicit transfer states; stale dependent-fact invalidation | Repaired | No known buyer-facing authority dead end remains in the in-memory seven-step fact model; hosted persistence must preserve these independent states without deriving one from another | Policy Fact Authoring: encode collection and retention as separate revision-owned facts; no automatic no-collection→no-retention rule | Persistence/schema invariant tests and exact-head UI tests |
| Review workspace | Live preview, total blocker count, warning-to-owner navigation, buyer-facing readiness guidance, deterministic step-heading focus transfer, proposed Playwright viewport/screenshot harness | Implemented foundation; browser execution pending | Exact-head browser artifact has not yet proved the new desktop/tablet/mobile cases | UX: run the proposed harness in exact-head CI, repair real failures, then extend interaction coverage | Exact-head screenshots, keyboard/focus and accessibility checks |
| Accessibility | Semantic controls, visible focus behavior, focus-token >=3:1 regression, muted-text >=4.5:1 authored-surface regression, jsdom focus transition, axe/browser checks | Partial; browser-discovered contrast repaired, rerun pending | Zoom, screen-reader, full focus-not-obscured scenarios, and manual WCAG evidence remain absent even if the automated run passes | UX/Test Engineering: verify the contrast repair in exact-head axe/Playwright and add a manual interaction record without claiming conformance from automation alone | Exact-head WCAG/browser matrix including no-collection and retention transitions |
| Review workspace | Live preview, total blocker count, warning-to-owner navigation, buyer-facing readiness guidance, deterministic step-heading focus transfer, Playwright viewport/screenshot harness | Implemented foundation; offscreen focus repaired, rerun pending | Exact-head GREEN has not yet proved the focus-scroll repair | UX: rerun the desktop/tablet/mobile harness, retain exact-head artifacts, then extend interaction coverage | Exact-head screenshots, keyboard/focus and accessibility checks |
| Accessibility | Semantic controls, visible focus behavior, focus-token >=3:1 regression, muted-text >=4.5:1 authored-surface regression, jsdom focus transition, axe/browser and focused-heading viewport checks | Partial; exact hosted RED repaired, rerun pending | Zoom, screen-reader, retention-transition and manual WCAG evidence remain absent even if the automated run passes | UX/Test Engineering: verify the focus repair in exact-head Playwright and add a manual interaction record without claiming conformance from automation alone | Exact-head WCAG/browser matrix including no-collection and retention transitions |
| Legal/rule traceability | `docs/research-traceability.md`; PIPA/PIPC source/effective-date model; PIPC Notice No. 2025-4 terminology bound to collection/retention separation | Source baseline established | Current readiness rules are product completeness only; no versioned article/section-level legal-rule engine | Legal Source Registry: map future legal validations to source/effective date/revision | Snapshot fixtures across effective dates |
| Policy model | ADRs, ARCHITECTURE, TRD | Designed, browser-memory only | No versioned durable schema, migrations, audit history, 3NF implementation, or explicit UPSERT/idempotency | Platform: define `policy_revision` schema and item-level conflict contracts before storage; persist no-collection and retention status independently on the revision-owned fact model | Schema tests and migration round trip |
| 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 | 46 unit/UI regressions plus a six-case desktop/tablet/mobile Playwright/axe matrix and screenshot artifact contract | Improved; first browser RED repaired, rerun pending | Exact-head all-GREEN browser execution and repository-wide 100% execution/docstring coverage are not yet evidenced | Test Engineering: verify the current browser repair, then measure coverage | Exact-head coverage + browser evidence |
| Tests | 46 unit/UI regressions plus a nine-case desktop/tablet/mobile Playwright/axe matrix and screenshot artifact contract | Improved; focus-scroll RED repaired, rerun pending | Exact-head all-GREEN browser execution and repository-wide 100% execution/docstring coverage are not yet evidenced | Test Engineering: verify the current browser repair, then measure coverage | Exact-head coverage + browser 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 | Live external gate | 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 + independent approval + resolved threads |

Expand Down
2 changes: 1 addition & 1 deletion src/AuthoringFocusController.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export function AuthoringFocusController() {
const heading = document.querySelector<HTMLElement>('.form-panel .section-head h1')
if (!heading) return
heading.tabIndex = -1
heading.focus({ preventScroll: true })
heading.focus()
}, 0)
pendingFocusTransfers.add(timer)
}
Expand Down
19 changes: 19 additions & 0 deletions tests/e2e/authoring.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,22 @@ test('preserves keyboard context through the explicit no-collection path', async
await expect(page.getByRole('heading', { level: 1, name: '3. 처리 목적' })).toBeFocused()
await expect(page.getByText('개인정보를 수집하지 않음으로 확인되었습니다.')).toBeVisible()
})

test('keeps the owning step heading visible after keyboard navigation from a review warning', async ({ page }) => {
await page.goto('/')

const serviceWarning = page
.locator('.document-warning')
.filter({ hasText: '서비스 이름 확인이 필요합니다.' })
.getByRole('button', { name: '서비스 정보 확인', exact: true })
await serviceWarning.scrollIntoViewIfNeeded()
await serviceWarning.focus()
await page.keyboard.press('Enter')

const serviceHeading = page.getByRole('heading', { level: 1, name: '1. 서비스 정보' })
await expect(serviceHeading).toBeFocused()
const headingBounds = await serviceHeading.boundingBox()
expect(headingBounds).not.toBeNull()
expect(headingBounds!.y).toBeGreaterThanOrEqual(0)
expect(headingBounds!.y + headingBounds!.height).toBeLessThanOrEqual(page.viewportSize()!.height)
})
Loading