Commit Graph
26 Commits
Author SHA1 Message Date
DongHyeonkaandClaude Opus 5 e4f9f81a3f docs: record the passthrough output validators as a known limitation
All 18 Studio operations declare `passthrough` (`z.unknown()`) input and
output validators. The choice is deliberate and commented in
`tech-log-studio-contract-contribution.ts`, but it was recorded nowhere a
spec reader looks, and it compounds the cycle's own non-goal: with no running
backend, MSW returns whatever the test author wrote and nothing compares it
to the canonical schemas, so `CONTRACT_VIOLATION` can never fire for a
success-payload shape mismatch. Compile time is currently the only layer that
catches a shape regression.

Recorded in §Task 12 완료 상태 beside "no running-backend verification" -- the
same class of risk -- with the two options for the backend-comparison cycle.
No code change.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-18 09:08:46 +09:00
DongHyeonkaandClaude Opus 5 172497591f docs: point the spec at canonical-source.json instead of a stale digest
§상태 pinned `sha256:85a65004…` / revision `0ec5582` while the canonical yaml
that actually shipped is `sha256:99f54f56…` / `ce2e748` -- the value
`canonical-source.json` records, the value the contract contribution imports,
and the value the spec's own Task 12 table already quotes. The canonical
source moved during implementation and only one of the two places was updated.

The spec no longer carries the values at all: it names
`contracts/studio/canonical-source.json` as the single record, which is what
the contract contribution reads and what `check:tech-log-contract` verifies,
so the two cannot drift apart again. Task 12 row 3 also records that the drift
gate is now wired into FE-GATE-010 and `test:all`.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-18 09:08:18 +09:00
DongHyeonka 5c997f3a7e docs: correct the test:visual root-cause attribution in the alignment record
Fix round 1 on Task 12's evidence. The design doc and task-12-report.md
attributed all 18 test:visual failures to Task 9 and described them as
uniformly taller. Independently re-derived from git log/git diff instead of
re-asserting the review's numbers on trust:

- 7 of 18 (both Public tests + 5 Studio preview/snapshot tests) render
  shorter, by 93-94px, caused by 79e9aa8 ("fix: align TechLog article
  content widths") — already on main, an ancestor of this branch's
  merge-base 9e5fbd1. case-body-renderer.tsx/evidence-figure.tsx are
  byte-identical across 9e5fbd1..HEAD; the golden PNGs were last written at
  3a7c5de, before 79e9aa8. Pre-existing at the merge-base, not caused by
  this branch; refresh belongs against 79e9aa8 on main.
- 6 of 18 (Studio editor surfaces) render taller, from this branch's
  sanctioned Asset Picker/upload UI (Task 10) — the only failures this
  branch actually produced.
- Condition-1's citation (check:architecture/check:registries) didn't
  support a Public-render claim; replaced with the actual evidence (empty
  renderer diff) plus the main-inherited visual failure.
- Softened test:coverage's "no new code is under-covered" — risk-coverage
  has zero tech-log entries, so its silence isn't evidence either way;
  stated the global thresholds that are actually cleared instead.

No code changed; no gates re-run.
2026-08-18 08:44:35 +09:00
DongHyeonka 83d47e7185 docs: record TechLog backend alignment completion state
Task 12 of the backend-alignment plan: document the TECH_LOG_STUDIO_SOURCE
switch and the generate/check:tech-log-contract scripts in README.md, and
record the spec's completion status (12/12 completion conditions met, the
two explicitly-out-of-scope items restated, and the gate findings from the
full verification pass) in the design doc's status section. No product code
changed.
2026-08-18 08:25:49 +09:00
DongHyeonkaandClaude Opus 5 35cc5c868a fix: invalidate the TechLog CSRF token on 403 and harden the bootstrap profile wiring
Item 1 (real bug): contractOperations.execute only invalidated the cached
CSRF token on UNAUTHENTICATED (401). A CSRF-specific rejection normally
arrives as FORBIDDEN (403) -- the platform classifies any 403 response as
FORBIDDEN unconditionally -- so a token rejected during an ordinary document
save left the stale token cached and every subsequent Studio mutation kept
failing until reload. Extracted invalidateTechLogCsrfOnOutcome() so
production and the composition test call the identical function; it now
invalidates on both UNAUTHENTICATED and FORBIDDEN.

Item 2: the upload transport's uncontracted-status fallback hardcoded status
503, so an uncontracted 401/403 body never reached the gateway's
error.status === 401 || 403 invalidation check. Passes the real
response.status through.

Item 3: safeOperation()'s auth-profile parameter is now typed as a union of
the two valid profile constants instead of a bare string, and
assertExactlyOneTechLogStudioBootstrapOperation() fails composition closed
if getStudioSession stops being the sole caller of the credential-free
bootstrap profile.

Item 4: corrected two stale operation counts in the adapter review doc.

Both new tests for items 1 and 2 were run and shown failing before their
fix, per this task's TDD standard for error-path changes.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-18 03:25:29 +09:00
DongHyeonkaandClaude Opus 5 2cab4974b7 fix: break the TechLog CSRF bootstrap cycle and close the review's fix-round-1 items
C1 (Critical): getStudioSession was stamped with the same
TECH_LOG_STUDIO_SESSION auth profile as every other Studio operation, and
that profile requires the CSRF header it is getStudioSession's own job to
issue -- an unconditional cycle that recursed without bound in HTTP mode.
Fixed with a credential-free TECH_LOG_STUDIO_BOOTSTRAP auth profile for
getStudioSession alone, a synchronous re-entrancy guard in
createCsrfTokenProvider as defense in depth, and a throwing stub in place of
the prior `let x!: T` assertion. Added a composition-level regression test
that wires the real executor, CSRF provider, and credential-attach function
together and proves getStudioSession dispatches exactly once while its token
reaches both a JSON operation and the multipart upload.

Also: invalidate the cached CSRF token on a 401/403 from the upload path
(I2), a throwing useStudioAssetGateway() accessor so Task 11 cannot silently
compile a null-gateway UI (I3), and the M1-M5 minors from the review (guard
a malformed success body, cover the untested error fallbacks, align aborted
uploads with the JSON path's non-retryable CANCELLED mapping, derive the
credential header name from one source instead of two, and correct the
adapter review doc's operation count).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-18 03:07:02 +09:00
DongHyeonkaandClaude Opus 5 c9c832c365 feat: add the TechLog asset multipart upload transport
Wires the whole Asset capability into the running application: the
multipart upload transport (the contract runtime can only express JSON
bodies), a single composition-root-owned CSRF provider shared between
the platform's credential collaborator (18 JSON operations) and the
upload transport (1 multipart operation), and Studio/StudioShell
exposure of the Asset gateway alongside the existing document gateway.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-18 02:39:51 +09:00
DongHyeonkaandClaude Opus 5 a6fc536d8a docs: scope the TechLog contract packageId to satisfy PACKAGE_ID
The platform models contract contributions as published npm packages and
rejects an unscoped packageId at composition time. Use
@tech-log/studio-contract, the name a real publish would carry.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-18 01:05:16 +09:00
DongHyeonkaandClaude Opus 5 ac555a85e8 docs: generate the TechLog contract outside the repo toolchain
openapi-typescript needs the TypeScript 5 classic compiler API; this repo
pins typescript@7.0.2 (VD-01), whose root export has no compiler API.
Run the generator in an isolated pnpm dlx environment instead, so the
lockfile and peer contract are untouched.

Also make check:tech-log-contract work without the canonical repo or the
generator — it read an absolute path to a sibling repo that CI never has.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-18 00:03:29 +09:00
DongHyeonkaandClaude Opus 5 9f0599a389 docs: correct the alignment plan against platform transport constraints
Pre-flight scan found five defects that would have failed at composition:

- authProfileId TECH_LOG_STUDIO_SESSION was never registered
- deleteStudioAsset declared responseByteLimit 0 (platform requires >= 1)
- gateways passed CSRF/idempotency through operation input, but contract
  projection has no header channel; both must use the platform seams
- the browser mutation intent factory generates its own key, discarding the
  caller-supplied one the port contract depends on
- instant preview was never wired to the loaded asset list

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-17 23:52:47 +09:00
DongHyeonkaandClaude Opus 5 78766accdf docs: plan the TechLog backend alignment implementation
12개 Task로 분해한다. 계약 생성·digest 고정(1), 오류/CSRF(2), 계약 기여(3),
StudioGateway HTTP(4), 런타임 스위치(5), Asset 포트(6), multipart 전송과
배선(7), alt 규칙 이동(8), evidence resolver(9), Picker(10), Library(11),
전체 게이트(12).

자체 검토에서 세 결함을 고쳤다.
- Asset gateway가 feature input에 배선되지 않아 UI가 도달할 수 없었다.
- Backend assetKey를 해석할 resolver가 없어 삽입한 directive가 즉시
  미리보기를 깨뜨렸다. 렌더러의 기존 주입점을 쓰는 Task를 추가했다.
- dialog/library 단계에 코드가 없었다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-17 23:44:25 +09:00
DongHyeonkaandClaude Opus 5 12329ec9c0 docs: define TechLog backend alignment
Studio 계약을 tech-log-design-package의 canonical studio-v1.yaml 단일
출처로 정합시키고, Asset capability를 편집 흐름에 연결하는 설계를 확정한다.

- 계약 drift는 EXTERNAL_PACKAGE provenance의 digest 고정으로 막는다.
- Studio 전송은 플랫폼 계약 런타임을 통과한다. multipart 업로드 1개만
  전용 seam으로 분리한다 — 런타임이 JSON 본문만 표현할 수 있기 때문이다.
- CSRF는 전송 관심사로 어댑터 내부에 둔다. Studio 인증 UI는 추가하지 않는다.
- Public 조회의 HTTP 전환은 별도 사이클로 분리한다. 동기 포트를 async로
  바꾸는 작업이 19개 파일 31개 호출 지점과 이식 parity 기준선을 흔든다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-17 23:24:29 +09:00
DongHyeonkaandClaude Opus 5 93ce86eef4 test: decouple the feature-switch gates from the template's demo screens
The template's demonstration screens exist to explain the template. A product
replaces them with its domain, so deleting them is the expected end state — but
two gates were coupled to them, and the merge accommodated that coupling instead
of fixing it.

product-features.test.ts derives its own scope now: a registry must gate on the
manifest when it imports a module belonging to a manifest-declared feature. The
previous fix put installed-feature-runtimes.tsx in the exempt list, which
silenced the guard for that file permanently. Verified by removing the manifest
reference from installed-feature-adapters.ts and watching the guard fail; a
counter asserts the sweep still watches at least one file.

product-feature-switch.test.tsx exercises the kill switch end to end again. The
mechanism is the ownership lookup plus isFeatureActive, which has nothing to do
with which screens ship, so the ownership map is the fixture: one real
registered route attributed to a real installed feature, with the product's own
router, components and codecs.

That restoration exposed a real gap. The navigation-withdrawal half is not
implemented here: it lives in the template's PrimaryNavigation and this product
does not render the template's AppShell at all — the public header is a
hand-written list of paths. A disabled feature's route is refused by the router
but its link would still be advertised. Harmless only while no feature-owned
route is navigable, which is now asserted so the gap cannot ship silently.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-17 19:08:42 +09:00
DongHyeonkaandClaude Opus 5 7d1ccccbcd Merge branch 'main' into feature/techlog-ui-migration
Integrates the frontend template sync (a0fbafb → 5434760) into the TechLog UI
migration. Merged in this direction so every conflict is resolved and proved in
the worktree; main is only fast-forwarded afterwards and never holds a state
that was not verified here.

15 conflicts. The rule throughout: keep the template's mechanism, keep the
product's content, and never invent a third state neither branch would accept.

The template's product manifest and its runtime feature kill switch are adopted.
The route registry is deliberately not composed from contract.routes: the
reference feature still declares screens this product deleted, and reducing over
them would register paths with no component behind them. ROUTE_FEATURE_OWNER is
narrowed to registered routes for the same reason. The first resolution did
compose from contract.routes and was rejected by product-features.test.ts.

Three files pinned counts and a digest describing the gate contract. Neither
side's numbers describe the merged config/ci/gates.json, so they were recomputed
from it rather than chosen: 27 gates, 82 commands, 94 command references, 107
evidence references, 128 artifacts, shape sha256 5063586d.

README.md and docs/accessibility/manual-checklist.md now enumerate this
product's 27 routes, which the template's own verify:documentation requires.

product-feature-switch.test.tsx was rewritten around the invariant that still
applies here — no registered route without a component — rather than deleted
with the screens it used to exercise.

docs/operations/template-merge-2026-08-17.md records every decision, the gate
results, and the three follow-ups this merge deliberately did not decide.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-17 18:38:08 +09:00
DongHyeonka 72669949bc docs: define TechLog content width alignment 2026-08-17 16:34:45 +09:00
DongHyeonka 47cbf4ddca docs: record TechLog migration evidence 2026-08-16 05:07:58 +09:00
DongHyeonka 3a7c5deca0 fix: complete TechLog migration evidence 2026-08-16 04:55:52 +09:00
DongHyeonka 6c2780b7a7 test: prove TechLog UI migration parity 2026-08-16 02:48:26 +09:00
DongHyeonkaandClaude Opus 5 bdee07a93b chore: sync the frontend template from a0fbafb to 5434760
Carries eight template commits: the provider sandbox actually running, release
admission to a named environment, the product feature manifest with its runtime
kill switch, architecture and documentation rules that match what is enforced,
the removability fixtures, and the browser, visual and performance evidence.

Product identity is unchanged. `package.json` keeps `tech-log-frontend` and the
catalog keeps the Tech Log naming; the home page was not in the delta. The
visual baselines are this product's own — the template's were excluded from the
transplant and these were regenerated here, where the only difference is the
platform overview's new product-feature section.

What this repository gains operationally: `config/runtime/{local,development,
staging,production}.json` with `FE-GATE-027` refusing an artifact whose runtime
document does not match the environment it is being admitted to, and
`FEATURE_OVERRIDES` for taking an installed feature out of service without a
rebuild.

Verified here: eight gates green, build green, visual 5/5, and 1,858 of 1,859
tests in the suites that do not need a sandbox — the one failure passes in
isolation and is a jsdom lazy-chunk timeout under parallel load. The provider
suites cannot run on this machine at all: `kernel.apparmor_restrict_unprivileged
_userns=1` makes `bwrap --unshare-net` fail, reproducible without any code from
either repository.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-15 21:34:19 +09:00
DongHyeonka 034b702e8e chore: establish TechLog migration baseline 2026-08-15 17:49:40 +09:00
DongHyeonka 05e3d50ba0 chore: prepare isolated migration worktree 2026-08-15 17:35:21 +09:00
DongHyeonka 954ca8a1fd docs: plan TechLog UI migration 2026-08-15 17:09:58 +09:00
DongHyeonka 325a2a0843 docs: define GitFlow delivery for UI migration 2026-08-15 16:46:36 +09:00
DongHyeonka c2d03165b3 docs: define TechLog UI migration design 2026-08-15 16:43:45 +09:00
DongHyeonkaandClaude Opus 5 4bff9ca151 chore: sync the frontend template from 4dc033c to 8157ad4
The product was materialized from the template at `4dc033c` and has stayed
on it through 43 template commits, so it was missing all three rounds of
adapter remediation — including files it never had, such as the shared
`abortable-operation` primitive and the `exact-snapshot` decoder that
later fixes are written against. Taking only the newest round was not
possible for that reason: the delta is coherent only as a whole.

The product had not touched `src/adapters` at all since materialization,
so the 140-file delta applied with a three-way merge and no conflicts.
`package.json` was the single overlap and merged cleanly: the product owns
`name`, the template contributed `check:adapter-inventory`,
`check:remediation-ledger` and the image-resolve-signal type fixture.
All 24 product-owned files — README, index.html, CI workflow, i18n
catalog, home page, generated schemas, evidence scripts, component and
visual snapshots — are byte-identical to `main`.

`template.lock.json` now pins the synced revision and tree.

Verified in this repository, not inherited from the template: six type
projects, lint, nine gates (adapter inventory, remediation ledger,
registries, diagnostics, realtime boundaries, architecture, browser
file/storage boundaries, optional recipes, documentation), the production
build, and 2,054 of 2,073 tests. The 19 failures are all in
`tests/unit/ci-artifact-contract.test.ts` and are the same pre-existing
sandbox RLIMIT, EMFILE, umask and `/tmp` permission behaviour the template
records; four suites that failed once under parallel load pass in
isolation.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-15 12:04:58 +09:00
DongHyeonka 40107eec84 chore: initialize from frontend template 4dc033c 2026-08-13 18:23:26 +09:00