diff --git a/.dev/STATE.md b/.dev/STATE.md index 53d1fe1..83e5c66 100644 --- a/.dev/STATE.md +++ b/.dev/STATE.md @@ -1,4 +1,4 @@ -verified: 2026-07-26 +verified: 2026-08-04 # STATE @@ -10,13 +10,14 @@ Roadmap detail lives in [PLAN.md](PLAN.md), not here. - **Week of 2026-07-27**: resume into Phase 2 per the work-plan issue (#198 — opened at Wave 1 close). First gate: reformulate the round-trip invariant ([`D-2026-07-24-tech-debt-audit-boundaries.md`](decisions/D-2026-07-24-tech-debt-audit-boundaries.md)). - The release decision is taken — v0.24.0 is cut (below). Wave 2 of the audit + v0.24.0 is cut; **v0.25.0 is prepared but not yet released** — PR #242 is open and the three + tags are uncut, so `@v0` still resolves to v0.24.0. Wave 2 of the audit (#169–#176 + backlog #177) remains available. - **Malayalam** — `ml` config landed in v0.24.0 (PR #71). The harness now drives it as a first-class third language and it passes 26/26. Its two seed reference translations are machine drafts awaiting native review (#207); the benchmark's Phase 1 (#194) is unrun. - **Glossary PR #69** (ja) — open, awaiting native review + a `LANGUAGE_CONFIGS` entry. -- **#210 — merged to `main` and CONFIRMED end-to-end; unreleased** (#214, 2026-07-26). Review +- **#210 — merged to `main` and CONFIRMED end-to-end; lands in v0.25.0** (#214, 2026-07-26). Review mode partitions source-PR deletions out before the F40 guard, reports a deletion-only PR with no model calls and an `editor` route, and gates a target deletion the source PR did not make as a blocker. Non-404 target-fetch failures now fail the run (the loop's catch-all is gone), @@ -34,6 +35,16 @@ Roadmap detail lives in [PLAN.md](PLAN.md), not here. ## Recently landed +- **v0.25.0** (2026-08-04) — ships everything since Wave 1: the #192 trust-gated workflow + templates, #117 demand-driven bibliography backfill (turns previously-green runs red by + design when a key resolves nowhere), #210 deletion partitioning (deletion-only PRs stop + failing review), the #202 one-version E2E harness, #237 ml packet rulings and #241 fr + editor rules + glossary v1.1. Moving `@v0` deploys all of it estate-wide at once. Watch: + the first organic **fr** review after the tag move — the new register rules feed review + mode and could not be exercised locally (no fr harness lane). The deployed estate's sync + workflows were already hand-gated (#220, closed); this release makes `translate setup` + and every documented template ship the gated shape. + - **#192 — the `\translate-resync` trust gate, CLOSED across all three rollout steps** (2026-07-26, #219 + QuantEcon/lecture-python-intro#805 + QuantEcon/lecture-python-programming#586; estate tracked in #220, also closed). The trigger diff --git a/AGENTS.md b/AGENTS.md index 0ef38af..5e490a8 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -179,7 +179,7 @@ End-to-end testing against real GitHub repos. Creates test PRs that trigger the ```bash ./tool-test-action-on-github/test-action-on-github.sh # main HEAD ./tool-test-action-on-github/test-action-on-github.sh --dry-run # Preview only -./tool-test-action-on-github/test-action-on-github.sh --action-ref v0.24.0 # Release gate +./tool-test-action-on-github/test-action-on-github.sh --action-ref vX.Y.Z # Release gate ./tool-test-action-on-github/test-action-on-github.sh --action-ref v0 # Post-release smoke ``` diff --git a/CHANGELOG.md b/CHANGELOG.md index 5d9ebed..50d9043 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [Unreleased] +## [0.25.0] - 2026-08-04 ### Security - **The `\translate-resync` comment trigger is gated on commenter trust, and the sync workflow's job token drops to read-only** (#192, absorbing #138; surfaced by Copilot on QuantEcon/test-translation-sync#671 and QuantEcon/lecture-python.myst#979): every documented copy of the source-sync workflow fired on *any* commenter. `issue_comment` workflows run in default-branch context with full access to secrets, and GitHub cannot filter the event by comment body at the trigger level — so the `if:` is the only gate, and it checked only that the body contained the magic string. Any GitHub account could comment `\translate-resync` on a merged PR and spend Anthropic credits and runner minutes at will, repeatedly. The commenter controls nothing but the trigger (translated content comes from the repo), so this is cost abuse rather than code execution — but it was live in the canonical template and therefore on every deployed instance. Two smaller holes came with it: the condition never required `github.event.issue.pull_request`, so a comment on a plain **issue** fired a run too; and the generated workflow carried no `permissions:` block at all, leaving the ambient `GITHUB_TOKEN` at whatever the repo default is. **Now** the `issue_comment` clause requires all four conditions — a comment on a PR, the command, and an author in `["OWNER", "MEMBER", "COLLABORATOR"]` — and the job declares `permissions: contents: read`, since the action authenticates to the target repo with the PAT input and checkout is the ambient token's only consumer. `CONTRIBUTOR` (anyone with one merged PR) is deliberately excluded: `src/inputs.ts` has always enforced exactly this three-way set *inside* the action, so admitting it at the workflow level would only buy a billed run that then no-ops — the outer gate has to be at least as tight as the inner one. The fix lands in all **fourteen** in-repo copies at once (the scaffolder in `src/cli/commands/setup.ts`, twelve documented copies across README, `examples/`, quickstart, action-reference and the three tutorials, and the E2E harness template) plus the FAQ's stated requirements, because the exposure was never one file — each new doc page had copied the shape from an older one. A new guard in `workflow-templates.test.ts` **sweeps** the publishable surfaces rather than enumerating them: it parses every workflow it finds under `README.md`, `examples/`, `docs/`, `tool-test-action-on-github/` and `.github/`, plus the scaffolder's generated output, and fails per job on a missing condition, a missing `contents: read`, or any surviving copy of the pre-fix one-line form — so a doc page added tomorrow is covered the day it lands. It also asserts the workflow's association set still matches `TRUSTED_ASSOCIATIONS` in `inputs.ts`, which is the invariant that keeps the two gates from drifting apart. The shape is the one already deployed on QuantEcon/lecture-python.myst, where both trigger branches have fired since 2026-07-22 — the folded `if:` is not a theory. Deployed instances still need the same edit; this ships the template they are copied from. diff --git a/README.md b/README.md index b5ccc86..9a92c60 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ A GitHub Action and CLI tool for managing translations of MyST Markdown documents using Claude AI. -**Version**: v0.24.0 | [Full Documentation](docs/) +**Version**: v0.25.0 | [Full Documentation](docs/) ## What it does diff --git a/docs/developer/architecture.md b/docs/developer/architecture.md index 5bf334b..9cf0d7d 100644 --- a/docs/developer/architecture.md +++ b/docs/developer/architecture.md @@ -4,7 +4,7 @@ title: Architecture # Architecture -**Last Updated**: 25 July 2026 — v0.24.0 +**Last Updated**: 4 August 2026 — v0.25.0 This document covers the complete system architecture: design philosophy, operational modes, module structure, data flow, and key design decisions. diff --git a/docs/index.md b/docs/index.md index 3f4940b..ee57e04 100644 --- a/docs/index.md +++ b/docs/index.md @@ -82,7 +82,7 @@ Step-by-step guides for common scenarios: ## Current status -**Version**: v0.24.0 +**Version**: v0.25.0 **Tests**: run `npm test` for current counts (exact count in CI) -**Glossary**: 357 terms (zh-cn, fa), 364 (fr), 52 (ml) +**Glossary**: 357 terms (zh-cn, fa), 367 (fr), 57 (ml) **Languages**: English → Simplified Chinese, Farsi, French, Malayalam (more planned) diff --git a/package-lock.json b/package-lock.json index 6985a9a..f10082a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "action-translation", - "version": "0.24.0", + "version": "0.25.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "action-translation", - "version": "0.24.0", + "version": "0.25.0", "license": "MIT", "dependencies": { "@actions/core": "^2.0.3", diff --git a/package.json b/package.json index 4bb6c29..8f405b7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "action-translation", - "version": "0.24.0", + "version": "0.25.0", "private": true, "type": "module", "description": "GitHub Action to sync and review translations across repositories", diff --git a/tool-test-action-on-github/README.md b/tool-test-action-on-github/README.md index 1c655ea..0ed13cd 100644 --- a/tool-test-action-on-github/README.md +++ b/tool-test-action-on-github/README.md @@ -38,7 +38,7 @@ The ref defaults to `main`, which is the code you are working on. Override it fo ```bash ./test-action-on-github.sh # main HEAD (development) -./test-action-on-github.sh --action-ref v0.24.0 # a specific release (the gate) +./test-action-on-github.sh --action-ref vX.Y.Z # a specific release (the gate) ./test-action-on-github.sh --action-ref v0 # the floating tag (post-release smoke) ```