Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 55adc1dbd7 | |||
| 138d8fbb6d |
@@ -0,0 +1,26 @@
|
||||
# I18N-00 baseline audit
|
||||
|
||||
Date: 2026-11-02. Verdict: **IN_PROGRESS; partial research checkpoint, not full I18N-00 acceptance. I18N-01 through 08 BLOCKED. Production NO-GO.**
|
||||
|
||||
Research only, authorised by master prompt and continuous-progress instruction. Branch `feature/i18n-00-audit`, worktree `C:/Users/Connor/.codex/worktrees/i18n-00-audit/Job tracker`, baseline `5cb903b989742b7a96cb22ddf4c0e24993b18980`. Application/API/tests/UI/sidecar diff against `ba04d817` was empty. This is the accepted conditional development handoff, not blanket runtime, language or production acceptance. No controller or approval state was changed. All ten supplied I18N prompts were read. Their implementation requirements are future specifications, not authority to execute them.
|
||||
|
||||
Architecture authority is `docs/architecture/current.md`, which redirects to `overview.md`. Existing React/MUI, ASP.NET/EF/MariaDB, Python sidecar and rendering ownership remain. Graph absent in this baseline: bounded source inspection used; no graph rebuild needed for documentation.
|
||||
|
||||
## Verified source findings
|
||||
|
||||
* `job-tracker-ui/src/i18n/translations.ts`: custom two-language `en | nb` object; it is not an i18next or FormatJS installation.
|
||||
* `I18nProvider.tsx`: local storage accepts `nb`, `nb-NO`, `no`; otherwise English. Auth hydration and cross-tab storage update language. `{word}` substitution handles simple values, not ICU plural/select grammar. Failed preference save offers retry; sequence tracking avoids stale error handling.
|
||||
* `JobTrackerApi/Controllers/AuthController.cs:601`: language endpoint accepts `en` or Bokmål aliases, writes `nb-NO`; unsupported input returns hardcoded English error. Do not rename canonical English to `en-GB` without migration tests.
|
||||
* `CoverLetterDocumentRenderer.cs:36`: labels distinguish `nb-NO` from English; document HTML has its own language. `ThemedCvRenderer.cs:60` derives HTML language from document settings. UI language must not become the output-language owner.
|
||||
* `HumanLanguageCatalog.cs` is CV skill-language recognition, including environment-independent seeds and variant collapsing. It is not an eligible UI-locale registry; reusing it would lose script/region distinctions.
|
||||
* Manifest dependencies: React `^19.2.4`, Next `16.4.1`, MUI `^7.3.9`, TypeScript `^5.9.3`, date-fns `^4.1.0`. These are manifest ranges, not freshly installed/runtime versions. No i18next/FormatJS direct dependency. Lockfile/runtime compatibility must be qualified before implementation.
|
||||
|
||||
## Gate evidence
|
||||
|
||||
`docs/pre-phase10-ux/ACCEPTANCE.md` grants conditional development review, not Phase 10 implementation. `docs/automation/handoffs/pre-phase10/FINAL_DEVELOPMENT_ENTRY.md` separates P10-00 assessment from candidate-specific P10-01 permission. This checkpoint cannot grant either. Product-review and launch-site accepted decisions are absent from this baseline; absence is not permission. Global Jobs planning exists separately at `0ec9f98` in the main workspace (`docs/global-jobs/00/DEPENDENCIES_AND_GATES.md` inspected read-only); it is not integrated here and does not authorise live providers or GJ-01.
|
||||
|
||||
## Honest limits
|
||||
|
||||
The TypeScript AST inventory contains 3,119 existing English catalogue entries and 3,164 syntactically identified static call sites across 134 non-test frontend files. It records 188 dynamic/unknown calls separately as an unresolved count; 853 catalogue entries have no identified static caller. These are not deletion candidates: wrappers, dynamic keys and direct object access remain unresolved. A subsequent partial JSX/accessibility literal inventory now contains 26 source-context-reviewed candidates. CONTEXT_TRIAGE.md records the current 80 unresolved dynamic calls after 108 finite-branch resolutions. This is still not a complete non-catalogue inventory. Every-string attribution, translator context, accessible states and country-specific legal recognition require additional review. Therefore the stage's complete-inventory criterion has not passed. No translations, native approval, screenshots, model results, browser results or locale release are manufactured.
|
||||
|
||||
The country matrix covers an initial 59 territory/market contexts from versioned CLDR 49, with targeted official-record checks for Norway, Switzerland and Serbia. The remaining legal cross-checks are pending. The draft catalogue contains 60 planned locale candidates, not 60 supported languages. Schema, uniqueness, BCP-47 parsing and rejection of a forged released status passed using existing local tools. Node/ICU canonicalises `cnr-ME` to `sr-ME`; retain this unresolved identity issue rather than accepting an automatic product alias. See BASELINE_TESTS.md.
|
||||
@@ -0,0 +1,19 @@
|
||||
# Planning evidence and baseline checks
|
||||
|
||||
2026-11-02. Baseline `5cb903b989742b7a96cb22ddf4c0e24993b18980`, branch `feature/i18n-00-audit`. Documentation only. No runtime code, test code, lockfiles or settings changed.
|
||||
|
||||
| Check | Result | Scope |
|
||||
| --- | --- | --- |
|
||||
| `git diff ba04d817fed26d659bfa2a56b089d6cac851dc34 HEAD --stat -- JobTrackerApi JobTrackerApi.Tests JobTrackerApi.MariaDb.Tests job-tracker-ui tools/summarizer` | PASSED: empty diff, exit 0 | Source identity only; no fresh runtime assertion |
|
||||
| English catalogue AST extraction using existing TypeScript | PASSED: 3,119 unique keys | Property assignments required to be string literals; duplicate/unsupported members throw; 134 non-test TS/TSX files scanned |
|
||||
| Static syntactic `t` call association | 3,164 sites; 188 dynamic/unknown calls; 853 entries without static caller | Partial inventory, not symbol resolution or coverage proof; no dead-code inference |
|
||||
| Existing Ajv draft-07 validation | PASSED: 60 entries | `LOCALE_SCHEMA.json` compiled and validated `LOCALE_CATALOG.json`; no installed dependency changes |
|
||||
| Uniqueness and `Intl.getCanonicalLocales` parsing | PASSED: 60 unique parseable tags | Node v24.19.0, ICU 78.3; syntax acceptance is not runtime translation availability |
|
||||
| Negative publication fixture | PASSED | In-memory copy changed first `surfaces.ui` from `planned` to `released`; validator rejected it |
|
||||
| Montenegrin identity | OPEN | Intl maps `cnr-ME` to `sr-ME`; product semantics require explicit resolution before registry implementation |
|
||||
| Product/unit/browser/MariaDB/Python suites | NOT RUN | No implementation changes; existing accepted evidence remains historical |
|
||||
| Native/legal/AT/device/PDF/hosted/production/provider/model qualification | NOT RUN | No authority or claim conferred by planning checks |
|
||||
|
||||
The inventory records its baseline, parser version, exact source SHA-256 and source line for each English message. Callers retain expressions and file/line, making manual review possible. Extraction covers the `en` object in `translations.ts`, excludes `*.test.*`, and associates literal first arguments of expressions named `t` or ending in `.t`. Dynamic keys, aliases, direct property reads, C#/Python messages and hardcoded JSX are not completely captured. Recompute after source changes; do not extrapolate counts to full application completeness.
|
||||
|
||||
Research sources checked on this date: CLDR 49 territory table, EU official-language list, i18next plural documentation, FormatJS ICU syntax, Norwegian Language Act, Swiss federal multilingualism guidance and Serbian government constitution. Specific links and limitations are in the matrix and implementation plan. No production data or private user text was sent to translation services.
|
||||
@@ -0,0 +1,31 @@
|
||||
# Source-context triage continuation
|
||||
|
||||
2026-11-02, unchanged application baseline `5cb903b989742b7a96cb22ddf4c0e24993b18980`. No translation or runtime implementation.
|
||||
|
||||
## Completed inventory refinement
|
||||
|
||||
- All 188 previously counted dynamic/unknown `t` calls now have source file/line/hash and exact expression in DYNAMIC_MESSAGE_CALLS.json.
|
||||
- 108 calls resolve to finite literal conditional branches, accounting for 240 possible-key references. Each referenced key exists in the English catalogue. Nested ternaries are included. This is key resolution, not translator or runtime acceptance.
|
||||
- 80 calls still need lookup-table, wrapper, template-token or runtime-key review. Type assertions such as `as any` or a single asserted literal must not be treated as proof of actual possible values.
|
||||
- Four direct catalogue reads were located in I18nProvider: save-failure/retry feedback and the evaluator/fallback. These are active consumers missed by a `t("key")`-only search; preserve them during migration.
|
||||
- 26 JSX text/selected accessibility-label candidates were extracted and individually reviewed in source context. The JSON records preservation/extraction decisions and excludes adjacent private runtime values. This scan does not cover every computed JSX expression, object-held label, string-returning helper, backend string or app-shell document text.
|
||||
|
||||
## Findings to carry into approved implementation
|
||||
|
||||
| ID | Source | Finding / required handling |
|
||||
| --- | --- | --- |
|
||||
| I00-13 | `App.tsx:488` | Session-invalidated alert is hardcoded English. Localisation must preserve disposal of the old application tree and must not depend on its discarded session/provider state |
|
||||
| I00-14 | `JobFlowBar.tsx:147` | `Flow` is controlled UI copy outside the catalogue; extract with workflow context |
|
||||
| I00-15 | `Attachments.tsx:361` | Preview iframe title is only `pdf`; use descriptive localised purpose while keeping private filenames out of translator exports |
|
||||
| I00-16 | `AppShell.tsx:692` | `EN`/`NO` with `English`/`Norsk` labels conflates country-like abbreviation and Norwegian variant. Future selector needs native/English names and explicit Bokmal/Nynorsk distinction; preserve existing nb aliases |
|
||||
| I00-17 | `ApplicationAssets.tsx:360` | File-size display uses `toFixed(1)` with KB. Review locale number formatting; filename and underlying byte count remain unchanged |
|
||||
| I00-18 | `I18nProvider.tsx:43` | Save-failure feedback accesses catalogue directly. Migration must preserve same-language retry and stale-save sequencing; static t-call inventory alone misses this contract |
|
||||
| I00-19 | `LandingPage.tsx:133` | Technology-name list is not ordinary translatable prose. Coordinate user-outcome copy with homepage design work; do not translate trademarks or add unverified feature claims |
|
||||
|
||||
Brand/provider names, host examples and technical identifiers were not blindly classified as missing translations. Unit/version fragments require formatting and accessibility context rather than mechanical dictionary substitution. All findings are planning tasks, not permission to edit application files.
|
||||
|
||||
## Verification and remaining work
|
||||
|
||||
The same 134 non-test TS/TSX files were scanned using the installed TypeScript AST parser. Assertions confirmed exactly 188 dynamic calls and that all 240 resolved branch-key references exist. No full application typecheck or browser suite was run. The 26 literal records were reviewed against adjacent source lines; broader semantic census remains IN_PROGRESS.
|
||||
|
||||
Next: resolve the remaining 80 table/template/wrapper calls; cover computed frontend values and app document metadata; inventory backend errors, queued communication text and Python processing messages. Country legal records, reviewer allocation and runtime-library choice remain separate unfinished tasks.
|
||||
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"baseline": "5cb903b989742b7a96cb22ddf4c0e24993b18980",
|
||||
"method": "TypeScript AST syntactic triage; no symbol resolution or runtime coverage claim",
|
||||
"filesScanned": 134,
|
||||
"entries": [
|
||||
{
|
||||
"file": "job-tracker-ui/src/i18n/I18nProvider.tsx",
|
||||
"line": 43,
|
||||
"sourceSha256": "95a930915cb2240547cc1a91af7cb0a475bc8f46ac75304b3241a401928ed3e4",
|
||||
"kind": "direct-catalogue-access",
|
||||
"text": "translations[l].settingsLanguageSaveFailed",
|
||||
"ownerComponent": "job-tracker-ui/src/i18n/I18nProvider.tsx",
|
||||
"contextStatus": "pending",
|
||||
"sensitivity": "unclassified-template; do-not-export-runtime-values"
|
||||
},
|
||||
{
|
||||
"file": "job-tracker-ui/src/i18n/I18nProvider.tsx",
|
||||
"line": 44,
|
||||
"sourceSha256": "95a930915cb2240547cc1a91af7cb0a475bc8f46ac75304b3241a401928ed3e4",
|
||||
"kind": "direct-catalogue-access",
|
||||
"text": "translations[l].retry",
|
||||
"ownerComponent": "job-tracker-ui/src/i18n/I18nProvider.tsx",
|
||||
"contextStatus": "pending",
|
||||
"sensitivity": "unclassified-template; do-not-export-runtime-values"
|
||||
},
|
||||
{
|
||||
"file": "job-tracker-ui/src/i18n/I18nProvider.tsx",
|
||||
"line": 67,
|
||||
"sourceSha256": "95a930915cb2240547cc1a91af7cb0a475bc8f46ac75304b3241a401928ed3e4",
|
||||
"kind": "direct-catalogue-access",
|
||||
"text": "translations[language][key]",
|
||||
"ownerComponent": "job-tracker-ui/src/i18n/I18nProvider.tsx",
|
||||
"contextStatus": "pending",
|
||||
"sensitivity": "unclassified-template; do-not-export-runtime-values"
|
||||
},
|
||||
{
|
||||
"file": "job-tracker-ui/src/i18n/I18nProvider.tsx",
|
||||
"line": 67,
|
||||
"sourceSha256": "95a930915cb2240547cc1a91af7cb0a475bc8f46ac75304b3241a401928ed3e4",
|
||||
"kind": "direct-catalogue-access",
|
||||
"text": "translations.en[key]",
|
||||
"ownerComponent": "job-tracker-ui/src/i18n/I18nProvider.tsx",
|
||||
"contextStatus": "pending",
|
||||
"sensitivity": "unclassified-template; do-not-export-runtime-values"
|
||||
}
|
||||
]
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,87 @@
|
||||
# Europe country and language research matrix
|
||||
|
||||
Research checkpoint 2026-11-02; not a market-launch list or legal opinion. All entries are candidate scope. CLDR 49 provides an initial language relationship dataset; national/regional official-record cross-checks remain incomplete. Blank CLDR status is not proof of absence or recognition. No tag decides sovereignty, EU membership, provider rights or support. XK is a CLDR user-assigned territory code, not ISO 3166-1; do not silently persist it as an ISO identifier.
|
||||
|
||||
Source: [Unicode CLDR 49 territory-language data](https://www.unicode.org/cldr/charts/49/tsv/territory_language_information.tsv); retrieved SHA-256 `29bcadbb4362e1a7a3685f4bf199152809635acca58fab10a3576a0f7b55868c`. Population percentages are deliberately omitted; they are not product usage evidence.
|
||||
|
||||
| Territory | Code | CLDR official/de-facto | CLDR regional/recognised | Legal cross-check |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| Andorra | AD | ca (official) | not recorded; further review required | PENDING |
|
||||
| Albania | AL | sq (official) | not recorded; further review required | PENDING |
|
||||
| Austria | AT | de (official) | hr (official_regional), sl (official_regional), hu (official_regional) | PENDING |
|
||||
| Åland Islands | AX | sv (official) | not recorded; further review required | PENDING |
|
||||
| Bosnia & Herzegovina | BA | bs (official), bs-Cyrl (official), hr (official), sr (official), sr-Latn (official) | not recorded; further review required | PENDING |
|
||||
| Belgium | BE | nl (official), fr (official), de (official) | not recorded; further review required | PENDING |
|
||||
| Bulgaria | BG | bg (official) | not recorded; further review required | PENDING |
|
||||
| Belarus | BY | ru (official), be (official) | not recorded; further review required | PENDING |
|
||||
| Switzerland | CH | de (official), gsw (de_facto_official), fr (official), it (official) | rm (official_regional) | PENDING |
|
||||
| Cyprus | CY | el (official), tr (official) | not recorded; further review required | PENDING |
|
||||
| Czechia | CZ | cs (official) | not recorded; further review required | PENDING |
|
||||
| Germany | DE | de (official) | frr (official_regional) | PENDING |
|
||||
| Denmark | DK | da (official) | de (official_regional), kl (official_regional) | PENDING |
|
||||
| Estonia | EE | et (official) | not recorded; further review required | PENDING |
|
||||
| Spain | ES | es (official) | ca (official_regional), gl (official_regional), eu (official_regional), ast (official_regional), oc (official_regional) | PENDING |
|
||||
| Finland | FI | fi (official), sv (official) | sms (official_regional) | PENDING |
|
||||
| Faroe Islands | FO | fo (official) | not recorded; further review required | PENDING |
|
||||
| France | FR | fr (official) | not recorded; further review required | PENDING |
|
||||
| United Kingdom | GB | en (official) | cy (official_regional), ga (official_regional), gd (official_regional) | PENDING |
|
||||
| Guernsey | GG | en (official) | not recorded; further review required | PENDING |
|
||||
| Gibraltar | GI | en (official) | not recorded; further review required | PENDING |
|
||||
| Greece | GR | el (official) | not recorded; further review required | PENDING |
|
||||
| Croatia | HR | hr (official) | it (official_regional), vec (official_regional) | PENDING |
|
||||
| Hungary | HU | hu (official) | not recorded; further review required | PENDING |
|
||||
| Ireland | IE | en (official), ga (official) | not recorded; further review required | PENDING |
|
||||
| Isle of Man | IM | en (official), gv (official) | not recorded; further review required | PENDING |
|
||||
| Iceland | IS | is (official) | not recorded; further review required | PENDING |
|
||||
| Italy | IT | it (official) | fr (official_regional), vec (official_regional) | PENDING |
|
||||
| Jersey | JE | en (official) | not recorded; further review required | PENDING |
|
||||
| Liechtenstein | LI | de (official), gsw (de_facto_official) | not recorded; further review required | PENDING |
|
||||
| Lithuania | LT | lt (official) | not recorded; further review required | PENDING |
|
||||
| Luxembourg | LU | fr (official), lb (official), de (official) | not recorded; further review required | PENDING |
|
||||
| Latvia | LV | lv (official) | not recorded; further review required | PENDING |
|
||||
| Monaco | MC | fr (official) | not recorded; further review required | PENDING |
|
||||
| Moldova | MD | ro (official) | not recorded; further review required | PENDING |
|
||||
| Montenegro | ME | sr-Latn (official) | not recorded; further review required | PENDING |
|
||||
| North Macedonia | MK | mk (official) | sq (official_regional) | PENDING |
|
||||
| Malta | MT | mt (official), en (official) | not recorded; further review required | PENDING |
|
||||
| Netherlands | NL | nl (official) | fy (official_regional) | PENDING |
|
||||
| Norway | NO | nb (official), no (official), nn (official) | se (official_regional) | PENDING |
|
||||
| Poland | PL | pl (official) | de (official_regional), csb (official_regional), lt (official_regional) | PENDING |
|
||||
| Portugal | PT | pt (official) | not recorded; further review required | PENDING |
|
||||
| Romania | RO | ro (official) | not recorded; further review required | PENDING |
|
||||
| Serbia | RS | sr (official), sr-Latn (official) | hu (official_regional), ro (official_regional), hr (official_regional), sk (official_regional), uk (official_regional) | PENDING |
|
||||
| Russia | RU | ru (official) | tt (official_regional), ce (official_regional), ba (official_regional), av (official_regional), kbd (official_regional), myv (official_regional), kum (official_regional), sah (official_regional), inh (official_regional), bua (official_regional), az-Cyrl (official_regional), lez (official_regional), mdf (official_regional), krc (official_regional), tyv (official_regional), udm (official_regional), ady (official_regional), kv (official_regional), lbe (official_regional), koi (official_regional) | PENDING |
|
||||
| Sweden | SE | sv (official) | fi (official_regional) | PENDING |
|
||||
| Slovenia | SI | sl (official) | vec (official_regional) | PENDING |
|
||||
| Svalbard & Jan Mayen | SJ | nb (official) | not recorded; further review required | PENDING |
|
||||
| Slovakia | SK | sk (official) | not recorded; further review required | PENDING |
|
||||
| San Marino | SM | it (official) | not recorded; further review required | PENDING |
|
||||
| Türkiye | TR | tr (official) | not recorded; further review required | PENDING |
|
||||
| Ukraine | UA | uk (official), ru (de_facto_official) | not recorded; further review required | PENDING |
|
||||
| Vatican City | VA | it (de_facto_official) | not recorded; further review required | PENDING |
|
||||
| Kosovo | XK | sq (official), sr (official), sr-Latn (official) | not recorded; further review required | PENDING |
|
||||
| Armenia | AM | hy (official) | not recorded; further review required | PENDING |
|
||||
| Azerbaijan | AZ | az (official), az-Cyrl (official) | not recorded; further review required | PENDING |
|
||||
| Georgia | GE | ka (official) | ab (official_regional), os (official_regional) | PENDING |
|
||||
| Kazakhstan | KZ | ru (official), kk (official) | not recorded; further review required | PENDING |
|
||||
| Greenland | GL | kl (official) | not recorded; further review required | PENDING |
|
||||
|
||||
## Scope and legal cross-check queue
|
||||
|
||||
Russia, Turkey, Cyprus, Armenia, Azerbaijan, Georgia and Kazakhstan are explicit geographic/market-review cases; inclusion here does not approve a market. Greenland, Faroe Islands, Aland, Crown dependencies, Gibraltar and Svalbard/Jan Mayen are separately considered territory contexts. This is an initial 59-code research envelope, not a claim to have exhausted every dependency or minority language.
|
||||
|
||||
Norway: [Language Act](https://lovdata.no/dokument/NLE/lov/2021-05-21-42) distinguishes Bokmal/Nynorsk and protected Sami/minority languages. Plan distinct nb-NO/nn-NO and investigate Sami/Kven review capacity; do not infer their status from the abbreviated CLDR row.
|
||||
|
||||
Switzerland: [federal multilingualism explanation](https://www.aboutswitzerland.eda.admin.ch/en/multilingualism) distinguishes national languages and official usage. Plan de-CH, fr-CH, it-CH and rm-CH with separate reviewers.
|
||||
|
||||
Serbia: [government constitution](https://www.srbija.gov.rs/tekst/56753/ustav-republike-srbije.php) establishes Serbian/Cyrillic official use. sr-Latn-RS remains an explicit product candidate, separately from sr-Cyrl-RS; not a claim of identical legal status. These source checks inform planning, not exhaustive legal clearance.
|
||||
|
||||
Regional/minority queue includes ca-ES, eu-ES, gl-ES, cy-GB, gd-GB, se-NO, smj-NO, sma-NO and fkv-NO. Country-specific recognition, applicable areas, reviewer capacity, orthography, fonts and locale-data support must be reviewed separately. No automatic mapping of Montenegrin to Serbian; cnr-ME remains a candidate requiring runtime/data validation.
|
||||
|
||||
## EU 24 language baseline
|
||||
|
||||
[EU official language list](https://european-union.europa.eu/principles-countries-history/languages_en), checked 2026-11-02: Bulgarian bg-BG; Croatian hr-HR; Czech cs-CZ; Danish da-DK; Dutch nl-NL; English en (preserve existing canonical ID; en-GB candidate); Estonian et-EE; Finnish fi-FI; French fr-FR; German de-DE; Greek el-GR; Hungarian hu-HU; Irish ga-IE; Italian it-IT; Latvian lv-LV; Lithuanian lt-LT; Maltese mt-MT; Polish pl-PL; Portuguese pt-PT; Romanian ro-RO; Slovak sk-SK; Slovenian sl-SI; Spanish es-ES; Swedish sv-SE. These locale choices are proposals, not mandated by the EU list.
|
||||
|
||||
## Proposed waves
|
||||
|
||||
Foundation candidates: preserve existing en/nb behavior, then nn-NO, sv-SE, da-DK, fi-FI and is-IS if reviewers exist. EU-24 next; broader national/script/region candidates thereafter. Actual usage analytics and reviewer allocation are unavailable, so no evidence-backed commercial ranking or promised dates are asserted. English fallback remains available irrespective of market.
|
||||
@@ -0,0 +1,319 @@
|
||||
{
|
||||
"baseline": "5cb903b989742b7a96cb22ddf4c0e24993b18980",
|
||||
"method": "TypeScript AST syntactic triage; no symbol resolution or runtime coverage claim",
|
||||
"filesScanned": 134,
|
||||
"entries": [
|
||||
{
|
||||
"file": "job-tracker-ui/src/App.tsx",
|
||||
"line": 488,
|
||||
"sourceSha256": "3b5645d12f2c92ed8999d7a072bd7d47fac77023d460a19a9b3bfc2a4191962f",
|
||||
"kind": "jsx-text",
|
||||
"text": "Session changed. Clearing this page…",
|
||||
"ownerComponent": "job-tracker-ui/src/App.tsx",
|
||||
"contextStatus": "source-context-reviewed; implementation-pending",
|
||||
"sensitivity": "public-ui-template; adjacent runtime identifiers excluded",
|
||||
"decision": "localise-with-session-boundary-preservation",
|
||||
"translatorContext": "Alert rendered while old application tree is invalidated; preserve unmount/privacy behavior and avoid dependencies on the discarded session/provider tree."
|
||||
},
|
||||
{
|
||||
"file": "job-tracker-ui/src/assets/JobbjaktMark.tsx",
|
||||
"line": 7,
|
||||
"sourceSha256": "5a539514876a66eaf17ec68eb7ce3d28c558384bc24ab76b61f73be8df754473",
|
||||
"kind": "jsx-attribute:aria-label",
|
||||
"text": "Jobbjakt",
|
||||
"ownerComponent": "job-tracker-ui/src/assets/JobbjaktMark.tsx",
|
||||
"contextStatus": "source-context-reviewed; implementation-pending",
|
||||
"sensitivity": "public-ui-template; adjacent runtime identifiers excluded",
|
||||
"decision": "preserve-proper-name-or-example",
|
||||
"translatorContext": "Public brand/provider label or synthetic host example; not user content. Retain original spelling; localise surrounding guidance separately."
|
||||
},
|
||||
{
|
||||
"file": "job-tracker-ui/src/components/ApplicationAssets.tsx",
|
||||
"line": 198,
|
||||
"sourceSha256": "25216c80ef92d519baad9e428a0e77390150605c1a3529a4809819d120661f29",
|
||||
"kind": "jsx-text",
|
||||
"text": "· v",
|
||||
"ownerComponent": "job-tracker-ui/src/components/ApplicationAssets.tsx",
|
||||
"contextStatus": "source-context-reviewed; implementation-pending",
|
||||
"sensitivity": "public-ui-template; adjacent runtime identifiers excluded",
|
||||
"decision": "version-or-unit-formatting-review",
|
||||
"translatorContext": "Keep numeric/version identity; review locale number formatting and descriptive accessible labels. Do not translate user file/name data."
|
||||
},
|
||||
{
|
||||
"file": "job-tracker-ui/src/components/ApplicationAssets.tsx",
|
||||
"line": 360,
|
||||
"sourceSha256": "25216c80ef92d519baad9e428a0e77390150605c1a3529a4809819d120661f29",
|
||||
"kind": "jsx-text",
|
||||
"text": "KB",
|
||||
"ownerComponent": "job-tracker-ui/src/components/ApplicationAssets.tsx",
|
||||
"contextStatus": "source-context-reviewed; implementation-pending",
|
||||
"sensitivity": "public-ui-template; adjacent runtime identifiers excluded",
|
||||
"decision": "version-or-unit-formatting-review",
|
||||
"translatorContext": "Keep numeric/version identity; review locale number formatting and descriptive accessible labels. Do not translate user file/name data."
|
||||
},
|
||||
{
|
||||
"file": "job-tracker-ui/src/components/ApplicationAssets.tsx",
|
||||
"line": 699,
|
||||
"sourceSha256": "25216c80ef92d519baad9e428a0e77390150605c1a3529a4809819d120661f29",
|
||||
"kind": "jsx-text",
|
||||
"text": "v",
|
||||
"ownerComponent": "job-tracker-ui/src/components/ApplicationAssets.tsx",
|
||||
"contextStatus": "source-context-reviewed; implementation-pending",
|
||||
"sensitivity": "public-ui-template; adjacent runtime identifiers excluded",
|
||||
"decision": "version-or-unit-formatting-review",
|
||||
"translatorContext": "Keep numeric/version identity; review locale number formatting and descriptive accessible labels. Do not translate user file/name data."
|
||||
},
|
||||
{
|
||||
"file": "job-tracker-ui/src/components/Attachments.tsx",
|
||||
"line": 361,
|
||||
"sourceSha256": "fe706526f36d92c10d2a0adfd7abb634d0ebee28f5d7e1794c590179b4fd884c",
|
||||
"kind": "jsx-attribute:title",
|
||||
"text": "pdf",
|
||||
"ownerComponent": "job-tracker-ui/src/components/Attachments.tsx",
|
||||
"contextStatus": "source-context-reviewed; implementation-pending",
|
||||
"sensitivity": "public-ui-template; adjacent runtime identifiers excluded",
|
||||
"decision": "descriptive-localised-accessible-title",
|
||||
"translatorContext": "Attachment preview iframe title; describe document preview purpose, without exposing private filename in exported translator context."
|
||||
},
|
||||
{
|
||||
"file": "job-tracker-ui/src/components/CoverLetterDocument.tsx",
|
||||
"line": 157,
|
||||
"sourceSha256": "17ea0c608db7bc05171fb3c44f378c1acaa78fbdd337f9330002ef6346b92546",
|
||||
"kind": "jsx-text",
|
||||
"text": "pt ·",
|
||||
"ownerComponent": "job-tracker-ui/src/components/CoverLetterDocument.tsx",
|
||||
"contextStatus": "source-context-reviewed; implementation-pending",
|
||||
"sensitivity": "public-ui-template; adjacent runtime identifiers excluded",
|
||||
"decision": "version-or-unit-formatting-review",
|
||||
"translatorContext": "Keep numeric/version identity; review locale number formatting and descriptive accessible labels. Do not translate user file/name data."
|
||||
},
|
||||
{
|
||||
"file": "job-tracker-ui/src/components/CoverLetterDocument.tsx",
|
||||
"line": 157,
|
||||
"sourceSha256": "17ea0c608db7bc05171fb3c44f378c1acaa78fbdd337f9330002ef6346b92546",
|
||||
"kind": "jsx-text",
|
||||
"text": "mm ·",
|
||||
"ownerComponent": "job-tracker-ui/src/components/CoverLetterDocument.tsx",
|
||||
"contextStatus": "source-context-reviewed; implementation-pending",
|
||||
"sensitivity": "public-ui-template; adjacent runtime identifiers excluded",
|
||||
"decision": "version-or-unit-formatting-review",
|
||||
"translatorContext": "Keep numeric/version identity; review locale number formatting and descriptive accessible labels. Do not translate user file/name data."
|
||||
},
|
||||
{
|
||||
"file": "job-tracker-ui/src/components/EmailProviderConnections.tsx",
|
||||
"line": 227,
|
||||
"sourceSha256": "b71228ee28ee73525014c8ece8690364e0f70ddaca3ee7211e9076123d120b1d",
|
||||
"kind": "jsx-attribute:label",
|
||||
"text": "Gmail",
|
||||
"ownerComponent": "job-tracker-ui/src/components/EmailProviderConnections.tsx",
|
||||
"contextStatus": "source-context-reviewed; implementation-pending",
|
||||
"sensitivity": "public-ui-template; adjacent runtime identifiers excluded",
|
||||
"decision": "preserve-proper-name-or-example",
|
||||
"translatorContext": "Public brand/provider label or synthetic host example; not user content. Retain original spelling; localise surrounding guidance separately."
|
||||
},
|
||||
{
|
||||
"file": "job-tracker-ui/src/components/EmailProviderConnections.tsx",
|
||||
"line": 239,
|
||||
"sourceSha256": "b71228ee28ee73525014c8ece8690364e0f70ddaca3ee7211e9076123d120b1d",
|
||||
"kind": "jsx-attribute:label",
|
||||
"text": "Outlook / Microsoft 365",
|
||||
"ownerComponent": "job-tracker-ui/src/components/EmailProviderConnections.tsx",
|
||||
"contextStatus": "source-context-reviewed; implementation-pending",
|
||||
"sensitivity": "public-ui-template; adjacent runtime identifiers excluded",
|
||||
"decision": "preserve-proper-name-or-example",
|
||||
"translatorContext": "Public brand/provider label or synthetic host example; not user content. Retain original spelling; localise surrounding guidance separately."
|
||||
},
|
||||
{
|
||||
"file": "job-tracker-ui/src/components/EmailProviderConnections.tsx",
|
||||
"line": 264,
|
||||
"sourceSha256": "b71228ee28ee73525014c8ece8690364e0f70ddaca3ee7211e9076123d120b1d",
|
||||
"kind": "jsx-attribute:placeholder",
|
||||
"text": "imap.example.com",
|
||||
"ownerComponent": "job-tracker-ui/src/components/EmailProviderConnections.tsx",
|
||||
"contextStatus": "source-context-reviewed; implementation-pending",
|
||||
"sensitivity": "public-ui-template; adjacent runtime identifiers excluded",
|
||||
"decision": "preserve-proper-name-or-example",
|
||||
"translatorContext": "Public brand/provider label or synthetic host example; not user content. Retain original spelling; localise surrounding guidance separately."
|
||||
},
|
||||
{
|
||||
"file": "job-tracker-ui/src/components/JobFlowBar.tsx",
|
||||
"line": 147,
|
||||
"sourceSha256": "643053f6ac883f23ef74c66def7a42678cd7917ed11ca802b11be25ec6df0cb2",
|
||||
"kind": "jsx-text",
|
||||
"text": "Flow",
|
||||
"ownerComponent": "job-tracker-ui/src/components/JobFlowBar.tsx",
|
||||
"contextStatus": "source-context-reviewed; implementation-pending",
|
||||
"sensitivity": "public-ui-template; adjacent runtime identifiers excluded",
|
||||
"decision": "extract-controlled-label",
|
||||
"translatorContext": "Workflow overline in JobFlowBar; ordinary user-facing UI label, not a persisted status."
|
||||
},
|
||||
{
|
||||
"file": "job-tracker-ui/src/components/QuickCommandDialog.tsx",
|
||||
"line": 166,
|
||||
"sourceSha256": "27cbbb8b8596fdf4e7474eccfdb6d9a8a219f4baff6a9b8013b825ce5fc2c411",
|
||||
"kind": "jsx-text",
|
||||
"text": "Ctrl/Cmd + K",
|
||||
"ownerComponent": "job-tracker-ui/src/components/QuickCommandDialog.tsx",
|
||||
"contextStatus": "source-context-reviewed; implementation-pending",
|
||||
"sensitivity": "public-ui-template; adjacent runtime identifiers excluded",
|
||||
"decision": "version-or-unit-formatting-review",
|
||||
"translatorContext": "Keep numeric/version identity; review locale number formatting and descriptive accessible labels. Do not translate user file/name data."
|
||||
},
|
||||
{
|
||||
"file": "job-tracker-ui/src/layout/AppShell.tsx",
|
||||
"line": 312,
|
||||
"sourceSha256": "e75a58f2984bf47d7edc3c2c51439242aba2df32675a30b1f17088095ea1d634",
|
||||
"kind": "jsx-text",
|
||||
"text": "Jobbjakt",
|
||||
"ownerComponent": "job-tracker-ui/src/layout/AppShell.tsx",
|
||||
"contextStatus": "source-context-reviewed; implementation-pending",
|
||||
"sensitivity": "public-ui-template; adjacent runtime identifiers excluded",
|
||||
"decision": "preserve-proper-name-or-example",
|
||||
"translatorContext": "Public brand/provider label or synthetic host example; not user content. Retain original spelling; localise surrounding guidance separately."
|
||||
},
|
||||
{
|
||||
"file": "job-tracker-ui/src/layout/AppShell.tsx",
|
||||
"line": 415,
|
||||
"sourceSha256": "e75a58f2984bf47d7edc3c2c51439242aba2df32675a30b1f17088095ea1d634",
|
||||
"kind": "jsx-text",
|
||||
"text": "Jobbjakt",
|
||||
"ownerComponent": "job-tracker-ui/src/layout/AppShell.tsx",
|
||||
"contextStatus": "source-context-reviewed; implementation-pending",
|
||||
"sensitivity": "public-ui-template; adjacent runtime identifiers excluded",
|
||||
"decision": "preserve-proper-name-or-example",
|
||||
"translatorContext": "Public brand/provider label or synthetic host example; not user content. Retain original spelling; localise surrounding guidance separately."
|
||||
},
|
||||
{
|
||||
"file": "job-tracker-ui/src/layout/AppShell.tsx",
|
||||
"line": 563,
|
||||
"sourceSha256": "e75a58f2984bf47d7edc3c2c51439242aba2df32675a30b1f17088095ea1d634",
|
||||
"kind": "jsx-text",
|
||||
"text": "commit",
|
||||
"ownerComponent": "job-tracker-ui/src/layout/AppShell.tsx",
|
||||
"contextStatus": "source-context-reviewed; implementation-pending",
|
||||
"sensitivity": "public-ui-template; adjacent runtime identifiers excluded",
|
||||
"decision": "localise-label-preserve-identifier",
|
||||
"translatorContext": "Technical display label may be translated; commit/job identifier remains invariant and must not enter translation resources."
|
||||
},
|
||||
{
|
||||
"file": "job-tracker-ui/src/layout/AppShell.tsx",
|
||||
"line": 692,
|
||||
"sourceSha256": "e75a58f2984bf47d7edc3c2c51439242aba2df32675a30b1f17088095ea1d634",
|
||||
"kind": "jsx-attribute:aria-label",
|
||||
"text": "English",
|
||||
"ownerComponent": "job-tracker-ui/src/layout/AppShell.tsx",
|
||||
"contextStatus": "source-context-reviewed; implementation-pending",
|
||||
"sensitivity": "public-ui-template; adjacent runtime identifiers excluded",
|
||||
"decision": "locale-selector-contract",
|
||||
"translatorContext": "Replace ambiguous country-like abbreviation/undifferentiated Norwegian label only within approved locale-selector work; preserve current nb behavior and native labels."
|
||||
},
|
||||
{
|
||||
"file": "job-tracker-ui/src/layout/AppShell.tsx",
|
||||
"line": 692,
|
||||
"sourceSha256": "e75a58f2984bf47d7edc3c2c51439242aba2df32675a30b1f17088095ea1d634",
|
||||
"kind": "jsx-text",
|
||||
"text": "EN",
|
||||
"ownerComponent": "job-tracker-ui/src/layout/AppShell.tsx",
|
||||
"contextStatus": "source-context-reviewed; implementation-pending",
|
||||
"sensitivity": "public-ui-template; adjacent runtime identifiers excluded",
|
||||
"decision": "locale-selector-contract",
|
||||
"translatorContext": "Replace ambiguous country-like abbreviation/undifferentiated Norwegian label only within approved locale-selector work; preserve current nb behavior and native labels."
|
||||
},
|
||||
{
|
||||
"file": "job-tracker-ui/src/layout/AppShell.tsx",
|
||||
"line": 693,
|
||||
"sourceSha256": "e75a58f2984bf47d7edc3c2c51439242aba2df32675a30b1f17088095ea1d634",
|
||||
"kind": "jsx-attribute:aria-label",
|
||||
"text": "Norsk",
|
||||
"ownerComponent": "job-tracker-ui/src/layout/AppShell.tsx",
|
||||
"contextStatus": "source-context-reviewed; implementation-pending",
|
||||
"sensitivity": "public-ui-template; adjacent runtime identifiers excluded",
|
||||
"decision": "locale-selector-contract",
|
||||
"translatorContext": "Replace ambiguous country-like abbreviation/undifferentiated Norwegian label only within approved locale-selector work; preserve current nb behavior and native labels."
|
||||
},
|
||||
{
|
||||
"file": "job-tracker-ui/src/layout/AppShell.tsx",
|
||||
"line": 693,
|
||||
"sourceSha256": "e75a58f2984bf47d7edc3c2c51439242aba2df32675a30b1f17088095ea1d634",
|
||||
"kind": "jsx-text",
|
||||
"text": "NO",
|
||||
"ownerComponent": "job-tracker-ui/src/layout/AppShell.tsx",
|
||||
"contextStatus": "source-context-reviewed; implementation-pending",
|
||||
"sensitivity": "public-ui-template; adjacent runtime identifiers excluded",
|
||||
"decision": "locale-selector-contract",
|
||||
"translatorContext": "Replace ambiguous country-like abbreviation/undifferentiated Norwegian label only within approved locale-selector work; preserve current nb behavior and native labels."
|
||||
},
|
||||
{
|
||||
"file": "job-tracker-ui/src/views/AdminAuditPage.tsx",
|
||||
"line": 146,
|
||||
"sourceSha256": "b78d0c5f6ec86a4ee3d2214e6854e638d9f73a5c69c8d5b01023d8c60b46ac81",
|
||||
"kind": "jsx-text",
|
||||
"text": "jobId=",
|
||||
"ownerComponent": "job-tracker-ui/src/views/AdminAuditPage.tsx",
|
||||
"contextStatus": "source-context-reviewed; implementation-pending",
|
||||
"sensitivity": "public-ui-template; adjacent runtime identifiers excluded",
|
||||
"decision": "localise-label-preserve-identifier",
|
||||
"translatorContext": "Technical display label may be translated; commit/job identifier remains invariant and must not enter translation resources."
|
||||
},
|
||||
{
|
||||
"file": "job-tracker-ui/src/views/AdminUsersPage.tsx",
|
||||
"line": 274,
|
||||
"sourceSha256": "674290a26fc279a25e43176194716dea87f427d1885ecce70dea7c368ab0c6f8",
|
||||
"kind": "jsx-attribute:label",
|
||||
"text": "—",
|
||||
"ownerComponent": "job-tracker-ui/src/views/AdminUsersPage.tsx",
|
||||
"contextStatus": "source-context-reviewed; implementation-pending",
|
||||
"sensitivity": "public-ui-template; adjacent runtime identifiers excluded",
|
||||
"decision": "empty-state-accessibility-review",
|
||||
"translatorContext": "No-role placeholder; visual glyph can stay but verify meaningful accessible context."
|
||||
},
|
||||
{
|
||||
"file": "job-tracker-ui/src/views/LandingPage.tsx",
|
||||
"line": 99,
|
||||
"sourceSha256": "2c550aa126e1db8786ed10b895d2403491ce50bf5073fc95b8a0fcb0cb0e083e",
|
||||
"kind": "jsx-text",
|
||||
"text": "Jobbjakt",
|
||||
"ownerComponent": "job-tracker-ui/src/views/LandingPage.tsx",
|
||||
"contextStatus": "source-context-reviewed; implementation-pending",
|
||||
"sensitivity": "public-ui-template; adjacent runtime identifiers excluded",
|
||||
"decision": "preserve-proper-name-or-example",
|
||||
"translatorContext": "Public brand/provider label or synthetic host example; not user content. Retain original spelling; localise surrounding guidance separately."
|
||||
},
|
||||
{
|
||||
"file": "job-tracker-ui/src/views/LandingPage.tsx",
|
||||
"line": 133,
|
||||
"sourceSha256": "2c550aa126e1db8786ed10b895d2403491ce50bf5073fc95b8a0fcb0cb0e083e",
|
||||
"kind": "jsx-text",
|
||||
"text": "React · TypeScript · ASP.NET Core · EF Core · FastAPI AI · Gmail",
|
||||
"ownerComponent": "job-tracker-ui/src/views/LandingPage.tsx",
|
||||
"contextStatus": "source-context-reviewed; implementation-pending",
|
||||
"sensitivity": "public-ui-template; adjacent runtime identifiers excluded",
|
||||
"decision": "launch-copy-review",
|
||||
"translatorContext": "Technology list is public brand names but poor user-value copy; coordinate replacement with Launch Site design approval."
|
||||
},
|
||||
{
|
||||
"file": "job-tracker-ui/src/views/career/CareerProfileSections.tsx",
|
||||
"line": 100,
|
||||
"sourceSha256": "0c772feb6bde8324676b0884aaf343283465c5cd3b3318128363063df4ea22ab",
|
||||
"kind": "jsx-attribute:label",
|
||||
"text": "GitHub",
|
||||
"ownerComponent": "job-tracker-ui/src/views/career/CareerProfileSections.tsx",
|
||||
"contextStatus": "source-context-reviewed; implementation-pending",
|
||||
"sensitivity": "public-ui-template; adjacent runtime identifiers excluded",
|
||||
"decision": "preserve-proper-name-or-example",
|
||||
"translatorContext": "Public brand/provider label or synthetic host example; not user content. Retain original spelling; localise surrounding guidance separately."
|
||||
},
|
||||
{
|
||||
"file": "job-tracker-ui/src/views/career/ProfileCompleteness.tsx",
|
||||
"line": 55,
|
||||
"sourceSha256": "95f017b1495cf9d88a2b69e7c6ae8ef83d55f2b1ad7b6f54895e280b147743b5",
|
||||
"kind": "jsx-text",
|
||||
"text": "v",
|
||||
"ownerComponent": "job-tracker-ui/src/views/career/ProfileCompleteness.tsx",
|
||||
"contextStatus": "source-context-reviewed; implementation-pending",
|
||||
"sensitivity": "public-ui-template; adjacent runtime identifiers excluded",
|
||||
"decision": "version-or-unit-formatting-review",
|
||||
"translatorContext": "Keep numeric/version identity; review locale number formatting and descriptive accessible labels. Do not translate user file/name data."
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
# Partial I18N-00 research handoff
|
||||
|
||||
Branch `feature/i18n-00-audit`, based on accepted conditional handoff `5cb903b989742b7a96cb22ddf4c0e24993b18980`. Only `docs/i18n/00/` changed. This checkpoint preserves research; I18N-00 acceptance remains IN_PROGRESS and I18N-01 implementation remains BLOCKED.
|
||||
|
||||
Completed: source-owner audit draft; ordered implementation contracts; source-bound English catalogue/static callers; initial 59-territory CLDR matrix; 60 planned locale candidates and schema; planning checks documented in BASELINE_TESTS.md. No locale translated, reviewed or released here.
|
||||
|
||||
Next authorised work, without implementation approval:
|
||||
|
||||
1. Resolve 188 dynamic/unknown calls, direct translation object access and wrappers. Review the 853 entries without static callers without treating them as unused.
|
||||
2. Inventory hardcoded frontend/ARIA/empty/error/export text and backend/Python/email/queue strings. Assign real namespace, translator context, parameter sensitivity and owning component rather than inferring from keys.
|
||||
3. Complete national/regional official-record checks beyond the initial Norway/Switzerland/Serbia checks. Expand territory/minority coverage where the current research envelope omits required contexts.
|
||||
4. Evaluate actual installed/locked library compatibility and Montenegrin canonicalisation before choosing a runtime migration. Do not install packages now.
|
||||
5. Obtain reviewer/market priorities when a concrete rollout proposal is ready. Keep human/native approval separate from planning completeness.
|
||||
|
||||
The delegated researcher was interrupted by a service usage limit; the parent continued, corrected references to nonexistent deliverables and produced the actual inventory/catalogue/matrix. No agent is working in the background. Full stage completion must not be inferred from the presence of the expected filenames.
|
||||
|
||||
Continuation: CONTEXT_TRIAGE.md records all 188 dynamic calls, 108 finite-branch resolutions (240 existing-key references), four direct catalogue reads and 26 source-context-reviewed JSX/accessibility literal candidates. Seven concrete planning findings I00-13 through I00-19 added. Remaining dynamic call queue is 80; prior 188 count is the original inventory total, not the remaining queue. No application changes.
|
||||
|
||||
Product tests NOT RUN; source equality and planning checks PASSED within their documented limits. Preserve existing PDF evidence. No application models, production services, orchestrator configuration or signing/approval material accessed.
|
||||
@@ -0,0 +1,31 @@
|
||||
# Ordered implementation specification — not execution authority
|
||||
|
||||
## Proposed architecture decision
|
||||
|
||||
Keep existing `useI18n` call sites and React/MUI owners. Replace only its message evaluation/storage behind that contract after entry approval. Compare: current substitution is smallest but cannot meet plural/select requirements; i18next offers namespace loading and CLDR plural suffixes but changes interpolation/catalogue shape; FormatJS ICU supports complete sentence plural/select messages behind the current helper with less caller churn. **Proposed preference: ICU message evaluation behind the existing API plus platform Intl formatting**, subject to actual lockfile/runtime compatibility, bundle and extraction prototype after approval. Do not install either now. Do not implement two competing message engines. .NET renders server communications from its own typed templates with shared IDs/parameter contracts; do not assume identical ICU parser support in .NET/Python.
|
||||
|
||||
Sources checked 2026-11-02: https://www.i18next.com/translation-function/plurals and https://formatjs.github.io/docs/core-concepts/icu-syntax/. These establish syntax capabilities, not repository compatibility.
|
||||
|
||||
## Independent preference contract
|
||||
|
||||
Residence `countryId`, `searchCountryIds`, typed location IDs, `uiLocale`, `adLanguageFilters`, document `outputLocale`, optional `communicationLocale` and `timeZone` are distinct. Country changes only suggestion ordering. Manual saved preference wins over URL/app choice, onboarding, browser negotiation and English fallback. Explicitly distinguish signed-out local storage from account hydration. Persist provenance and revision semantics without weakening tenant ownership. Existing `en` stays canonical until an approved compatibility migration; `en-GB` is a candidate variant, not a silent rewrite. `nb/no/nb-NO` legacy aliases preserve existing Bokmål behavior. `nn-NO` must never silently map to Bokmål. `sr-Latn` and `sr-Cyrl` retain script identity. Unsupported locale resolves to reliable English chrome; user content unchanged.
|
||||
|
||||
## Stage sequence and evidence
|
||||
|
||||
| Stage | Bounded change after prerequisites | Required exit evidence |
|
||||
|---|---|---|
|
||||
| 00 | Finish contextual census, country legal cross-check, reviewer ownership | Complete source-bound inventory; independent schema validation; planning review |
|
||||
| 01 | Registry, aliases, separate preferences, migration, formatting | Legacy roundtrip, invalid IDs, tenant/multi-device conflicts, MariaDB migration/reversal; new locales hidden |
|
||||
| 02 | Extract full UI and accessible strings into existing owners | Required-key completeness, placeholder parser, dirty-form language switch, pseudo/long-label responsive tests |
|
||||
| 03 | Stable backend codes; queued communication templates | Event-time locale snapshot proposed, retry determinism, isolated Mailpit/plain/HTML tests, legal approvals |
|
||||
| 04 | Per-document headings/fonts, import boundaries | RD21/history invariance; script/PDF extraction and layout; native/physical review distinct |
|
||||
| 05 | GJ-owned geography/provider/search integration | All-industry synthetic fixtures, explicit alias suggestions, source language and rights/retention evidence |
|
||||
| 06 | Translation supply chain and glossary | Licensed source, translator context, independent proficient review, source-change invalidation |
|
||||
| 07 | Launch Site localisation/SEO contract | Approved visual design; published-only alternates/sitemaps; truthful feature/provider claims |
|
||||
| 08 | Cross-surface/native/device/security acceptance | Locale × surface × market × profession × device matrix; exact commit and disjoint counts |
|
||||
|
||||
Phase 10 completion/appropriate accepted handoff, PRODUCT-REVIEW-01, accepted I18N-00 and explicit stage authority precede I18N-01. Sequential accepted stage integration is mandatory. Separate development commits, no main merge/deploy.
|
||||
|
||||
GJ owns source fetch, rights, stable geography/occupation IDs and search mechanics; I18N owns display labels, ad-language semantics and translated-summary labels. ESCO concept identity cannot be replaced by translated free text. Original advertisement always remains distinguishable. Provider rights are checked before requests, not inferred from locale availability. Launch Site owns visual design/routing architecture; I18N supplies market+content-locale+publication schema and claims binding to deployed capability. Future fixtures may be designed now but no dependent runtime is invented.
|
||||
|
||||
Terminology queue: Career Profile (canonical facts), CV (document variant), cover letter, application (pursuit), job (opportunity), apprenticeship, shift, seasonal work, salary, qualification, nursing/teaching licence. Define each English concept before translation; profession label never establishes accreditation. Planned fixtures include teacher, cook, nurse, electrician, construction worker, driver, cleaner, retail, office administrator and developer.
|
||||
@@ -0,0 +1,846 @@
|
||||
{
|
||||
"baseline": "5cb903b989742b7a96cb22ddf4c0e24993b18980",
|
||||
"status": "research-draft",
|
||||
"locales": [
|
||||
{
|
||||
"tag": "en",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "en-GB",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "nb-NO",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "nn-NO",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "sv-SE",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "da-DK",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "fi-FI",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "is-IS",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "bg-BG",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "hr-HR",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "cs-CZ",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "nl-NL",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "et-EE",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "fr-FR",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "de-DE",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "el-GR",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "hu-HU",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "ga-IE",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "it-IT",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "lv-LV",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "lt-LT",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "mt-MT",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "pl-PL",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "pt-PT",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "ro-RO",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "sk-SK",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "sl-SI",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "es-ES",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "uk-UA",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "sq-AL",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "sr-Latn-RS",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "sr-Cyrl-RS",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "bs-BA",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "cnr-ME",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "mk-MK",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "tr-TR",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "lb-LU",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "cy-GB",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "rm-CH",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "fo-FO",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "be-BY",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "ka-GE",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "hy-AM",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "az-Latn-AZ",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "ru-RU",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "fr-CH",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "de-CH",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "it-CH",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "nl-BE",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "fr-BE",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "de-BE",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "en-IE",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "ca-ES",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "eu-ES",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "gl-ES",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "gd-GB",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "se-NO",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "smj-NO",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "sma-NO",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "fkv-NO",
|
||||
"ownerRole": "localisation-product-owner",
|
||||
"reviewer": null,
|
||||
"status": "planned",
|
||||
"surfaces": {
|
||||
"ui": "planned",
|
||||
"backend": "planned",
|
||||
"communications": "planned",
|
||||
"documents": "planned",
|
||||
"jobDiscovery": "planned",
|
||||
"marketing": "planned"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "Research-only locale catalogue; no release authority",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"baseline",
|
||||
"status",
|
||||
"locales"
|
||||
],
|
||||
"properties": {
|
||||
"baseline": {
|
||||
"const": "5cb903b989742b7a96cb22ddf4c0e24993b18980"
|
||||
},
|
||||
"status": {
|
||||
"const": "research-draft"
|
||||
},
|
||||
"locales": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"tag",
|
||||
"ownerRole",
|
||||
"reviewer",
|
||||
"status",
|
||||
"surfaces"
|
||||
],
|
||||
"properties": {
|
||||
"tag": {
|
||||
"type": "string",
|
||||
"pattern": "^[a-z]{2,3}(-[A-Za-z0-9]{2,8})*$"
|
||||
},
|
||||
"ownerRole": {
|
||||
"const": "localisation-product-owner"
|
||||
},
|
||||
"reviewer": {
|
||||
"type": "null"
|
||||
},
|
||||
"status": {
|
||||
"const": "planned"
|
||||
},
|
||||
"surfaces": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"ui",
|
||||
"backend",
|
||||
"communications",
|
||||
"documents",
|
||||
"jobDiscovery",
|
||||
"marketing"
|
||||
],
|
||||
"properties": {
|
||||
"ui": {
|
||||
"const": "planned"
|
||||
},
|
||||
"backend": {
|
||||
"const": "planned"
|
||||
},
|
||||
"communications": {
|
||||
"const": "planned"
|
||||
},
|
||||
"documents": {
|
||||
"const": "planned"
|
||||
},
|
||||
"jobDiscovery": {
|
||||
"const": "planned"
|
||||
},
|
||||
"marketing": {
|
||||
"const": "planned"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,20 @@
|
||||
# Risks, blockers and independent approval
|
||||
|
||||
| ID | Risk / unresolved item | Owner and closure evidence |
|
||||
|---|---|---|
|
||||
| I00-01 | Catalogue scan is not every-string contextual inventory | UI/backend owners triage literals, all callers, runtime/ARIA/export states; no unknown required surface |
|
||||
| I00-02 | CLDR is not complete national/regional legal authority | Product research owner checks official country records, political/territory scope and versioned licence before activating suggestions |
|
||||
| I00-03 | No allocated translators/native reviewers | Product owner assigns named reviewers per locale/surface; critical legal/billing/security needs qualified review |
|
||||
| I00-04 | Implementation predecessor gates unresolved | Owner records Phase10/product review and explicit I18N entry against accepted baseline; this document cannot approve them |
|
||||
| I00-05 | Plurals, gender, inflection, word order | ICU whole-sentence contexts, Slavic/Irish/Welsh fixtures, native review; no fragment concatenation |
|
||||
| I00-06 | Turkish casing, Greek accents, Serbian script, names | Locale-aware search/display separate from invariant IDs; preserve original names and qualification titles |
|
||||
| I00-07 | Dates/timezones/DST, salary/currency | UTC storage, partial-date precision, explicit timezone; formatting never FX conversion |
|
||||
| I00-08 | Fonts/glyphs, RTL readiness, long labels | Licensed extended Latin/Greek/Cyrillic font tests, logical layout and focus; RTL activation only when approved |
|
||||
| I00-09 | Career fact loss, frozen PDF drift, stale writes | UI switch never mutates facts/history/undo; ApplicationAssetsService and revision contracts retained |
|
||||
| I00-10 | Private content external translation | No PII export; separately approved consent/contracts/data controls before external translation; no live-model calls |
|
||||
| I00-11 | Draft locale exposed as supported | Per-surface publication gate, English fallback; no selector/SEO claims from catalogue presence |
|
||||
| I00-12 | Backend literal errors and queue drift | Stable error codes, typed escaped params, deterministic event-time locale and retry tests |
|
||||
|
||||
Public release requires required-key completeness, syntax/placeholders/plurals and escaping checks, whole critical journeys, native/proficient review, accessibility/device/PDF tests, country/provider truthfulness, owner release decision and actual deployed identity. Status advances separately per surface: planned → draft/machine_draft → review_required → reviewed → qa_passed → release_approved → released. No generated JSON grants review or approval. Approval evidence must be externally controlled and source-bound. All catalogue entries here are `planned`; existing en/nb code presence is independently recorded, not relabelled as newly qualified release.
|
||||
|
||||
Human/native/legal/device/physical-print review: pending, not executed. Provider and live-model tests: not run. Implementation/release: not authorised. Independent planning can continue on I00-01/02 without waiting for runtime gates.
|
||||
@@ -0,0 +1,22 @@
|
||||
# Surface inventory and message accounting
|
||||
|
||||
All rows need a source-bound contextual census before I18N-00 acceptance. Existing-catalogue inventory is in `MESSAGE_INVENTORY.json`; partial JSX/accessibility literals are now recorded in `FRONTEND_LITERAL_CANDIDATES.json`, with direct reads and dynamic calls in separate inventories. This is not a 100% coverage claim. Namespace assignments remain provisional until caller review; translator context cannot be inferred safely from key names alone. The AST inventory identifies syntactically named `t` calls, not symbol-resolved calls. See CONTEXT_TRIAGE.md for reviewed literal context and the 108 resolved conditional calls; 80 table/template/wrapper calls remain.
|
||||
|
||||
| Surface / proposed namespace | Source owner / inspection target | Content boundary and required evidence |
|
||||
|---|---|---|
|
||||
| Account, onboarding, recovery / auth | views LoginPage, ForgotPasswordPage, ResetPasswordPage, VerifyEmailPage; AuthController | Forms, ARIA, errors, consent, email templates, multi-device hydration; preserve token URLs |
|
||||
| Dashboard, navigation, mobile / app | App routing, dashboard components | Hidden/empty/loading/error states, keyboard labels, tooltips and layout expansion |
|
||||
| Jobs, discovery, applications / jobs | JobDiscoveryPage, ApplicationWorkspacePage; JobPipeline | Translate controlled status labels, never stored identity/status codes or original advertisements |
|
||||
| Career facts, imports / career | CareerProfilePage, career/CvImportReview, CvImportMappingEditor; CareerProfileService; Python app.py | Original facts and uncertainty remain; parser/script quality separate from UI coverage |
|
||||
| CV editor, templates, letters / documents | CvBuilderEditor, DocumentsPage; ThemedCvRenderer, CoverLetterDocumentRenderer, ApplicationAssetsService | Output locale independent; headings, dates, filename labels; preserve null-as-inherit and JobApplication.Version |
|
||||
| PDF, public CV / exports | PublicCvPage, PlaywrightCvPdfExporter, CvDocumentFonts | Font licence/glyph matrix, selectable text, physical print, frozen snapshots and public access |
|
||||
| Email, inbox, reminders / communications | CorrespondenceInboxPage, GmailReviewPage, SmtpEmailSender, FollowUpReminderHostedService | User correspondence is private content; subject/preheader/plain/HTML copy and queued locale policy |
|
||||
| Settings, linked accounts / settings | ConnectedAccountsPage, EmailProviderConnections | Provider names stay proper nouns; OAuth errors and cancellation need usable fallback |
|
||||
| Billing, subscriptions / billing | StripeBillingGateway, entitlement UI | Amount and currency invariant; legal/tax wording needs qualified approval |
|
||||
| Admin and operations / admin | AdminUsersPage, AdminSystemPage, AdminProcessingPage, AdminAuditPage, OperationsPage; OperationEventLog | Stable diagnostic codes; localized presentation without multilingual log parsing or PII leaks |
|
||||
| Analytics, comparisons / analytics | AnalyticsPage, OfferComparisonPage | Plurals, dates, currency and accessible chart/table labels |
|
||||
| Marketing, SEO, legal / public | LandingPage, RouteErrorPage, NotFoundPage; future Launch Site | No locale claims, hreflang or indexing for draft pages; owner mockup gate untouched |
|
||||
| Backend/API/queues / errors | Controllers, UserNotificationStore, AiOperationQueue, CvProcessingQueue | Stable code plus typed parameters; UTC storage; deterministic queue-recipient locale |
|
||||
| Python/AI / processing | tools/summarizer/app.py | Machine codes vs user text, validation and document-language metadata; no live-model qualification |
|
||||
|
||||
For each required message record: stable ID, namespace, exact source, source hash/line, all callers, English text, context/screenshot, typed placeholders, plural/select variants, sensitivity, owner, translator and independent review state. Sensitive values are runtime parameters, never translation exports. Static public UI text is eligible; names, CV facts, messages, tokens, job ads and employer claims are not automatically translated. Existing flat keys remain stable through migration; do not bulk rename for aesthetics.
|
||||
@@ -1,20 +0,0 @@
|
||||
# Public content architecture — proposed, not implemented
|
||||
|
||||
2 November 2026. Independent preparation under the owner's current direct-roadmap instruction. No visual concept selected, public route added, marketing claim published or application source changed. Final layout/section order remains an owner decision.
|
||||
|
||||
Reuse the current Next static-export build, React Router private shell, MUI design tokens, shared plan ownership and en/nb translation contracts. Avoid a CMS or second application shell. Public descriptive content should be emitted as crawlable static HTML from repository-managed, locale-aware content; authenticated routes retain their current client-only providers. Do not turn private account data, feature flags or arbitrary query strings into build-time content.
|
||||
|
||||
Separate content domains:
|
||||
|
||||
- Feature catalogue: stable feature ID and links to implementation, scoped acceptance, deployed identity, entitlement, market, locale, approved screenshot and marketing approval. Missing evidence withholds a current-availability claim. Existing MARKETING_CLAIM_VALIDATION.md remains the authority; do not duplicate it into a competing status list.
|
||||
- Page copy: complete title, description, headings, feature narratives, links, FAQ and accessible text in approved locale resources. Whole sentences and explicit placeholders; reuse terminology and distinguish canonical Career Profile from a CV variant.
|
||||
- Market: available product/provider capabilities, actual billing/currency, legal links and applicable languages. A market is not a language, nationality or automatic grant to fetch jobs.
|
||||
- Assets: genuine synthetic product captures with source commit/date/surface/theme/viewport, rights and alt-text context. The five application design concepts are conceptual prototypes, not screenshots of a released product. No unlicensed images or invented customer testimonials.
|
||||
|
||||
Draft profession-neutral content options for later copy review: “Your job search, organised.” / “Jobbsøkingen din, organisert.” Supporting proposition: “Keep applications, career information and documents together.” / “Samle søknader, karriereinformasjon og dokumenter på ett sted.” These are unpublished candidate copy, not released-capability approval or native-language acceptance. Avoid promising universal import accuracy, live international sources, automatic employer actions, AI availability or privacy certifications.
|
||||
|
||||
Candidate narrative modules (not an approved order): clear outcome and product preview; tracking and next steps; Career Profile/document workflow; optional import review; how it works; verified plan information; factual FAQ; supported registration path; legal/support footer. Where registration is disabled, the CTA must use the existing truthful sign-in/access path rather than promise account creation. Legal destinations and final FAQ answers require verified content; never invent links or policies.
|
||||
|
||||
Implementation gate: after final visual approval, use the approved composition with static public copy and a small client interaction boundary for preference/navigation. Preserve signed-in redirect, protected-route return state and the existing dashboard-first optional onboarding. No second onboarding flow. Reverting future content is an ordinary version-controlled content rollback; no database migration is proposed by this architecture.
|
||||
|
||||
Open: final visual choice, actual released feature/plan/provider evidence, production origin/deployed identity, public asset provenance and native copy review. Full European catalogue work does not automatically publish locale pages.
|
||||
@@ -1,21 +0,0 @@
|
||||
# LAUNCH-00 source audit - partial checkpoint
|
||||
|
||||
2026-11-02. `feature/launch-site-redesign`, accepted conditional baseline `5cb903b989742b7a96cb22ddf4c0e24993b18980`. Full authoritative homepage prompt read. LAUNCH-00 IN_PROGRESS; LAUNCH-01 concepts NOT YET PRODUCED. No final design selected or implemented.
|
||||
|
||||
| Finding | Source evidence | User implication / proposed direction |
|
||||
| --- | --- | --- |
|
||||
| Main Get started opens sign-in | `LandingPage.tsx` passes `goToLogin` to hero CTA; Free-plan CTA separately goes to `/register` | Registration intent has an extra mode-selection step. Propose direct registration while preserving sign-in return state |
|
||||
| Existing signup owner should be reused | `App.tsx:522` maps `/register` to `LoginPage initialMode=register`; LoginPage respects auth config and registration availability | No second onboarding implementation; final CTA must reflect actual enabled registration |
|
||||
| Product previews are conceptual assets | `LandingPage.tsx` uses `/mockups/dashboard.svg`, `pipeline.svg`, `workspace.svg` | Replace with provenance-bound synthetic captures in approved design; never label current artwork a genuine screenshot |
|
||||
| Implementation details occupy hero copy | LandingPage renders React/TypeScript/ASP.NET/EF/FastAPI/Gmail text | Replace with plain user outcomes across professions; framework names do not explain job-search value |
|
||||
| Marketing content depends on client execution and auth probe | `app/page.tsx` loads ClientShell; `ClientShell.tsx` uses `ssr:false`; LandingPage shows loading until `/auth/me` resolves/rejects | Crawlable HTML and loading/failure behavior need measured review; cannot assume static export includes full marketing copy |
|
||||
| Metadata is generic | `app/layout.tsx` has global title/description and initial `lang=en` | Design market/content-locale metadata and canonical/alternate rules without disturbing authenticated routing; no SEO score claimed |
|
||||
| Brand continuity exists | Indigo/cyan hero, shared MUI/theme, custom en/nb translations | Explore distinct compositions while preserving identity; avoid rebuilding app shell |
|
||||
| Product presentation is limited | Six feature cards, six steps and three conceptual images; no actual redesigned CV/import/gallery imagery | Prioritise actual accepted tracking, canonical Career Profile and reviewed document workflow; do not imply new Global Jobs is shipped |
|
||||
| Pricing shows capabilities, not amounts | `planCatalog.ts` defines Free/Pro, explicitly delegates commercial terms to configured checkout | Do not invent amounts/currencies/trials or promise active Pro AI; release and entitlement validation required |
|
||||
| Footer lacks privacy/legal links in this component | LandingPage footer contains copyright text and sign-in button | Verify existing legal destinations and approved copy before adding links; no invented compliance claims |
|
||||
| Responsive layouts are declared | MUI breakpoints change hero controls, feature grids, plan columns and footer | Source intent only; mobile/tablet/keyboard/reflow/contrast require actual rendered checks |
|
||||
|
||||
Preserve signed-in redirect to `/dashboard`, interrupted protected-route return state, shared language behavior, plan policy ownership and existing registration constraints. New public market language must not overwrite job-ad or document output language. Existing custom en/nb implementation is not full European locale support.
|
||||
|
||||
Not yet checked: current rendered desktop/mobile site, external design-pattern research, runtime signup, slow/offline auth probe, keyboard/AT/contrast, image loading/performance, crawled output, real deployment availability and final asset rights. These omissions keep LAUNCH-00 open. No product tests were rerun for this Markdown-only source checkpoint.
|
||||
@@ -1,11 +0,0 @@
|
||||
# Marketing locale integration — proposed contract
|
||||
|
||||
2 November 2026. EN/Bokmål source support is existing; no additional locale is released by this report. Reuse I18N-00 registry/catalogue proposals and their review gates instead of a second country-language mapping. Full European locale identities, script distinctions and native review remain the localisation workstream's responsibility.
|
||||
|
||||
Keep marketing content locale, selected market, application UI language, ad-language preferences and document language distinct. A marketing selector may offer a deliberate explicit application-language action after sign-in; it must not silently write ad/document preferences. Current shared UI preference behavior must be inspected and migrated compatibly before introducing a separate persisted marketing choice. No persistence change is made here.
|
||||
|
||||
Supported choices show native and English names, retain English access, and allow another supported language independent of market. Bokmål/nb/nb-NO/no legacy compatibility does not grant Nynorsk support. Unreleased languages may be described truthfully as forthcoming only with approved copy; they do not receive public routes, hreflang or sitemap entries. User-generated CV/job text is not translated by changing chrome language.
|
||||
|
||||
Complete each published variant's visible, form, error, accessibility, metadata, social and legal text. Validate keys/placeholders, fallback behavior, interpolation escaping, long labels, plural/number/date/currency rules and dirty-form switching. Native terminology review is separate from syntactic coverage. Currency display follows real billing capability, not a selected country. Preserve provider names, original job language, rights/attribution and the distinction between source descriptions and any reviewed translation.
|
||||
|
||||
Acceptance remains BLOCKED for additional released locales until architecture entry, coverage, translation rights/proficient review, actual market capabilities, approved content and integrated QA are satisfied. This does not prevent independent catalogue, fixture, content and SEO planning. See SEO_STRATEGY.md for published-only URL constraints and CONTENT_ARCHITECTURE.md for content ownership.
|
||||
@@ -1,20 +0,0 @@
|
||||
# Preliminary claims and content boundaries
|
||||
|
||||
All claims below are **WITHHELD from public release approval**. Source implementation and conditional development acceptance do not establish production availability. No production inspection was authorised or performed.
|
||||
|
||||
| Proposed subject | Implementation/development evidence | Missing marketing proof |
|
||||
| --- | --- | --- |
|
||||
| Track applications in table/Kanban | Existing LandingPage/plan catalogue and conditional pre-P10 handoff | Deployed version, applicable account entitlement, genuine synthetic capture and approved copy |
|
||||
| Career Profile and CV variants | Canonical profile/document contracts in architecture and CV handoff | Current deployed behavior and accurate plan/theme availability |
|
||||
| Import, review and correct CV facts | Pre-P10 accepted deterministic supported-fixture workflow | No universal parsing or AI-accuracy claim; actual released formats/languages and limitations |
|
||||
| CV templates and PDF | Scoped development appearance/metric approval retained | Physical-print limits, deployed design/version and screenshots |
|
||||
| Reminders/mail/integrations | Existing source owners; provider qualification separate | Actual enabled countries/providers/consent/delivery; avoid blanket automation promises |
|
||||
| International job search | GJ-00 planning separately published; later implementation blocked | Accepted implementation, provider rights and per-country deployed capabilities |
|
||||
| AI assistance | Some contracts implemented; real CV model quality/activation blocked | Accepted model compatibility/accuracy, privacy/consent and enabled deployment |
|
||||
| Free/Pro | Shared public catalogue exists; no price encoded here | Server policy/checkout consistency, active billing, tax/currency wording and approved current prices |
|
||||
| Languages | Existing en/nb source catalogues; I18N audit separate | Native review and per-surface release state; additional locale candidates are not supported language packs |
|
||||
| Privacy/security | Existing controls and conditional security evidence | Approved truthful wording; no certification/compliance guarantee |
|
||||
|
||||
Each final catalogue entry needs feature ID, implementation commit, acceptance artifact, deployed version, entitlement, market, locale, screenshot provenance and owner marketing approval. Missing fields deny availability claims. This is a documentation contract, not a new executable publishing system.
|
||||
|
||||
Proposed section sequence for concept exploration: outcome-led hero; genuine tracking preview; career/document journey; broad-profession story; how it works; verified plans; FAQ; registration CTA; legal/support footer. Final order remains a design choice. No fabricated customer quotes, statistics, discounts or job-provider coverage.
|
||||
@@ -1,16 +0,0 @@
|
||||
# Partial homepage planning handoff
|
||||
|
||||
Continuation 2 November: CONTENT_ARCHITECTURE.md, INTERNATIONALISATION.md and SEO_STRATEGY.md add independent design-neutral content/routing/publication proposals. Byte-matched existing build-shell evidence confirms raw export lacks descriptive marketing HTML, canonical and hreflang. No public UI/routes/metadata implementation or final visual choice made. These source/build checks are not live SEO, performance or release qualification. The five application UI concepts remain separate from LAUNCH-01's required homepage exploration; no sixth application concept created.
|
||||
|
||||
Branch `feature/launch-site-redesign`, baseline `5cb903b989742b7a96cb22ddf4c0e24993b18980`. Documentation-only source audit. LAUNCH-00 remains IN_PROGRESS. LAUNCH-01 four actual desktop/mobile concepts are PENDING, not replaced by written descriptions. No owner design decision requested until reviewable concepts exist.
|
||||
|
||||
Next authorised work:
|
||||
|
||||
1. Inspect rendered homepage/signup and research contemporary patterns using credible public sources. Preserve existing routing and privacy boundaries.
|
||||
2. Obtain provenance-bound synthetic screenshots from accepted evidence or an isolated test environment. The committed pre-P10 visual manifest contains real PDF previews/contact sheets, not a complete set of dashboard/CV editor/mobile product captures. Inspect any image before reuse; do not touch the separate pre-p10-ux worktree.
|
||||
3. Produce four distinct, viewable desktop/mobile concepts and an asset/licence manifest. No external image/font acquisition without appropriate rights. Concept placeholders cannot be represented as real application screenshots.
|
||||
4. Present concrete concepts for mix-and-match owner feedback, then stop final implementation until explicit final-design approval. Design approval does not authorise publication.
|
||||
|
||||
No assets, app code, tests, routes, packages, production services or authenticated dashboard were changed. Rendered/browser/performance/accessibility/SEO checks NOT RUN. No production feature/pricing/language availability was asserted.
|
||||
|
||||
The delegated design task stopped at a service usage limit before saving deliverables. Parent continued the source audit and preserved this checkpoint. No design agent is running in the background.
|
||||
@@ -1,22 +0,0 @@
|
||||
# SEO baseline and design-neutral proposal
|
||||
|
||||
2 November 2026. Source/available-build review only; no deployment, crawl, search-engine ranking, Lighthouse or performance score claimed.
|
||||
|
||||
## Measured raw-export baseline
|
||||
|
||||
Reused the successful local I18N static build, checking byte identity of launch-branch `app/layout.tsx`, `app/page.tsx` and `app/[[...slug]]/ClientShell.tsx` first. Their SHA256 values respectively: `8e4f0cd2776d821c958480aec5c93943674acb0fe28cd60d0822df40009cb262`, `bf661f17c1c7c06ff8fda41b1afa44144bce694c815d52c3d5a927e32063b1b1`, `0afd4379fbfaeb2059cfa860b10523b212a20dc19c64f961de77bb8572ee6791`. ClientShell disables SSR for the application. This is reused build evidence for unchanged shell sources, not a fresh launch-branch build or proof of every bundle.
|
||||
|
||||
A standard-library HTML parser excluding script/style text found only `Jobbjakt` and `You need to enable JavaScript to run this app.` in out/index.html; canonical link count 0, hreflang count 0. This confirms missing descriptive raw HTML, not an assertion that JavaScript-capable crawlers cannot index the client UI. Root metadata is generic and document language initially en. Record post-implementation comparisons against this narrow baseline.
|
||||
|
||||
## Proposed contract after design/routing approval
|
||||
|
||||
- Emit approved public headings, descriptions, feature text and FAQs in static HTML. Keep private routes and provider/account content outside the prerendered marketing boundary.
|
||||
- Give each published page a descriptive locale-specific title/description, semantic heading hierarchy, Open Graph metadata and approved social asset. Use factual SoftwareApplication/Organization structured data only when supported by the actual page; no fabricated ratings, offers or testimonials.
|
||||
- Obtain the production public origin from release-approved configuration. Do not guess a hostname or use localhost as a public canonical. Canonicals must refer to the intended published page, with query/tracking variants normalised.
|
||||
- Derive canonical/reciprocal alternate/sitemap entries from the same approved published market/content-locale inventory. Include only fully supported published variants; self and reciprocal links must agree. An unreviewed locale is absent, not an empty indexable page. Use valid language/script/region tags; country NO must not be treated as Bokmål nb.
|
||||
- Decide URL shape separately from visuals: proposed explicit `/market/{market}/{contentLocale}/...` or another approved unambiguous scheme. This is a proposal, not an added route. Preserve existing auth and application links and static-host fallback behavior; do not implement speculative duplicate country pages.
|
||||
- Keep incomplete/pre-release previews outside production index publication. Robots directives are not an authorisation boundary or protection for private content. Do not expose private or admin routes through sitemap generation.
|
||||
|
||||
## Required verification before acceptance
|
||||
|
||||
Parse exported HTML per approved locale/market; assert meaningful non-JS content, title/description/lang, one intended h1, canonical origin, reciprocal published-only alternates and sitemap membership. Check no unpublished variants, private URLs or unsupported prices/providers. Follow links in an isolated browser; test auth redirect/registration configuration, language persistence and separation from ad/document preferences. Then measure responsive/accessibility/performance budgets on realistic test conditions, preserving manual/device/native-language and deployed-origin gates. No executable SEO publishing infrastructure is introduced by this report.
|
||||
Reference in New Issue
Block a user