Fix round 1 for the Task 11 asset library review. I1 (Important): a successful delete removed the row from state, so remove()'s reuse of closeDetail() queued .focus() on a now-detached button -- a silent no-op that stranded focus on <body>. Splits closeDetail() (cancel/close, row still on screen, restores focus to the trigger) from a new closeDetailAfterRemoval() (post-delete, focuses the page heading, the one anchor guaranteed to survive any list change) so the two paths stop sharing a helper that only one of them can safely use. Also closes four Minors from the same review round: - route-contract.test.ts's "27-route inventory" test title corrected to 28. - canHardDelete's usageCount clause gets its own isolating assertion (every prior case used usageCount: 0, so that clause was never independently falsified). - Dropped a duplicate role="status" announcement on a listAssets load failure; the existing role="alert" paragraph is now the sole announcement. - Added success-path tests for archive() and remove() via a new recordingGateway() test helper that pins the exact gateway call shape (expectedVersion, managementStatus: ARCHIVED, idempotency keys), not just the resulting UI text; the delete-success test also pins the I1 focus fix so a regression back to the removed trigger fails loudly. See task-11-report.md's "Fix round 1" section for the RED/GREEN evidence (the pre-fix code reliably crashes the test worker rather than failing the assertion cleanly -- explained there) and the correction to this task's original claim about matching publication-list.tsx's focus pattern. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Tech Log Frontend
Initialized from clean-architecture-frontend-template revision
4dc033cf33a5b6173bbf960d5eb464a406dc4c92. The exact source identity is
recorded in template.lock.json.
A React/Vite TechLog application where architecture boundaries, integration behavior, release coherence, accessibility, performance, and operations are executable contracts rather than conventions.
Start locally
Requirements: the exact Node.js version in .nvmrc (currently 24.14.0) and
Corepack. The repository pins pnpm in package.json.
Product source, tests, build/quality scripts, and supported tool configuration
are TypeScript/TSX. allowJs is disabled. Node-side .ts scripts run directly
on the pinned Node 24 runtime and are checked with NodeNext resolution plus
erasable-syntax enforcement. Project-owned executable source contains no
JavaScript-family files; negative architecture, security, and type-compatibility
fixtures are TypeScript/TSX as well.
corepack pnpm install --frozen-lockfile
corepack pnpm dev
Runtime-public settings live in public/config.json and are validated before
the product tree mounts. Client secrets are forbidden.
TechLog experience
The default build mounts the source-faithful TechLog Public and Studio
experience. Public routes provide discovery, search, documents, topics,
projects, releases, and profile content. /studio provides the session-scoped
mock authoring workflow: create, edit, validate, preview, publish, unpublish,
and immutable publication history.
The 27 canonical route definitions are divided into PUBLIC and STUDIO
nested layouts. Studio authentication remains deliberately deferred; its mock
gateway state lasts for one Studio shell session and resets on a full document
load. The exact route, dependency, stylesheet, asset, and parity inventory is
recorded in
docs/operations/techlog-ui-migration-baseline.md.
corepack pnpm build emits a self-contained dist/server.mjs production
boundary. corepack pnpm preview --host 127.0.0.1 --port 4174 serves known
Public and Studio routes as SPA documents, preserves the in-shell Studio 404,
and returns source-exact raw 404 text/plain responses for missing Public
content. With the read-only source temp-copy server on 4375, run:
TECH_LOG_SOURCE_URL=http://127.0.0.1:4375 \
TECH_LOG_TARGET_URL=http://127.0.0.1:4174 \
corepack pnpm verify:tech-log-source-parity
Architecture
Dependencies point inward:
presentation -> application -> domain
adapters -----^
bootstrap composes concrete adapters
contracts own cross-cutting registries
See docs/architecture/overview.md, docs/architecture/layers.md, and
docs/architecture/starter-experience.md. TechLog is one feature boundary
under src/features/tech-log. Its immutable Public catalog and session-scoped
Studio mock gateway are injected through the application feature input;
Public and Studio presentation code shares the typed content renderer without
importing concrete adapters. The retained reference feature remains a
non-product platform contract fixture and can be removed without changing the
TechLog route set.
Platform capability review
The starter shell is implemented, but the repository review also records the remaining work required before feature teams can use every declared contract through one end-to-end application path:
- platform capability review
- ports, adapters, and feature boundaries
- REST, GraphQL, Connect/gRPC-Web, Schema, Mapper, and Server State
- Protobuf browser transports and REST Gateway
- backend API and Server State handoff contract
- TypeScript, state ownership, and data flow
- routing, page templates, and reusable patterns
- browser data capability completion ledger
- browser file and origin-storage platform
- client cache and storage
- realtime events, Web Push, and bounded polling
- presigned transfer, resumable upload, streaming download, and Image CDN
- server file capability infrastructure
- design-system platform
- frontend platform testing strategy
- implementation roadmap
These documents distinguish repository defaults from opt-in adapters and project-owned integrations. They are target designs and review findings; a capability is not treated as implemented until its branch acceptance criteria and executable gates pass.
Verification
Common local checks:
corepack pnpm lint
corepack pnpm check:types
corepack pnpm check:types:app
corepack pnpm check:types:node
corepack pnpm check:types:test
corepack pnpm check:architecture
corepack pnpm test:all
corepack pnpm test:e2e
corepack pnpm test:a11y
corepack pnpm build
corepack pnpm check:bundle
corepack pnpm test:performance
corepack pnpm verify:compatibility
corepack pnpm verify:release
corepack pnpm check:registries
corepack pnpm drill:runbooks
corepack pnpm check:ci
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
check:types는 source, Node scripts/config와 tests를 분리된 TypeScript
project로 모두 검사한다. type/architecture/security/registry의 invalid
fixture는 config/ci/gates.json에서 “실패해야 통과”하는 negative gate로
실행된다. 도구 호환성 결정은
VD-01에 기록돼
있다.
Application feature input은 module augmentation으로 닫힌 ID와 정확한 input
shape를 제공하며, 공통 Result<Value, Failure = AppFailure>는 error registry의
failure kind만 application/presentation 경계를 통과시킨다. Architecture gate는
TypeScript/TSX의 static, dynamic, type import를 별도 정적 그래프로 분석하고
runtime/source 영역의 JavaScript 재유입도 거절한다. 해석되지 않은 import,
parse failure, 금지 계층 edge와 순환 의존은 모두 fail-closed이며 전용
TypeScript/TSX negative fixture로도 검증된다.
Install the pinned Playwright browser engines before the first cross-browser run:
corepack pnpm exec playwright install --with-deps chromium firefox webkit
Two gates intentionally need external evidence:
review:a11y-manualneeds a signed human keyboard/focus/screen-reader review for all 27 registered routes:NOT_FOUND,TECH_LOG_CASE,TECH_LOG_EXPLORE,TECH_LOG_EXPLORE_KIND,TECH_LOG_HOME,TECH_LOG_PROFILE,TECH_LOG_PROJECT,TECH_LOG_PROJECTS,TECH_LOG_PROJECT_ACTIVITY,TECH_LOG_PROJECT_DECISIONS,TECH_LOG_PROJECT_RECORDS,TECH_LOG_QUESTION,TECH_LOG_REFERENCE,TECH_LOG_RELEASE,TECH_LOG_RELEASES,TECH_LOG_SEARCH,TECH_LOG_STUDIO_DOCUMENTS,TECH_LOG_STUDIO_DOCUMENT_EDIT,TECH_LOG_STUDIO_DOCUMENT_NEW,TECH_LOG_STUDIO_DOCUMENT_PREVIEW,TECH_LOG_STUDIO_DOCUMENT_PUBLISH,TECH_LOG_STUDIO_DOCUMENT_VALIDATION,TECH_LOG_STUDIO_HOME,TECH_LOG_STUDIO_NOT_FOUND,TECH_LOG_STUDIO_PUBLICATIONS,TECH_LOG_STUDIO_PUBLICATION_PREVIEW,TECH_LOG_TOPIC.verify:documentationderives that list from the route registry and fails if this paragraph falls behind it.collect:web-vitals-evidencestaysFAIL_UNVERIFIEDuntil a reviewed minimum eligible-sample threshold and 28 days of production data exist.
Live release verification additionally requires HOSTING_BASE_URL.
CI and evidence
The 26-gate registry is config/ci/gates.json; the Gitea workflow is
.gitea/workflows/quality-gates.yml. It follows:
MERGE_READY -> RELEASE_READY -> PROD_PROMOTION_READY -> FIELD_SLO_READY
DOCUMENTATION_READY is independent. No gate is downgraded to a warning.
Machine-readable evidence is written below artifacts/; generated evidence is
ignored by Git while .gitkeep files preserve the taxonomy.
Operational details are in docs/operations/, with incident procedures in
docs/runbooks/.