53 KiB
TechLog Public and Studio UI Migration Implementation Plan
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: Move every Public and Studio screen from /home/donghyeon/workspace/techlog-studio-frontend into this Vite frontend while preserving the source DOM, text, assets, CSS, responsive behavior, accessibility semantics, and user-visible interactions exactly.
Architecture: Keep the target repository's Vite, React Router, application API, diagnostics, route lifecycle, and adapter boundaries. Install one tech-log feature whose presentation is split into nested PUBLIC and STUDIO layout groups; expose immutable Public queries and a factory-scoped StudioGateway through application feature inputs; use source-equivalent static Public data and the deterministic mock Studio adapter. The Public renderer is shared with Studio previews so one content-format implementation produces both views.
Tech Stack: Node 24, pnpm 11, TypeScript 7, React 19, React Router 7, Vite 8, Vitest 4, Testing Library, Playwright, Axe, Tailwind 4, Pretendard 1.3.9, IBM Plex Mono 5.3.0, Unified 11.0.5, Remark Parse 11.0.0, Remark GFM 4.0.1, Remark Directive 4.0.0.
Source of truth and delivery branch
- Approved design:
docs/superpowers/specs/2026-08-15-techlog-ui-migration-design.md. - Visual/behavior source:
/home/donghyeon/workspace/techlog-studio-frontendat the locally inspected revision used when Task 1 records the baseline. - Delivery flow is already initialized with
mainas production anddevelopas integration. Execute every task and commit onfeature/techlog-ui-migration; finish throughgit flow feature finish techlog-ui-migrationonly after Task 14 is green and the user authorizes integration. - Do not push, merge, finish the feature, or delete branches as part of an individual task.
Non-negotiable constraints
- Visual parity means no redesign: preserve source element order, nesting, class names, visible copy, labels, ARIA, SVGs, typography, spacing, color values, borders, shadows, animation, and responsive rules.
- Copy
app/globals.css,app/studio.css,app/studio-editor.css,components/studio/workflow.module.css, andcomponents/studio/publication-flow.module.csswithout value or selector changes. Remove only the source@import "tailwindcss"because targettheme.cssalready owns that import. - Preserve the source breakpoints, including 1179, 1050, 1024, 980, 900, 767, and 420 pixels. Do not substitute the target generic design-system components where doing so changes source markup or styles.
- Preserve
public/favicon.svgandpublic/media/fetch-strategy-boundary.svgbyte-for-byte. Add only assets demonstrably referenced by a migrated screen. - The only permitted framework translations are:
next/linkto React RouterLinkwithhrefrenamed toto; the Studio공개 사이트 보기boundary remains a plain<a href="/">so it performs the source-intended full reload/session reset;usePathname/Next navigation touseLocation/useNavigate;next/imageto animgthat preserves classes, dimensions, alt text, loading intent, and wrapper structure; server page inputs to validated route params/search plus injected feature queries. - No Next.js, Vinext, Cloudflare, server actions, or direct presentation-to-adapter imports enter the target.
- Public behavior stays deterministic and static. Studio behavior stays session-scoped and deterministic through one provider-owned mock gateway instance. Reload resets Studio state; remounting child routes does not.
- Studio authentication is deliberately deferred. Studio routes use
access: "public"in this migration so the current shell is reachable, whilelayoutGroup: "STUDIO"and the application feature input remain the future auth seam. Do not add fake sign-in UI. - Unknown public content renders the Public not-found experience; unknown
/studio/*and unknown document/publication IDs render Studio not-found inside the Studio shell. Param codecs accept non-empty strings and do not reject unknown IDs before gateway lookup. - Every production change follows red → green → focused regression → commit. Never update a test merely to legitimize a visual or behavioral difference.
- The pre-existing
tests/unit/ci-artifact-contract.test.tschild-process failures caused by the restricted environment are baseline infrastructure evidence, not permission to add failures. Record exact commands/counts; focused TechLog tests and static gates must pass.
Fixed contracts
Route grouping
Add this field to every route definition:
export type RouteLayoutGroup = "PUBLIC" | "STUDIO";
export type RouteDefinition = Readonly<{
routeId: string;
path: string;
layoutGroup: RouteLayoutGroup;
paramsSchema: string | null;
searchSchema: string | null;
access: "public" | "session-required";
loadingSurface: string;
errorSurface: string;
chunkId: string;
title: string;
navigationLabel: string | null;
navigationOrder: number | null;
}>;
The installed TechLog route IDs and paths are fixed:
| Layout | Route ID | Path |
|---|---|---|
| PUBLIC | TECH_LOG_HOME |
/ |
| PUBLIC | TECH_LOG_EXPLORE |
/explore |
| PUBLIC | TECH_LOG_EXPLORE_KIND |
/explore/:kind |
| PUBLIC | TECH_LOG_CASE |
/cases/:slug |
| PUBLIC | TECH_LOG_REFERENCE |
/references/:slug |
| PUBLIC | TECH_LOG_QUESTION |
/questions/:slug |
| PUBLIC | TECH_LOG_TOPIC |
/topics/:slug |
| PUBLIC | TECH_LOG_PROJECTS |
/projects |
| PUBLIC | TECH_LOG_PROJECT |
/projects/:slug |
| PUBLIC | TECH_LOG_PROJECT_RECORDS |
/projects/:slug/records |
| PUBLIC | TECH_LOG_PROJECT_DECISIONS |
/projects/:slug/decisions |
| PUBLIC | TECH_LOG_PROJECT_ACTIVITY |
/projects/:slug/activity |
| PUBLIC | TECH_LOG_RELEASES |
/releases |
| PUBLIC | TECH_LOG_RELEASE |
/releases/:version |
| PUBLIC | TECH_LOG_PROFILE |
/profile |
| PUBLIC | TECH_LOG_SEARCH |
/search |
| STUDIO | TECH_LOG_STUDIO_HOME |
/studio |
| STUDIO | TECH_LOG_STUDIO_DOCUMENTS |
/studio/documents |
| STUDIO | TECH_LOG_STUDIO_DOCUMENT_NEW |
/studio/documents/new |
| STUDIO | TECH_LOG_STUDIO_DOCUMENT_EDIT |
/studio/documents/:id/edit |
| STUDIO | TECH_LOG_STUDIO_DOCUMENT_VALIDATION |
/studio/documents/:id/validation |
| STUDIO | TECH_LOG_STUDIO_DOCUMENT_PREVIEW |
/studio/documents/:id/preview |
| STUDIO | TECH_LOG_STUDIO_DOCUMENT_PUBLISH |
/studio/documents/:id/publish |
| STUDIO | TECH_LOG_STUDIO_PUBLICATIONS |
/studio/publications |
| STUDIO | TECH_LOG_STUDIO_PUBLICATION_PREVIEW |
/studio/publications/:publicationEventId/preview |
| STUDIO | TECH_LOG_STUDIO_NOT_FOUND |
/studio/* |
| PUBLIC | NOT_FOUND |
* |
Route schema IDs are also fixed. Parameter codecs are TechLogExploreKindParams (kind non-empty; page-level lookup recognizes only cases | references | questions), TechLogSlugParams (slug non-empty), TechLogVersionParams (version non-empty), TechLogDocumentIdParams (id non-empty), TechLogPublicationEventIdParams (publicationEventId non-empty), TechLogStudioSplat, and the existing NotFoundSplat. Search codecs are TechLogHomeSearch (focus, state), TechLogExploreSearch (type, topic, project), TechLogExploreKindSearch (topic, project), TechLogSearchQuery (q), and TechLogCaseStateSearch (state); all fields are optional single strings and canonicalization keeps the first repeated value, trims selections where the source does, and drops unknown fields. Other routes use none.
Each TechLog route uses a unique kebab-cased chunk/module identity derived from its ID: lower-case the route ID, replace underscores with hyphens, and prefix route- (for example, TECH_LOG_STUDIO_DOCUMENT_EDIT → route-tech-log-studio-document-edit). The global NOT_FOUND keeps route-not-found. This same identity must appear in the runtime contract, lazy import map, release manifest, diagnostics, and chunk-recovery tests.
Feature input and gateway
export const TECH_LOG_FEATURE_ID = "tech-log" as const;
export type TechLogFeatureInput = Readonly<{
publicContent: PublicContentQueries;
createStudioGateway(): StudioGateway;
}>;
declare module "../../../application/ports/in/application-api.ts" {
interface ApplicationFeatureInputs {
"tech-log": TechLogFeatureInput;
}
}
export interface StudioGateway {
getDashboard(options?: RequestOptions): Promise<StudioDashboard>;
listDocuments(query: ListDocumentsQuery, options?: RequestOptions): Promise<DocumentPage>;
createDocument(input: CreateDocumentInput, options: IdempotentOptions): Promise<WorkingCopy>;
getDocument(documentId: string, options?: RequestOptions): Promise<WorkingCopyDetail>;
saveDocument(documentId: string, command: SaveDocumentCommand, options: IdempotentOptions): Promise<WorkingCopyDetail>;
validateDocument(documentId: string, command: ValidateDocumentCommand, options: IdempotentOptions): Promise<ValidationReport>;
createPreview(documentId: string, command: CreatePreviewCommand, options: IdempotentOptions): Promise<PublicPreview>;
getCurrentPreview(documentId: string, options?: RequestOptions): Promise<PreviewDetail>;
publishDocument(documentId: string, command: PublishDocumentCommand, options: IdempotentOptions): Promise<PublishResult>;
unpublishPublication(publicationId: string, command: UnpublishCommand, options: IdempotentOptions): Promise<PublishResult>;
listPublications(query: ListPublicationsQuery, options?: RequestOptions): Promise<PublicationPage>;
getPublicationSnapshot(publicationEventId: string, options?: RequestOptions): Promise<PublicationSnapshot>;
getCatalog(query: CatalogQuery, options?: RequestOptions): Promise<CatalogPage>;
}
Use the source generated contract names and exact payload fields from lib/studio/api/generated.ts. StudioGatewayError retains RFC 9457-like problem details, HTTP status, stable code, and retryability. Abort remains distinguishable from not-found/conflict/validation failures.
PublicContentQueries is the immutable boundary for the source functions listRecords, getRecord, getProject, getRelease, getProjectRecords, getProjectDecisions, getProjectActivity, getHomeFocusItems, and searchPublicContent, with the source argument and return types unchanged.
State derivation
Port the source pure functions and values exactly:
deriveValidationState(input: StateInput): ValidationState;
derivePreviewState(input: StateInput): PreviewState;
deriveNextAction(input: StateInput): NextAction;
deriveDocumentState(input: StateInput): StudioDocumentState;
Editor state is CLEAN | DIRTY | SAVING | CONFLICT; validation freshness is NONE | CURRENT | STALE; publication state is NEVER_PUBLISHED | PUBLISHED | UNPUBLISHED. The saved revision/version token owns optimistic concurrency.
Deterministic source-to-target map
| Source | Target |
|---|---|
lib/content-format/*, lib/public-render-content.ts |
src/features/tech-log/domain/content-format/*, src/features/tech-log/domain/public-render-content.ts |
lib/content.ts, lib/evidence-assets.ts, lib/public-content.ts, lib/public-query.ts |
src/features/tech-log/adapters/static/* behind PublicContentQueries |
lib/studio/api/*, contracts/studio-api.openapi.yaml |
src/features/tech-log/contracts/studio/* and src/features/tech-log/application/ports/studio-gateway.ts |
lib/studio/document-state.ts, lib/studio/local-id.ts |
src/features/tech-log/domain/studio/* |
lib/studio/mock/* |
src/features/tech-log/adapters/mock/* |
public components/*.tsx |
src/features/tech-log/presentation/public/components/* |
Studio components/studio/*.tsx |
src/features/tech-log/presentation/studio/components/* |
public app/**/page.tsx |
src/features/tech-log/presentation/public/pages/* |
Studio app/studio/** |
src/features/tech-log/presentation/studio/pages/* |
| source CSS | src/features/tech-log/presentation/styles/* |
public/favicon.svg, public/media/fetch-strategy-boundary.svg |
same target-relative paths |
Component and stylesheet ports must retain source file boundaries where practical. Rename a file only for Vite/React Router clarity; do not combine components in a way that obscures parity review.
Task 1: Freeze the migration baseline and dependency/assets contract
Files:
-
Create:
docs/operations/techlog-ui-migration-baseline.md -
Modify:
package.json -
Modify:
pnpm-lock.yaml -
Create:
public/favicon.svg -
Create:
public/media/fetch-strategy-boundary.svg -
Test:
tests/features/tech-log/migration-baseline.test.ts -
Step 1: Write the red asset-integrity test. Assert each target SVG's SHA-256 against a hand-recorded expected source hash (never an external source-path read in CI) and exercise the evidence asset lookup so an altered path/hash breaks a consumer-visible contract. Dependency pins are verified by the package manager's frozen-lockfile command; the human baseline document and its route/CSS inventory are reviewed rather than tested as source text. Include the source commit SHA or, if the source worktree has uncommitted changes, its HEAD SHA plus
git status --shortin the baseline document. -
Step 2: Run red.
corepack pnpm exec vitest run tests/features/tech-log/migration-baseline.test.ts
Expected: the migrated assets and evidence lookup are absent.
- Step 3: Add exact dependencies and assets. Run
corepack pnpm add pretendard@1.3.9 @fontsource/ibm-plex-mono@5.3.0 unified@11.0.5 remark-parse@11.0.0 remark-gfm@4.0.1 remark-directive@4.0.0, copy only the two approved assets, and record checksums, source state, the 27 expected routes, and the five CSS files in the baseline document. Do not add Next/Vinext/Cloudflare packages. - Step 4: Run green and lockfile verification.
corepack pnpm exec vitest run tests/features/tech-log/migration-baseline.test.ts
corepack pnpm verify:lockfile
git diff --check
- Step 5: Commit.
git add package.json pnpm-lock.yaml public/favicon.svg public/media/fetch-strategy-boundary.svg docs/operations/techlog-ui-migration-baseline.md tests/features/tech-log/migration-baseline.test.ts
git commit -m "chore: establish TechLog migration baseline"
Task 2: Port Studio API contracts and the application-facing feature seam
Files:
-
Create:
src/features/tech-log/contracts/studio/studio-api.openapi.yaml -
Create:
src/features/tech-log/contracts/studio/generated.ts -
Create:
src/features/tech-log/contracts/studio/contract.ts -
Create:
src/features/tech-log/application/ports/studio-gateway.ts -
Create:
src/features/tech-log/application/ports/studio-gateway-error.ts -
Create:
src/features/tech-log/application/ports/public-content-queries.ts -
Create:
src/features/tech-log/application/tech-log-feature-input.ts -
Test:
tests/features/tech-log/studio-contract.test.ts -
Test:
tests/features/tech-log/feature-input.test.ts -
Step 1: Write red contract tests. Port the source shape assertions and add compile/runtime assertions that the exact gateway method set above is exposed, feature ID is
tech-log, andApplicationFeatureInputs["tech-log"]accepts queries plus a gateway factory but no concrete adapter. -
Step 2: Run red.
corepack pnpm exec vitest run tests/features/tech-log/studio-contract.test.ts tests/features/tech-log/feature-input.test.ts
Expected: TechLog contracts and feature input do not exist.
- Step 3: Port contracts without reshaping payloads. Copy the OpenAPI and generated types, replace source-local aliases only, implement the port/error, define
PublicContentQueriesfrom the source query return shapes, and add the module augmentation shown above. - Step 4: Run green and inward-boundary checks.
corepack pnpm exec vitest run tests/features/tech-log/studio-contract.test.ts tests/features/tech-log/feature-input.test.ts
corepack pnpm check:types:app
corepack pnpm check:architecture
- Step 5: Commit.
git add src/features/tech-log/contracts src/features/tech-log/application tests/features/tech-log/studio-contract.test.ts tests/features/tech-log/feature-input.test.ts
git commit -m "feat: add TechLog feature contracts"
Task 3: Port Content Format v1 and the shared public render model
Files:
-
Create:
src/features/tech-log/domain/content-format/heading-id.ts -
Create:
src/features/tech-log/domain/content-format/inline-plain-text.ts -
Create:
src/features/tech-log/domain/content-format/parse-case-content.ts -
Create:
src/features/tech-log/domain/content-format/serialize-case-content.ts -
Create:
src/features/tech-log/domain/content-format/project-public-render-model.ts -
Create:
src/features/tech-log/domain/public-render-content.ts -
Create:
src/features/tech-log/presentation/shared/public-render/* -
Test:
tests/features/tech-log/content-format.test.ts -
Test:
tests/features/tech-log/public-render.test.tsx -
Step 1: Port the source parser/serializer/renderer tests first. Keep headings, inline text, GFM tables, directives, evidence figures, code blocks, callouts, malformed-input fallback, unsafe HTML/script/
javascript:/unknown-asset rejection, and parse→serialize round-trip fixtures byte-equivalent. Include code-copy success/failure/live-region reset and evidence zoom open/backdrop-close/button-close/trigger-focus restoration. -
Step 2: Run red.
corepack pnpm exec vitest run tests/features/tech-log/content-format.test.ts tests/features/tech-log/public-render.test.tsx
Expected: shared content functions/components are absent.
- Step 3: Port the pure format code and renderer components. Map
components/public-render/*,code-block.tsx,document-toc.tsx, and both evidence-figure implementations intopresentation/shared. Preserve emitted tags/classes/ARIA and sanitize/escape behavior; do not use raw HTML insertion. - Step 4: Run green and security/architecture gates.
corepack pnpm exec vitest run tests/features/tech-log/content-format.test.ts tests/features/tech-log/public-render.test.tsx
corepack pnpm check:browser-security
corepack pnpm check:architecture
- Step 5: Commit.
git add src/features/tech-log/domain src/features/tech-log/presentation/shared tests/features/tech-log/content-format.test.ts tests/features/tech-log/public-render.test.tsx
git commit -m "feat: port TechLog content format and renderer"
Task 4: Compose deterministic Public content and the mock Studio gateway
Files:
-
Create:
src/features/tech-log/adapters/static/content.ts -
Create:
src/features/tech-log/adapters/static/evidence-assets.ts -
Create:
src/features/tech-log/adapters/static/public-content.ts -
Create:
src/features/tech-log/adapters/static/public-query.ts -
Create:
src/features/tech-log/domain/studio/document-state.ts -
Create:
src/features/tech-log/domain/studio/local-id.ts -
Create:
src/features/tech-log/adapters/mock/* -
Create:
src/features/tech-log/adapters/create-tech-log-feature-input.ts -
Modify:
src/features/installed-feature-adapters.ts -
Test:
tests/features/tech-log/public-query.test.ts -
Test:
tests/features/tech-log/studio-document-state.test.ts -
Test:
tests/features/tech-log/mock-studio-gateway.test.ts -
Test:
tests/features/tech-log/runtime-composition.test.ts -
Step 1: Port red source tests. Cover Public type/kind/status/search filtering, stable ordering, source fixtures, state derivation, deterministic IDs/cursors, create/save conflict, validation, preview freshness/expiry, publish/unpublish, snapshots, idempotency, abort, and gateway error shapes.
-
Step 2: Run red.
corepack pnpm exec vitest run tests/features/tech-log/public-query.test.ts tests/features/tech-log/studio-document-state.test.ts tests/features/tech-log/mock-studio-gateway.test.ts tests/features/tech-log/runtime-composition.test.ts
Expected: data adapters and installed tech-log input are absent.
- Step 3: Port data/state/mock code exactly. Preserve fixture IDs, timestamps, copy, pagination cursors, validation issue order, error codes, stable stringify rules, preview content, and publication history. Add the TechLog input beside the temporarily retained reference-feature input in
createInstalledFeatureInputs; one call tocreateStudioGatewaycreates one isolated mutable session. - Step 4: Run green and boundary checks.
corepack pnpm exec vitest run tests/features/tech-log/public-query.test.ts tests/features/tech-log/studio-document-state.test.ts tests/features/tech-log/mock-studio-gateway.test.ts tests/features/tech-log/runtime-composition.test.ts
corepack pnpm check:types:app
corepack pnpm check:architecture
- Step 5: Commit.
git add src/features/tech-log/adapters src/features/tech-log/domain/studio src/features/installed-feature-adapters.ts tests/features/tech-log/public-query.test.ts tests/features/tech-log/studio-document-state.test.ts tests/features/tech-log/mock-studio-gateway.test.ts tests/features/tech-log/runtime-composition.test.ts
git commit -m "feat: compose TechLog static and mock adapters"
Task 5: Add the nested route-group capability and freeze TechLog route contracts
Files:
-
Modify:
src/contracts/routes.ts -
Modify:
src/contracts/route-runtime-contract.ts -
Modify:
src/features/installed-feature-contracts.ts -
Modify:
src/features/installed-feature-runtimes.tsx -
Modify:
src/features/reference-feature/contracts/reference-feature-contract.ts -
Modify:
config/contracts/registry-governance.json -
Modify:
src/presentation/routes/app-router.tsx -
Modify:
src/presentation/routes/route-codecs.ts -
Modify:
src/presentation/routes/platform-route-codecs.ts -
Create:
src/features/tech-log/contracts/tech-log-route-contract.ts -
Create:
src/features/tech-log/contracts/tech-log-message-catalog.ts -
Create:
src/features/tech-log/presentation/tech-log-route-codecs.ts -
Test:
tests/features/tech-log/route-contract.test.ts -
Modify:
tests/component/router.test.tsx -
Step 1: Add red route tests. Assert the exact standalone 27-entry TechLog contract table,
layoutGroup, Studio routes currently public, non-empty string codecs, generic Public/Studio parent assembly, Studio catch-all precedence over global catch-all, and canonical URL creation. The installed starter registry remains intact through this task so no route points to an unfinished screen. -
Step 2: Run red.
corepack pnpm exec vitest run tests/features/tech-log/route-contract.test.ts tests/component/router.test.tsx
Expected: layout grouping and the standalone TechLog route contract are missing.
- Step 3: Implement grouped route assembly without incomplete runtime entries. Build a pure
createGroupedRouteObjectshelper that accepts a registry, matching runtime, and layout elements, then creates Public/Studio parentRouteObjects while retainingRouteLifecycle,RouteInputProvider,ProtectedRoute, Suspense, render boundary, and chunk recovery around each registered leaf. AddlayoutGroup: "PUBLIC"to currently installed platform/reference definitions and keep the existingAppShellas the installed Public layout until Task 13 atomically installs the complete TechLog runtime. ExtendFE-REG-ROUTEgovernance with required string fieldlayoutGroup, allowed valuesPUBLIC | STUDIO, and the TechLog route/search schema IDs; addlayoutGroupto breaking fields because layout lifetime changes navigation behavior. - Step 4: Run green and registry gates.
corepack pnpm exec vitest run tests/features/tech-log/route-contract.test.ts tests/component/router.test.tsx
corepack pnpm check:registries:structure
corepack pnpm check:architecture
- Step 5: Commit.
git add src/contracts/routes.ts src/contracts/route-runtime-contract.ts src/features/installed-feature-contracts.ts src/features/installed-feature-runtimes.tsx src/features/reference-feature/contracts/reference-feature-contract.ts src/features/tech-log/contracts/tech-log-route-contract.ts src/features/tech-log/contracts/tech-log-message-catalog.ts src/features/tech-log/presentation/tech-log-route-codecs.ts src/presentation/routes/app-router.tsx src/presentation/routes/route-codecs.ts src/presentation/routes/platform-route-codecs.ts config/contracts/registry-governance.json tests/features/tech-log/route-contract.test.ts tests/component/router.test.tsx
git commit -m "feat: add grouped TechLog route contracts"
Task 6: Port exact styles, fonts, Public shell, header, and search dialog
Files:
-
Create:
src/features/tech-log/presentation/styles/globals.css -
Create:
src/features/tech-log/presentation/styles/studio.css -
Create:
src/features/tech-log/presentation/styles/studio-editor.css -
Create:
src/features/tech-log/presentation/styles/workflow.module.css -
Create:
src/features/tech-log/presentation/styles/publication-flow.module.css -
Modify:
src/main.tsx -
Create:
src/features/tech-log/presentation/public/components/site-header.tsx -
Create:
src/features/tech-log/presentation/public/components/search-dialog.tsx -
Create:
src/features/tech-log/presentation/public/components/fatal-error-state.tsx -
Create:
src/features/tech-log/presentation/public/public-shell.tsx -
Test:
tests/features/tech-log/style-contract.test.ts -
Test:
tests/features/tech-log/public-shell.test.tsx -
Step 1: Add red style and interaction contracts. Render the real shell and assert its DOM/class/ARIA relationships plus consumer-visible computed typography, color, width, spacing, focus, and minimum target behavior where the test browser supports it; media-query transitions and full computed-style/pixel equality remain Task 14 browser assertions. Assert header links/labels match,
/brand navigation works, search opens by click and keyboard, Escape/focus restoration work, and dialog results navigate to canonical routes. Do not grep CSS source text or assert private CSS-module key inventories. -
Step 2: Run red.
corepack pnpm exec vitest run tests/features/tech-log/style-contract.test.ts tests/features/tech-log/public-shell.test.tsx
Expected: source styles/shell are absent.
- Step 3: Copy styles and port shell components. Import fonts and TechLog CSS after target
theme.css; translate navigation APIs only. Preserve source header DOM and mobile behavior. Ensure Public pages render inside source-equivalent<main>without the oldAppShellchrome. - Step 4: Run green and static style checks.
corepack pnpm exec vitest run tests/features/tech-log/style-contract.test.ts tests/features/tech-log/public-shell.test.tsx
corepack pnpm lint
corepack pnpm check:types:app
- Step 5: Commit.
git add src/main.tsx src/features/tech-log/presentation/styles src/features/tech-log/presentation/public tests/features/tech-log/style-contract.test.ts tests/features/tech-log/public-shell.test.tsx
git commit -m "feat: port TechLog shells and styles"
Task 7: Port Public home, explore, and search screens
Files:
-
Create:
src/features/tech-log/presentation/public/components/home-focus.tsx -
Create:
src/features/tech-log/presentation/public/components/latest-index.tsx -
Create:
src/features/tech-log/presentation/public/components/explore-filter-form.tsx -
Create:
src/features/tech-log/presentation/public/components/public-record-list.tsx -
Create:
src/features/tech-log/presentation/public/pages/home-page.tsx -
Create:
src/features/tech-log/presentation/public/pages/explore-page.tsx -
Create:
src/features/tech-log/presentation/public/pages/explore-kind-page.tsx -
Create:
src/features/tech-log/presentation/public/pages/search-page.tsx -
Create:
src/features/tech-log/domain/public/focus-state.ts -
Test:
tests/features/tech-log/public-discovery-screens.test.tsx -
Step 1: Add red component cases. Port source expectations for headings, introductory copy, counts, latest records, focus-tab URL normalization and Arrow/Home/End keyboard movement, explore kind/status/query filters, empty results, URL search synchronization, result ordering, keyboard submit, and result navigation.
-
Step 2: Run red.
corepack pnpm exec vitest run tests/features/tech-log/public-discovery-screens.test.tsx
Expected: discovery pages are missing.
- Step 3: Port exact source JSX and bind queries. Replace async Next server inputs with
useRouteInputplusapplication.features.get("tech-log").publicContent; preserve DOM/classes/copy and query semantics. UseLink/useNavigatetranslations only. - Step 4: Run green and typecheck.
corepack pnpm exec vitest run tests/features/tech-log/public-discovery-screens.test.tsx
corepack pnpm check:types:app
- Step 5: Commit.
git add src/features/tech-log/domain/public/focus-state.ts src/features/tech-log/presentation/public tests/features/tech-log/public-discovery-screens.test.tsx
git commit -m "feat: port TechLog discovery screens"
Task 8: Port Public cases, references, questions, and topics
Files:
-
Create:
src/features/tech-log/presentation/public/components/public-document-header.tsx -
Create:
src/features/tech-log/presentation/public/components/public-document-relations.tsx -
Create:
src/features/tech-log/presentation/public/components/case-document-page.tsx -
Create:
src/features/tech-log/presentation/public/components/reference-document-page.tsx -
Create:
src/features/tech-log/presentation/public/components/question-document-page.tsx -
Create:
src/features/tech-log/presentation/public/pages/case-page.tsx -
Create:
src/features/tech-log/presentation/public/pages/reference-page.tsx -
Create:
src/features/tech-log/presentation/public/pages/question-page.tsx -
Create:
src/features/tech-log/presentation/public/pages/topic-page.tsx -
Test:
tests/features/tech-log/public-document-screens.test.tsx -
Step 1: Add red cases from source rendered-HTML and interaction tests. Assert each known slug's exact title, metadata, relation sections, table of contents, rendered blocks, evidence media, anchors, back links, and topic aggregation. Assert unknown slugs use Public not-found rather than a generic runtime error.
-
Step 2: Run red.
corepack pnpm exec vitest run tests/features/tech-log/public-document-screens.test.tsx
Expected: document route pages are missing.
- Step 3: Port page/component JSX and connect shared renderer. Preserve all source record ordering and classes. Keep specialized hard-coded source case pages represented by the same exact output at their canonical slugs.
- Step 4: Run green plus accessibility component checks.
corepack pnpm exec vitest run tests/features/tech-log/public-document-screens.test.tsx tests/features/tech-log/public-render.test.tsx
corepack pnpm check:types:app
- Step 5: Commit.
git add src/features/tech-log/presentation/public tests/features/tech-log/public-document-screens.test.tsx
git commit -m "feat: port TechLog document screens"
Task 9: Port projects, releases, profile, and Public fallbacks
Files:
-
Create:
src/features/tech-log/presentation/public/components/project-navigation.tsx -
Create:
src/features/tech-log/presentation/public/components/project-page-header.tsx -
Create:
src/features/tech-log/presentation/public/pages/projects-page.tsx -
Create:
src/features/tech-log/presentation/public/pages/project-overview-page.tsx -
Create:
src/features/tech-log/presentation/public/pages/project-records-page.tsx -
Create:
src/features/tech-log/presentation/public/pages/project-decisions-page.tsx -
Create:
src/features/tech-log/presentation/public/pages/project-activity-page.tsx -
Create:
src/features/tech-log/presentation/public/pages/releases-page.tsx -
Create:
src/features/tech-log/presentation/public/pages/release-page.tsx -
Create:
src/features/tech-log/presentation/public/pages/profile-page.tsx -
Create:
src/features/tech-log/presentation/public/pages/public-not-found-page.tsx -
Test:
tests/features/tech-log/public-index-screens.test.tsx -
Step 1: Add red cases. Assert exact project tabs/active states, record/decision/activity filtering and order, release index/detail text, profile content, cross-links, and Public unknown-route/unknown-record copy.
-
Step 2: Run red.
corepack pnpm exec vitest run tests/features/tech-log/public-index-screens.test.tsx
Expected: remaining Public screens are missing.
- Step 3: Port exact source markup and route wiring. Translate Next links only; derive active tab from React Router location without changing element structure.
- Step 4: Run complete Public green suite.
corepack pnpm exec vitest run tests/features/tech-log/public-*.test.tsx tests/features/tech-log/content-format.test.ts tests/features/tech-log/public-query.test.ts
corepack pnpm check:types:app
- Step 5: Commit.
git add src/features/tech-log/presentation/public tests/features/tech-log/public-index-screens.test.tsx
git commit -m "feat: complete TechLog public screens"
Task 10: Port Studio provider, runtime boundary, shell, dashboard, list, and creation
Files:
-
Create:
src/features/tech-log/presentation/studio/studio-provider.tsx -
Create:
src/features/tech-log/presentation/studio/use-studio.ts -
Create:
src/features/tech-log/presentation/studio/studio-runtime-boundary.tsx -
Create:
src/features/tech-log/presentation/studio/components/studio-header.tsx -
Create:
src/features/tech-log/presentation/studio/components/studio-dashboard.tsx -
Create:
src/features/tech-log/presentation/studio/components/document-list.tsx -
Create:
src/features/tech-log/presentation/studio/components/new-document-form.tsx -
Create:
src/features/tech-log/presentation/studio/pages/studio-home-page.tsx -
Create:
src/features/tech-log/presentation/studio/pages/documents-page.tsx -
Create:
src/features/tech-log/presentation/studio/pages/new-document-page.tsx -
Create:
src/features/tech-log/presentation/studio/pages/studio-not-found-page.tsx -
Create:
src/features/tech-log/presentation/studio/studio-shell.tsx -
Test:
tests/features/tech-log/studio-shell-smoke.test.tsx -
Test:
tests/features/tech-log/studio-screens-smoke.test.tsx -
Step 1: Port red shell/screen tests. Assert one gateway creation per Studio shell session, a new gateway plus cleared requests/dialogs on
pageshowwithpersisted === true, source header/nav/labels, dashboard totals/status links, list filters/pagination/empty/error/retry states, new-document type selection and redirect, direct route access without auth UI, and in-shell Studio not-found behavior. -
Step 2: Run red.
corepack pnpm exec vitest run tests/features/tech-log/studio-shell-smoke.test.tsx tests/features/tech-log/studio-screens-smoke.test.tsx
Expected: Studio provider and real pages are absent.
- Step 3: Port provider/shell/screens. Resolve
createStudioGatewaythrough the application feature input once via lazy state/ref, preserve gateway state across child navigation, cancel obsolete requests, and preserve source loading/error/not-found markup. Recreate the gateway and provider generation when a persisted bfcache page is shown; use provider generation keys so all child state and dialogs reset with it. - Step 4: Run green and composition regression.
corepack pnpm exec vitest run tests/features/tech-log/studio-shell-smoke.test.tsx tests/features/tech-log/studio-screens-smoke.test.tsx tests/features/tech-log/runtime-composition.test.ts
corepack pnpm check:architecture
- Step 5: Commit.
git add src/features/tech-log/presentation/studio tests/features/tech-log/studio-shell-smoke.test.tsx tests/features/tech-log/studio-screens-smoke.test.tsx
git commit -m "feat: port TechLog Studio shell and indexes"
Task 11: Port document editors and instant preview
Files:
-
Create:
src/features/tech-log/presentation/studio/components/common-document-fields.tsx -
Create:
src/features/tech-log/presentation/studio/components/case-fields.tsx -
Create:
src/features/tech-log/presentation/studio/components/reference-fields.tsx -
Create:
src/features/tech-log/presentation/studio/components/question-fields.tsx -
Create:
src/features/tech-log/presentation/studio/components/ordered-text-list.tsx -
Create:
src/features/tech-log/presentation/studio/components/relation-editor.tsx -
Create:
src/features/tech-log/presentation/studio/components/document-editor.tsx -
Create:
src/features/tech-log/presentation/studio/components/document-editor-screen.tsx -
Create:
src/features/tech-log/presentation/studio/components/instant-preview.tsx -
Create:
src/features/tech-log/presentation/studio/components/document-status-rail.tsx -
Create:
src/features/tech-log/presentation/studio/components/publication-flow-classes.ts -
Create:
src/features/tech-log/presentation/studio/pages/document-edit-page.tsx -
Test:
tests/features/tech-log/studio-editor-smoke.test.tsx -
Step 1: Port red editor tests. Assert exact controls/order/labels for case/reference/question, loaded working-copy values, add/remove/reorder relations and ordered lists, dirty state, status rail, instant preview updates, focus behavior, and source accessibility names.
-
Step 2: Run red.
corepack pnpm exec vitest run tests/features/tech-log/studio-editor-smoke.test.tsx
Expected: the edit route screen is missing or lacks source controls.
- Step 3: Port editor components exactly. Keep local working-copy state presentation-owned, reuse Content Format v1/shared Public renderer for preview, and preserve CSS module class-name composition through a typed
publication-flow-classes.tsequivalent. - Step 4: Run green and renderer regression.
corepack pnpm exec vitest run tests/features/tech-log/studio-editor-smoke.test.tsx tests/features/tech-log/content-format.test.ts tests/features/tech-log/public-render.test.tsx
corepack pnpm check:types:app
- Step 5: Commit.
git add src/features/tech-log/presentation/studio tests/features/tech-log/studio-editor-smoke.test.tsx
git commit -m "feat: port TechLog Studio editors"
Task 12: Implement save, conflict, dirty-leave, validation, and preview workflows
Files:
-
Create:
src/features/tech-log/presentation/studio/components/guarded-studio-link.tsx -
Create:
src/features/tech-log/presentation/studio/components/unsaved-leave-dialog.tsx -
Create:
src/features/tech-log/presentation/studio/components/use-before-unload.ts -
Create:
src/features/tech-log/presentation/studio/components/validation-report.tsx -
Create:
src/features/tech-log/presentation/studio/components/validation-screen.tsx -
Create:
src/features/tech-log/presentation/studio/components/public-preview-screen.tsx -
Create:
src/features/tech-log/presentation/studio/pages/document-validation-page.tsx -
Create:
src/features/tech-log/presentation/studio/pages/document-preview-page.tsx -
Modify:
src/features/tech-log/presentation/studio/components/document-editor-screen.tsx -
Test:
tests/features/tech-log/studio-save-navigation.test.tsx -
Test:
tests/features/tech-log/studio-validation-preview.test.tsx -
Step 1: Add red workflow cases. Cover save pending/success, revision conflict without data loss, gateway error/retry, internal link leave dialog, stay/discard/save-then-navigate choices, trigger focus restoration, browser
beforeunload, validation issue anchors, validation state/freshness, preview create/current/stale/expired states, and exact next-action labels. -
Step 2: Run red.
corepack pnpm exec vitest run tests/features/tech-log/studio-save-navigation.test.tsx tests/features/tech-log/studio-validation-preview.test.tsx
Expected: saves/guards and validation/preview pages are absent.
- Step 3: Port workflow behavior. Generate a new idempotency key per user command and reuse it only for that command's safe retry. Keep source dirty/conflict semantics, dialog DOM/focus trap/return focus, and derived state copy. Abort route-obsolete reads without converting aborts into visible errors.
- Step 4: Run green and relevant browser smoke.
corepack pnpm exec vitest run tests/features/tech-log/studio-save-navigation.test.tsx tests/features/tech-log/studio-validation-preview.test.tsx tests/features/tech-log/mock-studio-gateway.test.ts
corepack pnpm check:browser-security
- Step 5: Commit.
git add src/features/tech-log/presentation/studio tests/features/tech-log/studio-save-navigation.test.tsx tests/features/tech-log/studio-validation-preview.test.tsx
git commit -m "feat: port TechLog Studio validation workflow"
Task 13: Port publish, unpublish, publication history, and immutable snapshots
Files:
-
Create:
src/features/tech-log/presentation/studio/components/warning-acknowledgements.tsx -
Create:
src/features/tech-log/presentation/studio/components/publish-screen.tsx -
Create:
src/features/tech-log/presentation/studio/components/unpublish-dialog.tsx -
Create:
src/features/tech-log/presentation/studio/components/publication-list.tsx -
Create:
src/features/tech-log/presentation/studio/components/publication-event-preview-screen.tsx -
Create:
src/features/tech-log/presentation/studio/pages/document-publish-page.tsx -
Create:
src/features/tech-log/presentation/studio/pages/publications-page.tsx -
Create:
src/features/tech-log/presentation/studio/pages/publication-preview-page.tsx -
Create:
src/features/tech-log/presentation/tech-log-route-runtime.tsx -
Modify:
src/contracts/routes.ts -
Modify:
src/contracts/route-runtime-contract.ts -
Modify:
src/features/installed-feature-contracts.ts -
Modify:
src/features/installed-feature-runtimes.tsx -
Modify:
src/features/installed-feature-adapters.ts -
Modify:
src/features/installed-feature-messages.ts -
Modify:
src/presentation/routes/route-runtime.tsx -
Modify:
src/presentation/routes/platform-route-codecs.ts -
Modify:
public/release-manifest.json -
Modify:
scripts/test-performance.ts -
Modify:
tests/component/router.test.tsx -
Modify:
tests/component/runtime-application.test.tsx -
Modify:
tests/features/reference-feature/reference-contract.test.ts -
Remove:
src/features/reference-feature/presentation/** -
Remove:
src/presentation/examples/auth-example-page.tsx -
Remove:
src/presentation/examples/platform-overview-page.tsx -
Remove:
src/presentation/examples/state-gallery-page.tsx -
Remove:
src/presentation/examples/ui-gallery-page.tsx -
Remove:
src/presentation/pages/home-page.tsx -
Remove:
src/presentation/pages/not-found-page.tsx -
Remove:
tests/component/platform-overview-page.test.tsx -
Remove:
tests/features/reference-feature/reference-page.test.tsx -
Remove:
tests/features/reference-feature/reference-production-vertical.test.tsx -
Remove:
tests/e2e/platform-overview.spec.ts -
Remove:
tests/e2e/reference-form.spec.ts -
Remove:
tests/e2e/reference-route.spec.ts -
Remove:
tests/e2e/ui-gallery.spec.ts -
Test:
tests/features/tech-log/studio-publication-flow.test.tsx -
E2E:
tests/e2e/tech-log-studio-workflow.spec.ts -
Step 1: Port red publication tests. Assert blocked publish for invalid/stale preview, warning acknowledgement requirements, pending/error/retry behavior, successful event/URL/state, publication filtering, unpublish reason/confirmation, immutable historical snapshot rendering after later edits, and unknown publication Studio not-found.
-
Step 2: Run red.
corepack pnpm exec vitest run tests/features/tech-log/studio-publication-flow.test.tsx
Expected: publication screens are missing.
- Step 3: Port publication flow exactly. Preserve source DOM/classes/copy and gateway command ordering. Render event snapshots through the shared Public renderer; never substitute current working-copy content.
- Step 4: Atomically install the complete feature. Make
ROUTE_REGISTRY,ROUTE_RUNTIME_CONTRACT, codecs, runtime imports, and release-manifest chunk entries expose only the complete TechLog routes; configurePublicShellandStudioShellas their layout elements. Keep the non-UI reference contracts/adapters and their HTTP/platform tests installed as template contract fixtures, but remove their product routes, runtime pages, page-level tests, and every/examples/*screen. Update the reference contract test so it continues to prove API/schema/invalidation behavior without asserting product route installation. Retain platform boot, diagnostics, providers, lifecycle boundaries, service worker, and generic design-system infrastructure. - Step 5: Update route consumers. Rewrite router/runtime-application expectations for the TechLog home, point the performance probe at
TECH_LOG_HOME, and write all 27 derived chunk IDs topublic/release-manifest.json. Search the active source/tests/config for old product route imports and prove only deliberately retained platform test-fixture IDs remain. - Step 6: Run green, removal, and end-to-end workflow.
corepack pnpm exec vitest run tests/features/tech-log/studio-publication-flow.test.tsx tests/features/tech-log/studio-validation-preview.test.tsx tests/features/tech-log/mock-studio-gateway.test.ts
corepack pnpm exec vitest run tests/component/router.test.tsx tests/component/runtime-application.test.tsx tests/features/reference-feature/reference-contract.test.ts
corepack pnpm test:sample-removal
corepack pnpm check:registries:structure
corepack pnpm exec playwright test tests/e2e/tech-log-studio-workflow.spec.ts --project=chromium
- Step 7: Commit.
git add -A -- src/contracts src/features src/presentation/examples src/presentation/pages src/presentation/routes public/release-manifest.json scripts/test-performance.ts tests/features tests/component tests/e2e/platform-overview.spec.ts tests/e2e/reference-form.spec.ts tests/e2e/reference-route.spec.ts tests/e2e/ui-gallery.spec.ts tests/e2e/tech-log-studio-workflow.spec.ts
git commit -m "feat: complete TechLog Studio publication flow"
Task 14: Prove visual, responsive, accessibility, architecture, and release parity
Files:
-
Create:
tests/visual/tech-log.visual.spec.ts -
Create:
tests/e2e/tech-log-public-discovery.spec.ts -
Create:
tests/e2e/tech-log-accessibility.spec.ts -
Create:
tests/e2e/tech-log-responsive.spec.ts -
Modify:
tests/e2e/app-shell.spec.ts -
Modify:
tests/e2e/accessibility.spec.ts -
Modify:
tests/e2e/responsive.spec.ts -
Remove:
tests/e2e/compact-smoke.spec.ts -
Remove:
tests/e2e/design-system-interactions.spec.ts -
Remove:
tests/e2e/i18n.spec.ts -
Remove:
tests/e2e/theme.spec.ts -
Remove:
tests/visual/platform.visual.spec.ts -
Remove:
tests/visual/__snapshots__/platform.visual.spec.ts-snapshots/** -
Modify:
config/contracts/registry-change-evidence.json -
Modify:
config/contracts/registry-baseline.json -
Modify:
config/contracts/registry-baseline.approval.json -
Modify:
docs/operations/techlog-ui-migration-baseline.md -
Modify:
README.md -
Step 1: Add parity suites before accepting snapshots. Cover every canonical route definition, all known Public fixture slugs/versions, and every Studio screen/state. Capture full parity at 360 and 1440 pixels, breakpoint transitions at 1179/1180, 1050, 1024, 980, 900, 767/768, 420, 390, 820, and a compact 375-pixel viewport, with fixed timezone, fonts-ready wait, animation disabled, deterministic clock/data, and no masks.
-
Step 2: Establish source references. Run the source app and target app under the same Chromium viewport/device scale/color scheme, capture both into temporary artifact directories, and use pixel diff plus DOM/class/text/ARIA assertions. Require zero pixel difference after deterministic controls; if browser rasterization still differs, document the exact pixels/cause and obtain user approval before accepting a target baseline. Source reference images are not copied into target snapshots as a shortcut, and committed/CI tests read only target fixtures and snapshots rather than the external source path.
-
Step 3: Run visual/responsive/a11y red.
corepack pnpm exec playwright test tests/visual/tech-log.visual.spec.ts --config=playwright.visual.config.ts --project=chromium
corepack pnpm exec playwright test tests/e2e/tech-log-responsive.spec.ts tests/e2e/tech-log-accessibility.spec.ts --project=chromium
Expected before final corrections: any remaining framework-port drift is reported with a route/viewport-specific diff.
- Step 4: Correct only parity defects. Fix DOM/CSS/import ordering/router lifecycle differences without redesign. Confirm zero unexpected console errors, no horizontal overflow, keyboard-accessible dialogs/navigation, valid heading/landmark order, restored focus, and Axe results matching or improving on source without changing appearance.
- Step 5: Retire starter-only browser evidence. Rewrite
app-shell, registry-wide accessibility, and responsive suites against TechLog. Delete the example-gallery/theme/locale E2E cases because those controls intentionally leave the product UI, while retaining direct component/design-system tests for the underlying platform capabilities. Replace old platform screenshots with reviewed TechLog screenshots; do not leave stale snapshots unreferenced. - Step 6: Record and accept the governed route/schema migration. Run
corepack pnpm check:registriesonce to generateartifacts/quality/registries.jsonand list the exact breaking change IDs. Add one complete evidence row per reported breaking change toregistry-change-evidence.json, covering the TechLog route migration/version, atomic release-manifest/runtime update, same-release compatibility window, rollback to the prior feature commit, and ownertech-log-frontend. Rerun until evidence passes, then execute:
REGISTRY_BASELINE_OWNER=tech-log-frontend REGISTRY_BASELINE_REASON="Install approved TechLog Public and Studio route contract" node scripts/update-registry-baseline.ts artifacts/quality/registries.json
corepack pnpm check:registries
Expected: approval digest matches the newly committed snapshot and compatibility impact is none with no unacknowledged change.
- Step 7: Run focused full TechLog gates.
corepack pnpm exec vitest run tests/features/tech-log
corepack pnpm exec playwright test tests/e2e/tech-log-public-discovery.spec.ts tests/e2e/tech-log-studio-workflow.spec.ts tests/e2e/tech-log-responsive.spec.ts tests/e2e/tech-log-accessibility.spec.ts --project=chromium
corepack pnpm test:visual
- Step 8: Run repository gates and classify baseline-only failures.
corepack pnpm check:types
corepack pnpm lint
corepack pnpm check:architecture
corepack pnpm check:design-system
corepack pnpm check:i18n
corepack pnpm check:registries
corepack pnpm check:browser-security
corepack pnpm test:all
corepack pnpm build
git diff --check
git status --short
All gates must pass except an exactly reproduced, documented environment-only baseline. For any baseline exception, rerun its test in isolation, record command/output/count in the baseline document, and prove no TechLog test is among the failures.
- Step 9: Use the verification and review skills. Invoke
superpowers:verification-before-completion, thensuperpowers:requesting-code-review. Resolve findings with focused red/green tests and rerun affected gates. - Step 10: Commit final parity evidence.
git add -A -- tests/visual tests/e2e config/contracts/registry-change-evidence.json config/contracts/registry-baseline.json config/contracts/registry-baseline.approval.json README.md docs/operations/techlog-ui-migration-baseline.md
git commit -m "test: prove TechLog UI migration parity"
- Step 11: Stop before integration. Report the feature branch commit range, exact green commands, baseline-only exceptions, visual-diff result, and changed-route inventory. Wait for explicit user approval before
git flow feature finish techlog-ui-migration, merging intodevelop, pushing, or deleting the feature branch.
Definition of done
- All 27 canonical route definitions resolve under the correct nested shell, with source-equivalent unknown-content behavior.
- Public content/search/filter/navigation output matches the source data and UI.
- Studio create/edit/save/conflict/validate/preview/publish/unpublish/history flows match the source and persist for one shell session.
- No migrated presentation module imports an adapter, Next.js, Vinext, or Cloudflare module.
- Source assets and all non-Tailwind CSS rules are preserved exactly; every specified viewport has reviewed visual evidence with no unexplained pixel drift.
- Focus, keyboard, dialog, landmarks, labels, and Axe coverage pass.
- Focused tests, typecheck, lint, architecture, registry, browser-security, build, and applicable repository suites pass, with any infrastructure-only baseline reproduced and documented.
- The work remains on
feature/techlog-ui-migrationuntil the user explicitly authorizes GitFlow feature completion intodevelop.