AWS Builder Workshop

Build and Localize a Tagalog Learning App into Chinese Variants with Kiro Workshop

Audience: professional developers building multilingual static apps and learning products
Duration: 2 hours
Primary AWS AI service: Kiro
Project output: a Kiro-guided localization pipeline that creates zh-HK and zh-TW static sites while preserving Tagalog as the learning target.

Workshop Summary

Tagalog Kiro Workshop

This workshop teaches developers to localize a Tagalog learning app into Traditional Chinese variants without losing the original learning target. Participants use Kiro to define localization rules, preserve Tagalog practice fields, create zh-HK and zh-TW dictionaries, render localized pages, and validate output. The result is a repeatable workflow for multilingual learning products with reviewer-friendly handoff notes and safer updates later.

Workshop objective

Developers build a localization pipeline for a Tagalog learning app. UI labels, article metadata, grammar explanations, cultural guidance, and review notes are localized into Chinese variants. Natural Tagalog, Polite Tagalog, Friendly Filipino-English, and Playful Filipino-English remain visible for speaking practice.

2-hour agenda

Time Module Developer outcome
0–10 min Kiro setup Steering and spec folders prepared
10–25 min Localization contract Decide preserved and localized fields
25–45 min Language config Build zh-HK and zh-TW dictionaries
45–70 min Structured renderer Generate localized cards from data
70–90 min HTML migration Patch existing static HTML safely
90–105 min Validation Check lang markers, labels, card counts, ZIP output
105–115 min Hooks Automate localization QA
115–120 min Handoff Kiro creates review notes and backlog

Step 1 — Create Kiro steering for localization rules

Developer action

  1. Open the workspace in Kiro.
  2. Generate foundational steering docs.
  3. Add a localization-specific steering file.
  4. Ask Kiro to explain how the steering affects future code generation.

Kiro prompt sample

Create steering docs for a multilingual Tagalog learning app. Generate zh-HK and zh-TW versions. Preserve Tagalog learning phrases and localize UI labels, article summaries, cultural notes, grammar notes, pronunciation explanations, and review guidance.

System design decision

  1. Make Step 1 — Create Kiro steering for localization rules explicit before coding: Professional developers should not rely on hidden assumptions when using AI-assisted engineering. The workshop first writes the rule into steering or specs so Kiro has durable project context. This makes generated code more consistent, gives reviewers something concrete to inspect, and prevents repeated explanation in every chat. The decision also helps new developers understand why a file exists, what problem it solves, and which behavior is allowed or disallowed.
  2. Keep the implementation deterministic and reviewable: Kiro can help generate code, tests, and documentation, but the workshop output should be reproducible. Deterministic scripts, explicit configuration, stable schemas, and validation reports make the result easier to debug. When every transformation has a visible input and output, developers can review diffs, rerun checks, and explain the system to another engineer. This is especially important for language-learning content where correctness and cultural context require human review.
  3. Attach validation to the workflow, not only the final demo: The workshop treats validation as part of system design. Each step has a check, a report, or a hook so defects appear close to the change that caused them. This approach lets Kiro act as a coding assistant and quality reviewer while developers stay in control. The result is a practical professional workflow: plan with specs, guide with steering, implement in small tasks, validate output, and document handoff.

Code sample — .kiro/steering/localization.md

# Localization Steering

## Variants

- zh-HK: Cantonese / Hong Kong Chinese interface and explanations.
- zh-TW: Taiwan Traditional Chinese interface and explanations.

## Preservation rules

- Preserve Natural Tagalog.
- Preserve Polite Tagalog.
- Preserve Friendly Filipino-English.
- Preserve Playful Filipino-English and label it informal.

## Localized fields

- UI labels
- article titles and summaries
- grammar explanations
- pronunciation explanations
- cultural guidance
- review notes

## Review rules

- Tagalog content needs native-speaker review.
- Chinese copy needs locale review.
- Generated pages must show a review note.

Code explanation

  • Business logic: The steering file protects the Tagalog learning target while defining what should be localized.
  • Code logic: Kiro reads the Markdown file as persistent workspace context and uses it for specs, renderers, validators, hooks, and docs.
  • Expected result: Future Kiro-generated code preserves Tagalog fields and localizes surrounding explanations into zh-HK and zh-TW.

Step 2 — Create language configuration dictionaries

Developer action

  1. Create localization_config.py.
  2. Add required keys for zh-HK and zh-TW.
  3. Validate key parity.
  4. Ask Kiro to identify missing labels.

Kiro prompt sample

Create Python language configuration objects for zh-HK and zh-TW. Include html_lang, folder, zip, site title, article list label, card labels, review note, respect guidance, and casual guidance. Add a validator.

System design decision

  1. Make Step 2 — Create language configuration dictionaries explicit before coding: Professional developers should not rely on hidden assumptions when using AI-assisted engineering. The workshop first writes the rule into steering or specs so Kiro has durable project context. This makes generated code more consistent, gives reviewers something concrete to inspect, and prevents repeated explanation in every chat. The decision also helps new developers understand why a file exists, what problem it solves, and which behavior is allowed or disallowed.
  2. Keep the implementation deterministic and reviewable: Kiro can help generate code, tests, and documentation, but the workshop output should be reproducible. Deterministic scripts, explicit configuration, stable schemas, and validation reports make the result easier to debug. When every transformation has a visible input and output, developers can review diffs, rerun checks, and explain the system to another engineer. This is especially important for language-learning content where correctness and cultural context require human review.
  3. Attach validation to the workflow, not only the final demo: The workshop treats validation as part of system design. Each step has a check, a report, or a hook so defects appear close to the change that caused them. This approach lets Kiro act as a coding assistant and quality reviewer while developers stay in control. The result is a practical professional workflow: plan with specs, guide with steering, implement in small tasks, validate output, and document handoff.

Code sample — localization_config.py

REQUIRED_KEYS = {"html_lang", "folder", "zip", "site_title", "article_list", "labels", "review_note"}

LANGS = {
    "zh_hk": {
        "html_lang": "zh-HK",
        "folder": "dist_zh_hk",
        "zip": "tagalog-learning-zh-hk.zip",
        "site_title": "AWS 馬尼拉 Community Day Tagalog 學習站",
        "article_list": "文章清單",
        "review_note": "廣東話版本:Tagalog 句子保留原文,方便朗讀練習。",
        "labels": {"meaning": "中文意思", "natural": "自然 Tagalog", "polite": "禮貌 Tagalog", "grammar": "語法拆解", "pronunciation": "發音指南"}
    },
    "zh_tw": {
        "html_lang": "zh-TW",
        "folder": "dist_zh_tw",
        "zip": "tagalog-learning-zh-tw.zip",
        "site_title": "AWS 馬尼拉社群日 Tagalog 學習站",
        "article_list": "文章列表",
        "review_note": "繁體中文(台灣)版本:Tagalog 句子保留原文,方便朗讀練習。",
        "labels": {"meaning": "中文意思", "natural": "自然 Tagalog", "polite": "禮貌 Tagalog", "grammar": "語法拆解", "pronunciation": "發音指南"}
    }
}

def validate_language_configs():
    failures = []
    for lang, cfg in LANGS.items():
        missing = REQUIRED_KEYS - set(cfg)
        if missing:
            failures.append(f"{lang}: missing {sorted(missing)}")
    if failures:
        raise ValueError("
".join(failures))

Code explanation

  • Business logic: The configuration centralizes all locale-specific labels, guidance, folders, and package names.
  • Code logic: The validator checks that each locale implements required keys before rendering begins.
  • Expected result: Running validate_language_configs() succeeds for complete locale dictionaries and fails with clear missing-key messages.

Step 3 — Render localized cards from structured data

Developer action

  1. Define card data with localized meanings.
  2. Write a card renderer that accepts a locale key.
  3. Escape dynamic output.
  4. Keep Tagalog spans marked with lang=tl.

Kiro prompt sample

Create a Python renderer for localized sentence cards. Preserve naturalTagalog and politeTagalog. Localize labels, meaning, grammar explanation, tone, and review note. Escape all dynamic HTML content.

System design decision

  1. Make Step 3 — Render localized cards from structured data explicit before coding: Professional developers should not rely on hidden assumptions when using AI-assisted engineering. The workshop first writes the rule into steering or specs so Kiro has durable project context. This makes generated code more consistent, gives reviewers something concrete to inspect, and prevents repeated explanation in every chat. The decision also helps new developers understand why a file exists, what problem it solves, and which behavior is allowed or disallowed.
  2. Keep the implementation deterministic and reviewable: Kiro can help generate code, tests, and documentation, but the workshop output should be reproducible. Deterministic scripts, explicit configuration, stable schemas, and validation reports make the result easier to debug. When every transformation has a visible input and output, developers can review diffs, rerun checks, and explain the system to another engineer. This is especially important for language-learning content where correctness and cultural context require human review.
  3. Attach validation to the workflow, not only the final demo: The workshop treats validation as part of system design. Each step has a check, a report, or a hook so defects appear close to the change that caused them. This approach lets Kiro act as a coding assistant and quality reviewer while developers stay in control. The result is a practical professional workflow: plan with specs, guide with steering, implement in small tasks, validate output, and document handoff.

Code sample — render_localized.py

import html
from localization_config import LANGS

CARD = {
    "meaning": {"zh_hk": "我可唔可以問一個問題?", "zh_tw": "我可以問一個問題嗎?"},
    "naturalTagalog": "Puwede ba akong magtanong?",
    "politeTagalog": "Puwede po ba akong magtanong?",
    "grammar": {"zh_hk": ["Puwede:可以", "po:禮貌標記"], "zh_tw": ["Puwede:可以", "po:禮貌標記"]}
}

def render_card(card, lang_key):
    cfg = LANGS[lang_key]
    labels = cfg["labels"]
    grammar = "".join(f"<li>{html.escape(item)}</li>" for item in card["grammar"][lang_key])
    return f"""
<article class='sentence-card'>
  <p><strong>{html.escape(labels['meaning'])}:</strong> {html.escape(card['meaning'][lang_key])}</p>
  <p><strong>{html.escape(labels['natural'])}:</strong> <span lang='tl'>{html.escape(card['naturalTagalog'])}</span></p>
  <p><strong>{html.escape(labels['polite'])}:</strong> <span lang='tl'>{html.escape(card['politeTagalog'])}</span></p>
  <p><strong>{html.escape(labels['grammar'])}:</strong></p><ul>{grammar}</ul>
  <p class='review-note'>{html.escape(cfg['review_note'])}</p>
</article>
"""

Code explanation

  • Business logic: The renderer creates a localized card while preserving the Tagalog learning fields.
  • Code logic: It reads locale labels, escapes content, renders Chinese meaning and grammar, and marks Tagalog text as Tagalog.
  • Expected result: Calling render_card(CARD, 'zh_hk') produces a Cantonese/Hong Kong Chinese card with preserved Tagalog text.

Step 4 — Detect remaining untranslated labels

Developer action

  1. Create a detector for remaining English labels.
  2. Configure a watch list.
  3. Run it against each localized folder.
  4. Ask Kiro to suggest the smallest fix.

Kiro prompt sample

Create a localization validation script that scans generated zh-HK and zh-TW folders. Search for watched English labels such as Article List, Pronunciation Guide, Grammatical Breakdown, Cultural Context, and Extra Examples. Print JSON and fail if any watched label remains.

System design decision

  1. Make Step 4 — Detect remaining untranslated labels explicit before coding: Professional developers should not rely on hidden assumptions when using AI-assisted engineering. The workshop first writes the rule into steering or specs so Kiro has durable project context. This makes generated code more consistent, gives reviewers something concrete to inspect, and prevents repeated explanation in every chat. The decision also helps new developers understand why a file exists, what problem it solves, and which behavior is allowed or disallowed.
  2. Keep the implementation deterministic and reviewable: Kiro can help generate code, tests, and documentation, but the workshop output should be reproducible. Deterministic scripts, explicit configuration, stable schemas, and validation reports make the result easier to debug. When every transformation has a visible input and output, developers can review diffs, rerun checks, and explain the system to another engineer. This is especially important for language-learning content where correctness and cultural context require human review.
  3. Attach validation to the workflow, not only the final demo: The workshop treats validation as part of system design. Each step has a check, a report, or a hook so defects appear close to the change that caused them. This approach lets Kiro act as a coding assistant and quality reviewer while developers stay in control. The result is a practical professional workflow: plan with specs, guide with steering, implement in small tasks, validate output, and document handoff.

Code sample — validate_localized_labels.py

import json
from pathlib import Path

WATCHED_LABELS = ["Article List", "Pronunciation Guide", "Grammatical Breakdown", "Cultural Context", "Extra Examples"]

def scan_folder(folder):
    findings = []
    for path in sorted(Path(folder).glob("*.html")):
        text = path.read_text(encoding="utf-8")
        labels = [label for label in WATCHED_LABELS if label in text]
        if labels:
            findings.append({"file": path.name, "remainingLabels": labels})
    return findings

def validate_all(folders=("dist_zh_hk", "dist_zh_tw")):
    payload = {folder: scan_folder(folder) for folder in folders}
    print(json.dumps(payload, indent=2, ensure_ascii=False))
    if any(payload[folder] for folder in payload):
        raise SystemExit("Localized label validation failed")

if __name__ == "__main__":
    validate_all()

Code explanation

  • Business logic: The script prevents localized builds from reaching reviewers with obvious English UI labels still present.
  • Code logic: It scans generated HTML files, checks a curated watch list, prints JSON findings, and exits non-zero if labels remain.
  • Expected result: Running the script passes only when zh-HK and zh-TW generated pages have no watched English labels.

Additional Hands-on Developer Labs

These labs are unique to Workshop 4 — Localize a Tagalog Learning App into Chinese Variants. They extend the localization pipeline with locale-specific terminology governance, Chinese copy review, field-preservation tests, per-locale release manifests, and reviewer-ready diff packets. The focus is multilingual learning-product localization while preserving Tagalog as the speaking-practice target.

Hands-on Lab A — Build a locale terminology registry for zh-HK and zh-TW

Developer action

  • Ask Kiro to create a terminology registry for labels and learning-product terms.
  • Add separate preferred terms for zh_hk and zh_tw.
  • Add validator logic that detects missing locale terms.
  • Ask Kiro to generate a reviewer report for terms that still need approval.

Kiro prompt sample

Create a locale terminology registry for the Tagalog learning app localization pipeline.
Track conceptId, English source label, zh-HK preferred term, zh-TW preferred term, status, and reviewerNote.
Add validation for missing terms and export terms that need locale review.
Do not change Tagalog practice text.

System design decision

  • Terminology consistency matters across pages: Localized labels such as grammar, pronunciation, review note, informal badge, and article list should not drift between generated pages.
  • zh-HK and zh-TW need separate choices: Both variants use Traditional Chinese, but product wording, tone, and natural phrasing may differ by locale.
  • Review state belongs with terms: A term registry lets locale reviewers approve wording without searching through generated HTML.

Code sample — terminology_registry.py

from dataclasses import dataclass, asdict
from typing import Literal

ReviewStatus = Literal["draft", "locale-reviewed", "blocked"]

@dataclass(frozen=True)
class TermRecord:
    conceptId: str
    sourceEnglish: str
    zh_hk: str
    zh_tw: str
    status: ReviewStatus = "draft"
    reviewerNote: str = "Needs locale review."

TERMS = [
    TermRecord("article_list", "Article List", "文章清單", "文章列表", "locale-reviewed"),
    TermRecord("grammar", "Grammar Breakdown", "語法拆解", "語法解析"),
    TermRecord("pronunciation", "Pronunciation Guide", "發音指南", "發音指南"),
    TermRecord("informal_badge", "Informal", "非正式", "非正式")
]


def validate_terms(records: list[TermRecord]) -> list[dict]:
    failures = []
    for record in records:
        if not record.zh_hk.strip():
            failures.append({"conceptId": record.conceptId, "locale": "zh-HK", "reason": "missing term"})
        if not record.zh_tw.strip():
            failures.append({"conceptId": record.conceptId, "locale": "zh-TW", "reason": "missing term"})
    return failures


def terms_for_review(records: list[TermRecord]) -> list[dict]:
    return [asdict(record) for record in records if record.status != "locale-reviewed"]

Code explanation

  • Business logic: The registry centralizes locale wording decisions and review status.
  • Code logic: TermRecord stores per-locale terms, and validators return missing or unreviewed entries.
  • Expected result: Developers can generate consistent zh-HK and zh-TW labels and hand unreviewed terms to locale reviewers.

Hands-on Lab B — Add preservation tests for Tagalog learning fields

Developer action

  • Ask Kiro to write tests that compare source cards with localized output.
  • Verify that Natural Tagalog, Polite Tagalog, Friendly Filipino-English, and Playful Filipino-English are unchanged.
  • Confirm every preserved Tagalog span keeps lang="tl".
  • Fail the localization build if preserved practice text is rewritten.

Kiro prompt sample

Create preservation tests for localized zh-HK and zh-TW output.
Compare source card fields against rendered HTML.
Natural Tagalog, Polite Tagalog, Friendly Filipino-English, and Playful Filipino-English must remain unchanged.
Tagalog text must be wrapped with lang="tl".
Fail with cardId, fieldName, locale, and expected text when preservation breaks.

System design decision

  • Localization must not translate the practice target: The learner is practicing Tagalog, so Chinese localization should surround the Tagalog content, not replace it.
  • Field-level failures are easier to fix: Developers need to know which card and which field changed.
  • lang="tl" is part of accessibility: Preserved Tagalog text should remain machine-identifiable as Tagalog in localized pages.

Code sample — validate_preserved_fields.py

from bs4 import BeautifulSoup

PRESERVED_FIELDS = ["naturalTagalog", "politeTagalog", "friendlyFilipinoEnglish", "playfulFilipinoEnglish"]


def validate_preserved_fields(card: dict, html_text: str, locale: str) -> list[dict]:
    soup = BeautifulSoup(html_text, "html.parser")
    failures = []
    for field in PRESERVED_FIELDS:
        expected = card[field]
        if expected not in html_text:
            failures.append({"cardId": card["id"], "locale": locale, "fieldName": field, "reason": "preserved text missing"})
        if "Tagalog" in field or field in {"naturalTagalog", "politeTagalog"}:
            spans = [span.get_text(strip=True) for span in soup.select("span[lang='tl']")]
            if expected not in spans:
                failures.append({"cardId": card["id"], "locale": locale, "fieldName": field, "reason": "missing lang=tl span"})
    return failures

Code explanation

  • Business logic: The validator protects the core learning target during localization.
  • Code logic: It checks rendered HTML for exact preserved text and verifies Tagalog spans are marked with lang='tl'.
  • Expected result: The build fails if localized pages accidentally translate or remove Tagalog practice phrases.

Hands-on Lab C — Create localized copy status reports

Developer action

  • Ask Kiro to create a report for all localized fields per card and article.
  • Track whether each Chinese meaning, grammar explanation, cultural note, and review note is draft or locale-reviewed.
  • Export JSON and CSV reports for zh-HK and zh-TW separately.
  • Add summary counts by locale and status.

Kiro prompt sample

Create a localized copy status report for zh-HK and zh-TW.
Track articleTitle, articleSummary, cardMeaning, grammarExplanation, culturalGuidance, pronunciationExplanation, and reviewNote.
Each item should include locale, sourceId, fieldName, status, reviewerNote, and updatedAt.
Export JSON and CSV files per locale and summarize draft versus locale-reviewed counts.

System design decision

  • Chinese copy review is separate from Tagalog review: Tagalog language review and Chinese localization review have different reviewers and different approval states.
  • Status by field is more useful than status by page: A page can have reviewed labels but draft cultural guidance.
  • Per-locale reports reduce confusion: zh-HK reviewers should not need to filter Taiwan-specific copy, and vice versa.

Code sample — localized_copy_report.py

import csv
import json
from collections import Counter
from pathlib import Path

FIELDS = ["articleTitle", "articleSummary", "cardMeaning", "grammarExplanation", "culturalGuidance", "pronunciationExplanation", "reviewNote"]
COLUMNS = ["locale", "sourceId", "fieldName", "status", "reviewerNote", "updatedAt"]


def build_copy_rows(items: list[dict], locale: str) -> list[dict]:
    rows = []
    for item in items:
        for field in FIELDS:
            meta = item.get("localizedStatus", {}).get(locale, {}).get(field, {})
            rows.append({
                "locale": locale,
                "sourceId": item["id"],
                "fieldName": field,
                "status": meta.get("status", "draft"),
                "reviewerNote": meta.get("reviewerNote", "Needs locale review."),
                "updatedAt": meta.get("updatedAt", "")
            })
    return rows


def write_copy_report(rows: list[dict], locale: str) -> dict:
    summary = Counter(row["status"] for row in rows)
    json_path = Path(f"localized-copy-status-{locale}.json")
    csv_path = Path(f"localized-copy-status-{locale}.csv")
    json_path.write_text(json.dumps({"summary": dict(summary), "items": rows}, indent=2, ensure_ascii=False), encoding="utf-8")
    with csv_path.open("w", newline="", encoding="utf-8") as file:
        writer = csv.DictWriter(file, fieldnames=COLUMNS)
        writer.writeheader()
        writer.writerows(rows)
    return {"json": str(json_path), "csv": str(csv_path), "summary": dict(summary)}

Code explanation

  • Business logic: The report gives locale reviewers a clear queue of draft Chinese copy.
  • Code logic: It expands item-level localization metadata into field-level review rows and writes JSON/CSV outputs.
  • Expected result: Each locale receives a review packet showing what is draft, reviewed, or blocked.

Hands-on Lab D — Add Chinese punctuation and typography checks

Developer action

  • Ask Kiro to create typography checks for localized Chinese copy.
  • Flag mixed straight quotes, repeated spaces, missing Chinese punctuation, and accidental simplified/traditional drift candidates.
  • Keep the check as a warning report first, then decide which rules should fail the build.
  • Ask locale reviewers to approve the final rule set.

Kiro prompt sample

Create a typography validator for zh-HK and zh-TW generated HTML.
Warn about repeated spaces in Chinese text, ASCII quotes around Chinese phrases, missing sentence-ending punctuation in localized notes, and suspected simplified characters in Traditional Chinese pages.
Return JSON warnings with file, locale, snippet, and ruleId.
Do not flag preserved Tagalog text.

System design decision

  • Localization quality includes typography: Even correct translations can look unfinished if punctuation and spacing are inconsistent.
  • Warnings before failures are safer: Some typography rules are editorial preferences; reviewers should approve which rules become release gates.
  • Preserved Tagalog must be excluded: The validator should not apply Chinese punctuation rules to Tagalog phrases.

Code sample — validate_chinese_typography.py

import json
import re
from pathlib import Path
from bs4 import BeautifulSoup

SIMPLIFIED_CANDIDATES = {"学习", "语法", "发音", "礼貌"}


def localized_text_nodes(html_text: str) -> list[str]:
    soup = BeautifulSoup(html_text, "html.parser")
    for tagalog in soup.select("[lang='tl']"):
        tagalog.extract()
    return [text.strip() for text in soup.stripped_strings if text.strip()]


def typography_warnings(file_path: Path, locale: str) -> list[dict]:
    text_nodes = localized_text_nodes(file_path.read_text(encoding="utf-8"))
    warnings = []
    for text in text_nodes:
        if "  " in text:
            warnings.append({"file": file_path.name, "locale": locale, "ruleId": "double-space", "snippet": text[:80]})
        if re.search(r'"[^"\n]*[\u4e00-\u9fff][^"\n]*"', text):
            warnings.append({"file": file_path.name, "locale": locale, "ruleId": "ascii-quotes", "snippet": text[:80]})
        if any(char in text for char in SIMPLIFIED_CANDIDATES):
            warnings.append({"file": file_path.name, "locale": locale, "ruleId": "simplified-candidate", "snippet": text[:80]})
    return warnings


def write_typography_report(folder: str, locale: str, output_path: str) -> None:
    warnings = []
    for html_file in sorted(Path(folder).glob("*.html")):
        warnings.extend(typography_warnings(html_file, locale))
    Path(output_path).write_text(json.dumps({"warnings": warnings}, indent=2, ensure_ascii=False), encoding="utf-8")

Code explanation

  • Business logic: The validator catches common localization polish issues before reviewer handoff.
  • Code logic: It removes Tagalog spans, scans remaining localized text, and writes warning records.
  • Expected result: zh-HK and zh-TW builds include typography warning reports without misclassifying Tagalog practice phrases.

Hands-on Lab E — Create per-locale release manifests and ZIP evidence

Developer action

  • Ask Kiro to create a manifest for each locale build.
  • Include generated files, card count, label-validation result, preserved-field result, typography warning count, and ZIP name.
  • Write the manifest into each locale output folder.
  • Add the manifest to the ZIP package.

Kiro prompt sample

Create per-locale release manifests for zh-HK and zh-TW builds.
Each manifest should include locale, htmlLang, generatedFiles, cardCount, validationSummary, typographyWarningCount, zipName, and generatedAt.
Write manifest.json into each dist folder and include it in the locale ZIP.

System design decision

  • Each locale is its own release artifact: zh-HK and zh-TW may be reviewed, fixed, and shipped on different schedules.
  • Manifests provide release evidence: Reviewers can see what passed without rerunning every script.
  • ZIP packages should be self-describing: The localized artifact should contain both pages and validation evidence.

Code sample — locale_manifest.py

from datetime import datetime, timezone
import json
from pathlib import Path


def write_locale_manifest(folder: str, locale: str, html_lang: str, zip_name: str, validation_summary: dict) -> Path:
    output_dir = Path(folder)
    html_files = sorted(path.name for path in output_dir.glob("*.html"))
    manifest = {
        "locale": locale,
        "htmlLang": html_lang,
        "generatedAt": datetime.now(timezone.utc).isoformat(),
        "generatedFiles": html_files,
        "cardCount": validation_summary.get("cardCount", 0),
        "validationSummary": validation_summary,
        "typographyWarningCount": validation_summary.get("typographyWarningCount", 0),
        "zipName": zip_name
    }
    manifest_path = output_dir / "manifest.json"
    manifest_path.write_text(json.dumps(manifest, indent=2, ensure_ascii=False), encoding="utf-8")
    return manifest_path

Code explanation

  • Business logic: The manifest makes each localized build auditable and portable.
  • Code logic: It scans generated HTML files, combines validation evidence, and writes a UTF-8 JSON manifest.
  • Expected result: Every zh-HK and zh-TW ZIP includes pages plus release metadata.

Hands-on Lab F — Generate a localization diff packet for reviewers

Developer action

  • Ask Kiro to generate side-by-side diff records for changed localized fields.
  • Include source English, previous zh-HK/zh-TW copy, new zh-HK/zh-TW copy, and preserved Tagalog fields.
  • Export Markdown for human review and JSON for automation.
  • Add empty reviewer decision fields for approval or requested edits.

Kiro prompt sample

Create a localization diff packet for reviewers.
Compare previous and current localized card data.
For each changed localized field, include locale, sourceId, fieldName, sourceEnglish, previousValue, currentValue, preservedTagalogFields, reviewerDecision, and reviewerNote.
Export localization-diff-packet.json and localization-diff-packet.md.

System design decision

  • Reviewers should inspect changes, not entire sites: Diff packets reduce review workload after small localization updates.
  • Preserved Tagalog context helps reviewers judge meaning: Chinese reviewers need to see the Tagalog phrase that the localized explanation supports.
  • Reviewer decisions should round-trip later: Empty decision fields prepare the packet for future import workflows.

Code sample — localization_diff_packet.py

import json
from pathlib import Path


def diff_localized_fields(previous: dict, current: dict, locale: str, fields: list[str]) -> list[dict]:
    changes = []
    for field in fields:
        old = previous.get("localized", {}).get(locale, {}).get(field, "")
        new = current.get("localized", {}).get(locale, {}).get(field, "")
        if old != new:
            changes.append({
                "locale": locale,
                "sourceId": current["id"],
                "fieldName": field,
                "sourceEnglish": current.get("english", ""),
                "previousValue": old,
                "currentValue": new,
                "preservedTagalogFields": {
                    "naturalTagalog": current.get("naturalTagalog", ""),
                    "politeTagalog": current.get("politeTagalog", "")
                },
                "reviewerDecision": "",
                "reviewerNote": ""
            })
    return changes


def write_diff_packet(changes: list[dict], json_path="localization-diff-packet.json", md_path="localization-diff-packet.md") -> None:
    Path(json_path).write_text(json.dumps({"changes": changes}, indent=2, ensure_ascii=False), encoding="utf-8")
    lines = ["# Localization Diff Packet", ""]
    for change in changes:
        lines.extend([
            f"## {change['locale']} — {change['sourceId']} — {change['fieldName']}",
            f"- Source English: {change['sourceEnglish']}",
            f"- Previous: {change['previousValue']}",
            f"- Current: {change['currentValue']}",
            f"- Natural Tagalog: {change['preservedTagalogFields']['naturalTagalog']}",
            f"- Polite Tagalog: {change['preservedTagalogFields']['politeTagalog']}",
            "- Reviewer decision: ",
            ""
        ])
    Path(md_path).write_text("\n".join(lines), encoding="utf-8")

Code explanation

  • Business logic: The diff packet makes locale review focused and traceable.
  • Code logic: It compares selected localized fields, keeps Tagalog context, and writes JSON/Markdown outputs.
  • Expected result: Reviewers can approve or request edits for only the Chinese copy that changed.

Reference architecture notes

  • Kiro capabilities emphasized in this workshop: localization steering, locale-specific terminology governance, preservation testing, Chinese copy status reports, typography validation, per-locale release manifests, and reviewer diff-packet generation.
  • Product scope: zh-HK and zh-TW localized interfaces and explanations for a Tagalog learning product. Tagalog practice text remains preserved for speaking practice and requires native-speaker review.
  • Runtime scope: local Python localization pipeline first. Optional automation can later run the same locale checks in CI before packaging static localized sites.