okstra 0.194.0 → 0.195.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/lifecycle/config.mjs +7 -6
- package/dist/commands/lifecycle/config.mjs.map +1 -1
- package/docs/architecture.md +1 -1
- package/docs/cli.md +1 -1
- package/docs/for-ai/skills/okstra-setup.md +1 -1
- package/docs/project-structure-overview.md +2 -2
- package/package.json +1 -1
- package/runtime/BUILD.json +2 -2
- package/runtime/agents/workers/translator-worker.md +1 -1
- package/runtime/bin/okstra-inject-report-index.py +3 -4
- package/runtime/bin/okstra-report-translate.py +2 -60
- package/runtime/prompts/lead/okstra-lead-contract.md +2 -2
- package/runtime/prompts/lead/report-writer.md +8 -9
- package/runtime/prompts/profiles/_implementation-deliverable.md +1 -1
- package/runtime/python/okstra_ctl/i18n.py +11 -6
- package/runtime/python/okstra_ctl/render_final_report.py +5 -9
- package/runtime/python/okstra_ctl/report_finalize.py +9 -31
- package/runtime/python/okstra_ctl/report_html/render.py +1 -11
- package/runtime/python/okstra_ctl/report_language.py +17 -32
- package/runtime/python/okstra_ctl/report_translation.py +0 -51
- package/runtime/python/okstra_ctl/report_translation_dispatch.py +2 -6
- package/runtime/skills/okstra-setup/SKILL.md +3 -2
- package/runtime/skills/okstra-setup/references/project-config.md +6 -7
- package/runtime/templates/reports/html/macros/layout.html +4 -0
- package/runtime/templates/reports/html/tasks/implementation.template.html +2 -2
- package/runtime/templates/reports/html/tasks/release-handoff.template.html +2 -2
- package/runtime/validators/validate-run.py +0 -31
|
@@ -16,9 +16,10 @@ Supported keys (CLI alias -> JSON field):
|
|
|
16
16
|
only) relative to <project-root>.
|
|
17
17
|
|
|
18
18
|
report-language -> reportLanguage
|
|
19
|
-
Final-report language
|
|
20
|
-
|
|
21
|
-
the
|
|
19
|
+
Final-report language as a language tag
|
|
20
|
+
(en, ko, fr, pt-BR, ...). The Phase 7 translator
|
|
21
|
+
translates the human HTML into it; the data.json
|
|
22
|
+
stays English.
|
|
22
23
|
|
|
23
24
|
Usage:
|
|
24
25
|
okstra config get <key> [--scope project|global|all]
|
|
@@ -66,9 +67,9 @@ const KEYS = {
|
|
|
66
67
|
jsonField: "reportLanguage",
|
|
67
68
|
scopes: ["project", "global"],
|
|
68
69
|
validate(value) {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
70
|
+
if (typeof value !== "string" || !/^[a-z]{2,3}(-[A-Za-z0-9]{2,8})*$/.test(value)) {
|
|
71
|
+
return ("value must be a language tag such as en, ko, fr or pt-BR " +
|
|
72
|
+
`(got ${JSON.stringify(value)})`);
|
|
72
73
|
}
|
|
73
74
|
return null;
|
|
74
75
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.mjs","sourceRoot":"","sources":["../../../src/commands/lifecycle/config.mts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"config.mjs","sourceRoot":"","sources":["../../../src/commands/lifecycle/config.mts"],"names":[],"mappings":"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"}
|
package/docs/architecture.md
CHANGED
|
@@ -863,7 +863,7 @@ The manifest-provided `lead-events-*.jsonl` file is the canonical record for str
|
|
|
863
863
|
|
|
864
864
|
`activityContractVersion: 1` is an interpretation version for new `implementation-planning` artifacts. A run without that field remains a historical run and does not require activity events or an `agentActivity[]` projection.
|
|
865
865
|
|
|
866
|
-
The shared `okstra report-finalize` entrypoint reads canonical activity before translation
|
|
866
|
+
The shared `okstra report-finalize` entrypoint reads canonical activity before translation. Under contract v3 its in-process `project-activity` step assembles the report, filtering events by run identity and validating activity ID order before `agentActivity[]` is published. A schema-invalid composed record is still published so `validate-run` can scan it; the step itself fails. A historical v2 manifest retains the in-place projection path. A failed Phase 7 step does not skip later checks: `validate-run` still runs, and only `record-group-memory` and `teardown-stages` are skipped. For a non-English report, the `translate` step directly before `render-views` materializes and dispatches the translator worker itself (`okstra_ctl.report_translation_dispatch`) and requires the `*.i18n.<lang>.json` sidecar; the lead no longer splits the sequence around a manual dispatch. Conformance compares the resulting `agentActivity[]` IDs, order, and core fields with the canonical events for every lead host.
|
|
867
867
|
|
|
868
868
|
Approval blockers use `open`, `answered`, `resolved`, and `obsolete`. `open` blocks until the user judges. `answered` with `accept-risk` / `select` / `answer` does not block approval or the next phase; the DISAGREE votes stay on the plan item as evidence. A response sidecar with a proceeding disposition unblocks the same way. `request-revision` and `reject` still withhold the next phase until this report's `supersessionLedger` records that the answer was incorporated (`superseded` or `no-dependent-statement`).
|
|
869
869
|
|
package/docs/cli.md
CHANGED
|
@@ -847,7 +847,7 @@ The `okstra` Node CLI (`bin/okstra`) provides both installer/admin commands and
|
|
|
847
847
|
| `okstra approval-decision <open\|resolve\|carry> --ledger <approval-decisions.json> …` | Write the lead-owned clarification and approval ledger. `open` validates classification-specific dispositions and complete option fields, `resolve` requires real `A-NNN` check references, and `carry` keeps prior resolved decisions outside the active clarification list. `carry --from-responses <instruction-set/clarification-response.md>` is the source of truth for an answer given in an earlier run: the bundle is task-level and cumulative, each response section names the report that posed the question, and `--clarification-id` repeats to carry several ids in one call. `carry --source-ledger` remains for a prior run's ledger that is still on disk and needs `--source-run-ref`. Prepare seeds `carriedDecisions[]` itself when it creates a run's ledger from a `--clarification-response` that names a report record — every row that record answered or resolved, plus rows its user-responses sidecars answered (`scripts/okstra_ctl/approval_decisions.py` `seed_carried_decisions`) — so `carry` is for ids that record does not answer. |
|
|
848
848
|
| `okstra design-snapshot --narrative <report-narrative.md> --output <design-preparation.json>` | Detect implementation-planning design surfaces and write the detector-owned snapshot consumed by final report assembly. |
|
|
849
849
|
| `okstra plan-verify --narrative <report-narrative.md> --state <plan-body-verification.json>` | Recompute the plan-body gate from the convergence-owned state before `data.json` publication. `--report <historical-data.json>` remains the v2 reader. |
|
|
850
|
-
| `okstra report-finalize --project-root <dir> --run-manifest <path> --report <final-report.md>` | Run Phase 7 in the manifest's contract order. Contract v3 collects usage into team state, assembles all single-owner inputs into `data.json` once,
|
|
850
|
+
| `okstra report-finalize --project-root <dir> --run-manifest <path> --report <final-report.md>` | Run Phase 7 in the manifest's contract order. Contract v3 collects usage into team state, assembles all single-owner inputs into `data.json` once, translates (`translate`: for a non-English `reportLanguage` it materializes and dispatches the translator worker unless the `*.i18n.<lang>.json` sidecar already exists, and fails when the worker leaves none), then renders with that sidecar overlaid, spawns follow-ups, validates, records the run's conclusion and the group's start order into the task-group's `group-context.md` (`record-group-memory`, creating the file when absent), and tears down eligible stage worktrees. Contract v2 retains its historical in-place projection sequence as a read-only compatibility path. A failed step still runs every later check through `validate-run`; `record-group-memory` and `teardown-stages` are skipped so a failed run neither hands an unvalidated conclusion to sibling tasks nor reclaims worktrees. The result carries `nextInGroup` (the first task in start order not yet started) and, for a terminal pointer, `nextCommand` closes on starting it from its brief. Reports each step and prints the ordered `--only` recovery tail from the earliest failure. This is the shared path for every lead adapter. |
|
|
851
851
|
| `okstra render-views <final-report.data.json\|final-report.md>` | The Phase 7 `render-views` step, runnable on its own. Schema v2 data is rendered directly, and schema v3 data uses the same always-generated, task-specific human HTML path. The full reading copy uses `templates/reports/final-report-v2.template.md` and is rendered on demand with `okstra render-final-report`. Passing the Markdown sibling locates the same data.json. Schema v1 and quick reports keep the legacy conditional renderer. The Node wrapper calls `scripts/okstra-render-report-views.py`; `validators/validate-report-views.py` verifies source/schema/template digests, required human fields, form controls, external assets, diagram/table ID parity, Response ID parity, and that every in-page `href="#…"` lands on an element of the page. For a non-English report the command prints two counts: `translated N string(s) into <lang> (M left in English, K unresolved)` from the sidecar overlay, and `rendered R line(s) still in English on the <lang> page` from the written page itself — the second sees fields the extractor does not offer, so `M = 0` with `R > 0` means a reader-facing key is missing from `PROSE_KEYS`. |
|
|
852
852
|
| `okstra design-prep <list\|show\|write>` | Review AI-prepared implementation design requests, inspect their effective confirmed response, or append a confirmed user/wizard response without editing the planning report |
|
|
853
853
|
| `okstra wizard <init\|step\|render-args\|confirmation\|outcome> --state-file <path>` | Interactive input state machine for okstra-run, implemented by `okstra_ctl.wizard`. Seed a state file with `init`, then repeatedly call `step --answer <val>` to receive the next `Prompt` JSON. `--answer` is **required**; use `--no-submit` to peek at the next prompt without submitting a response. A `pick` with more choices than the host picker can display keeps `kind: "pick"` but adds `presentation: "numbered-text"`; render every option as a numbered Markdown list and submit the user's 1-based number, exact value, or exact label. Invalid, out-of-range, and ambiguous answers re-prompt without dropping choices. `render-args` returns the final `render-bundle` argument map, and `confirmation` returns the user echo block. On a completed wizard, `outcome` returns `renderArgs`, `persistActions`, and `confirmationText` together; project/global release-handoff PR-template persistence appears as `persistActions[].command == "config.set"`. For an `implementation` task type, `stage_pick` follows `approved_plan_pick` and selects the stage before `executor_pick`. The brief step appears only for entry task types—requirements-discovery, error-analysis, improvement-discovery, project-analysis, feature-analysis, and change-impact-analysis. Analysis inputs use `feature_evidence_pick` / `feature_evidence`, `project_evidence_pick` / `project_evidence`, and `analysis_target_pick` / `analysis_target`; a revision-requested report prioritizes its same-task, same-type rerun. Downstream lifecycle phases automatically carry the manifest brief, with a three-option `brief_carry` fallback when none is registered; `release-handoff` has no brief and enters multi-select `handoff_stage_pick` for eligible stage groups or the whole task |
|
|
@@ -104,7 +104,7 @@ Optional settings:
|
|
|
104
104
|
a user-owned advisory when the environment is unavailable or the result is
|
|
105
105
|
non-PASS.
|
|
106
106
|
- PR body template: `okstra config set pr-template-path "<path>" --scope project|global`
|
|
107
|
-
- final report language: `okstra config set report-language <
|
|
107
|
+
- final report language: `okstra config set report-language <language-tag> --scope project` (`en`, `ko`, `fr`, `pt-BR`, …; default `en`)
|
|
108
108
|
- `architecture.style`: the project's declared architecture — `hexagonal`,
|
|
109
109
|
`layered`, or `none` (default `none` when absent, unrecognized, or
|
|
110
110
|
unreadable). `okstra setup` never writes it; hand-add it to `project.json`
|
|
@@ -345,7 +345,7 @@ Important modules:
|
|
|
345
345
|
| `lead_events.py` | Structured JSONL events emitted by artifact-accounted lead runtimes. Its locked append path assigns monotonic `A-NNN` identifiers to activity events in the same canonical event file. |
|
|
346
346
|
| `worker_prompt_headers.py` | shared rendering of phase-aware worker prompt anchors (`worker_prompt_headers`): coding-preflight only for implementation and compact target identity for final-verification |
|
|
347
347
|
| `worker_prompt_body.py` | provider-neutral initial analysis body/input renderer shared by Codex and external/team dispatch paths |
|
|
348
|
-
| `report_language.py` | report-writer `**Report Language:**` resolution (`resolve_report_language`) — precedence project config → global config →
|
|
348
|
+
| `report_language.py` | report-writer `**Report Language:**` resolution (`resolve_report_language`) — precedence project config → global config → `en`; the value is a language tag the Phase 7 translator translates into, shared by both dispatchers so the stamped language does not depend on which dispatch path ran |
|
|
349
349
|
| `worker_prompt_policy.py` | `PromptPlan` generating SSOT — resolves functional audience, equality group, packet-only input, coding-preflight eligibility, required headers, and size limits without consulting provider/model identity |
|
|
350
350
|
| `worker_prompt_contract.py` | deterministic cross-task initial-prompt validator and normalized cross-worker equality SSOT, reused by dispatch adapters and the Phase 7 persisted-artifact validator |
|
|
351
351
|
| `initial_prompt_materialization.py` | sole owner of roster-derived initial prompt rendering, request compatibility checks, contract validation, and immutable create-if-absent publication; exposes `materialize_initial_prompts(InitialPromptMaterializationRequest) -> tuple[Path, ...]` |
|
|
@@ -360,7 +360,7 @@ Important modules:
|
|
|
360
360
|
| `scope_provenance.py` | single source of truth for the scope-provenance grammar every phase-emitted requirement must declare, shared by `validators/validate-run.py` and `validators/validate_fanout.py` so the planning report and fan-out packets cannot drift |
|
|
361
361
|
| `worker_artifact_paths.py` | canonical worker artifact path derivation (e.g. `audit_sidecar_rel` inserts `-audit-` after the first `-worker-` token), so dispatch and validation agree on non-canonical-path rejection |
|
|
362
362
|
| `report_translation_dispatch.py` | Phase 7 `translate` step — for a non-English `reportLanguage` and no `*.i18n.<lang>.json` sidecar, reuses or materializes this run's translator reservation (`agent-prompt materialize --audience translator` in-process, instruction file under `state/`), runs the CLI-wrapper dispatch, and succeeds only when the sidecar exists afterwards. Replaces the manual lead sequence that was skipped in practice |
|
|
363
|
-
| `report_finalize.py` | Phase 7 post-report sequence **SSOT** — runs `
|
|
363
|
+
| `report_finalize.py` | Phase 7 post-report sequence **SSOT** — runs `translate` → `token-usage` → `render-views` → `spawn-followups` → `validate-run` → `record-group-memory` → `teardown-stages` in that load-bearing order. A non-zero exit still runs every later check through `validate-run` and names the earliest failure; `record-group-memory` (this run's conclusion into the task-group's `group-context.md`, plus `nextInGroup` for the closeout) and `teardown-stages` are skipped when any earlier step failed. Both lead paths converge here: the Codex adapter calls it in-process (`codex_dispatch`), a Claude-led run reaches it through `okstra report-finalize`. Neither reimplements the sequence |
|
|
364
364
|
| `wrapper_status.py` | worker wrapper status sidecar reader — the host-side reader of the sidecar `worker_runner.py` writes. `is_terminal` is the one question it answers for the dispatch record and the pane reclaim: does `stage` read `exited` |
|
|
365
365
|
| `worker_runner.py` | runs one worker CLI and records what happened — shared by every provider entrypoint. Owns the `selectors` pump over the child's streams, the stream-arrival idle watchdog (`killpg` on breach), the run-wide progress cap on the log copy, and the status sidecar's whole life. A run that dies after launch still closes its sidecar, so `worker_liveness` never reads a dead worker as running |
|
|
366
366
|
| `session_transcript.py` | worker session transcript — one line per event (time, speaker, body) with a run-wide progress-line cap (`LOG_LINE_CAP`, elision notice) so a single-file dispatch's tool echo cannot dominate the project's `.okstra/` bytes; the fixed shape lets a later lead write share the same file |
|
package/package.json
CHANGED
package/runtime/BUILD.json
CHANGED
|
@@ -24,7 +24,7 @@ roster.
|
|
|
24
24
|
|
|
25
25
|
## Procedure
|
|
26
26
|
|
|
27
|
-
1. Read your dispatch prompt's `**Report Language:**` header. It is
|
|
27
|
+
1. Read your dispatch prompt's `**Report Language:**` header. It is a language tag (`ko`, `fr`, `pt-BR`, …); translate into that language.
|
|
28
28
|
2. Build your work list:
|
|
29
29
|
|
|
30
30
|
```bash
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
Usage:
|
|
5
5
|
python3 scripts/okstra-inject-report-index.py \\
|
|
6
6
|
<final-report.md> \\
|
|
7
|
-
[--report-language
|
|
7
|
+
[--report-language <language-tag>]
|
|
8
8
|
|
|
9
9
|
Adds the top-of-report Index (section list + ID index) and `<a id="...">`
|
|
10
10
|
scroll anchors to a markdown report that was authored *free-form* rather
|
|
@@ -26,7 +26,6 @@ from okstra_bootstrap import prefer_colocated_modules # noqa: E402
|
|
|
26
26
|
|
|
27
27
|
prefer_colocated_modules(__file__, "okstra_ctl/render_final_report.py")
|
|
28
28
|
|
|
29
|
-
from okstra_ctl.i18n import SUPPORTED_LANGS # noqa: E402
|
|
30
29
|
from okstra_ctl.render_final_report import ( # noqa: E402
|
|
31
30
|
FinalReportRenderError,
|
|
32
31
|
inject_index_into_file,
|
|
@@ -45,9 +44,9 @@ def main(argv: list[str]) -> int:
|
|
|
45
44
|
)
|
|
46
45
|
parser.add_argument(
|
|
47
46
|
"--report-language",
|
|
48
|
-
choices=list(SUPPORTED_LANGS),
|
|
49
47
|
default="en",
|
|
50
|
-
help="Language for the index labels
|
|
48
|
+
help="Language tag for the index labels; a language without its own "
|
|
49
|
+
"dictionary gets the English labels. Default: en.",
|
|
51
50
|
)
|
|
52
51
|
args = parser.parse_args(argv)
|
|
53
52
|
|
|
@@ -8,10 +8,7 @@ Usage:
|
|
|
8
8
|
``extract`` writes the translator's work list — every pointer the report holds
|
|
9
9
|
a translatable string at, paired with the English text. The translator fills
|
|
10
10
|
in the values rather than authoring pointers, so a sidecar cannot cite a path
|
|
11
|
-
the document does not have.
|
|
12
|
-
Korean-prose limit: the work list would pair every pointer with target-language
|
|
13
|
-
text, and the translator would spend a full pass translating a document into
|
|
14
|
-
the language it is already in.
|
|
11
|
+
the document does not have.
|
|
15
12
|
|
|
16
13
|
``check`` is the translator's own gate before it returns: it resolves every
|
|
17
14
|
pointer in the sidecar against the report and reports what is still English.
|
|
@@ -35,12 +32,7 @@ from okstra_bootstrap import prefer_colocated_modules # noqa: E402
|
|
|
35
32
|
|
|
36
33
|
prefer_colocated_modules(__file__, "okstra_ctl/report_translation.py")
|
|
37
34
|
|
|
38
|
-
from okstra_ctl.report_translation import
|
|
39
|
-
HANGUL_PROSE_LIMIT,
|
|
40
|
-
extract,
|
|
41
|
-
hangul_share,
|
|
42
|
-
overlay,
|
|
43
|
-
)
|
|
35
|
+
from okstra_ctl.report_translation import extract, overlay # noqa: E402
|
|
44
36
|
from okstra_ctl.final_report_paths import ( # noqa: E402
|
|
45
37
|
translation_sidecar_path,
|
|
46
38
|
translation_source_path,
|
|
@@ -118,31 +110,9 @@ def _validate_source_payload(
|
|
|
118
110
|
)
|
|
119
111
|
|
|
120
112
|
|
|
121
|
-
def _english_source_failure(data_path: Path, data: dict) -> str | None:
|
|
122
|
-
"""The Korean-prose message for *data*, or None when it reads as English."""
|
|
123
|
-
share, _ = hangul_share(data)
|
|
124
|
-
if share < HANGUL_PROSE_LIMIT:
|
|
125
|
-
return None
|
|
126
|
-
return (
|
|
127
|
-
f"error: {data_path.name} was authored in Korean "
|
|
128
|
-
f"({share:.0%} of its prose, limit {HANGUL_PROSE_LIMIT:.0%}). "
|
|
129
|
-
"The data.json is the English SSOT every later phase reads; the "
|
|
130
|
-
"report language selects the human HTML's language and is served "
|
|
131
|
-
"by the Phase 7 translator, not by authoring the SSOT in it.\n"
|
|
132
|
-
)
|
|
133
|
-
|
|
134
|
-
|
|
135
113
|
def cmd_extract(args: argparse.Namespace) -> int:
|
|
136
114
|
data_path = Path(args.data).resolve()
|
|
137
115
|
data = _load(data_path)
|
|
138
|
-
# Refuse before building the work list. Extracting from a Korean SSOT
|
|
139
|
-
# produces a translation from the target language into itself: a
|
|
140
|
-
# full-cost artifact whose English column is not English, discovered
|
|
141
|
-
# only later when `check-source` fails the finalize step.
|
|
142
|
-
failure = _english_source_failure(data_path, data)
|
|
143
|
-
if failure is not None:
|
|
144
|
-
sys.stderr.write(failure)
|
|
145
|
-
return 1
|
|
146
116
|
strings = extract(data)
|
|
147
117
|
out_path = translation_source_path(data_path)
|
|
148
118
|
lang = str((data.get("meta") or {}).get("reportLanguage") or "")
|
|
@@ -171,10 +141,6 @@ def cmd_source(args: argparse.Namespace) -> int:
|
|
|
171
141
|
authority, data_path = _translation_authority(Path(args.run_manifest))
|
|
172
142
|
snapshot = _report_snapshot(data_path)
|
|
173
143
|
data = snapshot.value
|
|
174
|
-
failure = _english_source_failure(data_path, data)
|
|
175
|
-
if failure is not None:
|
|
176
|
-
sys.stderr.write(failure)
|
|
177
|
-
return 1
|
|
178
144
|
payload = _source_payload(authority, data_path, snapshot.raw_bytes, data)
|
|
179
145
|
out_path = translation_source_path(data_path)
|
|
180
146
|
if out_path.is_symlink():
|
|
@@ -352,24 +318,6 @@ def _check_sidecar(sidecar_file: Path) -> tuple[dict, int]:
|
|
|
352
318
|
return payload, 0
|
|
353
319
|
|
|
354
320
|
|
|
355
|
-
def cmd_check_source(args: argparse.Namespace) -> int:
|
|
356
|
-
data_path = Path(args.data).resolve()
|
|
357
|
-
data = _load(data_path)
|
|
358
|
-
share, length = hangul_share(data)
|
|
359
|
-
failure = _english_source_failure(data_path, data)
|
|
360
|
-
payload = {
|
|
361
|
-
"ok": failure is None,
|
|
362
|
-
"hangulShare": round(share, 4),
|
|
363
|
-
"limit": HANGUL_PROSE_LIMIT,
|
|
364
|
-
"proseChars": length,
|
|
365
|
-
}
|
|
366
|
-
print(json.dumps(payload, ensure_ascii=False))
|
|
367
|
-
if failure is not None:
|
|
368
|
-
sys.stderr.write(failure)
|
|
369
|
-
return 1
|
|
370
|
-
return 0
|
|
371
|
-
|
|
372
|
-
|
|
373
321
|
_CLI_EPILOG = r"""A thin spawn shim over `scripts/okstra-report-translate.py` (installed at
|
|
374
322
|
`$HOME/.okstra/bin/okstra-report-translate.py`).
|
|
375
323
|
|
|
@@ -424,12 +372,6 @@ def _parser() -> argparse.ArgumentParser:
|
|
|
424
372
|
check_cmd = sub.add_parser("check", help="verify a filled sidecar against its report")
|
|
425
373
|
check_cmd.add_argument("sidecar", help="path to final-report-<type>-<seq>.i18n.<lang>.json")
|
|
426
374
|
check_cmd.set_defaults(func=cmd_check)
|
|
427
|
-
|
|
428
|
-
source_cmd = sub.add_parser(
|
|
429
|
-
"check-source", help="verify the data.json itself was authored in English"
|
|
430
|
-
)
|
|
431
|
-
source_cmd.add_argument("data", help="path to final-report-<type>-<seq>.data.json")
|
|
432
|
-
source_cmd.set_defaults(func=cmd_check_source)
|
|
433
375
|
return parser
|
|
434
376
|
|
|
435
377
|
|
|
@@ -464,8 +464,8 @@ The detailed persistence sequence lives in [report-writer](./report-writer.md).
|
|
|
464
464
|
|
|
465
465
|
Order of operations:
|
|
466
466
|
|
|
467
|
-
1. Run `okstra report-finalize ...`. Contract v3 collects usage, assembles the role-owned inputs into `data.json` once,
|
|
468
|
-
2. When `meta.reportLanguage` is not `en`, the same call dispatches the translator: its `translate` step (
|
|
467
|
+
1. Run `okstra report-finalize ...`. Contract v3 collects usage, assembles the role-owned inputs into `data.json` once, renders views, persists follow-ups, validates the run, records this run's conclusion into the task-group's `group-context.md` for the group's sibling tasks, and performs eligible teardown in order. When the task's pointer is terminal and the group has a task not yet started, the result's `nextInGroup` names it and `nextCommand` closes on starting it from its brief — the group's start order is the brief ordinal; the briefs' Related Task Graph edges are quoted as `waits for` and do not reorder it.
|
|
468
|
+
2. When `meta.reportLanguage` is not `en`, the same call dispatches the translator: its `translate` step (directly before `render-views`) materializes the translator prompt when this run has no undispatched reservation, runs the CLI-wrapper dispatch, and requires the `*.i18n.<lang>.json` sidecar. Do not dispatch the translator by hand or split the sequence around it; if the step fails, clear the cause and resume with the `--only translate --only render-views …` hint the result prints (**Enforced:** `okstra_ctl.report_translation_dispatch`).
|
|
469
469
|
|
|
470
470
|
Keep the assigned worker prompt history paths stable in `team-state`, `run-manifest`, and `task-manifest`. Do not rewrite prompt artifacts to `/tmp` or omit prompt metadata for attempted workers.
|
|
471
471
|
|
|
@@ -123,23 +123,22 @@ For historical schema-v1 Markdown only, the following heading table remains a re
|
|
|
123
123
|
|
|
124
124
|
**Enforced:** `okstra_ctl.report_finalize.V3_STEP_ORDER` is the order — `report-finalize` runs the steps from that tuple, so the sequence cannot be reordered by a caller. Running the steps by hand is what this rule forbids, and that path is not reachable through the CLI.
|
|
125
125
|
|
|
126
|
-
Do not run the
|
|
126
|
+
Do not run the eight steps below manually. Invoke `okstra report-finalize`; contract 3.0 runs them in this order:
|
|
127
127
|
|
|
128
128
|
1. **`token-usage`** — collect usage into team state without touching the final record.
|
|
129
129
|
2. **`project-activity`** — report assembly validates every owner input and publishes the final record once.
|
|
130
|
-
3. **`
|
|
131
|
-
4. **`
|
|
132
|
-
5. **`
|
|
133
|
-
6. **`
|
|
134
|
-
7. **`
|
|
135
|
-
8. **`
|
|
136
|
-
9. **`teardown-stages`** — remove eligible stage worktrees after successful validation.
|
|
130
|
+
3. **`translate`** — for a non-English `reportLanguage`, materialize and dispatch the translator worker and require its `*.i18n.<lang>.json` sidecar; a no-op for English or when the sidecar already exists.
|
|
131
|
+
4. **`render-views`** — render the Markdown reading copy and human HTML, with the translation sidecar overlaid.
|
|
132
|
+
5. **`spawn-followups`** — materialize registered follow-up tasks.
|
|
133
|
+
6. **`validate-run`** — validate the record, views, run manifest, and team state.
|
|
134
|
+
7. **`record-group-memory`** — write this run's conclusion (headline, decisions, watch-outs, open follow-ups, record path, next phase) and the group's start order into the task-group's `group-context.md` okstra region, creating the file when the group has none; skipped, like teardown, when an earlier step failed. Sibling tasks read it as `## Task-Group Memory`.
|
|
135
|
+
8. **`teardown-stages`** — remove eligible stage worktrees after successful validation.
|
|
137
136
|
|
|
138
137
|
After `report-finalize` returns, the lead — not the report writer — closes the run with the launch prompt's User closeout: one command the user can run now.
|
|
139
138
|
|
|
140
139
|
### The translation sidecar: the `translate` step
|
|
141
140
|
|
|
142
|
-
`report-finalize` dispatches the translator itself. Its `translate` step runs
|
|
141
|
+
`report-finalize` dispatches the translator itself. Its `translate` step runs directly before `render-views` (which overlays the sidecar), and it is a no-op when `reportLanguage` is `en` or the `*.i18n.<lang>.json` sidecar already exists. When the sidecar is missing, the step reuses this run's undispatched translator reservation if the lead already materialized one, otherwise it materializes the prompt itself — instruction file `state/translator-instructions-<task-type>-<seq>.md` (kept when the lead wrote one), prompt `prompts/translator-worker-prompt-<task-type>-<seq>.md`, `--result worker-results/translator-translations-<task-type>-<seq>.md`, `--audit-source worker-results/translator-worker-<task-type>-<seq>.md`, invocation id `<task-type>-<seq>-translator` (`-r2`, `-r3` after a failed attempt) — then runs the CLI-wrapper dispatch, which records the dispatch and links the result. Do not run `agent-prompt materialize --audience translator` or `worker-dispatch --workers translator` by hand before `report-finalize`; the sequence used to be a manual lead step and was skipped in practice (2026-09-09, fontsninja-v3-site dev-10628-3: a `ko` run finalized in one call, zero translator reservations, English HTML). **Enforced:** `okstra_ctl.report_finalize.V3_STEP_ORDER` places the step; `okstra_ctl.report_translation_dispatch.translate_report` owns it; `_translator_job_from_reservation` in `scripts/okstra_ctl/dispatch_core.py` still refuses two undispatched reservations for one run, which only a hand-made second reservation produces.
|
|
143
142
|
|
|
144
143
|
The step succeeds only when the sidecar exists afterwards; a translator that exits 0 without publishing it fails the step. A failed `translate` does not stop the sequence: `render-views` still writes the view from the English body, `validate-run` records the missing sidecar as an advisory, and the result's resume hint starts at `--only translate --only render-views …` — run that once the cause (a host approval gate, an unavailable provider) is cleared rather than closing the run on an English view.
|
|
145
144
|
|
|
@@ -12,7 +12,7 @@ are collected and convergence finished. Phase 1-5 do not need it.
|
|
|
12
12
|
|
|
13
13
|
- **Plan link & approval evidence**: path to the approved `final-report.md`, the exact quoted approval marker, AND the executed stage number / title quoted from the Stage Map row. For a selected-direction plan, also quote `selectedDirectionRef.optionId`, `snapshotPath`, and the validated snapshot digest; for a legacy plan, quote the effective `implementation-option` or the Recommended Option fallback.
|
|
14
14
|
- **Commit list**: each commit's SHA (or short SHA), message, and the plan step(s) / TDD cycle it satisfies
|
|
15
|
-
- **Diff summary**: `git diff --stat <base
|
|
15
|
+
- **Diff summary**: capture `git diff --stat <base>..<captured-head>` and `git diff --numstat <base>..<captured-head>` for the full implementation stage, including after a fix run. Supply both outputs to the report writer; populate each `diffSummary.files[].lines` with its added/deleted counts and a one-line change summary. Do not substitute a fix-run aggregate or carry forward older statistics. If the captured commits are unavailable, identify the missing reference in the evidence instead of inventing counts.
|
|
16
16
|
- **Out-of-plan edits block**: every file edited that was not in the approved plan's file list, with rationale (empty block is acceptable and preferred)
|
|
17
17
|
- **Clarification answers carried in**: when `instruction-set/clarification-response.md` exists, it holds the user's answers to the approved plan's `## 1. Clarification Items` rows. The report MUST render the `## 0. Clarification Response Carried In From Previous Run` section (set `clarificationCarryIn.sourceFile` to that path) and, for every carried-over `## 1.` row whose answer appears there, record the answer in the `User input` cell and flip `Status` to `resolved`. A row left `open`/`answered` despite a matching user answer is a contract violation; an answer that materially changes scope beyond the approved plan is routed to a new `implementation-planning` run, not silently executed.
|
|
18
18
|
- **Stage sidecar evidence**: the JSON payload of `runs/<impl-task-key>/carry/stage-<N>.json` is embedded verbatim in a fenced ```json``` block, AND the `consumers.jsonl` rows this run appended are quoted line-by-line, so reviewers can audit the carry surface without grepping artifact directories.
|
|
@@ -13,7 +13,7 @@ from typing import Any, Callable
|
|
|
13
13
|
|
|
14
14
|
from .json_boundary import JsonBoundaryError, load_owned_object
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
FALLBACK_LANG = "en"
|
|
17
17
|
DICTIONARY_REL = ("templates", "reports", "i18n")
|
|
18
18
|
# The human HTML has its own fixed strings — table headings, empty states,
|
|
19
19
|
# enum labels — that the AI-handoff Markdown never renders. Same loader, its
|
|
@@ -44,11 +44,16 @@ def _i18n_dir(rel: tuple[str, ...] = DICTIONARY_REL) -> Path:
|
|
|
44
44
|
|
|
45
45
|
|
|
46
46
|
def load_dictionary(lang: str, rel: tuple[str, ...] = DICTIONARY_REL) -> dict[str, Any]:
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
47
|
+
"""`<lang>.json` 이 있으면 그것, 없으면 영어 사전.
|
|
48
|
+
|
|
49
|
+
사전은 페이지 크롬(표 머리글·빈 상태·enum 라벨)의 고정 문자열이고 본문은
|
|
50
|
+
번역 사이드카가 덮는다. 사전이 없는 언어의 리포트는 본문은 그 언어, 크롬은
|
|
51
|
+
영어로 나온다 — 사전이 없다고 렌더를 거절하면 독자는 아무것도 못 받는다.
|
|
52
|
+
"""
|
|
53
|
+
directory = _i18n_dir(rel)
|
|
54
|
+
path = directory / f"{lang}.json"
|
|
55
|
+
if not path.is_file():
|
|
56
|
+
path = directory / f"{FALLBACK_LANG}.json"
|
|
52
57
|
try:
|
|
53
58
|
return load_owned_object(path, artifact="i18n dictionary")
|
|
54
59
|
except JsonBoundaryError as exc:
|
|
@@ -51,7 +51,8 @@ from okstra_ctl.final_report_schema import (
|
|
|
51
51
|
validate as schema_validate,
|
|
52
52
|
)
|
|
53
53
|
from okstra_ctl.json_boundary import JsonBoundaryError, load_owned_object
|
|
54
|
-
from okstra_ctl.i18n import I18nError,
|
|
54
|
+
from okstra_ctl.i18n import I18nError, load_dictionary, make_jinja_global
|
|
55
|
+
from okstra_ctl.report_language import is_language_tag
|
|
55
56
|
from okstra_ctl.md_table import UNESCAPED_PIPE_RE, to_cell_text
|
|
56
57
|
from okstra_ctl.models import UnknownModelError, resolve_model_metadata
|
|
57
58
|
from okstra_ctl.paths import find_asset_root
|
|
@@ -598,15 +599,10 @@ def validate_report_language(data: dict) -> str:
|
|
|
598
599
|
selects this renderer's dictionary.
|
|
599
600
|
"""
|
|
600
601
|
candidate = (data.get("meta") or {}).get("reportLanguage") or "en"
|
|
601
|
-
if candidate
|
|
602
|
+
if not is_language_tag(candidate):
|
|
602
603
|
raise FinalReportRenderError(
|
|
603
|
-
"reportLanguage
|
|
604
|
-
"
|
|
605
|
-
"'ko' from the run manifest into data.json.meta.reportLanguage."
|
|
606
|
-
)
|
|
607
|
-
if candidate not in SUPPORTED_LANGS:
|
|
608
|
-
raise FinalReportRenderError(
|
|
609
|
-
f"reportLanguage must be one of {SUPPORTED_LANGS}, got {candidate!r}"
|
|
604
|
+
f"reportLanguage must be a language tag such as en, ko, fr or "
|
|
605
|
+
f"pt-BR, got {candidate!r}"
|
|
610
606
|
)
|
|
611
607
|
return MARKDOWN_LANG
|
|
612
608
|
|
|
@@ -25,10 +25,8 @@ placeholders, which a v2 report never carries because its numeric cells are
|
|
|
25
25
|
`null` until this step fills them. Substituting the tokens on a later retry
|
|
26
26
|
then leaves the already-rendered html stale for `validators/validate-report-views.py`.
|
|
27
27
|
|
|
28
|
-
The translation sidecar is the `translate` step,
|
|
29
|
-
|
|
30
|
-
because the extractor refuses a work list from a non-English source. It used to
|
|
31
|
-
be a manual lead sequence outside this command (materialize the translator
|
|
28
|
+
The translation sidecar is the `translate` step, directly before `render-views`,
|
|
29
|
+
which overlays it. It used to be a manual lead sequence outside this command (materialize the translator
|
|
32
30
|
prompt, dispatch it, resume finalize at `render-views`), written only in a doc
|
|
33
31
|
the lead lazy-reads; a lead that ran the whole sequence at once skipped it and
|
|
34
32
|
the run kept an English view under a `ko` report (2026-09-09, fontsninja-v3-site
|
|
@@ -88,7 +86,6 @@ from okstra_project.phase_pointer import (
|
|
|
88
86
|
|
|
89
87
|
|
|
90
88
|
STEP_PROJECT_ACTIVITY = "project-activity"
|
|
91
|
-
STEP_CHECK_SOURCE = "check-source"
|
|
92
89
|
STEP_TRANSLATE = "translate"
|
|
93
90
|
STEP_TOKEN_USAGE = "token-usage"
|
|
94
91
|
STEP_RENDER_VIEWS = "render-views"
|
|
@@ -99,10 +96,6 @@ STEP_TEARDOWN_STAGES = "teardown-stages"
|
|
|
99
96
|
|
|
100
97
|
STEP_ORDER = (
|
|
101
98
|
STEP_PROJECT_ACTIVITY,
|
|
102
|
-
# First, because everything after it derives from the data.json: rendering
|
|
103
|
-
# a Korean SSOT into English chrome, spawning follow-ups from it, and
|
|
104
|
-
# validating it all succeed on a record the next phase cannot read.
|
|
105
|
-
STEP_CHECK_SOURCE,
|
|
106
99
|
STEP_TRANSLATE,
|
|
107
100
|
STEP_TOKEN_USAGE,
|
|
108
101
|
STEP_RENDER_VIEWS,
|
|
@@ -119,8 +112,7 @@ STEP_ORDER = (
|
|
|
119
112
|
V3_STEP_ORDER = (
|
|
120
113
|
STEP_TOKEN_USAGE,
|
|
121
114
|
STEP_PROJECT_ACTIVITY,
|
|
122
|
-
|
|
123
|
-
# After the English gate, before the render that overlays its sidecar.
|
|
115
|
+
# Before the render that overlays its sidecar.
|
|
124
116
|
STEP_TRANSLATE,
|
|
125
117
|
STEP_RENDER_VIEWS,
|
|
126
118
|
STEP_SPAWN_FOLLOWUPS,
|
|
@@ -334,19 +326,6 @@ def build_commands(ctx: FinalizeContext) -> list[tuple[str, list[str]]]:
|
|
|
334
326
|
str(ctx.data_path),
|
|
335
327
|
],
|
|
336
328
|
),
|
|
337
|
-
(
|
|
338
|
-
STEP_CHECK_SOURCE,
|
|
339
|
-
[
|
|
340
|
-
sys.executable,
|
|
341
|
-
str(
|
|
342
|
-
resolve_workspace_script(
|
|
343
|
-
ctx.workspace_root, "okstra-report-translate.py"
|
|
344
|
-
)
|
|
345
|
-
),
|
|
346
|
-
"check-source",
|
|
347
|
-
str(ctx.data_path),
|
|
348
|
-
],
|
|
349
|
-
),
|
|
350
329
|
(
|
|
351
330
|
STEP_TRANSLATE,
|
|
352
331
|
["<in-process>", "translate", str(ctx.data_path)],
|
|
@@ -976,18 +955,17 @@ _CLI_EPILOG = r"""Usage:
|
|
|
976
955
|
Runs the Phase 7 steps in their contractual order against one final-report:
|
|
977
956
|
|
|
978
957
|
1. project-activity project the run's activity events into the data.json
|
|
979
|
-
2.
|
|
980
|
-
3. translate for a non-English reportLanguage, materialize and
|
|
958
|
+
2. translate for a non-English reportLanguage, materialize and
|
|
981
959
|
dispatch the translator worker and require its
|
|
982
960
|
*.i18n.<lang>.json sidecar; a no-op for English or
|
|
983
961
|
when the sidecar already exists
|
|
984
|
-
|
|
985
|
-
|
|
962
|
+
3. token-usage substitute real token/cost numbers into the data.json
|
|
963
|
+
4. render-views write the schema-v2 task-specific *.html sibling with
|
|
986
964
|
the translation overlaid; v1 keeps the
|
|
987
965
|
legacy conditional interactive view
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
966
|
+
5. spawn-followups turn section 4 rows into task stubs
|
|
967
|
+
6. validate-run validate the finished run artifacts
|
|
968
|
+
7. record-group-memory / 8. teardown-stages after a clean validation
|
|
991
969
|
|
|
992
970
|
Every step is idempotent, so re-running after a fixed failure is safe. The
|
|
993
971
|
sequence stops at the first non-zero exit and reports which step failed, except
|
|
@@ -12,7 +12,7 @@ from jinja2 import Environment, FileSystemLoader, StrictUndefined, select_autoes
|
|
|
12
12
|
from ..final_report_paths import final_report_data_path, translation_sidecar_path
|
|
13
13
|
from ..final_report_schema import load_schema_for_data, validate
|
|
14
14
|
from ..i18n import HTML_DICTIONARY_REL, load_dictionary, make_jinja_global
|
|
15
|
-
from ..report_translation import overlay
|
|
15
|
+
from ..report_translation import overlay
|
|
16
16
|
from ..report_view_artifacts import user_responses_dir_for_report
|
|
17
17
|
from ..usage_cells import format_duration_ms
|
|
18
18
|
from ..json_boundary import load_owned_object
|
|
@@ -223,16 +223,6 @@ def render_v2_html_view(
|
|
|
223
223
|
document = env.get_template(route.template_name).render(**context)
|
|
224
224
|
document = inject_report_index(document, label=translate("base.contents"))
|
|
225
225
|
output_path.write_text(document, encoding="utf-8")
|
|
226
|
-
if lang != "en":
|
|
227
|
-
# 사이드카 보고("left in English")는 추출 범위 안만 센다. 페이지에 실제로
|
|
228
|
-
# 남은 영어 문장은 여기서 세어 같은 stdout 에 낸다 — 두 숫자가 갈리면
|
|
229
|
-
# `PROSE_KEYS` 밖의 필드가 화면에 나가고 있다는 뜻이다.
|
|
230
|
-
english = rendered_english_lines(document)
|
|
231
|
-
sys.stdout.write(
|
|
232
|
-
f"rendered {len(english)} line(s) still in English on the {lang} page"
|
|
233
|
-
+ (f" (e.g. {english[0][:80]!r})" if english else "")
|
|
234
|
-
+ "\n"
|
|
235
|
-
)
|
|
236
226
|
if context["clarificationItems"] or context.get("directionSelection"):
|
|
237
227
|
# The footer tells the reader to drop the exported file here, so the
|
|
238
228
|
# directory has to exist before they go looking for it.
|
|
@@ -6,28 +6,32 @@ the run manifest, which report assembly copies into `meta.reportLanguage` and
|
|
|
6
6
|
the HTML renderer reads. When only the prompt called this, a project could ask
|
|
7
7
|
for `ko`, get a Korean-instructed writer, and still ship an English report.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
The value is a language tag (`en`, `ko`, `fr`, `pt-BR`, …). The Phase 7
|
|
10
|
+
translator receives that tag and translates into it; nothing here knows any
|
|
11
|
+
particular language. Precedence: project config → global config → `en`.
|
|
10
12
|
"""
|
|
11
13
|
from __future__ import annotations
|
|
12
14
|
|
|
13
|
-
import json
|
|
14
15
|
import os
|
|
16
|
+
import re
|
|
15
17
|
from pathlib import Path
|
|
16
18
|
from typing import Any, Mapping
|
|
17
19
|
|
|
18
|
-
from .worker_prompt_body import instruction_path
|
|
19
20
|
from .json_boundary import JsonBoundaryError, load_owned_object
|
|
20
21
|
|
|
21
|
-
|
|
22
|
+
DEFAULT_REPORT_LANGUAGE = "en"
|
|
22
23
|
|
|
23
|
-
#
|
|
24
|
-
#
|
|
25
|
-
|
|
26
|
-
_BRIEF_SCAN_CHARS = 16000
|
|
24
|
+
# BCP 47 의 흔한 꼴만 — 소문자 2~3자 언어 코드와 선택적 하위 태그. 대문자
|
|
25
|
+
# 언어 코드나 단어(`english`)는 사이드카 파일명과 사전 파일명이 갈리므로 거절.
|
|
26
|
+
_LANGUAGE_TAG = re.compile(r"^[a-z]{2,3}(-[A-Za-z0-9]{2,8})*$")
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
class ReportLanguageError(ValueError):
|
|
30
|
-
"""A config file declares a reportLanguage
|
|
30
|
+
"""A config file declares a reportLanguage that is not a language tag."""
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def is_language_tag(value: object) -> bool:
|
|
34
|
+
return isinstance(value, str) and _LANGUAGE_TAG.match(value) is not None
|
|
31
35
|
|
|
32
36
|
|
|
33
37
|
def resolve_report_language(
|
|
@@ -36,11 +40,9 @@ def resolve_report_language(
|
|
|
36
40
|
active_context: Mapping[str, Any],
|
|
37
41
|
) -> str:
|
|
38
42
|
for value in _report_language_candidates(project_root):
|
|
39
|
-
if value == "auto":
|
|
40
|
-
return _infer_report_language(project_root, manifest, active_context)
|
|
41
43
|
if value:
|
|
42
44
|
return value
|
|
43
|
-
return
|
|
45
|
+
return DEFAULT_REPORT_LANGUAGE
|
|
44
46
|
|
|
45
47
|
|
|
46
48
|
def _report_language_candidates(project_root: Path) -> list[str]:
|
|
@@ -63,26 +65,9 @@ def _read_report_language(path: Path, label: str) -> str:
|
|
|
63
65
|
value = payload.get("reportLanguage")
|
|
64
66
|
if value in (None, ""):
|
|
65
67
|
return ""
|
|
66
|
-
if
|
|
68
|
+
if is_language_tag(value):
|
|
67
69
|
return value
|
|
68
70
|
raise ReportLanguageError(
|
|
69
|
-
f"{label} config reportLanguage must be en, ko,
|
|
71
|
+
f"{label} config reportLanguage must be a language tag such as en, ko, "
|
|
72
|
+
f"fr or pt-BR, got {value!r}: {path}"
|
|
70
73
|
)
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
def _infer_report_language(
|
|
74
|
-
project_root: Path,
|
|
75
|
-
manifest: Mapping[str, Any],
|
|
76
|
-
active_context: Mapping[str, Any],
|
|
77
|
-
) -> str:
|
|
78
|
-
task_brief = instruction_path(manifest, active_context, "taskBriefPath")
|
|
79
|
-
if not task_brief:
|
|
80
|
-
return "en"
|
|
81
|
-
path = Path(task_brief)
|
|
82
|
-
if not path.is_absolute():
|
|
83
|
-
path = project_root / path
|
|
84
|
-
if not path.is_file():
|
|
85
|
-
return "en"
|
|
86
|
-
text = path.read_text(encoding="utf-8", errors="replace")[:_BRIEF_SCAN_CHARS]
|
|
87
|
-
hangul = sum(1 for char in text if "가" <= char <= "힣")
|
|
88
|
-
return "ko" if hangul >= _HANGUL_THRESHOLD else "en"
|
|
@@ -441,57 +441,6 @@ def overlay(
|
|
|
441
441
|
return out, OverlayReport(applied, untranslated, tuple(sorted(unresolved)))
|
|
442
442
|
|
|
443
443
|
|
|
444
|
-
# Above this share of Hangul, the prose was authored in Korean rather than
|
|
445
|
-
# quoting some. Measured across real reports: Korean-authored ones sit at
|
|
446
|
-
# 35-38%, English ones that quote a Korean brief or a worker's Korean phrase
|
|
447
|
-
# reach 8% at most. The gap is wide enough that no threshold inside it is
|
|
448
|
-
# delicate. Only the strings `extract` offers are counted — a verbatim quote of
|
|
449
|
-
# the user's request is structural and never reaches this.
|
|
450
|
-
HANGUL_PROSE_LIMIT = 0.20
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
_RENDERED_SKIP_RE = re.compile(
|
|
454
|
-
r"<script.*?</script>|<style.*?</style>|<svg.*?</svg>|<pre.*?</pre>|<option.*?</option>",
|
|
455
|
-
re.DOTALL,
|
|
456
|
-
)
|
|
457
|
-
_TEXT_NODE_RE = re.compile(r">([^<>]{40,})<")
|
|
458
|
-
_ENTITY_RE = re.compile(r"&[#A-Za-z0-9]+;")
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
def rendered_english_lines(html: str, *, min_words: int = 6) -> list[str]:
|
|
462
|
-
"""Text nodes of a rendered page that carry no Hangul and read as a sentence.
|
|
463
|
-
|
|
464
|
-
`OverlayReport.untranslated` only sees the pointers the extractor offered,
|
|
465
|
-
so a reader-facing field outside `PROSE_KEYS` never shows up there — the
|
|
466
|
-
2026-09-05 audit found 40 plan-item explanations and 29 step actions in
|
|
467
|
-
English on a page that reported "0 left in English". This reads the page
|
|
468
|
-
itself. Scripts, styles, figures, code blocks and `<option>` values are
|
|
469
|
-
skipped: figure labels and response values are meant to stay verbatim.
|
|
470
|
-
Inline `<code>` is stripped so a sentence around a path still counts.
|
|
471
|
-
"""
|
|
472
|
-
body = html.split("<main", 1)[-1]
|
|
473
|
-
body = _RENDERED_SKIP_RE.sub(" ", body)
|
|
474
|
-
body = re.sub(r"</?code>", "", body)
|
|
475
|
-
lines: list[str] = []
|
|
476
|
-
for match in _TEXT_NODE_RE.finditer(body):
|
|
477
|
-
text = _ENTITY_RE.sub(" ", match.group(1)).strip()
|
|
478
|
-
if len(text.split()) < min_words:
|
|
479
|
-
continue
|
|
480
|
-
if any("가" <= char <= "힣" for char in text):
|
|
481
|
-
continue
|
|
482
|
-
lines.append(text)
|
|
483
|
-
return lines
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
def hangul_share(data: Mapping[str, Any]) -> tuple[float, int]:
|
|
487
|
-
"""Return the Hangul share of the report's authored prose, and its length."""
|
|
488
|
-
text = "".join(extract(data).values())
|
|
489
|
-
if not text:
|
|
490
|
-
return 0.0, 0
|
|
491
|
-
hangul = sum(1 for char in text if "가" <= char <= "힣")
|
|
492
|
-
return hangul / len(text), len(text)
|
|
493
|
-
|
|
494
|
-
|
|
495
444
|
def _schema_string_keys(schema: Mapping[str, Any], *, enums: bool) -> set[str]:
|
|
496
445
|
found: set[str] = set()
|
|
497
446
|
|
|
@@ -37,16 +37,12 @@ from .json_boundary import JsonBoundaryError
|
|
|
37
37
|
|
|
38
38
|
TRANSLATOR_WORKER_ID = "translator"
|
|
39
39
|
|
|
40
|
-
# 지시문의 언어 이름. 워커는 `**Report Language:**` 헤더로 코드를 받지만, 지시문은
|
|
41
|
-
# 사람이 읽는 문장이라 이름으로 적는다. 표에 없는 코드는 코드 그대로 쓴다.
|
|
42
|
-
_LANGUAGE_NAMES = {"ko": "Korean"}
|
|
43
|
-
|
|
44
40
|
# 리드가 종전에 손으로 쓰던 지시문(실측 2026-09-08, fontsninja-nlpvibe dev-10786
|
|
45
41
|
# requirements-discovery-002)과 같은 절차다. 명령은 `agents/workers/translator-worker.md`
|
|
46
42
|
# 의 Procedure 와 같은 세 개이고, 결과·감사 경로는 프롬프트 앵커가 이름한다.
|
|
47
43
|
_INSTRUCTIONS = """## Instructions
|
|
48
44
|
|
|
49
|
-
Translate the finalized report into {language} faithfully. This is translation only: no analysis, no source edits.
|
|
45
|
+
Translate the finalized report into the language whose IETF language tag is `{language}` faithfully. This is translation only: no analysis, no source edits.
|
|
50
46
|
|
|
51
47
|
1. Run `okstra report-translate source --run-manifest {manifest}` and read the complete work list, in chunks if it is long. Copy the `Source digest` it prints.
|
|
52
48
|
2. Write one translated block per `## T-NNN` item to the exact Result Path, using the same `## T-NNN` headings. Preserve every identifier, path, command, enum token, link, and qualification character for character.
|
|
@@ -229,7 +225,7 @@ def _materialize_translator(
|
|
|
229
225
|
instruction.parent.mkdir(parents=True, exist_ok=True)
|
|
230
226
|
instruction.write_text(
|
|
231
227
|
_INSTRUCTIONS.format(
|
|
232
|
-
language=
|
|
228
|
+
language=lang,
|
|
233
229
|
manifest=manifest_path.relative_to(project_root).as_posix()
|
|
234
230
|
if manifest_path.is_relative_to(project_root)
|
|
235
231
|
else str(manifest_path),
|
|
@@ -122,8 +122,9 @@ matching section:
|
|
|
122
122
|
diagnose a symlink/backup warning.
|
|
123
123
|
- **D. PR body template** (release-handoff) — opt-in pre-registration; also
|
|
124
124
|
offered on the first release-handoff run.
|
|
125
|
-
- **E. final report language** (`reportLanguage`) —
|
|
126
|
-
|
|
125
|
+
- **E. final report language** (`reportLanguage`) — a language tag (`en`,
|
|
126
|
+
`ko`, `fr`, …); default `en`. The Phase 7 translator translates the human
|
|
127
|
+
HTML into it.
|
|
127
128
|
- **F. declared architecture style** (`architecture.style`) — `hexagonal` /
|
|
128
129
|
`layered` / `none`; hand-added, default `none`. Declaring one makes that
|
|
129
130
|
architecture's placement rules binding in planning + verification.
|
|
@@ -195,23 +195,22 @@ per-run override prompt during the next release-handoff run.
|
|
|
195
195
|
|
|
196
196
|
## E. Final report language (`reportLanguage`)
|
|
197
197
|
|
|
198
|
-
The
|
|
199
|
-
the
|
|
200
|
-
|
|
201
|
-
report).
|
|
198
|
+
The value is a language tag (`en`, `ko`, `fr`, `pt-BR`, …). The data.json
|
|
199
|
+
stays English; the Phase 7 translator translates the human HTML into the tag.
|
|
200
|
+
If you skip, no `reportLanguage` field is written and the runtime uses `en`.
|
|
202
201
|
|
|
203
202
|
AskUserQuestion (fixed options):
|
|
204
203
|
- Question: `"Which language should the final report be written in?"`
|
|
205
204
|
- Options:
|
|
206
205
|
1. `English (recommended)` → `en`
|
|
207
206
|
2. `Korean` → `ko`
|
|
208
|
-
3. `
|
|
209
|
-
4. `Later` → skip (no field set →
|
|
207
|
+
3. `Other` → ask for the language tag (`fr`, `de`, `ja`, `pt-BR`, …)
|
|
208
|
+
4. `Later` → skip (no field set → `en`)
|
|
210
209
|
|
|
211
210
|
If the user picks 1/2/3:
|
|
212
211
|
|
|
213
212
|
```bash
|
|
214
|
-
okstra config set report-language <
|
|
213
|
+
okstra config set report-language <language-tag> --scope project
|
|
215
214
|
```
|
|
216
215
|
|
|
217
216
|
Set the global default manually with `--scope global` as described in the
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
{% macro file_paths(value) -%}
|
|
2
|
+
{% for path in value.splitlines() if path | trim %}<div><code>{{ path }}</code></div>{% endfor %}
|
|
3
|
+
{%- endmacro %}
|
|
4
|
+
|
|
1
5
|
{% macro narrative(value, field_name) -%}
|
|
2
6
|
<div class="narrative" data-report-field="{{ field_name }}">
|
|
3
7
|
{{ value.text | paragraphs }}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{% extends "html/base.template.html" %}
|
|
2
|
-
{% from "html/macros/layout.html" import narrative as render_narrative, summary_card, row_key %}
|
|
2
|
+
{% from "html/macros/layout.html" import narrative as render_narrative, summary_card, row_key, file_paths %}
|
|
3
3
|
{% from "html/macros/visualizations.html" import figure %}
|
|
4
4
|
|
|
5
5
|
{% block human_content %}
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
<section data-report-section="shipped-commits" data-report-field="implementation.commitList">
|
|
37
37
|
<h2>{{ t('tasks.implementation.commits-delivered') }}</h2>
|
|
38
38
|
{% if implementation.commitList is mapping %}<p>{{ t('tasks.implementation.there-are-no-commits') }}</p>{% else %}
|
|
39
|
-
<table><thead><tr><th>{{ t('tasks.implementation.commit') }}</th><th>{{ t('tasks.implementation.subject') }}</th><th>{{ t('tasks.implementation.files') }}</th></tr></thead><tbody>{% for row in implementation.commitList %}<tr>{{ row_key(pairs=[(t('macros.layout.sha'), row.shortSha), (t('macros.layout.order'), row.number), (t('macros.layout.plan-step'), row.planStep)]) }}<td>{{ row.subject | inline_code }}</td><td>{
|
|
39
|
+
<table><thead><tr><th>{{ t('tasks.implementation.commit') }}</th><th>{{ t('tasks.implementation.subject') }}</th><th>{{ t('tasks.implementation.files') }}</th></tr></thead><tbody>{% for row in implementation.commitList %}<tr>{{ row_key(pairs=[(t('macros.layout.sha'), row.shortSha), (t('macros.layout.order'), row.number), (t('macros.layout.plan-step'), row.planStep)]) }}<td>{{ row.subject | inline_code }}</td><td>{{ file_paths(row.files) }}</td></tr>{% endfor %}</tbody></table>{% endif %}
|
|
40
40
|
<table data-report-field="implementation.approvedPlanReference"><tbody><tr><th>{{ t('tasks.implementation.approved-plan') }}</th><td><code>{{ implementation.approvedPlanReference.planFile }}</code></td></tr><tr><th>{{ t('tasks.implementation.approval-evidence') }}</th><td>{{ implementation.approvedPlanReference.approvalEvidence | inline_code }}</td></tr><tr><th>{{ t('tasks.implementation.worktree') }}</th><td><code>{{ implementation.approvedPlanReference.executorWorktreePath }}</code> @ <code>{{ implementation.approvedPlanReference.baseRefSha }}</code></td></tr></tbody></table>
|
|
41
41
|
</section>
|
|
42
42
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{% extends "html/base.template.html" %}
|
|
2
|
-
{% from "html/macros/layout.html" import narrative as render_narrative, summary_card, row_key %}
|
|
2
|
+
{% from "html/macros/layout.html" import narrative as render_narrative, summary_card, row_key, file_paths %}
|
|
3
3
|
{% from "html/macros/visualizations.html" import figure %}
|
|
4
4
|
|
|
5
5
|
{% block human_content %}
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
<section data-report-section="delivered-commits" data-report-field="releaseHandoff.commitList">
|
|
39
39
|
<h2>{{ t('tasks.release-handoff.commits-delivered') }}</h2>
|
|
40
40
|
{% if handoff.commitList is mapping %}<p>{{ t('tasks.release-handoff.there-are-no-commits') }}</p>{% else %}
|
|
41
|
-
<table><thead><tr><th>{{ t('tasks.release-handoff.commit') }}</th><th>{{ t('tasks.release-handoff.subject') }}</th><th>{{ t('tasks.release-handoff.files') }}</th></tr></thead><tbody>{% for row in handoff.commitList %}<tr>{{ row_key(pairs=[(t('macros.layout.sha'), row.shortSha), (t('macros.layout.order'), loop.index)]) }}<td>{{ row.subject | inline_code }}</td><td>{
|
|
41
|
+
<table><thead><tr><th>{{ t('tasks.release-handoff.commit') }}</th><th>{{ t('tasks.release-handoff.subject') }}</th><th>{{ t('tasks.release-handoff.files') }}</th></tr></thead><tbody>{% for row in handoff.commitList %}<tr>{{ row_key(pairs=[(t('macros.layout.sha'), row.shortSha), (t('macros.layout.order'), loop.index)]) }}<td>{{ row.subject | inline_code }}</td><td>{{ file_paths(row.files) }}</td></tr>{% endfor %}</tbody></table>{% endif %}
|
|
42
42
|
{% if handoff.get("sourceVerificationReports") %}<p data-report-field="releaseHandoff.sourceVerificationReports"><strong>{{ t('tasks.release-handoff.the-verification-report-this-rests-on') }}</strong>{% for row in handoff.sourceVerificationReports %} — stage {{ row.stage }}: <code>{{ row.path }}</code> · {{ row.verdictTokenQuote | inline_code }}{% endfor %}</p>
|
|
43
43
|
{% else %}<p data-report-field="releaseHandoff.sourceVerificationReport"><strong>{{ t('tasks.release-handoff.the-verification-report-this-rests-on') }}</strong> — <code>{{ handoff.sourceVerificationReport.path }}</code> · {{ handoff.sourceVerificationReport.verdictTokenQuote | inline_code }}</p>{% endif %}
|
|
44
44
|
</section>
|
|
@@ -74,10 +74,6 @@ from okstra_ctl.mutation_probe import ( # noqa: E402
|
|
|
74
74
|
classify_reason,
|
|
75
75
|
)
|
|
76
76
|
from okstra_ctl.self_mock_signals import selfmock_path_key # noqa: E402
|
|
77
|
-
from okstra_ctl.report_translation import ( # noqa: E402
|
|
78
|
-
HANGUL_PROSE_LIMIT,
|
|
79
|
-
hangul_share,
|
|
80
|
-
)
|
|
81
77
|
from okstra_ctl.validation_contract import ( # noqa: E402
|
|
82
78
|
CURRENT_VALIDATION_CONTRACT_VERSION,
|
|
83
79
|
)
|
|
@@ -8134,32 +8130,6 @@ def _validate_improvement_discovery(
|
|
|
8134
8130
|
failures.append(f"improvement-discovery: {err}")
|
|
8135
8131
|
|
|
8136
8132
|
|
|
8137
|
-
def _validate_ssot_is_english(data: dict, failures: list[str]) -> None:
|
|
8138
|
-
"""Enforce: the final-report data.json is authored in English.
|
|
8139
|
-
|
|
8140
|
-
`meta.reportLanguage` names the language the human HTML renders in, and
|
|
8141
|
-
Phase 7's translator serves it from a sidecar. The data.json itself is the
|
|
8142
|
-
record every later phase, validator and agent reads, so a worker that
|
|
8143
|
-
authors it in the reader's language instead splits the record — and does so
|
|
8144
|
-
silently, because rendering, follow-up spawning and validation all succeed
|
|
8145
|
-
on it.
|
|
8146
|
-
|
|
8147
|
-
`report-finalize` runs the same check as its first step, before anything
|
|
8148
|
-
derives from the report. This is the second gate, for a report that reached
|
|
8149
|
-
validation by some other path.
|
|
8150
|
-
"""
|
|
8151
|
-
if not data:
|
|
8152
|
-
return
|
|
8153
|
-
share, length = hangul_share(data)
|
|
8154
|
-
if length and share >= HANGUL_PROSE_LIMIT:
|
|
8155
|
-
failures.append(
|
|
8156
|
-
f"final-report data.json was authored in Korean ({share:.0%} of its "
|
|
8157
|
-
f"prose, limit {HANGUL_PROSE_LIMIT:.0%}). The data.json is the "
|
|
8158
|
-
"English SSOT; meta.reportLanguage selects the human HTML's "
|
|
8159
|
-
"language and is served by the Phase 7 translator sidecar."
|
|
8160
|
-
)
|
|
8161
|
-
|
|
8162
|
-
|
|
8163
8133
|
def _validate_translation_sidecar(
|
|
8164
8134
|
data: Mapping[str, Any], report_path: Path, failures: list[str]
|
|
8165
8135
|
) -> None:
|
|
@@ -9434,7 +9404,6 @@ def main() -> int:
|
|
|
9434
9404
|
),
|
|
9435
9405
|
)
|
|
9436
9406
|
validation_data = report_data if isinstance(report_data, Mapping) else {}
|
|
9437
|
-
_validate_ssot_is_english(validation_data, failures)
|
|
9438
9407
|
_validate_translation_sidecar(
|
|
9439
9408
|
validation_data, _data_path_for(report_path), failures
|
|
9440
9409
|
)
|