okstra 0.26.0 → 0.28.0

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.
Files changed (52) hide show
  1. package/README.kr.md +15 -0
  2. package/README.md +15 -0
  3. package/docs/kr/architecture.md +2 -6
  4. package/docs/kr/cli.md +40 -6
  5. package/docs/kr/performance-improvement-plan-v2.md +23 -0
  6. package/docs/kr/performance-improvement-plan.md +22 -0
  7. package/package.json +1 -1
  8. package/runtime/BUILD.json +2 -2
  9. package/runtime/agents/workers/claude-worker.md +4 -3
  10. package/runtime/agents/workers/codex-worker.md +4 -3
  11. package/runtime/agents/workers/gemini-worker.md +4 -3
  12. package/runtime/agents/workers/report-writer-worker.md +7 -2
  13. package/runtime/bin/okstra.sh +0 -1
  14. package/runtime/prompts/launch.template.md +1 -1
  15. package/runtime/prompts/profiles/_common-contract.md +36 -4
  16. package/runtime/prompts/profiles/error-analysis.md +12 -0
  17. package/runtime/prompts/profiles/implementation-planning.md +20 -0
  18. package/runtime/prompts/profiles/requirements-discovery.md +20 -0
  19. package/runtime/python/lib/okstra/cli.sh +1 -7
  20. package/runtime/python/lib/okstra/globals.sh +0 -1
  21. package/runtime/python/lib/okstra/usage.sh +1 -4
  22. package/runtime/python/okstra_ctl/render.py +3 -0
  23. package/runtime/python/okstra_ctl/run.py +0 -6
  24. package/runtime/python/okstra_ctl/run_context.py +1 -1
  25. package/runtime/python/okstra_ctl/wizard.py +25 -2
  26. package/runtime/python/okstra_token_usage/blocks.py +5 -1
  27. package/runtime/python/okstra_token_usage/claude.py +16 -1
  28. package/runtime/python/okstra_token_usage/cli.py +9 -2
  29. package/runtime/python/okstra_token_usage/collect.py +17 -3
  30. package/runtime/python/okstra_token_usage/pricing.py +159 -24
  31. package/runtime/python/okstra_token_usage/report.py +32 -3
  32. package/runtime/skills/okstra-brief/SKILL.md +532 -65
  33. package/runtime/skills/okstra-context-loader/SKILL.md +25 -11
  34. package/runtime/skills/okstra-convergence/SKILL.md +38 -14
  35. package/runtime/skills/okstra-history/SKILL.md +68 -37
  36. package/runtime/skills/okstra-logs/SKILL.md +26 -4
  37. package/runtime/skills/okstra-report-finder/SKILL.md +49 -22
  38. package/runtime/skills/okstra-report-writer/SKILL.md +62 -65
  39. package/runtime/skills/okstra-run/SKILL.md +35 -34
  40. package/runtime/skills/okstra-schedule/SKILL.md +51 -20
  41. package/runtime/skills/okstra-setup/SKILL.md +31 -12
  42. package/runtime/skills/okstra-status/SKILL.md +20 -8
  43. package/runtime/skills/okstra-team-contract/SKILL.md +41 -25
  44. package/runtime/skills/okstra-time-summary/SKILL.md +53 -16
  45. package/runtime/templates/reports/final-report.template.md +227 -207
  46. package/runtime/templates/reports/settings.template.json +7 -4
  47. package/runtime/validators/lib/fixtures.sh +47 -2
  48. package/runtime/validators/lib/validate-assets.sh +50 -24
  49. package/runtime/validators/validate-brief.py +385 -0
  50. package/runtime/validators/validate-brief.sh +35 -0
  51. package/runtime/validators/validate-run.py +313 -1
  52. package/runtime/validators/validate-workflow.sh +7 -33
package/README.kr.md CHANGED
@@ -4,6 +4,21 @@
4
4
  >
5
5
  > English: [`README.md`](README.md)
6
6
 
7
+ ## 인덱스
8
+
9
+ - [1. 용도](#1-용도)
10
+ - [2. 구조](#2-구조)
11
+ - [2.1 repo 레이아웃](#21-repo-레이아웃)
12
+ - [2.2 설치 후 사용자 머신 레이아웃](#22-설치-후-사용자-머신-레이아웃)
13
+ - [2.3 단일 권위 요약](#23-단일-권위-요약)
14
+ - [3. 사용 매뉴얼](#3-사용-매뉴얼)
15
+ - [3.1 최초 셋업 (머신당 1회)](#31-최초-셋업-머신당-1회)
16
+ - [3.2 프로젝트 등록 (프로젝트당 1회)](#32-프로젝트-등록-프로젝트당-1회)
17
+ - [3.3 일상 명령](#33-일상-명령)
18
+ - [3.4 CLI 모드 (선택)](#34-cli-모드-선택)
19
+ - [3.5 운영 명령](#35-운영-명령)
20
+ - [4. 더 읽을 자료](#4-더-읽을-자료)
21
+
7
22
  ## 1. 용도
8
23
 
9
24
  `okstra` 는 **Claude Code 안에서 lead + worker 모델로 작업을 cross-verify 하기 위한 정형화된 task 실행 러너**입니다. Claude lead 가 phase 진행을 주도하고, 독립된 분석 worker — **기본 Claude · Codex** (Gemini 는 옵션으로 명시할 때만 추가) — 와 최종 보고서 작성을 전담하는 report-writer 를 dispatch 합니다.
package/README.md CHANGED
@@ -4,6 +4,21 @@
4
4
  >
5
5
  > 한국어 매뉴얼: [`README.kr.md`](README.kr.md)
6
6
 
7
+ ## Index
8
+
9
+ - [1. Purpose](#1-purpose)
10
+ - [2. Structure](#2-structure)
11
+ - [2.1 Repo layout](#21-repo-layout)
12
+ - [2.2 User-machine layout after install](#22-user-machine-layout-after-install)
13
+ - [2.3 Single-authority map](#23-single-authority-map)
14
+ - [3. Manual](#3-manual)
15
+ - [3.1 First-time setup (once per machine)](#31-first-time-setup-once-per-machine)
16
+ - [3.2 Register a project (once per project)](#32-register-a-project-once-per-project)
17
+ - [3.3 Day-to-day commands](#33-day-to-day-commands)
18
+ - [3.4 CLI mode (optional)](#34-cli-mode-optional)
19
+ - [3.5 Ops commands](#35-ops-commands)
20
+ - [4. Further reading](#4-further-reading)
21
+
7
22
  ## 1. Purpose
8
23
 
9
24
  `okstra` is a **structured task-execution runner for Claude Code that cross-verifies work with a lead + worker model**. The Claude lead drives phase progression and dispatches independent analysis workers — **Claude and Codex by default** (with **Gemini** available as an opt-in extra) — plus a dedicated report-writer for the final synthesis.
@@ -449,10 +449,7 @@ scripts/okstra.sh workflow가 사용하는 project-local Claude assets는 아래
449
449
  - `.project-docs/okstra/discovery/latest-task.json`: 현재 프로젝트에서 가장 최근에 준비된 okstra task bundle을 가리키는 current-task convenience pointer
450
450
  - `.project-docs/okstra/discovery/task-catalog.json`: 현재 프로젝트에 준비된 okstra task bundle 목록을 `taskKey`, `taskGroup`, `taskId` 기준으로 유지하는 canonical project-level catalog
451
451
  - `instruction-set/reference-expectations.md`: 현재 task가 참조해야 할 config files, deployment manifests, expected values를 task-level canonical artifact로 정리한 파일
452
- - `.claude/skills/...`, `.claude/agents/...`: `agents` 아래 Markdown asset project-local Claude asset 구조로 seed한 파일들
453
-
454
- 기본 rerun에서는 이미 존재하는 project-local asset을 유지합니다.
455
- `--refresh-assets`를 주면 mapped okstra asset을 source 기준으로 다시 생성합니다.
452
+ - `~/.claude/skills/okstra-*/...`, `~/.claude/agents/...`: `okstra install` 사용자 홈에 seed하는 Claude asset (project-local 시딩은 이상 발생하지 않음 — `okstra install --refresh` 로 갱신)
456
453
 
457
454
  이전의 아래 파일들은 더 이상 okstra 생성 대상이 아닙니다.
458
455
 
@@ -867,7 +864,6 @@ Claude가 작성하는 최종 보고서는 brief에 더 구체적인 형식이
867
864
  - brief의 `Configuration References and Expected Values`, `Deployment Manifests and Expected Values` 섹션은 task별 expected state의 canonical source입니다.
868
865
  - `task-type`가 프로필 선택까지 결정합니다.
869
866
  - `--render-only`는 dry-run 확인용이지만 task bundle과 run manifest는 생성합니다.
870
- - `--refresh-assets`는 `.claude/skills/`와 `.claude/agents/`의 okstra mapped asset을 source 기준으로 다시 생성합니다.
871
867
  - 기본 실행은 Claude print-mode 수집이 아니라 interactive handoff입니다.
872
868
  - 기본 최종 보고서 템플릿은 task bundle의 `instruction-set/final-report-template.md`에 렌더링됩니다.
873
869
  - task bundle의 `instruction-set/reference-expectations.md`는 config/deployment expected-state reference로 함께 생성됩니다.
@@ -880,7 +876,7 @@ Claude가 작성하는 최종 보고서는 brief에 더 구체적인 형식이
880
876
  - Executor 별 worktree cwd 주입: codex / gemini executor 는 wrapper(`okstra-codex-exec.sh -C` / `okstra-gemini-exec.sh --include-directories`) 가 CLI layer 에서 cwd 를 worktree 로 고정합니다. Claude executor 는 Bash tool 에 per-call cwd 인자가 없어 cwd 민감 toolchain (`cargo`/`npm`/`pnpm`/`bun`/`pytest`/`make`/`go`) 호출을 같은 Bash invocation 안에서 `cd {{EXECUTOR_WORKTREE_PATH}} && <cmd>` 로 prefix 합니다 — `bash -lc`/`bash -c` 래핑은 금지되며 (`cd` leading token 이 가려져 permission auto-allow 우회 실패), 작업 디렉터리 플래그 (`git -C`, `cargo --manifest-path` 등) 가 있으면 그것을 우선합니다. 자세한 규약은 `prompts/profiles/implementation.md` 의 *Executor Worktree* 블록과 `agents/workers/claude-worker.md` 의 Executor exception 항목 참고.
881
877
  - project-level current-task convenience pointer는 `.project-docs/okstra/discovery/latest-task.json`입니다.
882
878
  - project-level canonical task inventory는 `.project-docs/okstra/discovery/task-catalog.json`입니다.
883
- - project-local okstra Claude asset은 `.claude/skills/`와 `.claude/agents/` 아래에 seed되며, 기본 rerun에서는 보존되고 `--refresh-assets`로 다시 생성할있습니다.
879
+ - okstra Claude asset은 `~/.claude/skills/`와 `~/.claude/agents/` 아래에 `okstra install` 시점에 seed되며, `okstra install --refresh` 갱신할있습니다 (per-project seeding은 더 이상 수행되지 않음).
884
880
  - seeded okstra Claude assets는 Agent Teams 우선, sequential/background fallback 차선 규칙을 Claude에게 제공합니다.
885
881
  - 최종 판단은 스크립트가 아니라 Claude가 수행합니다.
886
882
  - stable task key를 유지해야 이후 bug 추적, 재수정, 재검증이 가능합니다.
package/docs/kr/cli.md CHANGED
@@ -4,12 +4,51 @@
4
4
 
5
5
  ---
6
6
 
7
+ ## 인덱스
8
+
9
+ - [Command forms](#command-forms)
10
+ - [Required arguments](#required-arguments)
11
+ - [`--project-id`](#--project-id)
12
+ - [`--task-group`](#--task-group)
13
+ - [`--task-id`](#--task-id)
14
+ - [`--task-type`](#--task-type)
15
+ - [`--task-brief`](#--task-brief)
16
+ - [`--yes`](#--yes)
17
+ - [Optional arguments and options](#optional-arguments-and-options)
18
+ - [`--task-key`](#--task-key)
19
+ - [`--clarification-response`](#--clarification-response)
20
+ - [`--resume-clarification`](#--resume-clarification)
21
+ - [`--project-root`](#--project-root)
22
+ - [`--directive`](#--directive)
23
+ - [`--workers`](#--workers)
24
+ - [`--claude-model`](#--claude-model)
25
+ - [`--lead-model`](#--lead-model)
26
+ - [`--codex-model`](#--codex-model)
27
+ - [`--gemini-model`](#--gemini-model)
28
+ - [`--report-writer-model`](#--report-writer-model)
29
+ - [`--executor`](#--executor)
30
+ - [`--approved-plan`](#--approved-plan)
31
+ - [`--approve`](#--approve)
32
+ - [`--work-category`](#--work-category)
33
+ - [`--related-tasks`](#--related-tasks)
34
+ - [`--render-only`](#--render-only)
35
+ - [Interactive input flow](#interactive-input-flow)
36
+ - [Confirmation flow](#confirmation-flow)
37
+ - [okstra Control Center — 설치 / 자주 쓰는 명령](#okstra-control-center--설치--자주-쓰는-명령)
38
+ - [okstra Control Center](#okstra-control-center)
39
+ - [설치 (전역 wrapper)](#설치-전역-wrapper)
40
+ - [자주 쓰는 명령](#자주-쓰는-명령)
41
+ - [`okstra` Node CLI — introspection subcommands](#okstra-node-cli--introspection-subcommands)
42
+ - [Live-log sidecar](#live-log-sidecar)
43
+
44
+ ---
45
+
7
46
  ## Command forms
8
47
 
9
48
  기본 명령(첫 진입 / full args):
10
49
 
11
50
  ```bash
12
- scripts/okstra.sh [--render-only] [--yes] [--refresh-assets] [--no-plan-verification] --task-type <task-type> [--workers worker1,worker2] [--lead-model <model>] [--claude-model <model>] [--codex-model <model>] [--gemini-model <model>] [--report-writer-model <model>] [--executor claude|codex|gemini] [--related-tasks taskA,taskB] [--work-category bugfix|feature|refactor|ops|improvement|unknown] [--clarification-response <previous-final-report>] [--approved-plan <plan-path>] [--approve] --project-id <project-id> --task-group <task-group> --task-id <task-id> --task-brief <brief-path> [--directive <directive>]
51
+ scripts/okstra.sh [--render-only] [--yes] [--no-plan-verification] --task-type <task-type> [--workers worker1,worker2] [--lead-model <model>] [--claude-model <model>] [--codex-model <model>] [--gemini-model <model>] [--report-writer-model <model>] [--executor claude|codex|gemini] [--related-tasks taskA,taskB] [--work-category bugfix|feature|refactor|ops|improvement|unknown] [--clarification-response <previous-final-report>] [--approved-plan <plan-path>] [--approve] --project-id <project-id> --task-group <task-group> --task-id <task-id> --task-brief <brief-path> [--directive <directive>]
13
52
  ```
14
53
 
15
54
  후속 phase 단축 형식(기존 task-manifest.json이 존재할 때):
@@ -394,11 +433,6 @@ scripts/okstra.sh --task-type error-analysis --related-tasks scanner-regression,
394
433
  - `history/timeline.json` 갱신
395
434
  - project-level discovery pointer 생성 또는 갱신
396
435
 
397
- ### `--refresh-assets`
398
-
399
- project-local `.claude/skills/`와 `.claude/agents/` 아래의 okstra mapped asset을 workspace source 기준으로 다시 생성합니다.
400
- 기본 rerun에서는 기존 project-local asset을 유지합니다.
401
-
402
436
  ### `--no-plan-verification`
403
437
 
404
438
  `implementation-planning` task-type 의 Phase 6 plan-body verification 라운드를 끕니다. 기본값은 활성. 다른 task-type 에서는 무시됩니다.
@@ -1,5 +1,28 @@
1
1
  # okstra-run 성능 개선 계획 v2
2
2
 
3
+ ## 인덱스
4
+
5
+ - [1. 목적](#1-목적)
6
+ - [2. 현재 구조 요약](#2-현재-구조-요약)
7
+ - [2.1 진입점](#21-진입점)
8
+ - [2.2 두 종류의 phase를 구분한다](#22-두-종류의-phase를-구분한다)
9
+ - [2.3 prepare 단계의 비용 특성](#23-prepare-단계의-비용-특성)
10
+ - [2.4 worker 구조](#24-worker-구조)
11
+ - [3. 성능 병목 가설](#3-성능-병목-가설)
12
+ - [4. 측정 기준](#4-측정-기준)
13
+ - [5. 개선 우선순위](#5-개선-우선순위)
14
+ - [P0. Baseline 계측과 용어 정리](#p0-baseline-계측과-용어-정리)
15
+ - [P1. Convergence 재검증 범위 축소](#p1-convergence-재검증-범위-축소)
16
+ - [P2. Prompt diet: analysis worker 입력 축소](#p2-prompt-diet-analysis-worker-입력-축소)
17
+ - [P3. Fast-track routing](#p3-fast-track-routing)
18
+ - [P4. Prompt caching 가능성 검증](#p4-prompt-caching-가능성-검증)
19
+ - [P5. Prepare render 병렬화](#p5-prepare-render-병렬화)
20
+ - [P6. Token usage 증분화](#p6-token-usage-증분화)
21
+ - [6. 병렬 작업 계획](#6-병렬-작업-계획)
22
+ - [7. P1 구현 체크리스트](#7-p1-구현-체크리스트)
23
+ - [8. 리스크와 방어선](#8-리스크와-방어선)
24
+ - [9. 이번 계획의 결론](#9-이번-계획의-결론)
25
+
3
26
  ## 1. 목적
4
27
 
5
28
  `okstra-run` 스킬 또는 `scripts/okstra.sh`로 시작하는 cross-verification run이 무겁게 느껴지는 문제를 줄인다. 이 문서는 현재 구조를 정확한 레이어로 나누고, 개선 후보의 우선순위, 측정 기준, 병렬 작업 가능성, 1차 구현 범위를 정리한다.
@@ -1,5 +1,27 @@
1
1
  # okstra-run 성능 개선 계획
2
2
 
3
+ ## 인덱스
4
+
5
+ - [1. 배경](#1-배경)
6
+ - [2. 현재 구조 요약](#2-현재-구조-요약)
7
+ - [2.1 진입점](#21-진입점)
8
+ - [2.2 라이프사이클 (Phase 1~7)](#22-라이프사이클-phase-17)
9
+ - [2.3 워커 구조](#23-워커-구조)
10
+ - [2.4 핵심 파이프라인](#24-핵심-파이프라인)
11
+ - [3. 무거움의 원인 분석](#3-무거움의-원인-분석)
12
+ - [4. 개선 방안 우선순위](#4-개선-방안-우선순위)
13
+ - [4.1 (P1) Convergence 루프 축소](#41-p1-convergence-루프-축소--본-작업의-1번-대상)
14
+ - [4.2 (P2) 프롬프트 캐싱 적용](#42-p2-프롬프트-캐싱-적용)
15
+ - [4.3 (P3) Phase 1 fast-track 라우팅](#43-p3-phase-1-fast-track-라우팅)
16
+ - [4.4 (P4) 워커 정의 공통부 추출 / 템플릿 슬림화](#44-p4-워커-정의-공통부-추출--템플릿-슬림화)
17
+ - [4.5 (P5~) Render 병렬화, token-usage 증분화](#45-p5-render-병렬화-token-usage-증분화)
18
+ - [5. 병렬 작업 가능성](#5-병렬-작업-가능성)
19
+ - [5.1 의존성 매트릭스](#51-의존성-매트릭스)
20
+ - [5.2 권장 분할](#52-권장-분할)
21
+ - [5.3 실행 형태](#53-실행-형태)
22
+ - [6. P1 작업 착수 시 다음 단계](#6-p1-작업-착수-시-다음-단계)
23
+ - [7. 트레이드오프 / 리스크](#7-트레이드오프--리스크)
24
+
3
25
  ## 1. 배경
4
26
 
5
27
  `okstra-run` 스킬(또는 `scripts/okstra.sh`)을 통한 cross-verification 실행이 무겁게 느껴진다는 사용자 피드백을 바탕으로, 현재 파이프라인 구조를 분석하고 개선 후보를 도출한다. 본 문서는 분석 결과와 우선순위, 그리고 병렬 작업 가능성을 정리한다.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "okstra",
3
- "version": "0.26.0",
3
+ "version": "0.28.0",
4
4
  "description": "Multi-agent cross-verification orchestrator runtime + Claude Code skills.",
5
5
  "license": "MIT",
6
6
  "author": "devonshin",
@@ -1,5 +1,5 @@
1
1
  {
2
- "package": "0.26.0",
3
- "builtAt": "2026-05-15T14:37:59.243Z",
2
+ "package": "0.28.0",
3
+ "builtAt": "2026-05-17T03:21:22.744Z",
4
4
  "repoRoot": "/home/runner/work/okstra/okstra"
5
5
  }
@@ -57,8 +57,8 @@ Unlike the Codex / Gemini workers, you are an in-process Claude subagent — you
57
57
  Before producing any output, you MUST read every input file enumerated in the `[Required reading]` block of the lead's prompt from the very first character to the very last character. This includes the task brief, analysis profile, analysis material (if present), reference expectations, the carry-in clarification response (if present), and the final report template.
58
58
 
59
59
  - Use a single `Read` call per file with no `offset` and no `limit`. If a file is genuinely too large for one read, page through it with explicit `offset` / `limit` calls that together cover the entire file, and record the page boundaries in your Findings.
60
- - For the carry-in clarification response, walk every row of `## 5. Clarification Items` (`C-001`, `C-002`, ...) in full, including rows whose `User input` cell is blank — a blank `User input` with `Status=open` is itself a signal you must surface, not skip. Skimming these rows is the most common failure mode here; the fact that the file you will eventually contribute to has a structurally similar section 5 is NOT a license to skim. If the prior report uses the deprecated `4.5.9 Open Questions` / `5.1` / `5.2` layout with `OQ-*` / `A*` / `Q*` IDs, walk all three blocks the same way (legacy carry-in transitional rule).
61
- - Before listing any Findings, state one sentence per input file confirming you read it end-to-end (e.g. "Read task-brief.md end-to-end (147 lines)."). If you cannot truthfully say this for a file, record a `tool-failure` in the errors sidecar instead of fabricating Findings.
60
+ - For the carry-in clarification response, walk every row of `## 5. Clarification Items` (`C-001`, `C-002`, ...) in full, including rows whose `User input` cell is blank — a blank `User input` with `Status=open` is itself a signal you must surface, not skip. Skimming these rows is the most common failure mode here; the fact that the file you will eventually contribute to has a structurally similar section 5 is NOT a license to skim.
61
+ - Before listing any Findings, write a Reading Confirmation block to your **audit sidecar** at `runs/<task-type>/worker-results/claude-worker-audit-<task-type>-<seq>.md` (sibling to your main worker-results file — substitute `claude-worker-<task-type>-<seq>.md` → `claude-worker-audit-<task-type>-<seq>.md`). The sidecar's body begins with `# Claude Worker Audit — <task-key>` followed by one short line per input file confirming end-to-end reading (e.g. `- Read task-brief.md end-to-end (147 lines).`). Do NOT include a `## 0. Reading Confirmation` heading in the main worker-results file — the validator now fails worker-results that contain one. If you cannot truthfully confirm a file end-to-end, record a `tool-failure` in the errors sidecar instead of fabricating Findings.
62
62
  - Do not skip a file because its name suggests its content is already familiar from a prior run. Each file is canonical for the current run only.
63
63
 
64
64
  ## Worker Output Structure
@@ -67,7 +67,6 @@ When returning results, start the file with a YAML frontmatter block, then organ
67
67
 
68
68
  **Frontmatter (mandatory)** — set `workerId: "claude"`. Copy `id`, `aliases`, `taskType`, `task-id`, `task-group`, `project-id`, `date` verbatim from the input files (`analysis-material.md` is canonical; if it lacks any field, record a `tool-failure` and stop). Full schema and a concrete example live in the `okstra-team-contract` skill's "Result Frontmatter" subsection.
69
69
 
70
- 0. **Reading Confirmation** - one short line per input file confirming end-to-end reading (e.g. `- Read task-brief.md end-to-end (147 lines).`). If any file was skipped, record a `tool-failure` and do NOT produce sections 1–5.
71
70
  1. **Findings** - what you identified
72
71
  2. **Missing Information or Assumptions** - gaps in the analysis
73
72
  3. **Safe or Reasonable Areas** - parts that look correct
@@ -76,6 +75,8 @@ When returning results, start the file with a YAML frontmatter block, then organ
76
75
 
77
76
  Include file paths and line numbers when discussing code evidence.
78
77
 
78
+ **Item IDs (mandatory).** Every row in sections 1–5 (and any optional section 6) MUST carry a worker-internal item ID unique within this file. Use the leading column for table-form items (`F-001`, `M-001`, `S-001`, `U-001`, `R-001` per section) or a `[<ID>]` prefix for bullet/numbered items. The ID shape is your choice but it MUST appear — the lead's §1.1 / §1.2 / §3.1 synthesis preserves these IDs in its `Source items (worker:item)` column to keep cross-worker traceability intact. See `prompts/profiles/_common-contract.md` "Cross-worker traceability" SSOT.
79
+
79
80
  **Ticket tagging:** For runs whose task type is `requirements-discovery`, `error-analysis`, `implementation-planning`, or `implementation`, every item in sections 1–5 MUST carry a ticket identifier. Use the `Ticket ID` column in table-form items and the `[TICKETID: <id>]` prefix in bullet/numbered items. Fill priority: `Issue / Ticket` from the input → `Task ID` (no prefix, e.g. `8852`) → `unknown`. Multiple tickets are comma-separated. Full rules live in the `okstra-team-contract` skill's Ticket Tagging section.
80
81
 
81
82
  This contract mirrors the `okstra-team-contract` skill's Worker Output Contract — that skill is the authoritative source if the two ever diverge.
@@ -125,8 +125,8 @@ This wrapper does NOT invoke MCP tools directly. MCP availability inside the Cod
125
125
  Before producing any output, you MUST ensure the underlying Codex CLI run reads every input file enumerated in the `[Required reading]` block of the lead's prompt from the very first character to the very last character. This includes the task brief, analysis profile, analysis material (if present), reference expectations, the carry-in clarification response (if present), and the final report template.
126
126
 
127
127
  - The lead's prompt body, which you persist verbatim and feed into Codex via stdin, already contains the explicit list of files and the end-to-end reading rule. Do not strip or summarize that block before passing it to the CLI.
128
- - For the carry-in clarification response, the CLI must walk every row of `## 5. Clarification Items` (`C-001`, `C-002`, ...) in full, including rows whose `User input` cell is blank — a blank `User input` with `Status=open` is itself a signal you must surface. The fact that the prior run's final report and the upcoming output share section 5 structure is NOT a license to skim. If the prior report uses the deprecated `4.5.9 Open Questions` / `5.1` / `5.2` layout with `OQ-*` / `A*` / `Q*` IDs, walk all three blocks the same way (legacy carry-in transitional rule).
129
- - The Codex output you return MUST begin with one sentence per input file confirming end-to-end reading (e.g. "Read task-brief.md end-to-end (147 lines)."). If any file was skipped, record a `tool-failure` in the errors sidecar instead of fabricating Findings.
128
+ - For the carry-in clarification response, the CLI must walk every row of `## 5. Clarification Items` (`C-001`, `C-002`, ...) in full, including rows whose `User input` cell is blank — a blank `User input` with `Status=open` is itself a signal you must surface. The fact that the prior run's final report and the upcoming output share section 5 structure is NOT a license to skim.
129
+ - The wrapper writes a Reading Confirmation block to the **audit sidecar** at `runs/<task-type>/worker-results/codex-worker-audit-<task-type>-<seq>.md` (sibling to the main worker-results file). The sidecar's body begins with `# Codex Worker Audit — <task-key>` followed by one short line per input file confirming end-to-end reading (e.g. `- Read task-brief.md end-to-end (147 lines).`). The main Codex output MUST NOT contain a `## 0. Reading Confirmation` heading — the validator now fails worker-results that contain one. If any file was skipped, record a `tool-failure` in the errors sidecar instead of fabricating Findings.
130
130
 
131
131
  ## Worker Output Structure
132
132
 
@@ -134,7 +134,6 @@ When returning results, start the file with a YAML frontmatter block, then organ
134
134
 
135
135
  **Frontmatter (mandatory)** — set `workerId: "codex"`. Copy `id`, `aliases`, `taskType`, `task-id`, `task-group`, `project-id`, `date` verbatim from the input files (`analysis-material.md` is canonical; if it lacks any field, record a `tool-failure` and stop). Full schema and a concrete example live in the `okstra-team-contract` skill's "Result Frontmatter" subsection.
136
136
 
137
- 0. **Reading Confirmation** - one short line per input file confirming end-to-end reading (e.g. `- Read task-brief.md end-to-end (147 lines).`). If any file was skipped, record a `tool-failure` and do NOT produce sections 1–5.
138
137
  1. **Findings** - what Codex identified
139
138
  2. **Missing Information or Assumptions** - gaps in the analysis
140
139
  3. **Safe or Reasonable Areas** - parts that look correct
@@ -143,6 +142,8 @@ When returning results, start the file with a YAML frontmatter block, then organ
143
142
 
144
143
  Include file paths and line numbers when discussing code evidence.
145
144
 
145
+ **Item IDs (mandatory).** Every row in sections 1–5 (and any optional section 6) MUST carry a worker-internal item ID unique within this file. Codex tends to use hierarchical numbering (`1.1`, `1.2`, `1.3`, ...); that shape is fine — keep what's natural. What matters is that each item is addressable. The lead's §1.1 / §1.2 / §3.1 synthesis preserves these IDs as `codex:<your-id>` entries in its `Source items (worker:item)` column. See `prompts/profiles/_common-contract.md` "Cross-worker traceability" SSOT.
146
+
146
147
  **Ticket tagging:** For runs whose task type is `requirements-discovery`, `error-analysis`, `implementation-planning`, or `implementation`, every item in sections 1–5 MUST carry a ticket identifier. Use the `Ticket ID` column in table-form items and the `[TICKETID: <id>]` prefix in bullet/numbered items. Fill priority: `Issue / Ticket` from the input → `Task ID` (no prefix, e.g. `8852`) → `unknown`. Multiple tickets are comma-separated. Full rules live in the `okstra-team-contract` skill's Ticket Tagging section.
147
148
 
148
149
  This contract mirrors the `okstra-team-contract` skill's Worker Output Contract — that skill is the authoritative source if the two ever diverge.
@@ -125,8 +125,8 @@ This wrapper does NOT invoke MCP tools directly. MCP availability inside the Gem
125
125
  Before producing any output, you MUST ensure the underlying Gemini CLI run reads every input file enumerated in the `[Required reading]` block of the lead's prompt from the very first character to the very last character. This includes the task brief, analysis profile, analysis material (if present), reference expectations, the carry-in clarification response (if present), and the final report template.
126
126
 
127
127
  - The lead's prompt body, which you persist verbatim and feed into Gemini via stdin, already contains the explicit list of files and the end-to-end reading rule. Do not strip or summarize that block before passing it to the CLI.
128
- - For the carry-in clarification response, the CLI must walk every row of `## 5. Clarification Items` (`C-001`, `C-002`, ...) in full, including rows whose `User input` cell is blank — a blank `User input` with `Status=open` is itself a signal you must surface. The structural similarity between the prior final report and the upcoming output is the most common reason this step gets skipped — do not repeat that. If the prior report uses the deprecated `4.5.9 Open Questions` / `5.1` / `5.2` layout with `OQ-*` / `A*` / `Q*` IDs, walk all three blocks the same way (legacy carry-in transitional rule).
129
- - The Gemini output you return MUST begin with one sentence per input file confirming end-to-end reading (e.g. "Read task-brief.md end-to-end (147 lines)."). If any file was skipped, record a `tool-failure` in the errors sidecar instead of fabricating Findings.
128
+ - For the carry-in clarification response, the CLI must walk every row of `## 5. Clarification Items` (`C-001`, `C-002`, ...) in full, including rows whose `User input` cell is blank — a blank `User input` with `Status=open` is itself a signal you must surface. The structural similarity between the prior final report and the upcoming output is the most common reason this step gets skipped — do not repeat that.
129
+ - The wrapper writes a Reading Confirmation block to the **audit sidecar** at `runs/<task-type>/worker-results/gemini-worker-audit-<task-type>-<seq>.md` (sibling to the main worker-results file). The sidecar's body begins with `# Gemini Worker Audit — <task-key>` followed by one short line per input file confirming end-to-end reading (e.g. `- Read task-brief.md end-to-end (147 lines).`). The main Gemini output MUST NOT contain a `## 0. Reading Confirmation` heading — the validator now fails worker-results that contain one. If any file was skipped, record a `tool-failure` in the errors sidecar instead of fabricating Findings.
130
130
 
131
131
  ## Worker Output Structure
132
132
 
@@ -134,7 +134,6 @@ When returning results, start the file with a YAML frontmatter block, then organ
134
134
 
135
135
  **Frontmatter (mandatory)** — set `workerId: "gemini"`. Copy `id`, `aliases`, `taskType`, `task-id`, `task-group`, `project-id`, `date` verbatim from the input files (`analysis-material.md` is canonical; if it lacks any field, record a `tool-failure` and stop). Full schema and a concrete example live in the `okstra-team-contract` skill's "Result Frontmatter" subsection.
136
136
 
137
- 0. **Reading Confirmation** - one short line per input file confirming end-to-end reading (e.g. `- Read task-brief.md end-to-end (147 lines).`). If any file was skipped, record a `tool-failure` and do NOT produce sections 1–5.
138
137
  1. **Findings** - what Gemini identified
139
138
  2. **Missing Information or Assumptions** - gaps in the analysis
140
139
  3. **Safe or Reasonable Areas** - parts that look correct
@@ -143,6 +142,8 @@ When returning results, start the file with a YAML frontmatter block, then organ
143
142
 
144
143
  Include file paths and line numbers when discussing code evidence.
145
144
 
145
+ **Item IDs (mandatory).** Every row in sections 1–5 (and any optional section 6) MUST carry a worker-internal item ID unique within this file. Gemini may use `F-1`, `F-2`, ... or numbered hierarchical IDs — either is fine. What matters is that each item is addressable. The lead's §1.1 / §1.2 / §3.1 synthesis preserves these IDs as `gemini:<your-id>` entries in its `Source items (worker:item)` column. See `prompts/profiles/_common-contract.md` "Cross-worker traceability" SSOT.
146
+
146
147
  **Ticket tagging:** For runs whose task type is `requirements-discovery`, `error-analysis`, `implementation-planning`, or `implementation`, every item in sections 1–5 MUST carry a ticket identifier. Use the `Ticket ID` column in table-form items and the `[TICKETID: <id>]` prefix in bullet/numbered items. Fill priority: `Issue / Ticket` from the input → `Task ID` (no prefix, e.g. `8852`) → `unknown`. Multiple tickets are comma-separated. Full rules live in the `okstra-team-contract` skill's Ticket Tagging section.
147
148
 
148
149
  This contract mirrors the `okstra-team-contract` skill's Worker Output Contract — that skill is the authoritative source if the two ever diverge.
@@ -46,9 +46,9 @@ If you find yourself thinking "I'll just return the report inline and let lead s
46
46
  Before writing the final report, you MUST read every input file enumerated in the `[Required reading]` block of the lead's prompt from the very first character to the very last character. This always includes `final-report-template.md` and every analysis worker's result file under `worker-results/`, plus the convergence output under `state/convergence-<task-type>-<seq>.json` (if present).
47
47
 
48
48
  - Use a single `Read` call per file with no `offset` and no `limit`. If a file is too large for one read, page through it with explicit `offset` / `limit` calls covering the full file.
49
- - For the carry-in `clarification-response.md` (if present), walk every row of `## 5. Clarification Items` (`C-001`, `C-002`, ...) including rows whose `User input` cell is blank — a blank cell with `Status=open` is itself a signal you must surface in section 0. The fact that the file you write has a structurally similar section 5 is NOT an excuse to skim. If the prior report uses the deprecated `4.5.9 Open Questions` / `5.1` / `5.2` layout with `OQ-*` / `A*` / `Q*` IDs, walk all three blocks the same way (legacy carry-in transitional rule).
49
+ - For the carry-in `clarification-response.md` (if present), walk every row of `## 5. Clarification Items` (`C-001`, `C-002`, ...) including rows whose `User input` cell is blank — a blank cell with `Status=open` is itself a signal you must surface in the conditional `## 0. Clarification Response Carried In From Previous Run` section (the template's `RENDER_IF` guard activates it when the carry-in path is non-empty). The fact that the file you write has a structurally similar section 5 is NOT an excuse to skim. When no carry-in path was provided, OMIT the `## 0.` heading entirely do NOT write an empty-state stub.
50
50
  - Open every analysis-worker result file under `worker-results/` end-to-end. Do not summarize them from convergence output alone — convergence captures classifications, not full evidence.
51
- - Before writing, state one sentence per input file confirming end-to-end reading. If you cannot truthfully say this for a file, record a `tool-failure` in the errors sidecar instead of fabricating the report.
51
+ - Write a Reading Confirmation block to your **audit sidecar** at `runs/<task-type>/worker-results/report-writer-worker-audit-<task-type>-<seq>.md` (sibling to the main worker-results file). The sidecar's body begins with `# Report Writer Worker Audit — <task-key>` followed by one short line per input file confirming end-to-end reading. The main final-report and the main worker-results file MUST NOT contain a `## 0. Reading Confirmation` heading — the validator now fails reports that contain one. If you cannot truthfully confirm a file end-to-end, record a `tool-failure` in the errors sidecar instead of fabricating the report.
52
52
  - When the convergence-state file is present, read it fully and reproduce the `roundHistory[]` array, `round2SkippedReason`, and `finalClassificationCounts` in the final report's Section 1 Round History sub-table. Do not derive these values from worker results alone — they live in `state/convergence-<task-type>-<seq>.json`.
53
53
 
54
54
  ## Authoring Contract
@@ -58,6 +58,11 @@ The final-report file MUST follow `instruction-set/final-report-template.md` if
58
58
  Hard rules:
59
59
 
60
60
  - The file's `Author:` header line is `Report writer worker` (your role) — NOT `Claude lead`.
61
+ - **Source items (worker:item) preservation.** When synthesising `## 1.1 Consensus` / `## 1.2 Differences` / `## 3.1 Primary Evidence` rows from worker outputs, the `Source items` / `Supporting workers` / `Workers (position)` / `Source` column MUST list each contributing worker's item ID as `worker:item-id` (e.g. `claude:F-001, codex:1.1, gemini:F-3`). Bare worker-name lists (e.g. `claude, codex, gemini`) are deprecated — they break traceability back to the original worker-results files. See `prompts/profiles/_common-contract.md` "Cross-worker traceability" SSOT.
62
+ - **Verdict Card (top)** is mandatory in every final-report. Its `Verdict Token` / `Direction` / `Next Step` cells MUST byte-match the corresponding cells in `## 2. Final Verdict` and the first item of `## 6. Recommended Next Steps`. The validator treats the card as a non-authoritative index — divergence is `contract-violated`.
63
+ - **No deprecated sections.** Do NOT emit `4.5.8 User Approval Request` (the body stub is deleted; the top-of-report Approval block is the only one), `4.5.9 Open Questions`, `5.1 추가 자료 요청`, or `5.2 사용자 확인 질문`. The validator fails reports that contain any of these headings.
64
+ - **Conditional Section 0.** Render `## 0. Clarification Response Carried In From Previous Run` ONLY when the carry-in path is non-empty. Never write an empty-state stub (`"No prior clarification response was provided."`). The validator fails empty Section 0.
65
+ - **Reading Confirmation** lives in the audit sidecar (`runs/<task-type>/worker-results/report-writer-worker-audit-<task-type>-<seq>.md`), never in the final-report or main worker-results file.
61
66
  - Include all four convergence categories (Full Consensus, Partial Consensus, Contested, Worker-Unique). Do not omit Contested or Worker-Unique findings.
62
67
  - Include a Round History sub-table in Section 1 (one row per executed round) and a `round2SkippedReason` line below it. When convergence is disabled, omit both. The values are quoted verbatim from `state/convergence-<task-type>-<seq>.json` — do not recompute.
63
68
  - Treat `verification-error` votes as their own verdict. They are listed in vote summaries as `verification-error`, not folded into AGREE/DISAGREE counts.
@@ -121,7 +121,6 @@ PY_ARGS=(
121
121
  [[ -n "${WORK_CATEGORY-}" ]] && PY_ARGS+=(--work-category "$WORK_CATEGORY")
122
122
  [[ -n "${BASE_REF-}" ]] && PY_ARGS+=(--base-ref "$BASE_REF")
123
123
  [[ "$RENDER_ONLY" == "true" ]] && PY_ARGS+=(--render-only)
124
- [[ "$REFRESH_OKSTRA_ASSETS" == "true" ]] && PY_ARGS+=(--refresh-assets)
125
124
  [[ "$PLAN_VERIFICATION_ENABLED" == "false" ]] && PY_ARGS+=(--no-plan-verification)
126
125
 
127
126
  if [[ "$RENDER_ONLY" == "true" ]]; then
@@ -85,4 +85,4 @@ Invoke the `okstra` skill now. Read the manifests below for all task metadata, p
85
85
 
86
86
  - Source path: `{{CLARIFICATION_RESPONSE_RELATIVE_PATH}}`
87
87
  - If the source path above is empty, no prior clarification response was attached to this run.
88
- - If the source path is set, a copy is staged at `{{INSTRUCTION_SET_RELATIVE_PATH}}/clarification-response.md`. Read it before running workers; reconcile each `C-*` row in section 5 (`## 5. Clarification Items`) of the prior report against new evidence and record the outcome in section 0 of this run's final report. If the prior report uses the deprecated `4.5.9 Open Questions` / `5.1` / `5.2` layout with `OQ-*` / `A*` / `Q*` IDs, follow the legacy-carry-in mapping rule in `final-report-template.md` section 0.
88
+ - If the source path is set, a copy is staged at `{{INSTRUCTION_SET_RELATIVE_PATH}}/clarification-response.md`. Read it before running workers; reconcile each `C-*` row in section 5 (`## 5. Clarification Items`) of the prior report against new evidence and record the outcome in the conditional `## 0. Clarification Response Carried In From Previous Run` section of this run's final report (render that heading only when carry-in is non-empty the validator fails empty Section 0 stubs).
@@ -37,11 +37,43 @@ profile document.
37
37
  - On `아니오` / `n` / `keep` → leave the panes intact; remind the user that they will be cleaned up automatically when Claude `/exit` fires the `SessionEnd` hook.
38
38
  - The question MUST be a clean yes/no — do NOT offer "close some / keep some" partial answers, do NOT propose alternatives like "close only codex panes". The whole-set decision keeps the wrap-up predictable.
39
39
  - This step is mandatory for every phase (`requirements-discovery`, `error-analysis`, `implementation-planning`, `implementation`, `final-verification`, `release-handoff`). It is silent-skipped when `$TMUX_PANE` is unset (lead running outside tmux); the lead MUST NOT fabricate a synthetic pane list in that case.
40
+ - Brief handoff contract (shared — applies whenever the run consumes a task brief produced by `okstra-brief`):
41
+ - the brief is a **pre-discovery artifact**: it converts a domain-reporter's words (non-expert *or* developer) into expert-consumable form so this and later phases can run with zero fill-in questions to the operator. The brief is **not** authoritative on solution decisions; it is authoritative on the reporter's intent.
42
+ - **Reporter confirmation precondition (BLOCKING)**: the brief's frontmatter carries `reporter-confirmations: <complete | partial | pending | skipped>` set by `okstra-brief` Step 6.5. Every phase that consumes the brief MUST read this field before doing analysis. The handling matrix is:
43
+ - `complete` → proceed normally.
44
+ - `partial` → proceed; treat still-unmarked `intent-check:` / `conversion-block:` rows as the `skipped` branch.
45
+ - `skipped` → do NOT silently infer the missing answers. Promote each unmarked `intent-check:` / `conversion-block:` row into this run's `## 5. Clarification Items` as `Kind=decision`. Use `Blocks=approval` in `implementation-planning`, where the row gates the User Approval Request; otherwise use `Blocks=next-phase`. The recommended answer is drawn from the brief's matching content and clearly labelled `보고자 직접 확인 권장`.
46
+ - `pending` (or field missing) → ABORT analysis; render the Verdict Card with `Verdict Token = blocked` + `Direction = hold` and write a single `## Reporter Confirmation Required` block (no leading number) summarising which rows are pending. The `## 5. Clarification Items` table carries one row per pending item with `Blocks=approval` in `implementation-planning`, otherwise `Blocks=next-phase`. The operator must rerun `okstra-brief` Step 6.5. Do NOT emit `## 0.` for this case — Section 0 is reserved for clarification-response carry-in only.
47
+ `[CONFIRMED <YYYY-MM-DD> → RC-N]` markers on `Open Questions` rows are the per-row signal that the reporter has answered; their answers live verbatim under `## Reporter Confirmations` in the brief.
48
+ - `Source Material` is reporter-verbatim. Do NOT paraphrase, summarize, reorder, or restructure it. Quote it directly when needed.
49
+ - `Augmentation` entries carry one of four labels — `evidence-link`, `format-conversion`, `terminology-mapping`, `intent-inference`. Treat them as follows:
50
+ - `evidence-link` / `format-conversion` → trust without re-verification.
51
+ - `terminology-mapping` → verify against `<PROJECT_ROOT>/.project-docs/okstra/glossary.md` (authoritative); raise a `Clarification Items` row if the mapping is missing or contradicts the glossary.
52
+ - `intent-inference` → treat as an **unverified hypothesis**. Every `intent-inference` augmentation MUST be paired in the brief with an `Open Questions` row prefixed `intent-check:`. Promote that row into the run's `## 5. Clarification Items` table as `Kind=decision, Blocks=next-phase` (or `Blocks=approval` for `implementation-planning`) with the recommended answer set to "보고자에게 직접 확인 후 응답" unless the codebase can be inspected to confirm or refute the inference.
53
+ - `Open Questions` row prefixes are signals — do not strip them when promoting:
54
+ - `intent-check:` → `Kind=decision`, recommended answer = reporter confirmation. NEVER silently resolve an `intent-check:` by inference at this layer.
55
+ - `terminology:` → `Kind=decision`, recommended answer = canonical term from `<PROJECT_ROOT>/.project-docs/okstra/glossary.md` (or "extend okstra glossary via brief Step 4.5").
56
+ - `conversion-block:` → `Kind=decision`, recommended answer = "보고자에게 직접 확인". The brief is explicitly signalling that translation failed; further inference is forbidden until the reporter clarifies.
57
+ - `adr-candidate:` → handled by `implementation-planning`; carry forward without modification. Approved decision files land at `<PROJECT_ROOT>/.project-docs/okstra/decisions/<NNNN>-<slug>.md` (okstra-internal), never at external `<PROJECT_ROOT>/docs/adr/`.
58
+ - `general:` → free-form; classify per the standard `Clarification Items` rules.
59
+ - Any decision in this run that contradicts the brief's `Source Material` must be raised back to the reporter via a `Clarification Items` row; it must NOT be silently overridden. Disagreement with the reporter is allowed only after the row is resolved.
60
+ - This contract is the single authority on brief consumption. Phase-specific addenda may *tighten* these rules but may not relax them.
40
61
  - Clarification request policy (shared — applies whenever a profile uses `## 5. Clarification Items`):
41
- - section 5 is a **single unified table** per `final-report-template.md`. Every clarification item whether the user must attach a file, choose between options, or supply a single number/path — is one row of that table. Do not split it into sub-sections, do not create a parallel table elsewhere in the report, and do not duplicate the same item into `## 4.5.8 User Approval Request` or any other section.
62
+ - **Canonical column schema (SSOT must match `templates/reports/final-report.template.md` §5.1 exactly):** every `## 5. Clarification Items` table has exactly these 8 columns, in this order:
63
+ `| ID | Ticket ID | Kind | Statement | Expected form | Blocks | Status | User input |`.
64
+ Profile-specific addenda may tighten cell content but MUST NOT add, remove, rename, or reorder columns. The `ID` cell uses `C-NNN` (3-digit zero-padded), the `Status` cell ∈ `{open, answered, resolved, obsolete}`, and the `Kind` / `Blocks` legal values are listed below.
65
+ - section 5 is a **single unified table** per `final-report-template.md`. Every clarification item — whether the user must attach a file, choose between options, or supply a single number/path — is one row of that table. Do not split it into sub-sections (`5.1 추가 자료 요청` / `5.2 사용자 확인 질문` / `4.5.9 Open Questions` are removed and the validator fails reports that reintroduce them), do not create a parallel table elsewhere in the report, and do not duplicate the same item into the top-of-report `User Approval Request (사용자 승인 게이트)` block or any other section.
42
66
  - each row's `Kind` column picks one of `{material, decision, data-point}`: `material` for files / snapshots / logs / screenshots the user must attach (the `User input` cell will hold a path or URL); `decision` for choices and yes/no confirmations only the user can make; `data-point` for a single number, ID, date, or short string the user can answer inline. Items that mix "yes/no + file path if yes" are one row of `Kind=material` with the combined expectation written into `Expected form`.
43
- - each row's `Blocks` column picks one of `{approval, next-phase, none}`. `approval` is reserved for items that gate the `implementation-planning` User Approval Request never use `approval` outside that task-type. `next-phase` blocks the next run from starting cleanly. `none` is informational/audit-only.
67
+ - each row's `Blocks` column picks one of `{approval, next-phase, none}`. `approval` is reserved for items that gate an approval action, especially the `implementation-planning` User Approval Request; outside `implementation-planning`, unresolved brief reporter-confirmation rows use `next-phase` instead. `next-phase` blocks the next run from starting cleanly. `none` is informational/audit-only.
44
68
  - write every entry in full, descriptive sentences that a non-developer can act on without further context. Avoid abbreviations and internal jargon. The `Statement` cell must state *what* is needed, *why* the answer / attachment changes the next step, and (for `material`) *where* the user can find it and *where* to place it. The `Expected form` cell must state the shape of the answer (예/아니오, 보기 중 하나, 숫자/날짜, 파일 경로, 짧은 서술 등); supply concrete option choices when applicable.
45
69
  - the same `final-report.md` file is the canonical artifact carried into the next run; the user appends answers inline before rerunning. The preferred turn-around is `scripts/okstra.sh --resume-clarification --task-key <project-id>:<task-group>:<task-id>` (opens the latest report in `$EDITOR`, then auto-reruns the same phase with `--clarification-response` carry-in). The lower-level form `--clarification-response <path>` remains available for scripted runs.
46
- - if a clarification response was carried in for this run, walk every `C-*` row of the prior report's `## 5. Clarification Items` table in section 0 of this report, reconcile each one against new evidence, and update its `Status` to `resolved` or `obsolete` before issuing the next decision/verdict.
47
- - transitional rule for legacy carry-in (one release cycle): if the prior report uses the deprecated `4.5.9 Open Questions` / `5.1 Additional Materials` / `5.2 Questions for the User` layout, follow the mapping described in section 0 of `final-report-template.md` collapse `OQ-*` / `A*` / `Q*` into `C-*` rows in this run's new section 5 (legacy ID preserved in the Statement for traceability).
70
+ - if a clarification response was carried in for this run, render the conditional `## 0. Clarification Response Carried In From Previous Run` section (the template's `RENDER_IF` guard activates it), walk every `C-*` row of the prior report's `## 5. Clarification Items` table, reconcile each one against new evidence, and update its `Status` to `resolved` or `obsolete` before issuing the next decision/verdict. When no carry-in path was provided, omit the `## 0.` heading entirely — the validator fails reports that emit an empty Section 0 stub (e.g. "No prior clarification response was provided for this run.").
71
+ - Verdict Card (shared applies to every final-report regardless of profile):
72
+ - The top-of-report `## Verdict Card` block is mandatory in every final-report. Its `Verdict Token`, `Direction`, and `Next Step` cells MUST byte-match the corresponding cells in `## 2. Final Verdict` and the first item of `## 6. Recommended Next Steps`. The validator treats the card as a non-authoritative index — when card values diverge from the authoritative sections, the run is `contract-violated`.
73
+ - Cross-worker traceability (shared — applies to every analysis worker output and to the lead's `## 1.` / `## 3.` tables in the final-report):
74
+ - **Worker-side item IDs (free-form but unique within the worker).** Every row item in sections 1–5 (and any optional section 6) of an analysis worker's output MUST carry an item ID that is unique within that one worker's result file. The ID convention is the worker's choice — `F-001` / `F-002` per the suggested schema, `1.1` / `1.2` / `1.3` as Codex tends to use, or any other shape — but it MUST appear as the leading column of the row (for table-form items) or as a `[<ID>]` prefix (for bullet/numbered items). Workers that emit findings without IDs make cross-worker reconciliation impossible.
75
+ - **Lead-side ID assignment + source preservation.** When the lead (or `report-writer-worker`) synthesises `## 1.1 Consensus` / `## 1.2 Differences` / `## 3.1 Primary Evidence` rows from worker outputs, the lead assigns a fresh `C-NNN` / `D-NNN` / `E-NNN` row ID. The `Source items` column (or, where the template still calls it `Supporting workers` / `Workers (position)` / `Source`, that same column) MUST list every contributing worker:item pair (e.g. `claude:F-001, codex:1.1, gemini:F-3`) so a reviewer can trace the synthesised row back to each worker's original wording without re-reading every worker-results file. Bare worker names without item IDs (e.g. `claude, codex, gemini`) are deprecated for these tables; the validator does not yet fail on them but the readability pass treats it as a contract violation.
76
+ - **Why this matters.** A real run had `claude=F-1..F-11`, `codex=1.1..1.8`, `gemini=F-3..F-9` — three incompatible ID schemes. When the lead synthesised `C-1..C-8`, the link from `C-3` back to "which sentence in which worker file" was lost. Source-item preservation restores that link without forcing every worker to adopt a single ID prefix, which would over-constrain worker output style.
77
+ - Audit sidecar (shared — applies to every analysis-worker output and every final-report):
78
+ - Reading Confirmation lines (one short line per input file confirming end-to-end reading) live in the **worker audit sidecar** at `runs/<task-type>/worker-results/<worker>-audit-<task-type>-<seq>.md`, NOT in the worker's main worker-results file. The worker-results body starts at section 1 (Findings). The validator fails worker-results files that contain a `## 0. Reading Confirmation` heading.
79
+ - The audit sidecar carries any other meta the worker wants to log (tool-call counts, MCP query summaries, timing notes). The lead's final-report does NOT duplicate this content — it is consumed by the validator and by post-run audit tooling, not by end-user readers.
@@ -8,6 +8,15 @@
8
8
  - Optional workers (opt-in via `--workers`):
9
9
  - gemini — when added to the roster it joins the analyser set; omitted by default
10
10
  {{INCLUDE:_common-contract.md}}
11
+ - Brief consumption (phase-specific addendum — shared rules live in `_common-contract.md` under "Brief handoff contract"):
12
+ - **Precondition check (BLOCKING — runs before any analysis)**: read the brief's frontmatter `reporter-confirmations:` field and inspect every `Open Questions` row prefixed `intent-check:` / `conversion-block:` for the `[CONFIRMED …]` marker.
13
+ - `reporter-confirmations: complete` → proceed normally.
14
+ - `reporter-confirmations: partial` → proceed; treat still-unmarked `intent-check:` / `conversion-block:` rows per the `skipped` branch below.
15
+ - `reporter-confirmations: skipped` (or `partial` with remainder) → do NOT silently infer the missing answers. Promote each unmarked `intent-check:` / `conversion-block:` row into this run's `## 5. Clarification Items` as `Kind=decision, Blocks=next-phase`, with the recommended answer drawn from the brief's matching `intent-inference` / `conversion-block:` text and clearly labelled `보고자 직접 확인 권장`. Then proceed with the root-cause analysis using the inference as a *hypothesis* only.
16
+ - `reporter-confirmations: pending` (or field missing) → ABORT analysis. Write only `## 0. Reporter Confirmation Required` summarising which rows are pending and stop. The final report carries `Blocks=next-phase`.
17
+ - the reporter's symptom description in `Source Material` is the ground truth for what to reproduce. Do not paraphrase it when stating the symptom in the report; quote it.
18
+ - any `intent-inference` augmentation that re-characterises the symptom (e.g. classifying "가끔 안 됨" as "intermittent failure on a specific code path") is a **hypothesis**, not a confirmed symptom. If `[CONFIRMED …]` appears on the matching `intent-check:` row, treat the confirmation as the symptom; otherwise, follow the precondition's `skipped` branch above and keep the inference labelled as hypothesis in the root-cause analysis.
19
+ - `conversion-block:` rows mean the brief could not map a reporter statement to project vocabulary; never attempt to invent the missing mapping in this phase — the precondition above already handled them.
11
20
  - Primary focus areas:
12
21
  - symptom and trigger clarification
13
22
  - root-cause candidates
@@ -22,6 +31,9 @@
22
31
  - Clarification request policy (phase-specific addenda — shared policy is in `_common-contract.md`):
23
32
  - if any blocking uncertainty remains at the time of writing the final report, populate `## 5. Clarification Items` in `final-report-template.md` (a single unified table; `Blocks=next-phase` for items the next run cannot start without)
24
33
  - prefer plain Korean over abbreviations (e.g. write "초당 평균 요청 수" instead of "QPS", "재현 절차" instead of "repro")
34
+ - every clarification row carries a `Recommended` answer + one-line rationale; rows that lack a recommendation are rejected as half-formed.
35
+ - **Codebase-first ambiguity resolution (defect rule)**: any ambiguity about repro, file behavior, or symbol semantics that can be answered by `Read` / `Grep` / log inspection MUST be resolved that way and recorded with file:line (or log-line) evidence. Writing a clarification row for something the codebase or shipped logs already answer is a defect of this phase.
36
+ - **`evidence-checked:` cell required**: every clarification row carries an `evidence-checked: <path:line> | none` cell. `evidence-checked: <path:line>` means the codebase / log / reproducer was inspected and the row records what was found. `evidence-checked: none` is allowed ONLY when the row's nature is "only the reporter can answer this" (reporter-side data, business priority, environment they observed); the row body must state which one in one line. A row with `evidence-checked: none` that *could* have been answered by code or logs is a defect.
25
37
  - Non-goals:
26
38
  - implementation details unless they are necessary to validate the cause
27
39
  - **source code edits, builds, migrations, or deployments** — this run produces evidence and cause analysis only; the fix belongs to a later `implementation-planning` run followed by an `implementation` run
@@ -8,11 +8,21 @@
8
8
  - Optional workers (opt-in via `--workers`):
9
9
  - gemini — when added to the roster it joins the analyser set; omitted by default
10
10
  {{INCLUDE:_common-contract.md}}
11
+ - Brief consumption (phase-specific addendum — shared rules live in `_common-contract.md` under "Brief handoff contract"):
12
+ - **Precondition check (BLOCKING — runs before option drafting)**: read the brief's frontmatter `reporter-confirmations:` field and inspect every `Open Questions` row prefixed `intent-check:` / `conversion-block:` for the `[CONFIRMED …]` marker.
13
+ - `reporter-confirmations: complete` → proceed normally.
14
+ - `reporter-confirmations: partial` → proceed; treat still-unmarked `intent-check:` / `conversion-block:` rows per the `skipped` branch below.
15
+ - `reporter-confirmations: skipped` (or `partial` with remainder) → do NOT silently infer the missing answers. Promote each unmarked `intent-check:` / `conversion-block:` row into this run's `## 5. Clarification Items` as `Kind=decision, Blocks=approval`, with the recommended answer drawn from the brief's matching `intent-inference` / `conversion-block:` text and clearly labelled `보고자 직접 확인 권장`. Then proceed; the operator cannot toggle `User Approval Request` until those rows are resolved.
16
+ - `reporter-confirmations: pending` (or field missing) → ABORT planning. Write only `## 0. Reporter Confirmation Required` summarising which rows are pending and stop. The final report carries `Blocks=approval`.
17
+ - never plan around an unconfirmed `intent-inference` augmentation as if it were a settled requirement. After the precondition runs, a `[CONFIRMED …]` marker on the matching `intent-check:` row is the signal that the inference can be treated as settled; otherwise it remains a `Blocks=approval` clarification item per the precondition's `skipped` branch.
18
+ - `conversion-block:` rows are handled by the precondition; planning around an untranslated reporter phrase is forbidden until it is resolved.
11
19
  - Pre-planning context exploration (mandatory before option drafting):
12
20
  - read the task brief, related-task briefs, and any cited spec / design doc end-to-end
13
21
  - inspect the current state of every file the task names (or the closest matching files if names are stale) — record current responsibilities, public interfaces, and known coupling points
14
22
  - skim recent commits touching those files (`git log -- <path>`) to surface in-flight work or contested areas
23
+ - **codebase-first ambiguity resolution**: any ambiguity that can be answered by `Read` / `Grep` MUST be resolved that way and recorded with file:line evidence. Only ambiguities that genuinely require a human decision are escalated as `Clarification Items` rows. Writing a clarification row for something the code already answers is a defect of this phase.
15
24
  - flag any requirement that is ambiguous, contradictory, or missing success criteria — register each one as a row in the report's `## 5. Clarification Items` table with `Blocks=approval` instead of guessing
25
+ - read in priority order — (authoritative) `<PROJECT_ROOT>/.project-docs/okstra/glossary.md` and `<PROJECT_ROOT>/.project-docs/okstra/decisions/` titles if present; (supplementary) `<PROJECT_ROOT>/CONTEXT.md` (or `CONTEXT-MAP.md` → per-context `CONTEXT.md`) and `<PROJECT_ROOT>/docs/adr/` titles if present. Absent external files are the normal state — do not error. Treat the brief's `terminology:*` resolutions from `requirements-discovery` (if any) as authoritative; if missing, resolve any remaining fuzzy term as a `Blocks=approval` clarification row.
16
26
  - Primary focus areas:
17
27
  - requirement gaps
18
28
  - affected components and boundaries
@@ -38,6 +48,9 @@
38
48
  - this run stays in `implementation-planning` regardless of user phrasing — the shared anti-escalation rule applies
39
49
  - dispatching parallel sub-agents beyond the required worker roster — okstra owns worker fan-out
40
50
  - writing artifacts to `docs/superpowers/specs/` or `docs/superpowers/plans/` — the run's `reports/` directory is the canonical location
51
+ - Clarification request policy (phase-specific addenda — shared policy is in `_common-contract.md`):
52
+ - every clarification row carries a `Recommended` answer + one-line rationale; rows that lack a recommendation are rejected as half-formed.
53
+ - **`evidence-checked:` cell required**: every clarification row carries an `evidence-checked: <path:line> | none` cell. `evidence-checked: <path:line>` means the codebase was inspected and the row records what was found. `evidence-checked: none` is allowed ONLY when the row's nature is "only a human can answer this" (reporter intent, business priority, organisational decision); the row body must state which one in one line. A row with `evidence-checked: none` that *could* have been answered by the codebase is a defect of this phase, restated from the pre-planning rule above.
41
54
  - Section heading contract (BLOCKING — validator scans for these literal English substrings):
42
55
  - The final report MUST include section headings containing each of the following exact strings: `Option Candidates`, `Trade-off`, `Recommended Option`, `Stepwise Execution Order`, `Dependency`, `Validation Checklist`, `Rollback`, `User Approval Request`.
43
56
  - Korean translations are allowed in parentheses (e.g. `### Recommended Option (권장 옵션)`), but the English keyword must be present verbatim in the heading line.
@@ -60,6 +73,13 @@
60
73
  - **the marker line is rendered only when the plan-body verification gate (§4.5.9) returns `passed` or `passed-with-dissent`.** When the gate returns `blocked-by-disagreement` or `aborted-non-result`, the top-of-report Approval block is rendered **without** the canonical `- [ ] Approved` bullet (the rest of the block — title, summary, audit lines — stays). The `validators/validate-run.py` `validate_phase_boundary` function enforces this exact correspondence between gate result and marker line presence.
61
74
  - every ambiguity flagged during pre-planning that the user must resolve before approval registered as a `Blocks=approval` row in the `## 5. Clarification Items` table (do NOT create a separate `Open Questions` block under `4.5.x` — the unified table is the single home)
62
75
  - **§4.5.9 Plan Body Verification (BLOCKING).** After report-writer finishes the draft, the lead MUST run a worker peer-review round on the consolidated plan body (sections 4.5.1 – 4.5.7) and populate `### 4.5.9 Plan Body Verification` in the final report. The round protocol, plan-item ID scheme (`P-Opt-*` / `P-Step-*` / `P-Dep-*` / `P-Val-*` / `P-Rb-*`), verdict semantics, gate-result classification, and dissent log format are defined in `skills/okstra-convergence/SKILL.md` "Plan-body verification mode". The four gate-result values are `passed`, `passed-with-dissent`, `blocked-by-disagreement`, `aborted-non-result`. When the gate would have been `blocked-by-disagreement` or `aborted-non-result`, the lead MUST NOT silently flip it to one of the passing values to "unblock" the run — that is a contract violation.
76
+ - **ADR evaluation (grill-with-docs adopted, sole owner)**: this phase is the **single owner** of ADR evaluation in the okstra lifecycle. The brief never evaluates or drafts ADRs — it only forwards `adr-candidate:*` signals. Every `adr-candidate:*` entry inherited from the brief's `Open Questions` is a mandatory evaluation target. In addition, evaluate every decision the recommended option introduces against the three ADR criteria:
77
+ 1. **Hard to reverse** — would changing the decision later cost meaningfully more than deciding now?
78
+ 2. **Surprising without context** — would a future reader, seeing only the code, wonder "why was it built this way?"?
79
+ 3. **Real trade-off** — were there named alternatives, and was one picked for specific reasons?
80
+ If **all three** hold, attach a decision draft as a report appendix section titled `Decision Drafts` (one decision per subsection). Each draft uses the `## Context / ## Decision / ## Consequences / ## Alternatives Considered` shape, names the alternatives that were rejected and why, and starts with `## Status: Proposed`. The next decision number is `(max existing in <PROJECT_ROOT>/.project-docs/okstra/decisions/ + 1)` zero-padded to 4 digits. If any of the three criteria is missing, do NOT raise a decision draft — instead record `skipped adr-candidate: <topic> — reason: <criterion that failed>` on one line under `Decision Drafts` so the next reader knows the candidate was evaluated and intentionally dropped.
81
+ The drafts are NOT written by this phase. The approved plan's stepwise execution order MUST include the step `Create <PROJECT_ROOT>/.project-docs/okstra/decisions/<NNNN>-<slug>.md from the decision draft in section X` so the `implementation` run commits the file. External `<PROJECT_ROOT>/docs/adr/` is never touched.
82
+ - **Domain-doc proposals**: if `CONTEXT.md` / `CONTEXT-MAP.md` needs a new term or edited definition, add the step `Update CONTEXT.md: <term> = <definition>` to the stepwise execution order. Do NOT edit the file in this phase.
63
83
  - No-placeholder rule (plan failures — reject any option or step that contains these):
64
84
  - "TBD", "TODO", "implement later", "fill in details", "add appropriate error handling", "handle edge cases", "write tests for the above" without actual test code
65
85
  - "similar to Option/Task N" without repeating the concrete content (readers may consume sections out of order)
@@ -8,19 +8,39 @@
8
8
  - Optional workers (opt-in via `--workers`):
9
9
  - gemini — when added to the roster it joins the analyser set; omitted by default
10
10
  {{INCLUDE:_common-contract.md}}
11
+ - Brief consumption (phase-specific addendum — shared rules live in `_common-contract.md` under "Brief handoff contract"):
12
+ - **Precondition check (BLOCKING — runs before any analysis)**: read the brief's frontmatter `reporter-confirmations:` field and inspect every `Open Questions` row prefixed `intent-check:` / `conversion-block:` for the `[CONFIRMED …]` marker.
13
+ - `reporter-confirmations: complete` → proceed normally (no unresolved reporter-only rows).
14
+ - `reporter-confirmations: partial` → proceed; treat the still-unmarked `intent-check:` / `conversion-block:` rows per the `skipped` branch below.
15
+ - `reporter-confirmations: skipped` (or `partial` with remainder) → do NOT silently infer the missing answers. Promote each unmarked `intent-check:` / `conversion-block:` row into this run's `## 5. Clarification Items` as `Kind=decision, Blocks=next-phase`, with the recommended answer drawn from the brief's matching `intent-inference` / `conversion-block:` text and clearly labelled `보고자 직접 확인 권장`. Then proceed with the rest of the classification work.
16
+ - `reporter-confirmations: pending` (or field missing) → ABORT analysis. Write only `## 0. Reporter Confirmation Required` summarising which rows are pending and stop. The operator must rerun `okstra-brief` Step 6.5 to collect answers, then restart this phase. The final report carries `Blocks=next-phase`.
17
+ - before classifying (after the precondition passes), scan the brief for every `Open Questions` row prefixed `intent-check:` / `terminology:` / `conversion-block:` and every `Augmentation` entry labelled `intent-inference` / `terminology-mapping`. Each one is a translation signal that this phase must resolve OR carry forward.
18
+ - `intent-inference` augmentations whose paired `intent-check:` row carries `[CONFIRMED …]` are treated as **confirmed**; trust the confirmation text in `## Reporter Confirmations` over the original inference if they differ. Unconfirmed `intent-inference` rows under `reporter-confirmations: skipped` follow the precondition's `skipped` branch above.
19
+ - `conversion-block:` rows are explicit "translation failed" signals — never attempt to resolve them by inference here; the precondition above already handled them.
11
20
  - Primary focus areas:
12
21
  - classify the work as bugfix, feature, improvement, refactor, or ops-change
13
22
  - determine whether `error-analysis` or `implementation-planning` is the next safe step; direct `implementation` handoff is not a valid routing target because implementation requires an approved `implementation-planning` report
14
23
  - identify missing materials that block reliable routing
15
24
  - define task continuity expectations for long-running work under the same task key
16
25
  - capture approval or confirmation points before the next phase starts
26
+ - **domain alignment check**: read in priority order — (authoritative) `<PROJECT_ROOT>/.project-docs/okstra/glossary.md` and `<PROJECT_ROOT>/.project-docs/okstra/decisions/` titles if present; (supplementary) `<PROJECT_ROOT>/CONTEXT.md` (or `CONTEXT-MAP.md` → per-context `CONTEXT.md`) and `<PROJECT_ROOT>/docs/adr/` titles if present. Absent external files are normal — do not error. Validate that every `terminology:*` entry under the brief's `Open Questions` has a canonical resolution before routing. Fuzzy or overloaded terms in the brief MUST be resolved to a single canonical term in this phase.
27
+ - Decision-tree walk (grill-me adopted, bounded):
28
+ - When the brief's `Desired Outcome`, classification, or routing target depends on a chain of decisions, walk that chain one branch at a time. Each branch is one `Clarification Items` row, not a free-form interview.
29
+ - For every clarification row, write the row's `Recommended` cell with the single best answer plus a one-line rationale. Other options are listed in `Alternatives` with one-sentence consequences.
30
+ - **Codebase-first rule**: if a branch can be resolved by `Read` / `Grep` / file inspection, resolve it that way and record the evidence in the same row's `Evidence` cell. Do NOT escalate to the user.
31
+ - Budget: the unified `## 5. Clarification Items` table caps at the smaller of (a) one row per unresolved decision branch, (b) 8 rows total. Beyond the cap, fold remaining ambiguity into the routing recommendation's risk notes.
17
32
  - Expected output emphasis:
18
33
  - evidence-backed routing decision
19
34
  - uncertainty boundaries and missing inputs
20
35
  - next recommended phase and safe resume guidance
36
+ - canonical-term resolution for every `terminology:*` brief item, written as a one-line `<term> = <definition>` line in a new `Domain Alignment` subsection of the final report; alongside each, propose whether `<PROJECT_ROOT>/.project-docs/okstra/glossary.md` should be updated (proposal only — actual writes happen via `okstra-brief` Step 4.5 on a subsequent run)
21
37
  - Clarification request policy (phase-specific addenda — shared policy is in `_common-contract.md`):
22
38
  - if any blocking input is missing at the time of writing the final report, populate `## 5. Clarification Items` in `final-report-template.md` (a single unified table; `Blocks=next-phase` for items the next run cannot start without)
23
39
  - prefer concrete questions whose answers map directly to a routing decision (`bugfix` vs `feature`, `error-analysis` vs `implementation-planning`, etc.). State each option in plain language with one sentence describing what choosing it would mean for the next phase.
40
+ - every clarification row carries a `Recommended` answer + one-line rationale; rows that lack a recommendation are rejected as half-formed.
41
+ - **Codebase-first ambiguity resolution (defect rule)**: any ambiguity that can be answered by `Read` / `Grep` / file inspection MUST be resolved that way and recorded with file:line evidence. Writing a clarification row for something the codebase already answers is a defect of this phase.
42
+ - **`evidence-checked:` cell required**: every clarification row carries an `evidence-checked: <path:line> | none` cell. `evidence-checked: <path:line>` means the codebase was inspected and the row records what was found (or that the code did not contain the answer). `evidence-checked: none` is allowed ONLY when the row's nature is "only a human can answer this" (reporter intent, business priority, external authority); the row body must state which one in one line. A row with `evidence-checked: none` that *could* have been answered by the codebase is a defect.
24
43
  - Non-goals:
25
44
  - full implementation design unless it is required to decide the next phase
26
45
  - **source code edits, plan authoring, builds, or deployments** — this run only classifies the work and routes it; deeper analysis and planning belong to subsequent phases
46
+ - **edits to any path outside `<PROJECT_ROOT>/.project-docs/okstra/`** — okstra never writes to external paths. Glossary additions land in `<PROJECT_ROOT>/.project-docs/okstra/glossary.md` (via `okstra-brief` Step 4.5); decision drafts land in `<PROJECT_ROOT>/.project-docs/okstra/decisions/` (via `implementation-planning`). External `<PROJECT_ROOT>/CONTEXT.md` / `CONTEXT-MAP.md` / `docs/adr/` are read-only references.