Commit Graph
103 Commits
Author SHA1 Message Date
DongHyeonkaandClaude Opus 5 7ff9728a5c fix: un-collapse evidence gate 1 from gate 2 to close a raw-Error escape
Fix round 2 (review of 9864958):

Round 1's I2 fix made gate 1 (supportsEvidenceKeyIn) read the same
merged catalog gate 2 already checks, so gate 1 stopped asking "does a
real Asset (or the legacy key) back this key" and started asking the
identical question gate 2 asks ("is there any EVIDENCE catalog row for
it"). A real EVIDENCE catalog row that exists for something other than
media (fixtures.ts's row for a QUESTION resolution target) then passed
gate 1 with nothing backing it as evidence. validateDocument reported
VALID; createPreview's resolver -- which only ever knew the legacy key
and real Assets -- threw a raw, unwrapped Error, violating the port's
StudioGatewayError-only contract. I2's disagreement reproduced in the
opposite direction.

Rebuilt gate 1 in all three callers (validate-working-copy.ts,
adapters/mock/project-public-render-model.ts, instant-preview.tsx) as
"legacy key OR an Asset-derived catalog entry only" -- never the
merged document catalog -- while gate 2 keeps reading the merged
catalog as before. Also stopped emitting the real Asset UUID as the
synthesized CatalogEntry's id (prefixed instead), closing a path where
pasting an Asset's real id -- never something the Picker itself
produces -- would have resolved as an evidence key.

Restored content-format.test.ts's domain tests to exercise the same
gate-1 composition production callers now use instead of a bare
hand-injected predicate, and added coverage for: a real non-asset
EVIDENCE row still being rejected, an Asset-backed key being accepted
with no document-catalog row at all, the fixture-UUID case failing
both mock paths with no raw Error crossing the gateway port, and the
EVIDENCE_ALT_REQUIRED decorative-Asset pairing that had no test.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-18 05:54:21 +09:00
DongHyeonkaandClaude Opus 5 98649585e6 fix: generate fresh upload idempotency keys and reconcile mock preview/validation on evidence keys
Fix round 1 (review of 54d9bf9):

I1: AssetUploadDialog reused one idempotency key across every upload
attempt in a session, generated once when the dialog opened. Every
terminal state re-enables the file input, so retrying with a different
file after a failure sent two distinct payloads under the same key.
The key is now generated fresh inside submit() on each call, matching
every other mutation call site in the repo, and dropped from the
dialog's public props entirely (it was never in the task's own
"Produces" interface).

I2: the mock's validateDocument gate only recognized the one legacy
hardcoded evidence key, completely disconnected from the Asset system
Instant Preview now consults -- so a directive the Picker or upload
dialog inserted always previewed live and then failed validation with
EVIDENCE_UNSUPPORTED for every other key. Extracted the Asset-to-
CatalogEntry mapping (evidenceCatalogEntriesFromAssets) and the
domain's one EVIDENCE-catalog matching rule (evidenceCatalogEntryFor)
into shared domain modules that both the preview path
(instant-preview.tsx) and the validation path (validate-working-copy.ts,
the mock's own createPreview) now call. Reconciled the underlying MOCK
studioSource gap that caused this: built a mock asset gateway
(mock-studio-asset-gateway.ts) sharing one in-memory Asset store with
the mock document gateway, wired per composition-root instance in
create-tech-log-feature-input.ts, so an Asset the editor actually
loaded is visible to validation too, while a key backed by nothing
still fails both paths.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-18 05:31:01 +09:00
DongHyeonkaandClaude Opus 5 54d9bf9120 feat: insert evidence directives from the TechLog asset picker
Adds an Asset Picker and upload dialog to the CASE editor so authors can
insert `:::evidence` directives that reference backend assets, and opens
projectWorkingCopy's two evidence gates so Instant Preview accepts a key
backed by a freshly loaded READY asset instead of only the one hardcoded
legacy key. The editor screen now owns the loaded Asset list so the
Picker, the upload dialog, and Instant Preview all read the same array,
and a freshly uploaded asset appears in the preview without a refetch.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-18 04:32:56 +09:00
DongHyeonkaandClaude Opus 5 e2c1d076f4 fix: overlay legacy evidence labels instead of shadowing the whole descriptor
Review finding I1: the static-key-first resolution order protected the
entire legacy fixture (image and labels), when only the hand-authored labels
ever needed protecting -- ResolvedAsset carries no label fields, so nothing
else could recover them, but a real descriptor's publicPath/width/height were
never actually at risk of mismatching. Narrowed resolveWith so a resolved
descriptor's data fields always win; the legacy registry only overlays
triggerLabel/dialogLabel for keys it recognizes, and only supplies the full
descriptor when nothing else resolves the key at all. A future backend asset
colliding with the legacy key now degrades to a wrong caption, never a wrong
image.

Review finding I2: renamed and rewrote a test whose title claimed a
READY-vs-QUARANTINED same-key guarantee its body never constructed. It now
puts both a QUARANTINED and a READY entry under one assetKey and asserts the
READY one wins.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-18 04:03:43 +09:00
DongHyeonkaandClaude Opus 5 9d91001a31 feat: resolve evidence figures from backend asset descriptors
Public Preview and Publication Snapshot now resolve evidence figures from the
ResolvedAsset descriptor the server already attaches to each EVIDENCE_FIGURE
block, instead of a local literal that only knew one hardcoded key and threw
on anything else. Instant Preview gains an `assets` prop (defaults to `[]`,
unwired until the Asset Picker task) and stops throwing when a key has no
catalog match yet.

Builds on Task 1's existing seam (resolveCaseEvidenceAssets /
ResolveEvidenceAsset) via a new asset-resolvers.ts rather than a parallel
path. Kept out of adapters/ (presentation may not import it) by carrying a
small local copy of the one legacy fixture entry, checked before any
descriptor match so the pre-existing key keeps rendering byte-identically
across surfaces during the migration window. Non-READY assets never resolve;
unresolvable keys return a placeholder instead of throwing.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-18 03:54:30 +09:00
DongHyeonka 0c071aaabc fix: judge evidence alt text with asset metadata, not syntax
The parser has no asset catalogue, so it cannot know whether an
evidence figure is decorative. Move the empty-alt rejection from
parse-time (a syntax error) to publish validation, where the mock
treats static evidence assets as decorative: false since the static
registry predates the Asset capability. The real rule is that the
server judges alt against Asset.decorative.
2026-08-18 03:33:19 +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
DongHyeonka d9c2d8bc5e feat: add the TechLog Studio asset gateway port and JSON adapter 2026-08-18 02:16:51 +09:00
DongHyeonka 7724a8720c fix: account for TECH_LOG_STUDIO_SESSION in the auth profile registry pin
Task 3's contract contribution legitimately registered a TECH_LOG_STUDIO_SESSION
auth profile, growing INSTALLED_REST_AUTH_PROFILES from 2 to 3 entries. The
exact-key-set regression test at contract-registry-immutability.test.ts:91
correctly caught the drift; test:unit was left off Task 3's verification list,
so it went unnoticed until Task 5 ran the full suite. Updates the expected key
list rather than weakening the assertion, so it keeps forcing a reviewer to
confirm any future registry change was intended.
2026-08-18 02:05:29 +09:00
DongHyeonka 3b641906b8 feat: select the TechLog Studio adapter from runtime configuration
Adds TECH_LOG_STUDIO_SOURCE (MOCK | HTTP, default MOCK) to the V2 runtime
config schema so a build can switch createTechLogFeatureInstalledInput
between the mock and HTTP Studio gateways without a rebuild. V1 documents
predate the key and always normalize to MOCK. The HTTP gateway is
constructed with only { operations } per Task 4's actual signature -
no CSRF provider is wired here; that lands with attachCredentials at a
later composition-root task.

Updates every existing Studio test call site to the new required
createTechLogFeatureInstalledInput(context) signature via a shared
tests/helpers/studio-install-context.ts MOCK fixture, so the whole
existing Studio suite keeps exercising the mock adapter unchanged.
2026-08-18 01:57:15 +09:00
DongHyeonkaandClaude Opus 5 7424ed4594 fix: forward every documented Studio query filter and pin canonicalInputIdentity
Two review Minor findings against the brief itself, both closed:

- tests/mocks/handlers/tech-log-studio.ts silently dropped documented
  query filters instead of mirroring the mock gateway it wraps:
  listStudioDocuments forwarded only q/limit (dropping kind,
  publicationStatus, nextAction, projectId, sort, cursor),
  listStudioCatalog forwarded only type (dropping q/cursor/limit), and
  listStudioPublications ignored all four of its parameters outright.
  Added a shared queryParams() helper and forward every field each
  operation's projectRequest actually emits, plus a regression test
  that narrows the fixture set by kind through the real HTTP gateway
  (confirmed it fails without the fix).

- canonicalInputIdentity (on the idempotency-safety path, reused by
  Task 6) had no test. Added three tests against mutationIntent(): a
  large Korean payload stays within the byte bound, the same input
  retried twice yields an identical identity, and a mid-codepoint
  truncation cut leaves no replacement character (confirmed the third
  fails without the strip). The known collision limitation of any
  bounded-length identity scheme is documented in the test file rather
  than solved.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-18 01:43:51 +09:00
DongHyeonkaandClaude Opus 5 1d01a522de feat: implement the TechLog Studio HTTP gateway
Adds createHttpStudioGateway, the adapter the Studio UI calls in
production. It drives every mutation through mutationIntent()
(defineMutationIntent/defineIdempotencyKey, not
createBrowserMutationIntentFactory, so the caller-supplied idempotency
key is preserved rather than regenerated) and leaves header
construction to the executor/credential collaborator entirely - the
gateway never sees or sets Idempotency-Key or x-csrf-token itself.

Also moves stable-stringify.ts out of adapters/mock/ so the mock and
http adapters share one pure function without production code
depending on the mock directory, and fixes the resulting import in
cursor.ts, mock-studio-gateway.ts, and mock-studio-gateway.test.ts.

Adds MSW handlers (tests/mocks/handlers/tech-log-studio.ts) that wrap
the reference mock-studio-gateway implementation, and a contract test
suite that drives the gateway through a thin fetch-based executor
built from the contract's own projectRequest, proving canonical
path/body/header construction without assembling the full platform
transport.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-18 01:30:24 +09:00
DongHyeonkaandClaude Opus 5 9313018ef5 fix: restore contract-set regression coverage and mirror canonical problem bounds
release-manifest.test.ts's fixture derived manifest.contractSet.packages
from EXPECTED_CONTRACT_SET_PACKAGES itself, so the equality it checked was
satisfied by construction and CONTRACT_SET_PACKAGE_MISSING became
unreachable from any test in the repo. Adds two independent checks: a
literal (not derived) assertion that EXPECTED_CONTRACT_SET_PACKAGES really
contains @tech-log/studio-contract@2.0.0, and a negative test with a
manifest that omits a package the real expected set requires, asserting
CONTRACT_SET_PACKAGE_MISSING. Confirmed the negative test has teeth by
temporarily disabling the missing-package branch in
verifyContractSet (src/contracts/contract-set.ts) and observing the test
fail before reverting.

Also narrows tech-log-studio-contract-contribution.ts's problemSchema to
match canonical ProblemDetails exactly: title max 200 (was 240) and type
unbounded (was max 512; canonical only constrains it as
format: uri-reference). Both prior values were over-permissive, so no
previously-accepted document is now rejected.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-18 01:21:14 +09:00
DongHyeonkaandClaude Opus 5 66c047cec8 feat: register the TechLog Studio contract contribution
Registers the TECH_LOG_STUDIO_SESSION SAME_ORIGIN_COOKIE auth profile and
declares the tech-log-studio-http-v1 contribution covering all 18 JSON
Studio operations (everything except the multipart uploadStudioAsset),
built from two shared builders (safeOperation/keyedOperation) so every
KEYED command gets IDEMPOTENCY_REPLAY recovery and a zero retry budget,
and every SAFE read gets a plain retry budget, without repeating the
declaration shape 18 times.

Rescopes the canonical package identity from "tech-log-studio-contract"
to "@tech-log/studio-contract" (generator, canonical-source.json,
contract-generation.test.ts) because the platform's contribution
composer requires an npm-scoped packageId; the unscoped form failed
composition. Updates the release-manifest test fixture, which hardcoded
an empty expected contract set, to derive its expected packages from the
real installed set now that TechLog is always installed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-18 01:10:04 +09:00
DongHyeonka 6c40c291d9 test: cover Studio error mapping's remaining outcome branches and CSRF rejection recovery 2026-08-18 00:51:50 +09:00
DongHyeonka 7381be1477 feat: add TechLog Studio error mapping and CSRF token provider 2026-08-18 00:44:37 +09:00
DongHyeonkaandClaude Opus 5 a0e0be6522 test: cover dashboard needsValidation and detail() nextAction regression risk
Round 3 of the TechLog contract task added two pieces of genuinely new
logic with no assertion on their output: the totals.needsValidation
count in getDashboard(), and the detail() rewrite that avoids a
self-reference when computing WorkingCopyDetail.nextAction. Both would
have passed every existing test if they regressed.

- needsValidation is checked against an independent count derived from
  listDocuments()'s per-document nextAction, with sanity bounds so a
  filter that always returns 0 or the full count can't pass silently.
- detail()'s nextAction is asserted on two fixtures whose expected
  value is justified by the asserted preconditions alongside it
  (published-at-current-version -> NONE; INVALID-but-current-validation
  -> FIX_VALIDATION). Verified locally that hardcoding nextAction to a
  constant in detail() makes the second assertion fail, and that
  zeroing needsValidation's count makes the dashboard assertion fail.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-18 00:38:03 +09:00
DongHyeonkaandClaude Opus 5 639e1a49c9 build: generate the TechLog Studio contract from canonical source
Vendors the canonical studio-v1.yaml, generates types via an isolated
`pnpm dlx` toolchain (openapi-typescript needs TypeScript 5's classic
compiler API; this repo pins TypeScript 7.0.2 per VD-01, whose root
export has none), and adds an offline drift gate that checks the
vendored yaml/generated types/canonical-source.json against each
other without touching the sibling design-package repo or the network.

Regenerating from canonical surfaces real, new required fields on
existing schemas (WorkingCopyDetail.nextAction, PreviewDetail/PublicPreview
.dependencyRevision, StudioDashboard.totals.needsValidation,
PublicationSnapshot.contentFormatVersion/rendererContractVersion) and a
new required EvidenceFigureBlock.asset. The mock gateway and fixtures
are updated to satisfy the former; the latter exposes a real authoring-
vs-rendering conflation in the content-format parser (it declared its
output as the server's fully-resolved PublicRenderModel type, which it
has no asset catalog to satisfy). Split that boundary: the parser now
produces an authoring block type omitting the resolved asset, and each
of its three consumers (the mock gateway, the Studio instant preview,
and the static Case demo page) attaches the resolved descriptor from
its own asset source through a shared, pure domain-level resolver.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-18 00:27:59 +09:00
DongHyeonkaandClaude Opus 5 9e5fbd1384 refactor: derive TechLog navigation from the route contract
Both headers carried their own literal list of {label, path}. That made the
route contract and the header two sources for the same three facts — which
routes are navigable, what they are called, and in what order — with nothing
keeping them in step: a renamed route or a reordered menu could be right in one
place and stale in the other.

techLogNavigation(layoutGroup) derives the menu from TECH_LOG_ROUTE_REGISTRY,
where navigationOrder is what makes a route navigable. Output is byte-identical
to the previous literal lists, pinned by a new test.

Derived from TechLog's own route contract rather than from the composed
registries: .dependency-cruiser.json freezes an exact allowlist of files that
may read src/features/installed-*, explicitly so that coupling cannot spread,
and a feature header is not on it.

The studio header keeps its active-state rules — "작업본" stays highlighted
across /studio/documents/* except on the new-document screen — because that is
presentation behaviour the contract has no opinion about.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-17 20:34:36 +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 0355b644a0 feat: add TechLog project decision authoring 2026-08-17 17:23:42 +09:00
DongHyeonka 79e9aa8328 fix: align TechLog article content widths 2026-08-17 16:49:20 +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
DongHyeonka c5c8b9423c feat: complete TechLog Studio publication flow 2026-08-16 00:35:11 +09:00
DongHyeonka 9c6906fc6f feat: port TechLog Studio validation workflow 2026-08-15 23:59:08 +09:00
DongHyeonka 5933265975 feat: port TechLog Studio editors 2026-08-15 23:41:34 +09:00
DongHyeonka 887f5e6eb1 feat: port TechLog Studio shell and indexes 2026-08-15 23:29:32 +09:00
DongHyeonka 2b6fa42620 feat: complete TechLog public screens 2026-08-15 23:19:04 +09:00
DongHyeonka 4283e40bb2 feat: port TechLog document screens 2026-08-15 23:06:57 +09:00
DongHyeonka 512aa4a1e9 fix: synchronize TechLog focus and not-found runtime 2026-08-15 22:52:42 +09:00
DongHyeonka ef1d5cc548 feat: port TechLog discovery screens 2026-08-15 22:29:57 +09:00
DongHyeonka c9164c1a03 test: assert TechLog search focus style 2026-08-15 21:54:09 +09:00
DongHyeonka 3bc74e0195 test: strengthen TechLog shell contracts 2026-08-15 21:42:49 +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 627df884dd feat: port TechLog shells and styles 2026-08-15 21:20:47 +09:00
DongHyeonka 01316763e3 fix: inject grouped route codecs 2026-08-15 20:51:22 +09:00
DongHyeonka adb8613cb9 feat: add grouped TechLog route contracts 2026-08-15 20:30:32 +09:00
DongHyeonka 27dda3e0e3 feat: compose TechLog static and mock adapters 2026-08-15 19:36:46 +09:00
DongHyeonka 708680b28e fix: reject TechLog protocol-relative links 2026-08-15 19:10:05 +09:00
DongHyeonka 8342fb14dc fix: reject unsafe TechLog network paths 2026-08-15 19:00:10 +09:00
DongHyeonka 16753f53af feat: port TechLog content format and renderer 2026-08-15 18:44:09 +09:00
DongHyeonka 82f94423e5 test: enforce exact TechLog contract keys 2026-08-15 18:16:21 +09:00
DongHyeonka 01ed1e9300 feat: add TechLog feature contracts 2026-08-15 18:07:12 +09:00
DongHyeonka 5479101c8c fix: exercise production evidence asset lookup 2026-08-15 17:55:37 +09:00
DongHyeonka 034b702e8e chore: establish TechLog migration baseline 2026-08-15 17:49:40 +09:00
DongHyeonkaandClaude Opus 5 93db3c184b chore: carry the RPC-02 deadline-race test fix and re-pin the template
The synced suite contained an assertion that pinned one of two equally
configured deadlines, so it passed alone and failed in a full parallel
run. Fixed upstream and carried here with the template pin moved to
`a0fbafb`.

Three consecutive runs of the 27-file set that reproduced the failure now
pass at 485 tests.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-15 12:33:43 +09:00