docs: record TechLog migration evidence

This commit is contained in:
DongHyeonka
2026-08-16 05:07:58 +09:00
parent 3a7c5deca0
commit 47cbf4ddca
3 changed files with 20202 additions and 80 deletions
@@ -2,30 +2,40 @@
## Status
`DONE_WITH_CONCERNS`. The migrated UI, committed browser evidence, source-to-target
comparison, sample-removal gate, focused suites, static gates, and production
build pass. The only concern is the repository's pre-existing restricted-runner
`test:all` baseline: child-process-heavy tests cannot spawn in the managed
sandbox, and 19 provider-environment cases remain red even when isolated with
the required process scope. The isolation and exact counts below prove that no
TechLog test is among those failures.
`DONE_WITH_CONCERNS`. The production serving correction, 130-case
source-to-target comparison, full recursive product-tree evidence, direct HTTP
contract, target visuals, focused browser suites, and static gates pass. The
automated Chromium accessibility suite passes 29/29, but the 27 signed human
keyboard/focus/screen-reader records remain `PENDING`; `FE-GATE-009` is not
claimed as passing. The other concern is the repository's pre-existing
restricted-runner `test:all` baseline: 19 provider-environment cases remain
red. The isolation and exact counts below prove that no TechLog test is among
those failures.
The work remains on `feature/techlog-ui-migration`. It was not merged, pushed,
finished with GitFlow, or deleted. Task 14 is committed by this report's commit,
`test: prove TechLog UI migration parity`.
finished with GitFlow, or deleted. The immutable code candidate is
`3a7c5deca06679fb9b8710da2cce87bbca07ce8a`
(`fix: complete TechLog migration evidence`). This report and the durable
parity JSON are deliberately recorded afterward in
`docs: record TechLog migration evidence`, so the evidence can name the exact
candidate it verifies.
## Evidence files
Added or replaced product evidence:
- `tests/visual/tech-log.visual.spec.ts` and 111 target-only PNG snapshots. The
suite has 112 cases because canonical and state coverage for the 1440-pixel
- `tests/visual/tech-log.visual.spec.ts` and 129 target-only PNG snapshots. The
suite has 130 cases because canonical and state coverage for the 1440-pixel
`/studio/publications` screen deliberately share the same reviewed image.
- `scripts/lib/tech-log-production-server.ts`, the generated self-contained
`dist/server.mjs` build artifact, its serving contract/generator, and 39-case
direct HTTP regression coverage.
- `tests/e2e/tech-log-public-discovery.spec.ts`,
`tests/e2e/tech-log-accessibility.spec.ts`, and
`tests/e2e/tech-log-responsive.spec.ts`.
- `tests/support/browser/tech-log-fixtures.ts` and the external, manually run
`tests/support/browser/verify-tech-log-source-parity.ts` evidence harness.
- `tests/support/browser/tech-log-fixtures.ts`, the checked Node 24 parity
runner, and durable
`docs/operations/evidence/tech-log-source-parity.json` evidence.
- Focused regressions in `tests/unit/vite-route-chunks.test.ts`,
`tests/unit/design-system-source.test.ts`, the bounded-body reader tests, the
router component suite, and TechLog feature suites.
@@ -50,8 +60,9 @@ left referenced.
The supplied source at `/home/donghyeon/workspace/techlog-studio-frontend` was
never written. It was copied to `/tmp/techlog-source-parity.I0CBK7`; build and
Vinext runtime caches were created only in that temporary copy. The source
production server and target Vite preview were opened by one Playwright Chromium
instance with two fresh contexts and the following identical controls:
production server on `4375` and target `dist/server.mjs` production artifact on
`4174` were opened by one Playwright Chromium instance with two fresh contexts
and the following identical controls:
- device scale factor 1, light color scheme, `ko-KR`, `Asia/Seoul`, reduced
motion, service workers blocked, 1000-pixel viewport height, and full-page
@@ -59,22 +70,41 @@ instance with two fresh contexts and the following identical controls:
- fixed clock `2026-08-14T01:00:00.000Z`, deterministic in-memory data,
`document.fonts.ready`, matching Pretendard/IBM Plex Mono font-face state,
and zero-duration animation, transition, and caret styles;
- no masks and no tolerance: exact RGBA pixel comparison, product-subtree
tag/class/text/ARIA projection, layout diagnostics, and console/page/request
failure collection.
- no masks and no tolerance: exact RGBA pixel comparison, normalized recursive
product-subtree tags, ordered child nodes, complete classes, attributes,
text and ARIA relationships, layout diagnostics, response metadata, boot
lifecycle, and console/page/request failure collection.
The only attributes normalized by name are diagnostics-confirmed framework
outputs: React Router `data-discover`; Next Image `data-nimg`, `decoding`, and
`srcset`; and Next SSR `selected` for a controlled select. Generated React IDs
and CSS-module hashes are normalized by value; there is no broad attribute
omission.
The final external comparison command was:
```bash
TECH_LOG_SOURCE_URL=http://127.0.0.1:4275 TECH_LOG_TARGET_URL=http://127.0.0.1:4274 corepack pnpm exec tsx tests/support/browser/verify-tech-log-source-parity.ts
TZ=Asia/Seoul corepack pnpm verify:tech-log-source-parity
```
Result: **112/112 passed**, 0 failed, `totalDifferentPixels=0`, every DOM/class/
text/ARIA projection equal, and 0 unexplained source/target errors. Source
Result: **130/130 passed**, 0 failed, `totalDifferentPixels=0`, every recursive
DOM/class/attribute/text/ARIA tree equal, all HTTP metadata equal, and 0
unexplained source/target errors. Source
screenshots were temporary comparison inputs; none was copied into target
snapshots. The no-update target visual run also passed 112/112 with
snapshots. The no-update target visual run also passed 130/130 with
`maxDiffPixels=0` and `maxDiffPixelRatio=0`.
The durable evidence identifies source-tree digest
`6724c2f898eefc62d2fc0ee695bccc3ae61a69c5153ed43c69f2cf99ee45bca5`,
candidate `3a7c5deca06679fb9b8710da2cce87bbca07ce8a`, build-manifest digest
`3579650faa482f566553c00d8b4a05a05b4f7a1ab93b83e48676289bbcf02984`,
Vite-manifest digest
`cfd583ed7b6c27dce7f47389447608636b6b9df3e28df00c6416674da2c7c46d`,
case-inventory digest
`5689bcdb5d5637205cdeb92b7c57f72d99f0b039818b8f90afdde526bbafe0ac`,
and evidence-payload digest
`f046047beded19ce468be607dcf99c6b74d4e07323457ec7145c56d2f67d2c79`.
The comparison found and corrected actual integration defects rather than
accepting drift: the TechLog Tailwind bootstrap is loaded exactly once in the
same cascade order as source; the starter theme import is removed; CSS-module
@@ -84,10 +114,12 @@ source/target CSS pairs pass `cmp -s`; their hashes are recorded in the
operations baseline.
Source production returns missing dynamic slugs and an unmatched Public path as
HTTP 404, `text/plain`, with the exact nine-byte body `Not Found`. Curl and
Chromium regression evidence therefore fixes the target to that shell-free
response. This is an observed source-production contract and satisfies the
planned prohibition on a generic runtime error; it is not a redesign.
HTTP 404, `text/plain;charset=UTF-8`, with the exact nine-byte body `Not Found`.
The target production boundary now returns that exact shell-free response;
known Public paths and all known Studio paths remain SPA-served, while an
unknown Studio path preserves the source's HTML Studio shell with HTTP 404.
This is an observed source-production contract and satisfies the planned
prohibition on a generic runtime error; it is not a redesign.
## Route, viewport, and state inventory
@@ -105,9 +137,10 @@ All known Public fixtures were exercised: two cases, two references, two open
questions, three topics, both projects and all three nested views, and release
`0.1.0`. Ten unknown Public dynamic shapes were also compared at both widths.
The 112-case matrix is 54 canonical-route captures, 12 home breakpoints (1180,
1179, 1050, 1024, 980, 900, 820, 768, 767, 420, 390, and 375), 19 Studio
states, 20 unknown-Public captures, and 7 interactions. Studio states cover the
The 130-case matrix is 54 canonical-route captures, 18 additional known Public
fixture captures, 12 home breakpoints (1180, 1179, 1050, 1024, 980, 900, 820,
768, 767, 420, 390, and 375), 19 Studio states, 20 unknown-Public captures, and
7 interactions. Studio states cover the
dashboard, list/new, Case/Reference/Question/conflict editors, valid/invalid
validation, current/missing/expired previews, ready/blocked publish,
publications/snapshot, missing document/publication, and unknown Studio route.
@@ -120,8 +153,14 @@ warning acknowledgement through publish-ready state.
- Required four-spec Chromium command: **48/48 passed**. It covers Public
discovery, the full Studio workflow, responsive behavior, and accessibility.
- Responsive plus accessibility focused command: **26/26 passed**.
- Exact target visual command: **112/112 passed** in 2.5 minutes with no masks
- Direct production HTTP contract: **39/39 passed**, including exact raw Public
404s, the in-shell Studio 404, known SPA routes, and boot documents.
- Exact target visual command: **130/130 passed** in 2.5 minutes with no masks
and zero pixel tolerance.
- Automated Chromium `@a11y`: **29/29 passed**. The 27 human review records are
intentionally pending, so `corepack pnpm review:a11y-manual` exits 1 and
lists missing status, candidate release ID, reviewer/signature/attestation,
reviewed time, M1-M7, and screen-reader evidence for every route.
- Keyboard/focus checks cover Public search dismissal/restoration, Studio mobile
navigation, dirty-leave and unpublish dialogs, labels, heading/landmark order,
and focus-visible behavior. Axe reports no violations in the required route
@@ -133,6 +172,8 @@ Commands:
```bash
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 exec playwright test tests/e2e/tech-log-responsive.spec.ts tests/e2e/tech-log-accessibility.spec.ts --project=chromium
corepack pnpm exec playwright test tests/e2e/tech-log-http-contract.spec.ts --project=chromium
corepack pnpm exec playwright test tests/e2e/accessibility.spec.ts --project=chromium --grep @a11y
corepack pnpm exec playwright test tests/visual/tech-log.visual.spec.ts --config=playwright.visual.config.ts --project=chromium
corepack pnpm test:visual
```
@@ -181,12 +222,12 @@ corepack pnpm test:sample-removal
```
Result: **PASS (13 checks, no fixture IDs)**. Its internal evidence included
types; reduced architecture (383 modules/1,173 dependencies, 12 graph checks,
types; reduced architecture (382 modules/1,170 dependencies, 12 graph checks,
9 forbidden fixtures); 11 registry checks; runtime schema 3 files/40 tests;
unit 115/1,247; component 18/124; integration 8/74; recipes 2/17; coverage 164
files/1,653 tests at 77.41% statements, 73.26% branches, 83.89% functions, and
80.03% lines; risk coverage 382/382 with 76 thresholds; source evidence 198
files/111 baselines; artifact/CI checks; router smoke 9/9; and production build.
unit 118/1,250; component 18/124; integration 8/74; recipes 2/17; coverage at
77.40% statements, 73.26% branches, 83.88% functions, and 80.02% lines; risk
coverage 381/381 with 76 thresholds; source evidence 202 files/129 baselines;
artifact/CI checks; router smoke 9/9; and production build.
Fresh completion commands and results:
@@ -194,34 +235,41 @@ Fresh completion commands and results:
| --- | --- |
| `corepack pnpm exec vitest run tests/features/tech-log` | 21 files, 170 tests passed |
| required four-spec Chromium command above | 48 tests passed |
| `corepack pnpm test:visual` | 112 tests passed |
| `corepack pnpm exec playwright test tests/e2e/tech-log-http-contract.spec.ts --project=chromium` | 39 tests passed |
| Chromium `@a11y` command above | 29 tests passed |
| `corepack pnpm test:visual` | 130 tests passed |
| `corepack pnpm check:types` | app/node/test/recipes/web-worker/service-worker passed |
| `corepack pnpm lint` | passed with 0 warnings |
| `corepack pnpm check:architecture` | 392 modules, 1,215 dependencies, 12 graph checks, 9 forbidden fixtures passed |
| `corepack pnpm check:architecture` | 391 modules, 1,212 dependencies, 12 graph checks, 9 forbidden fixtures passed |
| `corepack pnpm check:design-system` | 48 tokens and vendor boundaries passed |
| `corepack pnpm check:i18n` | 194 keys across 4 locales passed |
| `corepack pnpm check:registries` | 11 registries passed; compatibility `none` |
| `corepack pnpm check:browser-security` | injection rejected; Public source maps absent |
| `corepack pnpm build` | 2,352 modules transformed; build and manifest completed |
| `corepack pnpm build` | 2,351 modules transformed; build and manifest completed |
| `git diff --check` | passed |
The exact managed-workspace `corepack pnpm test:all` passed runtime schema 3/40,
then its unit phase passed 117 files/1,738 tests and failed 50 tests in only
three child-process-heavy files due to `spawnSync ... EPERM`: 39
`ci-artifact-contract`, 2 `ci-workflow-generation`, and 9
`http-scenario-evidence`. No TechLog test failed. The exact isolated command:
The fresh staged-candidate `corepack pnpm test:all` passed runtime schema 3/40,
then its unit phase passed 122 files/1,773 tests and failed 19 tests in only
`ci-artifact-contract`. The failures are the documented provider/cgroup,
RLIMIT/EMFILE, restrictive-umask, `/tmp`, timing, and identity environment
cases; no TechLog test failed. A pre-staging run had also exposed 39
release-inventory `APP_HOME` failures because the new serving files were not
yet visible to `git ls-files`; staging the complete candidate corrected that
test precondition, and all 39 disappeared. Its one aggregate guardian timeout
passed 1/1 in isolation and 21/21 in the fresh staged aggregate.
The earlier exact baseline-isolation command:
```bash
corepack pnpm exec vitest run tests/unit/ci-artifact-contract.test.ts tests/unit/ci-workflow-generation.test.ts tests/unit/http-scenario-evidence.test.ts
```
ran 3 files/529 tests: 510 passed; all 407 CI-workflow and all 14 HTTP-scenario
tests passed; the remaining 19 pre-existing CI-artifact provider/cgroup,
RLIMIT/EMFILE, umask, `/tmp`, timing, and identity cases failed. Direct runs of
the aggregate's remaining phases passed: component 18/124, integration 11/82
under the required child-process scope, reference feature 4/13, and recipes
2/17. This environment-only baseline is also recorded in the operations
baseline.
tests passed, leaving the same 19 environment-only CI-artifact cases. Direct
runs of the aggregate's remaining phases passed: component 18/124, integration
11/82 under the required child-process scope, reference feature 4/13, and
recipes 2/17. This environment-only baseline is also recorded in the
operations baseline.
## Fixes, branch audit, and handoff
@@ -235,9 +283,28 @@ presentation import of adapters, Next.js, Vinext, or Cloudflare. The 27 route
chunks are present in the release manifest and derive from actual Vite output,
not hard-coded generated filenames.
Before the Task 14 commit, the full migration range contains the 21 prior
commits from baseline establishment through `c5c8b94` and changes 352 files
(26,025 insertions, 3,467 deletions). This report's commit adds the integrated
parity evidence and fixes with the exact message
`test: prove TechLog UI migration parity`. Final status and range are checked
again after the commit; integration remains explicitly deferred.
The immutable code candidate
`3a7c5deca06679fb9b8710da2cce87bbca07ce8a` contains the production 404
boundary, parity runner, tests, snapshots, and 27 pending human-review records.
Only after that commit existed was the target rebuilt cleanly and the final
130-case parity, visual, HTTP, accessibility, and static verification rerun.
This report and its JSON are committed separately as
`docs: record TechLog migration evidence`; later human accessibility evidence
must cite the candidate SHA, not the evidence-only commit.
The independent `final-review.md` remains the immutable review input with its
historical `CHANGES_REQUESTED` verdict. This candidate addresses its production
404 issue with a real build artifact and 39 direct HTTP tests; expands the
source matrix from 112 to 130 and makes recursive tree equality part of pass;
and replaces the missing `tsx` invocation with a checked Node runner and
durable provenance. Its accessibility inventory issue is structurally fixed
and automated Chromium coverage is green, but the reviewer-dependent 27 human
records deliberately remain pending. No review verdict was rewritten or
self-approved.
Manual completion requires a human to check out candidate
`3a7c5deca06679fb9b8710da2cce87bbca07ce8a`, review every route according to
`docs/accessibility/manual-checklist.md`, fill each record's exact candidate
Release ID, reviewer, signature, attestation, reviewed time, M1-M7, and screen
reader result, commit that evidence separately, then rerun
`corepack pnpm review:a11y-manual`. Until then `FE-GATE-009` remains pending.
File diff suppressed because it is too large Load Diff
@@ -96,39 +96,82 @@ the resulting browser comparison is pixel-identical.
The source was copied to `/tmp/techlog-source-parity.I0CBK7` before build and
runtime caches were created. The supplied source directory was used only for
read-only file comparison; it was not edited. The temp-copy Vinext production
server and the target Vite preview were captured by one Playwright Chromium
instance with two fresh contexts under identical conditions:
server on `4375` and the target `dist/server.mjs` production artifact on `4174`
were captured by one Playwright Chromium instance with two fresh contexts
under identical conditions:
- `ko-KR`, `Asia/Seoul`, light color scheme, reduced motion, device scale 1,
service workers blocked, and a fixed `2026-08-14T01:00:00.000Z` clock;
- 1000-pixel viewport height, full-page screenshots, `document.fonts.ready`,
Pretendard/IBM Plex font checks, zero-duration animation/transition/caret;
- no screenshot masks; exact RGBA pixel comparison plus product-subtree
tag/class/text/ARIA projection and console/request failure comparison.
- no screenshot masks; exact RGBA pixel comparison plus normalized recursive
product-subtree tags, ordered children, complete classes, relevant
attributes, text/ARIA relationships, response metadata, boot lifecycle, and
console/request failure comparison.
The only attributes omitted by name after concrete diagnostics are React
Router `data-discover`, Next Image `data-nimg`/`decoding`/`srcset`, and Next SSR
`selected`; generated React IDs and CSS-module hashes are normalized by value.
No broad attribute class is omitted.
| Evidence group | Cases |
| --- | ---: |
| 27 canonical routes at 360 and 1440 pixels | 54 |
| Every additional known Public fixture slug/version | 18 |
| Public home breakpoint transitions | 12 |
| Studio screen/state fixtures | 19 |
| Ten unknown Public dynamic shapes at 360 and 1440 pixels | 20 |
| Search/menu/preview/dialog/publication interactions | 7 |
| **Total** | **112** |
| **Total** | **130** |
Result: 112/112 passed, zero failed, zero different pixels, all DOM/class/text/
ARIA projections equal, and zero unexplained source or target console/request
errors. The target-only visual regression suite exercises the same 112 cases
against 111 committed PNGs; the canonical and Studio-state 1440-pixel
Result: 130/130 passed, zero failed, zero different pixels, all recursive
DOM/class/attribute/text/ARIA trees and HTTP response metadata equal, and zero
unexplained source or target console/request errors. The target-only visual
regression suite exercises the same 130 cases against 129 committed PNGs; the
canonical and Studio-state 1440-pixel
`/studio/publications` cases intentionally share one identical snapshot.
Source screenshots were temporary comparison inputs and were not copied into
the target snapshot directory.
The checked clean-checkout command is
`TZ=Asia/Seoul corepack pnpm verify:tech-log-source-parity`; it runs directly
under the installed Node 24 runtime and has no `tsx` dependency. Durable
evidence is committed at
`docs/operations/evidence/tech-log-source-parity.json`. It records 178 source
checksums with tree digest
`6724c2f898eefc62d2fc0ee695bccc3ae61a69c5153ed43c69f2cf99ee45bca5`,
target candidate `3a7c5deca06679fb9b8710da2cce87bbca07ce8a`, build-manifest digest
`3579650faa482f566553c00d8b4a05a05b4f7a1ab93b83e48676289bbcf02984`,
Vite-manifest digest
`cfd583ed7b6c27dce7f47389447608636b6b9df3e28df00c6416674da2c7c46d`,
case inventory digest
`5689bcdb5d5637205cdeb92b7c57f72d99f0b039818b8f90afdde526bbafe0ac`,
and evidence payload digest
`f046047beded19ce468be607dcf99c6b74d4e07323457ec7145c56d2f67d2c79`.
The production source responds to both a missing dynamic slug such as
`/projects/missing-project` and an unmatched path such as
`/definitely-not-a-product-route` with HTTP 404, `text/plain`, and the exact
nine-byte body `Not Found`. The target intentionally removes the Public shell
for those paths and matches that response in curl and Chromium regressions;
this is the observed production source contract, not a generic runtime error.
`/definitely-not-a-product-route` with HTTP 404,
`text/plain;charset=UTF-8`, and the exact nine-byte body `Not Found`. The
target production server intentionally removes the Public shell for those
paths and matches that response in direct HTTP and Chromium regressions. Known
Public routes and all known Studio routes remain SPA-served; `/studio/*`
unknown paths preserve the source's in-shell HTML with HTTP 404. This is the
observed production source contract, not a generic runtime error.
## Accessibility review boundary
Automated Chromium `@a11y` coverage passes 29/29. The source-controlled manual
inventory contains exactly the 27 installed route IDs and removes the obsolete
starter records. Every human record remains `pending-manual-review` until one
reviewer evaluates keyboard, focus, modal/error behavior, color, reduced
motion, and screen-reader output against immutable candidate
`3a7c5deca06679fb9b8710da2cce87bbca07ce8a`. Therefore
`corepack pnpm review:a11y-manual` intentionally exits nonzero with 27
incomplete records and `release IDs do not match`; neither the manual gate nor
`FE-GATE-009` is represented as passing. The exact completion format is in
`docs/accessibility/manual-checklist.md`, and signed evidence must be committed
separately after it cites the candidate SHA.
## Governed route migration
@@ -148,11 +191,15 @@ The exact repository aggregate command was run in the managed workspace:
corepack pnpm test:all
```
Its runtime-schema phase passed 3 files/40 tests. The unit phase passed 117
files/1,738 tests and reported 50 failures in three child-process-heavy files:
39 `ci-artifact-contract`, 2 `ci-workflow-generation`, and 9
`http-scenario-evidence`. Every failure was rooted in `spawnSync ... EPERM` in
the restricted process sandbox; no `tests/features/tech-log` test failed.
Its fresh staged-candidate runtime-schema phase passed 3 files/40 tests. The
unit phase passed 122 files/1,773 tests and reported 19 failures, all in the
pre-existing `ci-artifact-contract` provider/cgroup, RLIMIT/EMFILE,
restrictive-umask, `/tmp`, timing, and identity environment cases. No
`tests/features/tech-log` test failed. A pre-staging diagnostic run also found
39 `APP_HOME` release-inventory failures because new serving files were not yet
visible to `git ls-files`; staging the complete candidate fixed that test
precondition, and all 39 disappeared. The same run's one guardian aggregate
timeout passed 1/1 in isolation and 21/21 in the fresh staged aggregate.
The failing files were then reproduced in isolation outside that child-process
restriction:
@@ -161,14 +208,13 @@ restriction:
corepack pnpm exec vitest run tests/unit/ci-artifact-contract.test.ts tests/unit/ci-workflow-generation.test.ts tests/unit/http-scenario-evidence.test.ts
```
Result: 3 files/529 tests, 510 passed and the pre-existing 19 environment-only
Result: 3 files/529 tests, 510 passed and the same 19 environment-only
`ci-artifact-contract` cases failed. The 407 `ci-workflow-generation` and 14
`http-scenario-evidence` tests all passed. The remaining exact 19 are the
documented provider lifecycle/cgroup, RLIMIT/EMFILE, restrictive-umask, and
`/tmp` timing/identity cases; they contain no TechLog code or test. The
aggregate phases after unit were also run directly: component 18 files/124
tests, integration 11 files/82 tests under the required child-process scope,
reference feature 4 files/13 tests, and recipes 2 files/17 tests all passed.
`http-scenario-evidence` tests all passed. These 19 contain no TechLog code or
test. The aggregate phases after unit were also run directly: component 18
files/124 tests, integration 11 files/82 tests under the required child-process
scope, reference feature 4 files/13 tests, and recipes 2 files/17 tests all
passed.
The inventories in this document are human review baselines. Automated
coverage is intentionally limited to the two SVG byte contracts, evidence