Programming & Technical Jul 15, 2026

jq Gate Sketch for localization_freeze_receipt_v1.json Weekly Locale Row Diff - 2026

2026 jq gate sketch—weekly localization_freeze_receipt locale row diff after freeze; J1–J6 locale schema (≠ April catalog / March sprint), localization_freeze_weekly_log.jsonl, verify_localization_freeze_weekly.sh.

By GamineAI Team

jq Gate Sketch for localization_freeze_receipt_v1.json Weekly Locale Row Diff - 2026

Pixel-art hero for jq gate sketch localization freeze weekly locale row diff 2026

Week three after localization string freeze evening: localization_freeze_ok: true, Weblate pin hash recorded, Supported languages match the selector. Tuesday someone merges a “tiny” Spanish store blurb hotfix. Thursday a contractor opens Catalan “for soft-launch only.” Monday stand-up asks “did freeze locales drift since last week?” Someone pastes April catalog weekly jq—wrong schema: April diffs Addressables catalog_sha256. March sprint weekly diffs BUILD_RECEIPT sprint columns. Freeze weeks need locale identity—locale IDs, string counts, PO/Weblate pins—week-over-week.

August–October 2026 punish teams that treat the freeze evening L1–L6 latch as forever-honest without a weekly locale row ritual. Silent locale adds and string-count bumps reopen the freeze while BUILD_RECEIPT still says green.

This Programming & Technical sketch ships a weekly instance of localization freeze honesty: localization_freeze_weekly_log.jsonl, weekly receipt fields on localization_freeze_receipt_v1 (or a dated weekly sibling documenting the same freeze pin), verify_localization_freeze_weekly.sh, gates J1–J6 on the locale schema (same letter prefix as April/March; different columns).

Non-repetition note: April catalog jq owns Addressables catalog hashes. March sprint jq owns post-fest BUILD_RECEIPT sprint rows. Freeze evening owns one-evening L1–L6 latch. Freeze challenge owns five-day habit closes. Forward #11 owns Friday capstone row review. This URL owns Monday weekly locale count / hash / ID set diff after freeze.

Pair freeze evening #1, freeze challenge #4, April catalog jq (cousin cadence), Guide #52 / Course 290 / Help #58 forward; forward blog #11.

Why this matters now (August–October 2026)

  1. Freeze evening is a point latch — L6 proves one night; weeks silently add locales without a new freeze.
  2. Soft-launch pressure — Marketing wants “one more language” without reopening L1 (soft-launch windows).
  3. CJK art and string drift travel together — Capsule typography Z passes can land while PO counts change (multilingual capsule).
  4. October upload queues — Discovery of an extra store language on upload week is too late for honest receipts.
  5. Wrong jq cousin ruins CI — Catalog and sprint scripts pass while locale sets lie.

Direct answer: Each ISO week after freeze, append localization_freeze_weekly_log.jsonl, file a weekly receipt with locale_row_diff[], run verify_localization_freeze_weekly.sh, clear J1–J6, set BUILD_RECEIPT localization_freeze_weekly_ok: true. Any locale ID add/remove or unexplained string-count delta requires a documented exception or a new freeze evening.

Who this sketch is for

Audience You will…
Beginner Run Monday locale count / hash one-liners
Facilitator Paste weekly locale diff into #loc-freeze
Engineer Cron Monday 09:00 from freeze through October upload
Producer Block store language edits until J5 honesty clears

Time: ~40 minutes first weekly template; ~5–8 minutes per Monday after scripts pin.

Prerequisites: Freeze evening L6 GREEN; locale_manifest_v1.json path known; jq on CI or facilitator laptop; optional Weblate API/export folder.

Beginner path — Monday checklist (5–10 minutes)

  1. Open last week’s freeze pin path from BUILD_RECEIPT.
  2. Count locales in locale_manifest_v1.json (jq '.locales | length').
  3. Compare to last Monday’s jsonl line—same count?
  4. Hash the manifest file (sha256sum / Get-FileHash).
  5. If count or hash changed without a receipt note → stop shipping store claims; reopen freeze or file exception.
  6. Paste results into stand-up.

Memorize one sentence: April weekly = catalog identity; freeze weekly = locale identity.

Question April catalog jq This freeze locale jq
When? ISO weeks after april_content_update_allowed ISO weeks after localization_freeze_ok
Log file april_content_update_weekly_log.jsonl localization_freeze_weekly_log.jsonl
Anchor Warm catalog / capstone pointer Freeze receipt + Weblate pin
Diff fields catalog_sha256, content hash, RemoteLoadPath locale_ids[], locale_count, strings_per_locale, weblate_pin, manifest_sha256
Prereq Capstone + warm Freeze evening L1–L6
Wrong reuse March sprint schema April catalog schema

Beginner mistake: Appending April catalog lines into a localization folder—use a new jsonl and locale columns once freeze is latched.

Format ladder

Artifact Role
Freeze evening One-evening L1–L6 latch
Freeze challenge Five-day habit closes F1–F5
This jq sketch Weekly locale row diff J1–J6
Forward #11 Friday localization freeze capstone row review Ten-minute promote ritual
April catalog jq Cousin cadence, different columns
Guide #52 forward One tool step

Order: Freeze evening → (optional challenge week) → weekly locale jq through soft-launch/October → Friday #11 capstone review.

Developer path — gates J1–J6 (locale schema)

These J gates belong to localization freeze weekly—not April catalog J1–J6 and not March sprint J1–J6.

Gate Pass criterion
J1 Weekly receipt schema is localization freeze weekly (schema string documents localization_freeze_weekly_v1 or nested weekly block on freeze receipt) and iso_week set
J2 Freeze pointer resolves (localization_freeze_ok true; freeze receipt path present)
J3 Prior ISO week jsonl line exists (or week-1 bootstrap note referencing freeze night)
J4 locale_ids sorted, locale_count matches length, manifest_sha256 non-empty
J5 locale_row_diff[] honest for ID set, counts, pin, and per-locale string totals (no silent adds)
J6 Receipt filed; BUILD_RECEIPT localization_freeze_weekly_ok: true

Weekly receipt template

File as release-evidence/localization/weekly/2026-W36.json (example):

{
  "schema": "localization_freeze_weekly_v1",
  "iso_week": "2026-W36",
  "freeze_pointer": {
    "path": "release-evidence/localization/2026-08-25/localization_freeze_receipt_v1.json",
    "localization_freeze_ok": true,
    "weblate_pin_at_freeze": "a1b2c3d4e5f6789012345678abcdef01"
  },
  "snapshot": {
    "manifest_path": "release-evidence/localization/2026-08-25/locale_manifest_v1.json",
    "manifest_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111",
    "locale_ids": ["de", "en", "es", "fr", "ja", "ko"],
    "locale_count": 6,
    "weblate_pin": "a1b2c3d4e5f6789012345678abcdef01",
    "strings_per_locale": {
      "en": 1840,
      "de": 1840,
      "es": 1840,
      "fr": 1838,
      "ja": 1840,
      "ko": 1840
    },
    "fuzzy_nonzero_locales": []
  },
  "locale_row_diff": [
    {
      "field": "locale_ids",
      "before": ["de", "en", "es", "fr", "ja", "ko"],
      "after": ["de", "en", "es", "fr", "ja", "ko"],
      "delta": "unchanged"
    },
    {
      "field": "locale_count",
      "before": 6,
      "after": 6,
      "delta": "0"
    },
    {
      "field": "manifest_sha256",
      "before": "sha256:1111111111111111111111111111111111111111111111111111111111111111",
      "after": "sha256:1111111111111111111111111111111111111111111111111111111111111111",
      "delta": "unchanged"
    },
    {
      "field": "weblate_pin",
      "before": "a1b2c3d4e5f6789012345678abcdef01",
      "after": "a1b2c3d4e5f6789012345678abcdef01",
      "delta": "unchanged"
    },
    {
      "field": "strings_per_locale.fr",
      "before": 1840,
      "after": 1838,
      "delta": "-2",
      "note": "EXCEPTION-LOC-004: retired two debug strings; freeze amendment logged"
    }
  ],
  "gates": {
    "J1": "GREEN",
    "J2": "GREEN",
    "J3": "GREEN",
    "J4": "GREEN",
    "J5": "GREEN",
    "J6": "GREEN"
  },
  "localization_freeze_weekly_ok": true,
  "notes": "FR -2 with numbered exception; no ID set change"
}

Weekly log (jsonl)

release-evidence/localization/localization_freeze_weekly_log.jsonlone line per ISO week:

{"iso_week":"2026-W35","locale_count":6,"manifest_sha256":"sha256:1111…","weblate_pin":"a1b2c3d4…","locale_ids":["de","en","es","fr","ja","ko"],"receipt":"release-evidence/localization/weekly/2026-W35.json"}
{"iso_week":"2026-W36","locale_count":6,"manifest_sha256":"sha256:1111…","weblate_pin":"a1b2c3d4…","locale_ids":["de","en","es","fr","ja","ko"],"receipt":"release-evidence/localization/weekly/2026-W36.json"}

BUILD_RECEIPT latch fields:

{
  "localization_freeze_ok": true,
  "localization_freeze_weekly_ok": true,
  "localization_freeze_weekly_receipt": "release-evidence/localization/weekly/2026-W36.json"
}

Keep localization_freeze_ok as the night of freeze latch. Weekly OK is ongoing honesty—orthogonal columns.

Copy-paste jq one-liners

Schema + latch

jq -e '.schema == "localization_freeze_weekly_v1"
  and .localization_freeze_weekly_ok == true' \
  release-evidence/localization/weekly/2026-W36.json

Freeze pointer

jq -e '.freeze_pointer.localization_freeze_ok == true' \
  release-evidence/localization/weekly/2026-W36.json

Locale count matches ID array

jq -e '
  (.snapshot.locale_count == (.snapshot.locale_ids | length))
  and (.snapshot.locale_ids | sort == .snapshot.locale_ids)
' release-evidence/localization/weekly/2026-W36.json

Diff vs prior jsonl week (locale set)

PREV=$(jq -s -c '.[-2].locale_ids' release-evidence/localization/localization_freeze_weekly_log.jsonl)
CUR=$(jq -s -c '.[-1].locale_ids' release-evidence/localization/localization_freeze_weekly_log.jsonl)
echo "prev=$PREV"
echo "cur=$CUR"
test "$PREV" = "$CUR"

Manifest hash drift alert

PREV=$(jq -s -r '.[-2].manifest_sha256' release-evidence/localization/localization_freeze_weekly_log.jsonl)
CUR=$(jq -s -r '.[-1].manifest_sha256' release-evidence/localization/localization_freeze_weekly_log.jsonl)
if [ "$PREV" != "$CUR" ]; then
  echo "FAIL: manifest_sha256 changed — require locale_row_diff note or new freeze"
  exit 1
fi

Honest exception for string count only

jq -e '
  any(.locale_row_diff[];
    (.field | startswith("strings_per_locale."))
    and (.note | type == "string")
    and (.note | startswith("EXCEPTION-LOC-"))
  )
  or (all(.locale_row_diff[];
    (.field | startswith("strings_per_locale.") | not)
      or .delta == "unchanged" or .delta == "0"
  ))
' release-evidence/localization/weekly/2026-W36.json

(Adjust the last expression to your studio rule: every string delta needs an EXCEPTION-LOC-### note.)

PowerShell twin (Windows facilitators)

$Weekly = "release-evidence/localization/weekly/2026-W36.json"
$Log = "release-evidence/localization/localization_freeze_weekly_log.jsonl"
$ok = jq -e '.schema == "localization_freeze_weekly_v1" and .localization_freeze_weekly_ok == true' $Weekly
if ($LASTEXITCODE -ne 0) { throw "J1/J6 latch failed" }
$prev = jq -s -c '.[-2].locale_ids' $Log
$cur  = jq -s -c '.[-1].locale_ids' $Log
if ($prev -ne $cur) { throw "locale_ids drifted vs prior week" }
Write-Host "localization_freeze_weekly_ok"

verify_localization_freeze_weekly.sh

#!/usr/bin/env bash
set -euo pipefail
WEEKLY="${1:-release-evidence/localization/weekly/latest.json}"
LOG="${2:-release-evidence/localization/localization_freeze_weekly_log.jsonl}"

jq -e '.schema == "localization_freeze_weekly_v1"' "$WEEKLY" >/dev/null
jq -e '.freeze_pointer.localization_freeze_ok == true' "$WEEKLY" >/dev/null
jq -e '.snapshot.locale_count == (.snapshot.locale_ids | length)' "$WEEKLY" >/dev/null
jq -e '.localization_freeze_weekly_ok == true' "$WEEKLY" >/dev/null

for g in J1 J2 J3 J4 J5 J6; do
  test "$(jq -r --arg g "$g" '.gates[$g]' "$WEEKLY")" = "GREEN"
done

MANIFEST=$(jq -r .snapshot.manifest_path "$WEEKLY")
test -f "$MANIFEST"
test -f "$LOG"

# Prior week bootstrap: allow single-line log on first Monday after freeze
LINES=$(wc -l < "$LOG" | tr -d ' ')
if [ "$LINES" -ge 2 ]; then
  PREV=$(jq -s -c '.[-2].locale_ids' "$LOG")
  CUR=$(jq -s -c '.[-1].locale_ids' "$LOG")
  if [ "$PREV" != "$CUR" ]; then
    # Allow only if weekly receipt documents locale_ids delta
    jq -e 'any(.locale_row_diff[]; .field == "locale_ids" and .delta != "unchanged")' "$WEEKLY" >/dev/null \
      || { echo "locale_ids changed without locale_row_diff"; exit 1; }
  fi
fi

echo "localization_freeze_weekly_ok"

Wire to CI as a Monday job:

# example GitHub Actions fragment
- name: localization freeze weekly
  run: |
    bash scripts/verify_localization_freeze_weekly.sh \
      "release-evidence/localization/weekly/${{ env.ISO_WEEK }}.json"

Proof table

Artifact Proves Does not prove
Freeze evening L6 Night-of string + parity latch Week-three honesty
Weekly jsonl Locale set / hash history Translation quality
locale_row_diff Honest deltas Capsule typography
Weekly OK latch CI may continue soft ads Dual-SKU depot readiness
Exception notes Documented string retirements Legal / font licenses

Scenarios A–H

A — New locale ID appears in manifest

Fail J5 unless locale_row_diff records add and producer reopens freeze evening (new L1 list). Prefer: new freeze over silent weekly “exception.”

B — Locale removed “because soft-launch dropped KR”

Store claim and in-game selector must match. Diff must show remove; update store Supported languages same day—or fail soft honesty (soft-launch).

C — Weblate pin advanced without string count change

Still a freeze breach if pin was locked. File exception or re-freeze. Weekly jq must show pin delta in locale_row_diff.

D — April catalog jq GREEN, freeze weekly RED

Expected when CDN catalogs move but locale sets drift—different schemas. Do not merge verify scripts.

E — FR string count −2 with EXCEPTION-LOC-004

J5 can GREEN if note present and producer accepted retire. Document msgid list in exception file.

F — Freeze challenge week overlaps Monday ritual

Challenge F gates keep habits; weekly jq still appends jsonl. Do not skip Monday because challenge stand-up happened Tuesday.

G — Multilingual capsule Z6 while weekly locale drift

Art can be GREEN and freeze weekly RED—block JP/KR soft creatives until weekly OK (capsule typography).

H — First Monday after freeze (bootstrap)

J3 accepts a bootstrap note: prior = freeze-night snapshot written as week-0 line in jsonl. Do not invent fake prior hashes.

Common mistakes

  • Copying April catalog_row_diff field names into localization folders.
  • Sorting locale IDs inconsistently (ja before en one week)—always sort for stable diffs.
  • Updating Weblate pin in chat only—jsonl must change.
  • Letting contractors add “preview locales” outside manifest.
  • Treating fuzzy-zero as weekly proof without recounting strings.
  • Clearing localization_freeze_ok to false just because weekly failed—weekly is separate; reopen with a new freeze if IDs change.
  • Skipping weeks during vacation—append skipped: true with owner, or fail closed next Monday.

Troubleshooting

“jq not found on Windows laptop.” Install jq via scoop/choco, or run CI-only and paste artifacts. PowerShell twin still shells out to jq for JSON honesty.

“String counts disagree between Weblate and PO export.” Pick one source of truth in freeze evening notes; weekly must use the same path.

“Manifest path moved.” Update freeze pointer and note path migration in weekly notes; hash the new file—don’t edit old weekly lines.

“Producer wants Catalan for press only.” Either add to manifest + re-freeze, or refuse store claim. Weekly jq exists to catch the middle ground.

Schedule pairing

When Action
Freeze L6 night Write week-0 jsonl snapshot
Each Monday to October Weekly receipt + verify script
Soft-launch weeks Block language claim edits without J5
Before October upload Confirm last weekly OK + freeze pin unchanged
Friday #11 capstone Row-review weekly trail

Evidence folder layout

release-evidence/localization/
  2026-08-25/
    locale_manifest_v1.json
    localization_freeze_receipt_v1.json
  weekly/
    2026-W35.json
    2026-W36.json
    latest.json   # copy or symlink to current ISO week
  localization_freeze_weekly_log.jsonl
  exceptions/
    EXCEPTION-LOC-004.md

CI severity matrix

Failure Severity Action
Schema wrong / latch false Block merge Fix receipt
locale_ids drift no diff Block release Re-freeze or document
manifest hash drift unexplained Block store publish Diff review
string count delta with exception Warn + require LQA sign Continue if signed
Skip week without note Block following Monday Backfill jsonl

Micro-studio capacity

Team Approach
Solo 8-minute Monday terminal ritual + jsonl append
2–3 Eng owns verify; producer owns exceptions
With LQA LQA signs string-count deltas; eng owns ID set

Generating Monday snapshots from locale_manifest_v1.json

Assume freeze locked a manifest shaped like:

{
  "schema": "locale_manifest_v1",
  "locales": [
    {"id": "en", "store_claim": true, "string_count": 1840},
    {"id": "ja", "store_claim": true, "string_count": 1840}
  ]
}

Extract weekly snapshot columns:

MANIFEST=release-evidence/localization/2026-08-25/locale_manifest_v1.json
jq -c '{
  locale_ids: [.locales[].id] | sort,
  locale_count: (.locales | length),
  strings_per_locale: (reduce .locales[] as $l ({}; .[$l.id] = $l.string_count))
}' "$MANIFEST"

Hash for jsonl:

# Linux/macOS
sha256sum "$MANIFEST" | awk '{print "sha256:" $1}'
# PowerShell
(Get-FileHash $MANIFEST -Algorithm SHA256).Hash.ToLower() | ForEach-Object { "sha256:$_" }

Write week-0 on freeze night using the same commands so Monday-1 has an honest prior line. Facilitators who only copy screenshot chat into stand-up skip the hash—and fail closed when someone edits store names inside the manifest without adding locales.

Freeze night → Monday handoff card

Paste into the freeze PR description:

## Localization freeze weekly handoff
- Freeze receipt: …
- Manifest path: …
- Week-0 jsonl appended: yes/no
- First Monday owner: …
- Exception series prefix: EXCEPTION-LOC-
- Do not open Weblate writes without new freeze or numbered exception

Producers who skip the handoff card rediscover “which folder is truth?” every Soft-launch panic week.

Pair next — contractor burn-down (#9 published)

Weekly locale jq catches identity drift. It does not catch cash drift: LQA invoices and emergency translator nights that appear while engineering still pays patch contractors. When Monday shows stable locale_ids but finance asks why localization burn doubled, run the localization contractor burn-down worksheet—cash caps sit beside this receipt, not inside it.

FAQ

Is this the same as freeze evening?

No. Evening latches once. Weekly proves the latch still matches disk and exports.

Same as freeze challenge?

Challenge is a five-day social/habit close. Weekly is calendar CI through October.

Can we reuse April verify script?

No. Different schema, fields, and failure modes.

What if we only claim English?

Weekly still trivial-passes with locale_ids: ["en"]—cheap insurance against accidental adds.

Does weekly OK replace typography Z6?

No. Glyph geometry is art; this is locale identity.

How do exceptions work?

Numbered EXCEPTION-LOC-### files; reference in locale_row_diff[].note. Capstone #11 should list open exceptions.

When do we stop Monday runs?

After October fest upload closeout—or when a new freeze night starts a new series (new jsonl recommended).

What about Crowdin instead of Weblate?

Same columns: replace weblate_pin with crowdin_pin consistently in schema notes.

Key takeaways

  1. After freeze, run a weekly locale row diff—not April catalog jq.
  2. Gates J1–J6 here mean locale schema, not catalog or sprint.
  3. Append localization_freeze_weekly_log.jsonl every ISO week.
  4. Latch localization_freeze_weekly_ok separately from localization_freeze_ok.
  5. Silent locale ID adds fail J5—prefer a new freeze evening.
  6. String-count deltas need numbered EXCEPTION-LOC notes.
  7. Pair freeze evening #1 and challenge #4; forward Friday #11.
  8. Soft-launch must not invent preview languages outside the manifest.
  9. Sort locale_ids for stable diffs.
  10. Guide #52 / Course 290 / Help #58 continue the format ladder.
  11. Bootstrap week-0 from freeze night—don’t invent prior hashes.
  12. Wrong cousin jq (April/March) is a class of CI false greens—keep scripts separated.

Related reads

Closing

Freeze night without Monday honesty is how Catalan appears in Supported languages three weeks later with no receipt. File the weekly locale row diff, keep April catalog jq in its lane, and let localization_freeze_weekly_ok be the boring green light soft-launch and October upload both respect.

When someone asks for one more language “just for soft ads,” the jsonl has an answer: same set, new freeze, or no.