Merge pull request #21 from salestech-group/fix/i18n-8-backfill-zh-json

fix(i18n): backfill english-only entries in zh.json
This commit is contained in:
Dominik Seemann 2026-05-07 17:41:55 +02:00 committed by GitHub
commit 063b7fb17d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 580 additions and 9 deletions

View File

@ -0,0 +1,221 @@
# Design Document — i18n-backfill-zh-json
## Overview
**Purpose**: Backfill ten English-only values in `locales/zh.json` with
natural Chinese translations so the Chinese UI renders fully Chinese
labels on Step 3, Step 4, Step 5, and the graph panel, plus the Step 2
log line that prints a task ID.
**Users**: Chinese-locale UI users; secondarily, frontend engineers and
i18n reviewers who depend on `en.json` and `zh.json` being structurally
aligned.
**Impact**: Pure data change — modifies values for ten keys in
`locales/zh.json`. No code, no schema, no contract changes. Tracks
GitHub issue #8.
### Goals
- Translate the nine user-facing English values into natural Chinese.
- Translate `log.prepareTaskId` to Chinese (gap analysis confirmed it is
user-facing) while preserving the leading two-space indent, the `└─`
glyph, and the `{taskId}` placeholder.
- Keep `home.heroDescBrand` literally as `MiroFish` (proper noun).
- Keep `locales/en.json` and `locales/zh.json` structurally aligned
(same scalar key paths, same key order in unchanged objects).
### Non-Goals
- Translating `en.json` (covered by other epic tickets).
- Restructuring the locale files or the i18n loader.
- Adding new keys for currently-untranslated UI elements.
- Any frontend code change (`*.vue` / `*.js` / `*.ts`).
## Boundary Commitments
### This Spec Owns
- The values of exactly ten scalar keys in `locales/zh.json`:
`home.heroDescBrand`, `step3.waitingForActions`,
`step4.waitingForReportAgent`, `step5.interactiveTools`,
`step5.agentsAvailable`, `step5.reportAgentChat`,
`graph.panelTitle`, `graph.nodeDetails`, `graph.relationship`,
`log.prepareTaskId`.
- The decision and rationale for `log.prepareTaskId` (translate, see
research.md).
### Out of Boundary
- Any other value in `locales/zh.json` (must remain byte-identical).
- Any value in `locales/en.json` or `locales/languages.json`.
- The i18n loader, the Vue components that consume these keys, and any
backend code.
### Allowed Dependencies
- The existing structural contract: `locales/en.json` and
`locales/zh.json` MUST contain the same set of scalar key paths
(verified by the `jq paths(scalars)` diff).
- The existing placeholder syntax used by `vue-i18n`
(`{count}`, `{taskId}`, …).
### Revalidation Triggers
- A change to `vue-i18n` placeholder syntax (none expected).
- Any new English key added to `en.json` after this spec lands — that is
a separate ticket (out of scope) and would invalidate the alignment
diff if not mirrored to `zh.json`.
## Architecture
### Existing Architecture Analysis
- Locale files are flat JSON trees grouped by feature
(`home`, `step3`, `step5`, `graph`, `log`, …) and consumed by
`vue-i18n` via `frontend/src/i18n/`.
- `locales/en.json` and `locales/zh.json` are kept structurally aligned
by convention; the alignment is verified by the `jq paths(scalars)`
diff cited in the requirements doc and is currently empty.
- Translation convention in `zh.json`: surrounding `step*`, `graph.*`,
and `log.*` values are direct natural-Chinese renderings of their
English siblings, preserving placeholders and any leading/trailing
glyphs.
### Architecture Pattern & Boundary Map
This change has no architectural surface area — it is a value-only edit
inside a configuration data file. No diagram needed.
- Selected pattern: **In-place data edit** of `locales/zh.json`.
- Domain boundary: locale data only.
- Existing patterns preserved: `vue-i18n` key/value contract; placeholder
syntax; key order; key set.
- New components: none.
- Steering compliance: matches `tech.md`'s i18n setup
(`vue-i18n` + JSON files in `/locales/`); no new dependency.
### Technology Stack
| Layer | Choice / Version | Role in Feature | Notes |
|-------|------------------|-----------------|-------|
| Frontend | `vue-i18n` | Consumes the translated keys at runtime | Unchanged |
| Data | `locales/zh.json` (UTF-8 JSON) | Storage of the translated values | Only file edited |
| Tooling | `jq`, `python -c "import json"` | Validation of JSON parseability and key alignment | No new tool |
## File Structure Plan
### Modified Files
- `locales/zh.json` — replace the value of ten specific keys (see the
table in *Translation Contract* below). No keys are added, removed,
reordered, or restructured.
No other file is touched.
## Requirements Traceability
| Requirement | Summary | Realized by |
|-------------|---------|-------------|
| 1.1 | Step 3 waiting label is Chinese | Edit value of `step3.waitingForActions` |
| 1.2 | Step 4 waiting label is Chinese | Edit value of `step4.waitingForReportAgent` |
| 1.3 | Step 5 labels are Chinese | Edit values of `step5.interactiveTools`, `step5.agentsAvailable`, `step5.reportAgentChat` |
| 1.4 | Graph panel labels are Chinese | Edit values of `graph.panelTitle`, `graph.nodeDetails`, `graph.relationship` |
| 1.5 | `step5.agentsAvailable` keeps `{count}` once, naturally placed | Translation contract row |
| 1.6 | `home.heroDescBrand` stays `MiroFish` | No edit (verified by spot check) |
| 2.1 | Decision recorded if scaffold kept English | N/A — decision is to translate (R2.2) |
| 2.2 | Translate scaffold preserving indent / `└─` / `{taskId}` | Edit value of `log.prepareTaskId` |
| 2.3 | PR description lists English-by-design keys | Done at /done time (PR description) |
| 3.1 | `en.json``zh.json` key sets identical | Validated by alignment diff in *Validation Strategy* |
| 3.2 | Key order preserved in unchanged objects | Enforced by using `Edit` (string replace) only |
| 3.3 | Placeholders preserved byte-for-byte | Enforced by translation contract + parse check |
| 3.4 | Reject change if placeholder drifts | Enforced by review + grep check in *Validation Strategy* |
| 3.5 | `zh.json` remains valid JSON | Enforced by `jq empty` check |
| 4.1 | Only `locales/zh.json` changes | Enforced at /done time (`git status` review) |
| 4.2 | No add/rename/delete of keys | Enforced by using `Edit` only on values |
| 4.3 | If a value is already Chinese (upstream change), skip and note | Enforced by pre-edit re-read of current values |
## Components and Interfaces
There is no software component to design. The "interface" is the set of
exact value strings that `locales/zh.json` will contain after the
change.
## Translation Contract
The implementation MUST replace each listed value with exactly the
target string below, using `Edit` (string replace) on the JSON value
only. Leading/trailing whitespace inside the JSON value, all
placeholders, and the surrounding double quotes / commas are preserved
because the Edit operates only on the value bytes.
| Key | Current value (English) | Target value (Chinese) |
|-----|--------------------------|------------------------|
| `home.heroDescBrand` | `MiroFish` | `MiroFish` (unchanged — brand) |
| `step3.waitingForActions` | `Waiting for agent actions...` | `等待智能体执行动作...` |
| `step4.waitingForReportAgent` | `Waiting for Report Agent...` | `等待报告智能体...` |
| `step5.interactiveTools` | `Interactive Tools` | `交互工具` |
| `step5.agentsAvailable` | `{count} agents available` | `{count} 个智能体可用` |
| `step5.reportAgentChat` | `Report Agent - Chat` | `报告智能体 - 对话` |
| `graph.panelTitle` | `Graph Relationship Visualization` | `图谱关系可视化` |
| `graph.nodeDetails` | `Node Details` | `节点详情` |
| `graph.relationship` | `Relationship` | `关系` |
| `log.prepareTaskId` | ` └─ Task ID: {taskId}` | ` └─ 任务 ID: {taskId}` |
Translation rationale (matches existing `zh.json` conventions):
- "Agent" → "智能体" (e.g. existing `agent.title: "🤖 智能体详情"`).
- "Report Agent" → "报告智能体" (e.g. existing
`step4.reportAgentReady: "报告智能体就绪"`).
- "Task ID" → "任务 ID" (Chinese tech UI keeps "ID" as a loanword;
preserves the two-space indent and the `└─` continuation glyph used
across the surrounding `log.*` lines).
- The trailing `...` is preserved on `waitingForActions` and
`waitingForReportAgent` because it is a meaningful UI cue ("in
progress") and the English source uses it.
- The ` - ` separator in `step5.reportAgentChat` is kept literally so the
Chinese label keeps the same visual structure as the English one.
## Data Models
Not applicable. No schema or domain model is defined or changed.
## Error Handling
The only failure modes are (a) invalid JSON after edit and
(b) accidental key-set drift. Both are caught by the validation script
in the next section before the change is committed.
## Testing Strategy
### Static checks (mandatory before commit)
1. `jq empty locales/zh.json` — file remains valid JSON.
2. `diff <(jq -r 'paths(scalars) | join(".")' locales/en.json | sort)
<(jq -r 'paths(scalars) | join(".")' locales/zh.json | sort)` —
produces no output (key sets identical).
3. `jq -r '<key>' locales/zh.json` for each of the ten keys — output
matches the *Target value* column of the Translation Contract.
4. `git diff --stat` shows exactly one file changed: `locales/zh.json`.
5. `git diff locales/zh.json` shows only value changes (no key adds,
removes, or reorders) — visually confirm via `grep -nE
'^[+-]' <(git diff locales/zh.json)` that every `+` line has a
matching `-` line for the same key.
### Manual smoke test (recommended, optional)
- Run `npm run dev`, switch UI to Chinese (`zh`), and visit:
- Step 2 (look for the translated `└─ 任务 ID: …` log line),
- Step 3 (waiting state placeholder),
- Step 4 (waiting state placeholder),
- Step 5 (Interactive Tools heading, agent count, Report Agent chat
panel title),
- Graph panel (title, node details, relationship label).
- Confirm no English text remains for the targeted UI elements.
## Supporting References
- `.kiro/specs/i18n-backfill-zh-json/gap-analysis.md` — current-state
inventory, `log.prepareTaskId` usage analysis, and the rationale for
Option A (single targeted edit).
- `.ticket/8.md` — original GitHub issue snapshot.

View File

@ -0,0 +1,116 @@
# Gap Analysis — i18n-backfill-zh-json
## Scope
Translate ten English-only values in `locales/zh.json` to natural Chinese,
preserving structural alignment with `locales/en.json`. Data-only change.
## Current State Investigation
- **Locale files** live at the repo root: `locales/en.json`, `locales/zh.json`,
`locales/languages.json`. The frontend loader is `frontend/src/i18n/`
(vue-i18n).
- **Key alignment**: `diff <(jq -r 'paths(scalars) | join(".")'
locales/en.json | sort) <(jq -r 'paths(scalars) | join(".")'
locales/zh.json | sort)` is currently empty — same key set, no drift.
- **Confirmed English-only values in `zh.json`** (verified via `jq`):
- `home.heroDescBrand``"MiroFish"` (brand, keep as-is)
- `step3.waitingForActions``"Waiting for agent actions..."`
- `step4.waitingForReportAgent``"Waiting for Report Agent..."`
- `step5.interactiveTools``"Interactive Tools"`
- `step5.agentsAvailable``"{count} agents available"`
- `step5.reportAgentChat``"Report Agent - Chat"`
- `graph.panelTitle``"Graph Relationship Visualization"`
- `graph.nodeDetails``"Node Details"`
- `graph.relationship``"Relationship"`
- `log.prepareTaskId``" └─ Task ID: {taskId}"`
- `en.json` contains the same English values for these keys (as expected).
### `log.prepareTaskId` usage
Confirmed via `Grep`: this key is consumed by
`frontend/src/components/Step2EnvSetup.vue:801`
`addLog(t('log.prepareTaskId', { taskId: res.data.task_id }))` — i.e. it is
rendered into the in-UI log panel that the user reads. The surrounding
`log.*` keys in `zh.json` are all translated to natural Chinese (e.g.
`prepareTaskStarted: "准备任务已启动"`, `simEnvClosed: "✓ 模拟环境已关闭"`).
**Conclusion**: this is a user-facing log line, not a locale-neutral
scaffold; it should be translated, with the leading two-space indent, the
`└─` continuation glyph, and the `{taskId}` placeholder preserved.
## Implementation Approach
### Option A — Single targeted edit to `locales/zh.json` (recommended)
Open `locales/zh.json`, locate each of the ten keys, and replace the value
with its Chinese translation. Re-run the `jq` alignment diff and parse-check
afterward.
- ✅ Minimal blast radius, single file changed.
- ✅ Matches the surrounding convention (other `log.*`, `step3.*`, `step5.*`
Chinese values are already direct translations of their English siblings).
- ✅ No risk of key reorder or shape change if edits are value-only.
- ❌ None — this is the only sensible approach for a 10-value backfill.
### Option B — Script-driven rewrite
Write a one-off `jq` or Node script to set the ten values. Overkill for ten
values and increases the chance of accidental key reorder (`jq` does not
guarantee key-order preservation in older versions).
**Decision**: Option A.
## Translation Plan (proposed values)
| Key | Proposed Chinese value |
| --- | --- |
| `home.heroDescBrand` | `MiroFish` (unchanged — brand) |
| `step3.waitingForActions` | `等待智能体执行动作...` |
| `step4.waitingForReportAgent` | `等待报告智能体...` |
| `step5.interactiveTools` | `交互工具` |
| `step5.agentsAvailable` | `{count} 个智能体可用` |
| `step5.reportAgentChat` | `报告智能体 - 对话` |
| `graph.panelTitle` | `图谱关系可视化` |
| `graph.nodeDetails` | `节点详情` |
| `graph.relationship` | `关系` |
| `log.prepareTaskId` | ` └─ 任务 ID: {taskId}` |
Notes:
- "Agent" is rendered as "智能体" — consistent with existing `zh.json` usage
(e.g. `step3.recentActions: "最近行为"`, `agent.title: "🤖 智能体详情"`).
- "Report Agent" → "报告智能体" — matches existing translations such as
`step4.reportAgentReady: "报告智能体就绪"`.
- `step5.reportAgentChat` keeps the ` - ` separator literally to match the
English style in the same key family.
- `log.prepareTaskId` keeps the two leading spaces and `└─` glyph because
surrounding log lines (e.g. `simEnvClosed: "✓ 模拟环境已关闭"`) preserve
their leading glyph; the indent is meaningful in the log panel.
These are proposals to be finalized at design time; minor wording polish
(e.g. "对话" vs "聊天") can be revisited during /kiro:spec-design.
## Validation Strategy
1. `jq empty locales/zh.json` — file remains valid JSON.
2. `diff <(jq -r 'paths(scalars) | join(".")' locales/en.json | sort)
<(jq -r 'paths(scalars) | join(".")' locales/zh.json | sort)` — empty.
3. Spot-check via `jq -r '<key>'` that the ten target values now match the
translation table (or the brand/scaffold exception, where applicable).
4. Manual: launch the dev server, switch UI to Chinese, walk through Step 2
logs (look for translated `log.prepareTaskId` line), Step 3 / Step 4
waiting states, Step 5 interactive tools, and the graph panel.
## Risks / Unknowns
- **Wording quality**: My proposed translations follow the conventions used
elsewhere in `zh.json`; a native reviewer may prefer alternatives. The PR
description should call this out so reviewers can suggest edits.
- **Key order preservation**: `Edit` (string-replace) is safe; `jq`-based
rewrites would not be. We will use `Edit` exclusively.
- **No additional research needed** — this is a well-bounded data change.
## Recommendation
Proceed to `/kiro:spec-design` with Option A and the translation table
above. Design phase will only need to specify the exact `Edit` operations
and the validation script — no architecture work.

View File

@ -0,0 +1,63 @@
# Requirements Document
## Project Description (Input)
Backfill 10 keys in `locales/zh.json` that still hold English values, so Chinese UI users see Chinese strings everywhere. The `locales/en.json` and `locales/zh.json` files are structurally aligned (629 keys each) and `en.json` contains zero Chinese — this is the inverse problem (zh.json with English values), bundled into the i18n epic for symmetry.
## Introduction
This spec covers the work to translate ten remaining English-only natural-language values in `locales/zh.json` into natural Chinese, so that Chinese UI users see Chinese labels across the affected workflow steps and the graph panel. The change is data-only (locale JSON edits) and must keep `locales/en.json` and `locales/zh.json` structurally aligned (same key set, same key order). Tracks GitHub issue #8.
## Boundary Context
- **In scope**:
- Translation of nine user-facing English values in `locales/zh.json` (the keys listed in the project description, excluding the brand string).
- A documented decision for `log.prepareTaskId` — translate or keep English, recorded in the PR description with rationale.
- Preservation of all interpolation placeholders (`{count}`, `{taskId}`, etc.) verbatim.
- Preservation of the existing key set and key order in `locales/zh.json` so it remains structurally aligned with `locales/en.json`.
- **Out of scope**:
- Any English-side translation work in `locales/en.json` (covered by other tickets in the i18n epic).
- Restructuring locale files, moving keys between sections, or changing the i18n loader.
- Adding new keys for currently-untranslated UI elements (file a separate issue if any are discovered).
- Frontend code changes (`*.vue`, `*.js`, `*.ts`).
- **Adjacent expectations**:
- The frontend i18n loader (`vue-i18n` + `frontend/src/i18n/`) reads `locales/en.json` and `locales/zh.json` directly; it expects identical key trees in both files.
- The acceptance check `diff <(jq -r 'paths(scalars) | join(".")' locales/en.json | sort) <(jq -r 'paths(scalars) | join(".")' locales/zh.json | sort)` must remain empty after the change.
## Requirements
### Requirement 1: Backfill English-only values in `locales/zh.json` with natural Chinese
**Objective:** As a Chinese-locale UI user, I want all user-facing labels on Step 3, Step 4, Step 5, and the graph panel to be displayed in Chinese, so that I do not see English text mixed into a Chinese UI.
#### Acceptance Criteria
1. When the Chinese locale is active and a user views the Step 3 simulation screen, the MiroFish frontend shall render `step3.waitingForActions` as a natural Chinese translation of "Waiting for agent actions..." (preserving the trailing ellipsis).
2. When the Chinese locale is active and a user views the Step 4 report screen, the MiroFish frontend shall render `step4.waitingForReportAgent` as a natural Chinese translation of "Waiting for Report Agent...".
3. When the Chinese locale is active and a user views the Step 5 interaction screen, the MiroFish frontend shall render `step5.interactiveTools`, `step5.agentsAvailable`, and `step5.reportAgentChat` as natural Chinese strings.
4. When the Chinese locale is active and a user opens the graph panel, the MiroFish frontend shall render `graph.panelTitle`, `graph.nodeDetails`, and `graph.relationship` as natural Chinese strings.
5. The translated value for `step5.agentsAvailable` shall contain the placeholder `{count}` exactly once and at a position that produces grammatically natural Chinese when interpolated.
6. The MiroFish locale data shall keep `home.heroDescBrand` set to the literal string `"MiroFish"` because it is a proper noun.
### Requirement 2: Documented decision for `log.prepareTaskId`
**Objective:** As a maintainer, I want a recorded, justified decision about whether `log.prepareTaskId` should be translated, so that future contributors understand why this value differs from the surrounding policy.
#### Acceptance Criteria
1. Where `log.prepareTaskId` is intentionally retained as a locale-neutral English log scaffold, the MiroFish PR description shall document that decision and the reason (log scaffold convention).
2. Where `log.prepareTaskId` is treated as a user-facing string, the MiroFish locale data shall translate it to natural Chinese while preserving the leading whitespace, the `└─` glyph, and the `{taskId}` placeholder verbatim.
3. The MiroFish PR description shall list any keys that remain English on purpose (brand strings and any retained log scaffolds) so reviewers can see they were not overlooked.
### Requirement 3: Preserve structural alignment and placeholders
**Objective:** As a frontend developer relying on `vue-i18n`, I want `locales/en.json` and `locales/zh.json` to keep the same key set and the same key order, so that fallbacks and tooling continue to work and diffs stay reviewable.
#### Acceptance Criteria
1. The MiroFish locale data shall keep the set of scalar key paths in `locales/zh.json` identical to the set in `locales/en.json` (the diff command in the boundary context shall produce no output).
2. The MiroFish locale data shall preserve the existing order of keys in `locales/zh.json` for every object that is not modified by this change.
3. For every translated value, the MiroFish locale data shall preserve interpolation placeholders (`{count}`, `{taskId}`, …) byte-for-byte.
4. If a translation requires inserting or removing a placeholder, then the MiroFish change shall be rejected and the translation revised, because placeholder drift breaks runtime interpolation.
5. The MiroFish locale data shall remain valid JSON (parseable by `JSON.parse` / `jq`) after the change.
### Requirement 4: No frontend code changes
**Objective:** As a reviewer, I want the diff to be limited to `locales/zh.json`, so that the change is easy to verify and unrelated risk is excluded.
#### Acceptance Criteria
1. The MiroFish change shall modify only `locales/zh.json`; no `*.vue`, `*.js`, `*.ts`, `*.py`, or other source files shall be edited.
2. The MiroFish change shall not add, rename, or delete keys in `locales/zh.json`; only the values of the listed keys may change.
3. If a listed value in `locales/zh.json` already contains natural Chinese (an upstream change landed first), then the MiroFish change shall leave that value untouched and note the skip in the PR description.

View File

@ -0,0 +1,115 @@
# Research & Design Decisions — i18n-backfill-zh-json
## Summary
- **Feature**: `i18n-backfill-zh-json`
- **Discovery Scope**: Simple Addition (data-only edits to one JSON file).
- **Key Findings**:
- All ten flagged keys in `locales/zh.json` currently hold the exact
English value listed in issue #8 (verified via `jq`).
- `en.json` and `zh.json` key sets are currently identical
(`paths(scalars)` diff is empty), so we must preserve that
invariant.
- `log.prepareTaskId` is consumed by `Step2EnvSetup.vue:801` via
`addLog(t('log.prepareTaskId', { taskId: ... }))` — it IS
user-facing, and surrounding `log.*` keys are translated; therefore
we translate it.
## Research Log
### Current values of the targeted keys
- **Context**: Confirm the issue's claim that ten specific values are
English-only.
- **Sources Consulted**: `locales/zh.json`, `locales/en.json` (via `jq`).
- **Findings**:
- Each of the ten target keys in `zh.json` matches the English value
in `en.json` byte-for-byte today.
- `home.heroDescBrand` is the brand name `MiroFish` and should stay
English.
- **Implications**: Direct value replacement is safe; no upstream
changes have already translated any of them.
### `log.prepareTaskId` usage classification
- **Context**: Issue requires a documented decision on whether this
value is locale-neutral scaffold or a user-facing string.
- **Sources Consulted**: `Grep` for `prepareTaskId` across the repo;
inspection of `frontend/src/components/Step2EnvSetup.vue:801`;
inspection of sibling `log.*` values in `zh.json`.
- **Findings**:
- The key is rendered into the in-UI log panel via `addLog(t(...))`.
- All sibling `log.*` values in `zh.json` are translated to natural
Chinese while preserving placeholders and continuation glyphs.
- **Implications**: Translate the value; preserve the leading two-space
indent, the `└─` glyph, and the `{taskId}` placeholder.
### Translation conventions in `zh.json`
- **Context**: Choose Chinese wordings consistent with the existing
vocabulary so reviewers don't need to debate terminology.
- **Sources Consulted**: `jq` dumps of `home.*`, `step3.*`, `step4.*`,
`step5.*`, `graph.*`, `agent.*`, `log.*` in `zh.json`.
- **Findings**:
- "Agent" → "智能体" (e.g. `agent.title: "🤖 智能体详情"`).
- "Report Agent" → "报告智能体"
(e.g. `step4.reportAgentReady: "报告智能体就绪"`).
- "Graph" → "图谱" (e.g. existing `graphLoadFailed: "图谱加载失败"`).
- "Task ID" → "任务 ID" — keeps "ID" as a loanword, which is the
standard rendering in Chinese tech UIs and matches surrounding
log-line tone.
- **Implications**: Wording table in `design.md` follows these
conventions; a native reviewer can still suggest polish but no
reviewer should be surprised by the chosen vocabulary.
## Architecture Pattern Evaluation
| Option | Description | Strengths | Risks / Limitations | Notes |
|--------|-------------|-----------|---------------------|-------|
| In-place value `Edit` (selected) | Use the `Edit` tool for each of the ten lines in `zh.json` | No risk of key reorder; minimal blast radius; reviewable diff | Requires care that `old_string` is unique per edit | Matches surrounding convention |
| `jq` script rewrite | One-off `jq --arg ... '.x = $v'` script | Mechanizable | Older `jq` versions may reorder object keys, breaking structural alignment | Rejected |
| Manual full-file rewrite via `Write` | Rewrite the file with new values | Fewer edits | Highest risk of accidental whitespace/key-order drift | Rejected |
## Design Decisions
### Decision: Translate `log.prepareTaskId` rather than leave it English
- **Context**: Issue allows either choice, conditional on a documented
rationale.
- **Alternatives Considered**:
1. Leave English on the grounds that it is a "log scaffold".
2. Translate, matching the surrounding `log.*` translations.
- **Selected Approach**: Translate to ` └─ 任务 ID: {taskId}`.
- **Rationale**: The key is consumed by a user-visible log panel
(`Step2EnvSetup.vue:801`), and every other `log.*` key in `zh.json`
is already translated. Leaving this one in English would be the
inconsistent choice.
- **Trade-offs**: None material; the indent and `└─` glyph carry the
scaffold semantics and are preserved.
- **Follow-up**: Document the decision in the PR description so a
reviewer can override if they prefer to keep "Task ID" as a literal
technical identifier.
### Decision: Use `Edit` (string replace) rather than a `jq` rewrite
- **Context**: Need to change ten values without disturbing key order
or the file's whitespace.
- **Selected Approach**: One `Edit` per key, matching the value with
enough surrounding context to be unique.
- **Rationale**: `Edit` operates on raw bytes — it cannot reorder keys
or drop comments/whitespace. `jq` rewrites are not safe across all
versions for object key order.
- **Trade-offs**: Slightly more tool calls; offset by safety.
- **Follow-up**: After the edits, run the alignment diff and the
`jq empty` check before committing.
## Risks & Mitigations
- **Translation polish disagreements** — Reviewer may prefer different
wording. *Mitigation*: PR description lists the chosen renderings and
invites suggestions; copy changes are cheap.
- **Accidental placeholder drift**`{count}` or `{taskId}` lost during
edit. *Mitigation*: post-edit `grep` check that each placeholder
still appears exactly once in its key's value.
- **Accidental key reorder** — JSON tooling sometimes reorders keys.
*Mitigation*: use `Edit` only; do not run `jq` write-back.
## References
- `.kiro/specs/i18n-backfill-zh-json/gap-analysis.md`
- `.ticket/8.md`
- `frontend/src/components/Step2EnvSetup.vue:801` — usage of
`log.prepareTaskId`.

View File

@ -0,0 +1,27 @@
{
"feature_name": "i18n-backfill-zh-json",
"created_at": "2026-05-07T15:24:17Z",
"updated_at": "2026-05-07T15:24:17Z",
"language": "en",
"phase": "tasks-generated",
"approvals": {
"requirements": {
"generated": true,
"approved": true
},
"design": {
"generated": true,
"approved": true
},
"tasks": {
"generated": true,
"approved": true
}
},
"ready_for_implementation": true,
"ticket": {
"number": 8,
"url": "https://github.com/salestech-group/MiroFish/issues/8",
"snapshot": ".ticket/8.md"
}
}

View File

@ -0,0 +1,29 @@
# Implementation Plan
- [x] 1. Backfill English-only values in `locales/zh.json` with the natural Chinese translations from the design's Translation Contract
- Edit `step3.waitingForActions``等待智能体执行动作...`
- Edit `step4.waitingForReportAgent``等待报告智能体...`
- Edit `step5.interactiveTools``交互工具`
- Edit `step5.agentsAvailable``{count} 个智能体可用` (placeholder `{count}` preserved exactly once)
- Edit `step5.reportAgentChat``报告智能体 - 对话`
- Edit `graph.panelTitle``图谱关系可视化`
- Edit `graph.nodeDetails``节点详情`
- Edit `graph.relationship``关系`
- Edit `log.prepareTaskId`` └─ 任务 ID: {taskId}` (preserves the two-space indent, the `└─` glyph, and the `{taskId}` placeholder verbatim)
- Leave `home.heroDescBrand` as the literal string `MiroFish` (brand)
- Use the `Edit` tool only (do not run any `jq` write-back); do not add, remove, or reorder any keys
- Observable completion: `git diff --stat` shows exactly one file changed (`locales/zh.json`); `git diff locales/zh.json` shows only value changes for the listed keys (no key adds/removes/reorders)
- _Requirements: 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 2.2, 3.2, 3.3, 4.1, 4.2, 4.3_
- [x] 2. Validate JSON parseability, key alignment, and placeholder preservation after the backfill
- Run `jq empty locales/zh.json` and confirm exit code 0 (file is valid JSON)
- Run `diff <(jq -r 'paths(scalars) | join(".")' locales/en.json | sort) <(jq -r 'paths(scalars) | join(".")' locales/zh.json | sort)` and confirm output is empty (key sets identical)
- Run `jq -r '<key>'` for each of the ten keys and confirm the value matches the design's Translation Contract row (or `MiroFish` for `home.heroDescBrand`)
- Confirm `{count}` appears exactly once inside the new value of `step5.agentsAvailable`, and `{taskId}` appears exactly once inside the new value of `log.prepareTaskId`
- Observable completion: all five checks above pass; if any fails, return to task 1 and revise the offending edit before re-running validation
- _Requirements: 3.1, 3.3, 3.4, 3.5_
- [x] 3. Capture the `log.prepareTaskId` decision and any English-by-design exceptions for the PR description
- Record in a short note (in `.kiro/specs/i18n-backfill-zh-json/HANDOFF.md` if needed, or directly in the PR body at /done time) that: (a) `home.heroDescBrand` is intentionally kept as `MiroFish` because it is a brand; (b) `log.prepareTaskId` was translated to ` └─ 任务 ID: {taskId}` because it is rendered into the user-visible log panel by `Step2EnvSetup.vue:801` and surrounding `log.*` keys are translated.
- Observable completion: the rationale text is ready for inclusion in the PR description so reviewers can see the decisions at a glance
- _Requirements: 2.1, 2.3_

View File

@ -185,7 +185,7 @@
"step3": {
"startGenerateReport": "开始生成结果报告",
"generatingReport": "启动中...",
"waitingForActions": "Waiting for agent actions...",
"waitingForActions": "等待智能体执行动作...",
"errorMissingSimId": "错误:缺少 simulationId",
"startingDualSim": "正在启动双平台并行模拟...",
"graphMemoryUpdateEnabled": "已开启动态图谱更新模式",
@ -216,7 +216,7 @@
"step4": {
"generatingSection": "正在生成{title}...",
"goToInteraction": "进入深度互动",
"waitingForReportAgent": "Waiting for Report Agent...",
"waitingForReportAgent": "等待报告智能体...",
"collapse": "收起 ▲",
"expandAll": "展开全部 {count} 条 ▼",
"expandAllEntities": "展开全部 {count} 个 ▼",
@ -256,13 +256,13 @@
"world2": "世界2"
},
"step5": {
"interactiveTools": "Interactive Tools",
"agentsAvailable": "{count} agents available",
"interactiveTools": "交互工具",
"agentsAvailable": "{count} 个智能体可用",
"chatWithReportAgent": "与Report Agent对话",
"chatWithAgent": "与世界中任意个体对话",
"selectChatTarget": "选择对话对象",
"sendSurvey": "发送问卷调查到世界中",
"reportAgentChat": "Report Agent - Chat",
"reportAgentChat": "报告智能体 - 对话",
"reportAgentDesc": "报告生成智能体的快速对话版本,可调用 4 种专业工具拥有MiroFish的完整记忆",
"toolInsightForge": "InsightForge 深度归因",
"toolInsightForgeDesc": "对齐现实世界种子数据与模拟环境状态结合Global/Local Memory机制提供跨时空的深度归因分析",
@ -291,13 +291,13 @@
"selectAgentFirst": "请先选择一个模拟个体"
},
"graph": {
"panelTitle": "Graph Relationship Visualization",
"panelTitle": "图谱关系可视化",
"refreshGraph": "刷新图谱",
"graphMemoryRealtime": "GraphRAG长短期记忆实时更新中",
"realtimeUpdating": "实时更新中...",
"pendingContentHint": "还有少量内容处理中,建议稍后手动刷新图谱",
"nodeDetails": "Node Details",
"relationship": "Relationship",
"nodeDetails": "节点详情",
"relationship": "关系",
"graphDataLoading": "图谱数据加载中...",
"waitingOntology": "等待本体生成...",
"toggleMaximize": "最大化/还原",
@ -578,7 +578,7 @@
"preparingSimEnv": "正在准备模拟环境...",
"detectedExistingPrep": "检测到已有完成的准备工作,直接使用",
"prepareTaskStarted": "准备任务已启动",
"prepareTaskId": " └─ Task ID: {taskId}",
"prepareTaskId": " └─ 任务 ID: {taskId}",
"zepEntitiesFound": "从Zep图谱读取到 {count} 个实体",
"entityTypes": " └─ 实体类型: {types}",
"startPollingProgress": "开始轮询准备进度...",