Redesign: information architecture, content, and design (merge 1 of 2) - #22
Merged
Merged
Conversation
Six defects found by a four-axis site diagnosis. All were reproduced before being fixed; none are redesign work. - ai-security-review: the workflow did not parse as YAML because the Python f-string inside `run: |` dropped to column 0 and ended the block scalar. Re-indented; verified with PyYAML and actionlint. - trivy-action: `@0.36.0` is not a real tag (the tag is `v0.36.0`). Fixed in 12 places, not the 7 first counted. All 17 `uses:` refs in published content were resolved with git ls-remote. - iac-security: `CKV_AWS_52` does not exist in Checkov 3.3.16, so the skip did nothing. Replaced with `CKV_AWS_144`, which actually fails on that resource; confirmed by running Checkov before and after. - customTheme.scss: a dark-mode selector used `[class*="Button"]`, a React Native naming leftover that misses Docusaurus's lowercase `button--primary`. It repainted every landing link, leaving the FinalCTA button at 1.00:1. The rule gave nothing Infima does not already give, so it is removed. Measured after the fix: 16.27:1, 7.72:1, 13.40:1, link colour unchanged at 8.16:1. - license grades: method1 and method4 contradicted the canonical classification on LGPL, CC-BY-SA, SSPL and Commons Clause. Aligned to canon, and CC-BY-SA now has a canonical entry of its own instead of being inferred. The CI grep also needed word boundaries: `GPL-2\.0` was matching inside `LGPL-2.0`. - trivy supply chain: an earlier correction went too far. Only the advisory ID was wrong; the March 2026 tag re-pointing did happen (GHSA-69fq-xp46-6x23, 76 of 77 trivy-action tags). The two Trivy incidents are separate and are now described separately. Signed-off-by: Haksung Jang <haksung@sk.com>
The site deploys to GitHub Pages, which does not read Netlify _redirects, so the repository had no working redirect mechanism for the upcoming URL moves. website/static/_redirects held React Native template rules and was shipped to production on every build. Add @docusaurus/plugin-client-redirects 3.9.2, pinned to match @docusaurus/core. Measured its behaviour with a probe rule before wiring the real ones: it duplicates rules per locale, prefixes `to` with the locale baseUrl (/ for ko, /en/ for en), and emits <path>/index.html under trailingSlash: false. One rule set therefore covers both locales. Disable the blog. It generated /blog and its feeds but the navbar and footer links were commented out, so nothing on the site reached it and the only post was the template placeholder. The eight blog URLs per locale now redirect to the site root. Remove the React Native leftovers this touched: static/_redirects, scripts/src/update-redirects.ts and its package script, and netlify.toml. With netlify.toml gone, process.env.NETLIFY can never be set, so drop the isProductionDeployment branch and pin concatenateModules to false, which is what GitHub Pages builds already did. Add .claude/scripts/check-redirects.py as the gate. The plugin validates `to` but not `from`, so a missing redirect is silent. The script diffs the baseline routes against the current sitemaps and requires every vanished URL to have a redirect whose target actually exists. It confirms exactly 16 removed URLs, all covered. verify.sh 13/13, build passes for ko and en, yarn install --immutable passes. Signed-off-by: Haksung Jang <haksung@sk.com>
website/static/blog held 119 React Native blog images totalling 81MB. They came in with the Docusaurus template fork, nothing in this site references them, and there is no plan to reuse them. Because they sat in static/, every build copied them to /blog/assets/ for both locales. The previous commit removed the blog instance, so the site was serving blog images for a blog that no longer exists. A plain string grep never surfaced these: the only signal is the directory name and the files themselves are binaries. That is why the diagnosis and the plan both missed them. Kept as a separate commit from the blog removal so an 81MB deletion is distinguishable in history. Sitemaps are unchanged, the redirect gate still reports the same 16 removed URLs all covered, build passes for ko and en, verify.sh 13/13. Signed-off-by: Haksung Jang <haksung@sk.com>
Acts on the information-architecture findings. Four changes to how pages are placed, plus the guard rails that keep the moves honest. Entry point. /docs served the overview page while the sidebar listed it third, so the page a reader landed on was not the page the sidebar started with. The overview is now first, followed by quick start and the standards mapping. start-path had no inbound link from any page. It was built as a routing page for readers choosing a path, but the landing CTA went to quick start instead, so only sidebar browsers ever found it. Its three routes now live in the overview's next-steps section, where a reader choosing a path actually is, and the page is gone. The agent guide moves from docs to reference. reference/intro already claimed an "agent selection guide" section that held nothing but a link out to docs, so the reference instance advertised a page it did not own. The table also listed only the nine program-building agents; the seven automation agents shipped with no entry anywhere. All sixteen are now covered, split into program-building and automation groups. pipeline-security is registered in the DevSecOps sidebar. Eight pages link to it and it was in none of them, so it had no sidebar highlight and no prev/next. Supporting changes. The three standard-mapping pages get parallel labels so the sidebar shows they are one family. sidebar_position values are aligned with the manual sidebar arrays across all four instances, which removes two duplicates and one out-of-order entry. The 08 chapter drops its redundant `id:`, which only made the sidebar reference a numbered doc id; the URL is unaffected and needs no redirect. verify.sh checks 3, 6 and 7 now search website/reference as well as docs. Without this the agent guide would leave the admonition check simply by moving, and the gate would keep passing while covering less. The expanded roots surface no new failures on current content. check-redirects.py reports 20 removed URLs, 10 per locale, all covered. verify.sh 13/13, build passes for ko and en, ko-style lint 0 findings. Signed-off-by: Haksung Jang <haksung@sk.com>
The overview chapter sent newcomers through four competing entry pages and told them to read a 613-line requirements matrix as step 2 of self-study. - Point self-study step 2 at what the two standards require rather than at the 31-item structure, and make every step a real link - Keep the git clone instructions in 01-setup only; the overview and the 5-minute quick start now link there - Keep the no-install SBOM demo in the quick start only; the tools index links to it - Keep the chapter and deliverable tables in the overview only; the reference index links to them - Finish the three-way branch in the overview's next-steps section - Promote the h4 headings under sections 3 and 4 of supply-chain to h3 so heading order no longer skips a level Signed-off-by: Haksung Jang <haksung@sk.com>
Sections 3 and 4 jumped from h2 straight to h4, which Lighthouse reports as a heading-order violation. The Korean page was fixed in the previous commit; this brings the English page back in line with it. Heading text and body are untouched, and heading ids derive from the text rather than the level, so no anchor changes. The eight promoted headings now appear in the page table of contents, which stops at h3. Signed-off-by: Haksung Jang <haksung@sk.com>
…atrix The checklist mapping was 613 lines and self-study step 2 sent first-time readers straight into it, even though the document says it exists for the harness rather than for readers. It now splits by audience. - docs/00-overview/checklist-mapping.md keeps its URL and becomes a 69-line summary: the two-standard comparison, the four requirement groups with the chapter that fills each, and why doing both together saves about 39% - website/reference/requirements-matrix.md is new and holds the 31 per-item blocks verbatim, for the self-certification stage - test-coverage.py reads the new path; the G-block structure it parses is unchanged, so [8/13] still finds 31 items - iso-verifier, kwg-drift-checker, check-kwg-drift, harness-guide, the iso-18974 reference and the four conformance templates point at the matrix Signed-off-by: Haksung Jang <haksung@sk.com>
The OpenChain self-certification questions only existed inside eight chapter admonitions, so the document that calls itself canonical never carried them. They now live once, next to the item each one belongs to. - Every one of the 31 matrix blocks gains a certification question bullet - The eight chapter admonitions keep the ISO section numbers and link to the matrix instead of restating the question text - devsecops/iso-mapping drops the standard introduction and the registration procedure, both of which restate the conformance chapter, and is retitled so it no longer collides with ai-coding/iso-mapping in search - 07-conformance section 6 keeps the recommended order and links out for the counts; the gap analysis section points at the matrix - 03-policy links to 01-setup for the clone command instead of repeating it - Stale ko-style baseline entries for the shrunk mapping file are dropped Signed-off-by: Haksung Jang <haksung@sk.com>
The overview repeated the G1-G4 table and the 39% figure that the summary page now carries, so a change to either had two places to land. - The overview keeps a two-sentence orientation and links to the summary for the per-group chapter table and to the matrix for per-item detail - The chapter CLAUDE.md reading order matches the split, and names the file that test-coverage.py parses Signed-off-by: Haksung Jang <haksung@sk.com>
Seven places restated something another page already owned, and in one case the same word carried two different scales on a single page. - sbom-generation drops its own SBOM definition and links to sbom-101, which it already claims as the prerequisite - The six AI coding tool pages replace the license list with a placeholder comment and a link, so a policy change lands in the rules template only - sca keeps both complete workflows and gains a table of the three things that differ from the Quick CI/CD one, instead of restating the setup prose - devsecops strategy renames its maturity ladder to levels 1-4, so "stage" now refers only to the AI coding 5-stage strategy on that page - The training resource table gains a role column that ties it to section 3 - The data walkthrough in ai-security-review folds into a details block, leaving 329 lines of body - pipeline-design points at the SCA page for the grype policy file Signed-off-by: Haksung Jang <haksung@sk.com>
Chapter 08 split one task across five pages. The index already summarized all four methods with short examples, so a reader who wanted to actually apply anything had to open a second page, and the effect and limitation of each method were stated twice. The four method pages are folded into the index. Each method section now carries the full content that used to live on its own page. The two long artifacts, the complete SKILL.md and the complete workflow YAML, go into <details> so they stay available without pushing the reading flow past them. Section 5 is gone. It promised detailed guidance in a claude-oss-policy-guard project that does not exist, marked "in preparation", and the same promise appeared again under next steps. Neither is a thing a reader can act on. The license list in method 1 stays complete rather than becoming a placeholder. It differs from the six tool pages cleaned up earlier: those show where a config file goes, while this fence is the artifact a reader pastes into their own CLAUDE.md, so removing the list would remove the point of the section. Both the prose and the note keep the link to the canonical classification page, and a comment at the top of the file records that a category change now has to be applied in three places. The four method headings get explicit anchor ids so the redirects and the inbound link from agent-governance land on the right section rather than the top of the page. The redirect plugin accepts an anchor in `to`, verified by build. check-redirects.py gained anchor handling. It compared the whole `to` value against the sitemap, so any anchored redirect looked like a dangling one. It now splits the fragment, checks the page against the sitemap, and then checks that the anchor id actually exists in the built page, which onBrokenAnchors does not cover for redirects. check-redirects.py reports 28 removed URLs, 14 per locale, all covered. Body outside <details> is 241 lines ko and 245 en, file total 396 and 404, within the limits. verify.sh 13/13, build passes for ko and en. Signed-off-by: Haksung Jang <haksung@sk.com>
Each sample page stitches two to seven deliverables into one document, and the reader needs one of them at a time to compare against their own output. Five of the seven pages had no table of contents, and the two that did listed plain text rather than links. - All seven pages, in both locales, list their deliverables as anchor links - Every section heading carries an explicit id taken from its output-sample filename, so the anchor survives a title change and is the same in ko and en - The gap analysis table in conformance now uses those ids instead of slugs generated from headings, which would have broken silently on a retitle - The dependabot block in sbom-management-plan is yaml, not bash, fixed in output-sample so a regeneration keeps it - The skill documents the table of contents rule, warns that sync-output-samples.sh runs output/ to output-sample/ and would overwrite the golden fixtures, and records that the English pages are hand-maintained Signed-off-by: Haksung Jang <haksung@sk.com>
The chapter CLAUDE.md still pointed at a claude-oss-policy-guard project for detailed implementation and called it "to be released". No such repository exists. This is the same promise removed from the reader-facing page, and it matters more here: a session working in this folder reads this file as context, so it would go looking for a project that is not there, or write documentation assuming it exists. Detailed implementation now lives in index.md itself, so the next-steps section says what actually follows the chapter: renewal, quarterly allowlist review, rescanning on new CVEs, and the DevSecOps and AI coding tracks for wider automation. Adds a file-layout section recording that the four method pages were merged into index.md, that the two long artifacts sit in <details>, and that the old URLs redirect to the per-method anchors. The self-study path now names those anchors so a reader of this file can jump straight to the right section. verify.sh 13/13. Signed-off-by: Haksung Jang <haksung@sk.com>
customTheme.scss had grown to 2784 lines mixing tokens, layout and components, which made any design change hard to scope. It is now an entry file that @use-s eight partials, and the React Native fork leftovers are gone. The split is a pure move. Each partial holds a contiguous slice of the original in its original order, so the cascade is unchanged. The built CSS was normalised and compared before and after: 783 rules, identical order, identical declarations, identical selector sets. The only textual difference was the order of selectors inside four comma-separated groups, which is semantically inert. Deleted after confirming zero references, both in the sources and in the built HTML: - 44 unused custom properties (--toss-deep-*, --hero-bg, --home-hero-*, --home-feature-*, --logo, --tintColor and the rest) - the blog rules left behind when K1 removed the blog instance - RN-only blocks: the Native Code Required banner, Snack Player, the colour preview box, the component grid, the two-column code block, pill tabs and the code diff lines - PlatformSupport and the six platform icons it alone imported - seven unreferenced files under core/, the three get*Version helpers, the version banner and dropdown swizzles, versionsArchived.json - snackPlayerInitializer.ts and its type declaration, neither of which was registered as a client module Two things were deliberately left alone. The light-mode `a:not([class*="Button"])` guard in _surfaces.scss still has the capital B from React Native's naming, so it matches every homepage link and gives the CTA buttons `display: block` instead of `inline-flex`. That is live styling, not dead code, and changing it would move pixels, so it belongs with the landing rework rather than here. `--home-button-primary` reads like residue but has nine live references. Meta copyright notices were judged per file rather than stripped. The partials carry derived code and keep the MIT notice. The entry file was written from scratch during the split and has none, so it carries a project header instead. Verified against the 40 baseline screenshots taken at the parent commit: 32 identical, 8 differing by under 0.1% in the Algolia spinner and a few antialiasing pixels, none over tolerance. verify.sh 13/13, build clean. Also drops the netlify.toml entry from .claudeignore, left dangling when K1 deleted that file. Signed-off-by: Haksung Jang <haksung@sk.com>
Design option A was approved at gate 3, with the current font kept (Roboto for Latin, Pretendard for Korean). This lands its tokens plus the five corrections the diagnosis called for. Headings now carry weight, not just size. Every heading was 400, the same as body text, so an h3 at 20px sat four pixels away from a paragraph and read as one. h1 is 700, h2 through h4 are 600. Of the four reference sites measured, all separate headings by weight or by size; this site did neither. The size tokens are rem instead of px, so a reader who enlarges their browser font now gets larger text. Code blocks move from a line height of 1.4, the tightest of the four references, to 1.6. Corner radii become a two-step scale. The primary colour is split in two. #1a73e8 clears AA on white by 0.01, so any tinted surface pushed it under: the landing card link measured 4.22:1 and the final CTA note 4.17:1. Text now uses #1967d2 (5.37:1 on white, 4.86:1 on the tint) while #1a73e8 stays for large fills. The same split fixes the sidebar active item, which sat at 4.10:1 on its own highlight. Three further contrast failures surfaced while measuring and are fixed: the search shortcut keys (2.36:1), table headers (4.07:1), and the Hero attribution line (4.39:1). Hardcoded colours in the Hero, FinalCTA and WhyKwg modules now reference tokens. The Hero secondary CTA gets an opaque background token: it was translucent white over a gradient, which is why the diagnosis could not put a number on it. Measured after the change with text hidden so sampled pixels are true background, not glyphs: 1202 text elements across nine screens, two widths and both themes, none below AA. Lighthouse accessibility on the landing goes 96 to 100 and colour-contrast passes on all four sampled pages. Heading and code values match the option A spec exactly. No px remains in the font size tokens. verify.sh 13/13, build clean. Signed-off-by: Haksung Jang <haksung@sk.com>
index.scss was 788 lines of styling for the React Native homepage:
.HeaderHero, .GetStarted, .CrossPlatform, .FastRefresh, .NativeApps,
.VideoContent and the rest. None of those elements exist here. Every one
of its 37 top-level selectors was run through querySelectorAll on eight
real pages and matched nothing.
One rule in it was load-bearing and nearly went out with the rest:
.homepage { width: 100%; max-width: 100%; }
.homepage is the landing page's wrapperClassName, and this overrides the
Infima container width so the Hero band reaches both edges. Deleting the
file first cost the landing its full bleed: the Hero measured left 20,
width 1400 in a 1440 viewport, leaving a 20px white gutter down each
side. That is exactly 40 pixels per row, which is what the pixel diff
reported before the cause was found. The rule now lives in
_surfaces.scss next to the other landing styles.
The normalised CSS diff is 102 rules out, 1 in, and the one added is byte
identical to one of the removed: the relocation, not a change. The other
101 are the dead marketing rules.
Checked against the 20 screenshots taken at the end of the previous
chunk: 18 identical, one differing in a 3x3 pixel patch, and the mobile
dark landing alternating between two renders on every load independently
of this change, confirmed by comparing the same build against itself and
by a 0 diff against a capture in the same state. Hero geometry back to
left 0, width 1440. verify.sh 13/13, build clean.
Signed-off-by: Haksung Jang <haksung@sk.com>
The Hero was a fixed dark navy band in both themes, so a reader in light mode met a hard reversal between the first screen and the docs below it. Its colours are now tokens that swap: a pale gradient with dark type in light, the existing navy in dark. The terminal mock stays dark in both, which is what a terminal looks like, and its surfaces are opaque now so contrast can be measured rather than guessed at. Two long-standing rules come out together, as they were one problem. The light-mode `a:not([class*="Button"])` guard on .homepage carried React Native's capital B, so it never excluded Docusaurus's lowercase button--primary and applied `display: initial` from %link-style to every landing anchor. That is why the Hero CTAs rendered as blocks instead of flex. The guard is gone and `display: initial` is out of %link-style, where its only remaining user was an inline `.markdown a` and it did nothing. Landing links keep their hover underline from Infima. While wiring the Hero tokens the same cascade trap appeared again: the CTA colours were losing to a global dark-theme button rule, so the tokens read correctly only because the values happened to agree. The CTA selectors now outrank it, and the tokens actually decide. Also here: a fourth track card for Reference, matching the four docs instances in the navbar, with the grid at four columns and two on narrow screens; width and height on the navbar logo; English placeholders for the new card's strings. Landing measured with the method from the previous chunk, text hidden so sampled pixels are background: 112 elements across both widths and themes, none below AA. The three the script flagged are .titleAccent, whose gradient is painted through background-clip, so hiding the text leaves the gradient in the glyphs and the sampler reads it as its own background; every gradient stop clears 4.68:1 against the Hero. Lighthouse accessibility 100, colour-contrast and unsized-images pass, CLS 0. No horizontal overflow at 390px. verify.sh 13/13. Signed-off-by: Haksung Jang <haksung@sk.com>
…body The 404 was the stock Docusaurus page: no search, no links anywhere except the footer, a title and a first paragraph saying the same thing twice, and a heading copy button that belongs to documents. It now carries a search box, the four instance links with a line each, and one sentence. Its heading is a plain h1, not the Heading swizzle, so no copy button appears. The copy button also showed on the search results page, which is a theme page rather than a document. The h1 branch of the Heading swizzle now skips it there. Document pages keep theirs, eight on the SBOM chapter. BoxLink and Badge join Term, Prerequisite and JourneyProgress in the global MDX registration, so writers can use all five without an import. Badge had fallen to zero references when PlatformSupport was deleted two chunks ago; it resolves again. Document bodies narrow to 740px, the width chosen with option A. The column was 807px. Of the four sites measured during the diagnosis, Stripe sits at 492, Astro 720, MDN 768 and web.dev 854, so this lands between the two developer-documentation references. The cap is on the article, so body, footer and pagination share one edge, and tables still scroll inside it. One thing had to move out of the theme namespace. The 404 title kept rendering the old Korean string because Docusaurus ships its own translations for `theme.*` ids, which override an inline default. These strings are `notFound.*` now, and the English file follows. Nine screens across two widths and both themes: no horizontal overflow at 390px, and 36 captures taken for review. Lighthouse accessibility is 100 on all six configured URLs with colour-contrast passing. verify.sh 13/13, build clean. Signed-off-by: Haksung Jang <haksung@sk.com>
The gate has been advisory since it was added: every assertion was a warn, and the performance threshold of 0.9 was unreachable because the CI serves the build directory without compression or cache headers, so nobody could act on it. Accessibility, best practices and SEO become error assertions, joined by unsized-images and font-display. The performance category assertion is dropped in favour of two audits that say something actionable: total blocking time and unused JavaScript, both as warnings. font-display was failing on the two Source Code Pro faces, the only ones declared in CSS rather than through modules/fonts.ts, where Roboto and Pretendard already set swap. Both now do too, and the audit passes. The focus-visible polyfill is gone. Every rule in the codebase uses the native :focus-visible selector, none the polyfill's class form, so it was a CDN request for nothing. react-github-btn goes with it: a dependency no file imports. Removing it keeps yarn install --immutable green, which is what CI runs. numberOfRuns rises to three. The reason was that the landing sat one point above the accessibility threshold; it now scores 100, but run to run variance is worth absorbing regardless. Measured across all six configured URLs after the change: accessibility, best practices and SEO all 100, unsized-images and font-display passing. Blocking time stays under the 600ms warning on every page, the highest being 265ms. Unused JavaScript is over the 100KiB warning everywhere, between 130 and 477KiB, which is why it is a warning and not a gate. The dark contrast step is deferred. It needs the page rendered with prefers-color-scheme dark, and Lighthouse resets emulated media, so --force-prefers-color-scheme=dark has no effect: its screenshot comes back light. Doing it in CI would mean adding a browser automation dependency, which is a supply chain decision rather than a gate tweak. Dark is covered by the manual procedure instead, and the harness guide now describes it correctly. That guide had a warning worth acting on: switching data-theme by attribute leaves code blocks at their light colours, because Prism needs a React re-render. Confirmed: the pre background stays rgb(246,248,250). Earlier chunks measured dark that way, so dark code blocks had never actually been checked. Re-measured with the theme genuinely switched: 452 elements over nine screens, none below AA. The guide now gives prefers-color-scheme emulation as the simpler route, and records the contrast method and its background-clip exception. Signed-off-by: Haksung Jang <haksung@sk.com>
The docs and reference instances still described the entry path the way it worked before the overview was rebuilt. - The overview and the quick start point at 01-setup for the clone command instead of repeating it, matching the Korean - The tools index links to the quick start for the no-install demo - The reference index links to the overview for the deliverable file list - sbom-management step 6 gains the ls command and the note that myapp is only an example, which Korean already had - The chapter 08 sidebar key becomes a doc key, since chunk K6 turned that category into a single document Code blocks are identical to the Korean; only comments are translated. Fence counts now match across every file in both instances. Signed-off-by: Haksung Jang <haksung@sk.com>
English pages linked to /docs, /reference, /devsecops and /ai-coding without a locale prefix. Docusaurus does not add one to a hardcoded absolute path, so every one of those links dropped an English reader onto the Korean site. All 275 are now /en/... across the four instances. External URLs, bare anchors and image paths were out of scope and none were touched; no link inside a code block was affected. The English sample pages are edited directly because they are hand-maintained translations, not output of the reference-samples skill, so a regeneration cannot undo this. Signed-off-by: Haksung Jang <haksung@sk.com>
The sidebar showed "개발자 가이드 (선택)" where every other chapter showed
its number, because front matter sidebar_label overrides the label set on
the sidebars.ts item. Chapter 07 renders "7. 자체 인증" from sidebars.ts;
chapter 08 was the only index carrying its own sidebar_label, so it lost
the "8." the sidebar config supplies.
The line predates this redesign, and chapters 01 through 07 have no
sidebar_label at all, so removing it matches the existing convention and
drops the duplicate label that had to be kept in sync by hand.
The English translation key already carried the number
("8. Developer Guide (Optional)"), so both locales pick it up once the
front matter stops winning. Verified by build: ko now renders
"8. 개발자 가이드 (선택)" and en "8. Developer Guide (Optional)".
The English counterpart of this change, removing the same front matter
line, landed in b7df0bb: that commit rewrote absolute links across the
English tree and touched this same file, so the one-line removal could not
be separated from it.
verify.sh 13/13.
Signed-off-by: Haksung Jang <haksung@sk.com>
The repository style forbids the em dash, and the English landing, glossary tooltips and about page still used it as a clause separator. - code.json: 14 strings reworded, covering the hero and track subtitles, the three showcase captions and the seven glossary tooltips - about.md: the two contact bullets The Korean source strings in website/src still carry em dashes, so the two locales now differ in punctuation on these strings. Reported separately: the body content of both locales uses the em dash heavily, and test-coverage.py requires it in the requirements matrix headings, so a blanket sweep is not safe and is out of scope here. Signed-off-by: Haksung Jang <haksung@sk.com>
GitHub Pages serves one fallback file for anything missing: the root 404.html. build/en/404.html is generated correctly and is fine when opened directly, but nothing ever routes a broken /en/ link to it. An English reader following a dead link landed on a Korean page. Static hosting gives no way to pick a fallback by path prefix, so the choice has to happen in the browser. It renders English in place rather than redirecting. The address stays as the reader typed it, so they can see which link is broken, and there is no redirect flash. The page also names the path it could not find. The four cards point at /en/, so any of them leads into the English site. The English strings are inlined rather than translated. translate() resolves at build time, and this decision has to happen at run time inside the Korean bundle. The locale swap runs after mount so the first client render still matches the server HTML. lang and title needed Docusaurus's Head. Setting them on the DOM directly appeared to work but did not survive: measured, the body turned English while lang stayed ko and the title stayed Korean, because Helmet reapplies both. Verified against a running server, not just the build output, since the files alone look fine either way. Four missing paths under /en/ (/en/no-such-page, /en/docs/does-not-exist, /en/devsecops/broken-link-abc, /en/reference/samples/gone) all render English with lang=en, an English title and the path shown. Missing paths under / are unchanged, and /en/404 opened directly is untouched. One limit worth stating: only the 404 content swaps. The navbar and footer come from the Korean bundle and stay Korean on that page. Making those English would mean rendering the whole app in another locale, which the client cannot do. The English cards are the way out. Signed-off-by: Haksung Jang <haksung@sk.com>
haksungjang
force-pushed
the
redesign-2026-09
branch
from
September 3, 2026 21:31
cf37d05 to
09c57f3
Compare
Merge-1 verification found the new script missing from CONTRIBUTING's quick reference and harness-guide's script inventory, and the reference/ instance missing from CLAUDE.md's directory table after this redesign moved agents.md there and added requirements-matrix.md. Signed-off-by: Haksung Jang <haksung@sk.com>
eslint flags _config and isServer as unused, which fails ci:lint and blocks the pull request. Neither is referenced in the function body. The rule has been failing since before this redesign, but pre-merge.yml only runs on pull requests and recent work landed directly on main, so no run had exercised it. Signed-off-by: Haksung Jang <haksung@sk.com>
haksungjang
force-pushed
the
redesign-2026-09
branch
from
September 3, 2026 21:48
09c57f3 to
33ea92b
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
First of two merges in the site-wide redesign (K0 through K15-a). Covers information
architecture, content restructuring, and visual design. Example-code fixes, CI automation,
and the TRUSCA link check remain on the branch for a second merge.
@docusaurus/plugin-client-redirects) replaces the deadNetlify-era
_redirectsfile; the blog instance and its React Native image assets(81MB) are removed.
agents.mdmoved to the reference instance,checklist-mapping.mdsplit into a summary and a canonical
requirements-matrix.md, chapter 08's four methodpages merged into a single index.
customTheme.scsssplit into six partials, dead fork-era stylesheet removed,type scale and primary colour replaced per the approved mockup, landing/doc pages/404
rebuilt, Lighthouse gate reset to the new assertions.
back to the Korean 404 page) is worked around client-side.
the pre-merge checklist against live script output before this PR was opened.
Test plan
bash .claude/scripts/verify.sh13/13cd website && npm run build(ko + en)python3 .claude/scripts/check-redirects.py docs/_plan/routes-baseline.txt website/build— all 28 dropped URLs redirect to a real destinationSigned-off-by