okstra 0.97.0 → 0.98.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.
- package/README.kr.md +4 -3
- package/README.md +4 -3
- package/docs/kr/architecture.md +2 -2
- package/docs/kr/cli.md +2 -0
- package/docs/kr/container.md +122 -0
- package/docs/project-structure-overview.md +12 -2
- package/docs/superpowers/plans/2026-06-21-okstra-container-local-user-test.md +714 -0
- package/docs/superpowers/specs/2026-06-21-okstra-container-local-user-test-design.md +125 -0
- package/package.json +1 -1
- package/runtime/BUILD.json +2 -2
- package/runtime/agents/workers/antigravity-worker.md +2 -18
- package/runtime/agents/workers/claude-worker.md +10 -33
- package/runtime/agents/workers/codex-worker.md +2 -18
- package/runtime/agents/workers/report-writer-worker.md +2 -10
- package/runtime/bin/lib/okstra/interactive.sh +10 -2
- package/runtime/bin/lib/okstra-ctl/cmd-tail.sh +5 -2
- package/runtime/prompts/profiles/_clarification-recommendation.md +1 -0
- package/runtime/prompts/profiles/_coding-conventions-preflight.md +1 -1
- package/runtime/prompts/profiles/_common-contract.md +3 -3
- package/runtime/prompts/profiles/_coverage-critic.md +17 -0
- package/runtime/prompts/profiles/_implementation-deliverable.md +2 -2
- package/runtime/prompts/profiles/_implementation-executor.md +2 -2
- package/runtime/prompts/profiles/_implementation-self-check.md +2 -1
- package/runtime/prompts/profiles/_implementation-verifier.md +3 -3
- package/runtime/prompts/profiles/_stage-discipline.md +5 -8
- package/runtime/prompts/profiles/error-analysis.md +5 -5
- package/runtime/prompts/profiles/final-verification.md +4 -4
- package/runtime/prompts/profiles/implementation-planning.md +7 -7
- package/runtime/prompts/profiles/implementation.md +5 -5
- package/runtime/prompts/profiles/improvement-discovery.md +6 -6
- package/runtime/prompts/profiles/release-handoff.md +3 -3
- package/runtime/prompts/profiles/requirements-discovery.md +4 -4
- package/runtime/prompts/wizard/prompts.ko.json +0 -1
- package/runtime/python/okstra_ctl/__init__.py +4 -1
- package/runtime/python/okstra_ctl/container.py +970 -0
- package/runtime/python/okstra_ctl/container_registry.py +93 -0
- package/runtime/python/okstra_ctl/error_zip.py +4 -4
- package/runtime/python/okstra_ctl/handoff.py +7 -1
- package/runtime/python/okstra_ctl/ids.py +40 -1
- package/runtime/python/okstra_ctl/listing.py +3 -5
- package/runtime/python/okstra_ctl/log_report.py +102 -0
- package/runtime/python/okstra_ctl/pane_reclaim.py +5 -4
- package/runtime/python/okstra_ctl/paths.py +40 -0
- package/runtime/python/okstra_ctl/plan_run_root.py +78 -0
- package/runtime/python/okstra_ctl/reconcile.py +4 -2
- package/runtime/python/okstra_ctl/resolve_task_key.py +54 -0
- package/runtime/python/okstra_ctl/run.py +48 -30
- package/runtime/python/okstra_ctl/stage_integrate.py +8 -2
- package/runtime/python/okstra_ctl/stage_targets.py +79 -0
- package/runtime/python/okstra_ctl/time_report.py +200 -0
- package/runtime/python/okstra_ctl/tmux.py +67 -0
- package/runtime/python/okstra_ctl/wizard.py +35 -20
- package/runtime/python/okstra_project/__init__.py +2 -0
- package/runtime/python/okstra_project/state.py +50 -2
- package/runtime/skills/okstra-brief/SKILL.md +17 -7
- package/runtime/skills/okstra-container/SKILL.md +169 -0
- package/runtime/skills/okstra-inspect/SKILL.md +64 -178
- package/runtime/skills/okstra-memory/SKILL.md +8 -6
- package/runtime/skills/okstra-run/SKILL.md +4 -4
- package/runtime/skills/okstra-schedule/SKILL.md +9 -16
- package/runtime/skills/okstra-setup/SKILL.md +10 -9
- package/runtime/templates/reports/brief.template.md +1 -1
- package/runtime/templates/reports/final-report.template.md +1 -1
- package/runtime/templates/reports/settings.template.json +3 -1
- package/runtime/validators/validate-implementation-plan-stages.py +11 -3
- package/src/cli-registry.mjs +28 -0
- package/src/commands/inspect/container.mjs +27 -0
- package/src/commands/inspect/log-report.mjs +26 -0
- package/src/commands/inspect/resolve-task-key.mjs +26 -0
- package/src/commands/inspect/task-list.mjs +26 -15
- package/src/commands/inspect/time-report.mjs +26 -0
- package/src/commands/lifecycle/check-project.mjs +7 -1
- package/src/commands/lifecycle/doctor.mjs +16 -0
- package/src/lib/skill-catalog.mjs +1 -0
- package/runtime/agents/TODO.md +0 -226
|
@@ -10,9 +10,7 @@ resolver matches it anywhere and would recurse on this file itself.
|
|
|
10
10
|
|
|
11
11
|
## Stage discipline — preceding stages are behavior-frozen
|
|
12
12
|
|
|
13
|
-
A stage that is already `done`
|
|
14
|
-
into this run's base) is **behavior-frozen**: code it added or modified keeps its
|
|
15
|
-
existing behavior. Later stages MAY call, extend, or compose with that code, but
|
|
13
|
+
A stage that is already `done` — a `depends-on` predecessor whose work is merged into this run's base — is **behavior-frozen**: code it added or modified keeps its existing behavior. Later stages MAY call, extend, or compose with that code, but
|
|
16
14
|
MUST NOT change what it already does. This preserves the verified-stays-verified
|
|
17
15
|
invariant — a completed, conformance-passed stage must not silently regress when
|
|
18
16
|
a later stage runs.
|
|
@@ -27,10 +25,9 @@ a later stage runs.
|
|
|
27
25
|
or modified by a preceding done stage. Touching such a file to *extend* it (a
|
|
28
26
|
new branch, a new caller, an additive field) is allowed; changing its existing
|
|
29
27
|
behavior is not. If a plan step appears to require a behavior change to
|
|
30
|
-
prior-stage code, treat it as a planning defect: record the finding
|
|
31
|
-
to a new `implementation-planning` run
|
|
28
|
+
prior-stage code, treat it as a planning defect. Do two things and only these: record the finding, then route
|
|
29
|
+
to a new `implementation-planning` run. Never silently rewrite the prior-stage code.
|
|
32
30
|
- **Report evidence (declaration-level).** When this stage modifies a file that
|
|
33
|
-
a preceding stage added or modified, the final report MUST record
|
|
34
|
-
|
|
35
|
-
it was touched, and how the prior stage's behavior was preserved. Absent that
|
|
31
|
+
a preceding stage added or modified, the final report MUST record three facts in the deliverable's edits / Validation Evidence section: which file,
|
|
32
|
+
why it was touched, and how the prior stage's behavior was preserved. Absent that
|
|
36
33
|
note, a reviewer treats a prior-stage edit as an unverified regression risk.
|
|
@@ -11,10 +11,10 @@
|
|
|
11
11
|
- Brief consumption (phase-specific addendum — shared rules live in `_common-contract.md` under "Brief handoff contract"):
|
|
12
12
|
- Apply the shared reporter-confirmation precondition exactly as written. In this phase, unresolved `intent-check:` / `conversion-block:` rows use `Blocks=next-phase`; any unconfirmed inference may be used as a labelled hypothesis only.
|
|
13
13
|
- 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.
|
|
14
|
-
- 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
|
|
15
|
-
- `conversion-block:` rows mean the brief could not map a reporter statement to project vocabulary; never
|
|
14
|
+
- 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 that confirmation as the symptom. Otherwise follow the precondition's `skipped` branch above and keep the inference labelled as a hypothesis in the root-cause analysis.
|
|
15
|
+
- `conversion-block:` rows mean the brief could not map a reporter statement to project vocabulary; never invent the missing mapping in this phase.
|
|
16
16
|
- Diagnosis loop:
|
|
17
|
-
- **Symptom lock:** state the reporter's symptom verbatim, then translate it into one observable failure condition. If
|
|
17
|
+
- **Symptom lock:** state the reporter's symptom verbatim, then translate it into one observable failure condition. If no observable condition can be derived from the brief, record that gap as the first blocker instead of guessing.
|
|
18
18
|
- **Reproduction status:** classify the run as `reproduced`, `not-reproduced`, or `blocked-before-repro`. Cite the command/log/file evidence used. If no command can be run safely in this phase, explain the read-only evidence path and the exact material needed next.
|
|
19
19
|
- **Falsifiable cause candidates:** every root-cause candidate must include supporting evidence, the strongest falsifying evidence checked, confidence, and the next diagnostic action that would disprove it. A candidate that cannot be falsified is too vague for this phase.
|
|
20
20
|
- **Sharp next diagnostic:** end with the single highest-value diagnostic command, log capture, or file inspection that should happen next, plus the expected signal that would confirm or reject the leading cause.
|
|
@@ -33,12 +33,12 @@
|
|
|
33
33
|
- Clarification request policy (phase-specific addenda — shared policy is in `_common-contract.md`):
|
|
34
34
|
- if any blocking uncertainty remains at the time of writing the final report, populate `## 1. Clarification Items` in `final-report-template.md` (a single unified table; `Blocks=next-phase` for items the next run cannot start without)
|
|
35
35
|
- prefer plain Korean over abbreviations (e.g. write "초당 평균 요청 수" instead of "QPS", "재현 절차" instead of "repro")
|
|
36
|
-
|
|
36
|
+
{{INCLUDE:_clarification-recommendation.md}}
|
|
37
37
|
- **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.
|
|
38
38
|
- **Evidence note required inside `Statement`**: every clarification row includes `Evidence checked: <path:line>` or `Evidence checked: none — <reporter-only reason>` in the `Statement` cell. `none` is allowed ONLY when the row's nature is "only the reporter can answer this" (reporter-side data, business priority, environment they observed). A row with `none` that *could* have been answered by code or logs is a defect.
|
|
39
39
|
- Cross-verification mode:
|
|
40
40
|
- Phase 5.5 convergence runs in **adversarial mode** for this phase (`convergence.adversarial=true`). Verifiers actively try to refute each root-cause / reproduction claim by directly re-inspecting the cited code, logs, or config; the burden of proof sits on the claim. See `prompts/lead/convergence.md` §"Adversarial Verification Mode". A single evidence-backed refutation prevents a finding from reaching consensus.
|
|
41
|
-
|
|
41
|
+
{{INCLUDE:_coverage-critic.md}}
|
|
42
42
|
- Non-goals:
|
|
43
43
|
- implementation details unless they are necessary to validate the cause
|
|
44
44
|
- **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
|
|
@@ -14,10 +14,10 @@
|
|
|
14
14
|
- delivered artifacts match recorded expected values in `reference-expectations` (config files, deployment manifests, other recorded expected states); when reference-expectations are absent, record it as missing information rather than assuming a match
|
|
15
15
|
- test & validation suite pass status — independently re-run the read-only two-tier command set (Tier 1 = brief/approved-plan `validation`, Tier 2 = `project.json` `qaCommands`) and confirm each passes on the verified head, citing exact command + exit code
|
|
16
16
|
- test correctness — delivered tests actually assert the intended behaviour: no gutted/weakened assertions, no tautological or always-passing tests, no tests exercising only mocks; new behaviour has matching coverage
|
|
17
|
-
- DB / IO / SQL real-execution evidence —
|
|
17
|
+
- DB / IO / SQL real-execution evidence — trigger: the diff touches DB/IO/SQL (ORM / query-builder, `*.repository.*`, model / `migrations/**` / `*.sql`, or changed query strings). Then Validation Evidence MUST cite a real (or faithful-replica) DB execution — the `db-test` command + exit code — not a mock-only suite. Rationale: a mock-only suite cannot observe the SQL actually emitted (`count({ col: 'FontFamily.fontFamily' })` passed mocks yet threw `Unknown column` on the real DB). A DB-touching change whose only evidence is mocked, or for which no `db-test` ran, is an **Acceptance Blocker** (`major`+); since `accepted` requires zero blockers the verdict becomes `conditional-accept` / `blocked`. This gate stops an unverified DB change from reaching `release-handoff` and being pushed.
|
|
18
18
|
- no new defects introduced — the diff does not break previously-working behaviour and adds no new bug (logic/off-by-one, null/empty handling, resource leaks, broken error paths)
|
|
19
19
|
- scope conformance — the delivered diff stays within the approved plan's scope; flag out-of-scope edits, unrelated file changes, leftover debug/commented-out code, and unintended deletions
|
|
20
|
-
- project review-rule packs (when present) — search `<PROJECT_ROOT>/skills/*review*`, `<PROJECT_ROOT>/.claude/skills/*review*`, and up to two parent directories' `skills/*review*/SKILL.md`; read the matching `SKILL.md` + referenced `references/*.md` and apply their rules as an acceptance overlay (record `project-review-rules: <paths read>` or `project-review-rules: none found`). This is a static review pass, not a PR-comment workflow — do NOT dispatch reviewer subagents. Because this phase verifies the **whole-task merged diff**, it is the gate that catches **cross-stage findings a per-stage `implementation` verifier structurally cannot see** (each implementation run reviews only its own stage diff): most importantly the same helper stack / transform / domain rule duplicated across stages or services — byte-identical duplication is always an Acceptance Blocker, and semantically-equivalent transforms across services are blockers unless the approved plan explicitly justified keeping them separate
|
|
20
|
+
- project review-rule packs (when present) — search `<PROJECT_ROOT>/skills/*review*`, `<PROJECT_ROOT>/.claude/skills/*review*`, and up to two parent directories' `skills/*review*/SKILL.md`; read the matching `SKILL.md` + referenced `references/*.md` and apply their rules as an acceptance overlay (record `project-review-rules: <paths read>` or `project-review-rules: none found`). This is a static review pass, not a PR-comment workflow — do NOT dispatch reviewer subagents. Because this phase verifies the **whole-task merged diff**, it is the gate that catches **cross-stage findings a per-stage `implementation` verifier structurally cannot see** (each implementation run reviews only its own stage diff): most importantly two cross-stage conditions: (a) the same helper stack / transform / domain rule duplicated across stages or services — byte-identical duplication is always an Acceptance Blocker, and semantically-equivalent transforms across services are blockers unless the approved plan explicitly justified keeping them separate; (b) an API newly orphaned because its only caller was removed in a different stage. A confirmed cross-stage duplication of this kind is an Acceptance Blocker (`major`+) that cites every `path:line` location and names the shared-module location to converge on. (Single-stage scope sees only one stage, so it cannot raise cross-stage findings — note that limitation rather than implying coverage.)
|
|
21
21
|
- Residual-tracked — note as Residual Risk unless severe enough to block:
|
|
22
22
|
- unresolved edge cases
|
|
23
23
|
- regression risk in adjacent code paths not directly changed
|
|
@@ -36,8 +36,8 @@
|
|
|
36
36
|
- **Residual Risk block** (under section 4): risks that are not blockers but should be tracked, each with mitigation owner and a trigger that would escalate them to a blocker.
|
|
37
37
|
- **Validation Evidence**: for every requirement in the originating plan or task brief, cite the artifact (commit SHA, test output, log line, MCP SELECT result) that demonstrates coverage. Paraphrased "verified" claims without an artifact are rejected.
|
|
38
38
|
- **Read-only command log**: any pre-existing test/validation command executed during this run MUST be listed with its exact command line and exit code. No mutating commands may appear here.
|
|
39
|
-
- **Two-tier command lookup (shared with `implementation`):** when this phase performs its own independent re-validation, the command source is exactly the same two tiers `implementation` verifiers use — Tier 1 is the originating task brief / approved plan's `validation` set, Tier 2 is `<PROJECT_ROOT>/.okstra/project.json` under `qaCommands`. Auto-detecting tools from manifest files is forbidden; missing tiers are recorded as `qa-command not configured: <category>`
|
|
40
|
-
- **Tier 3 — stage conformance scripts (whole-task union):** because this phase verifies the **integrated, merged** state, it re-runs conformance against that state rather than per-stage. Read the task-level manifest `<task_root>/qa/conformance-manifest.json` (the directory is the `TASK_QA_PATH` token) and, in **whole-task scope**, run the `runCommand` of **every** `entries[]` item against the merged worktree, refreshing each `<task_root>/qa/result-<stageKey>.json` (`{ "stageKey", "overall": "PASS"|"FAIL"|"MISSING", "ranAt", "requirements" }`). In **single-stage scope**, run only the entry whose `stageKey` matches the verified stage. An entry carrying an `exemption` or user `waiver` is NOT executed — record the skip and reason; a `waiver` becomes a `conditional-accept` condition surfaced in the section 7 Verdict (conformance left unverified by user acknowledgement). Each `runCommand` runs in the worktree cwd with `qaEnv` env (replica DB DSN / app base URL / env file) — **replica / test environment only**, never shared / staging / prod, and the same source/lockfile mutation deny-list applies (a conformance script MAY mutate only its `qaEnv` replica datastore). Interpret each result from the exit code + stdout `QA-RESULT: PASS|FAIL` (last wins) and `REQ <id>: PASS|FAIL: <reason>` lines; no `QA-RESULT` marker → `MISSING`. Any entry whose result is not `PASS` (including `MISSING` or a never-run/missing sidecar) is an **Acceptance Blocker** (`major`+)
|
|
39
|
+
- **Two-tier command lookup (shared with `implementation`):** when this phase performs its own independent re-validation, the command source is exactly the same two tiers `implementation` verifiers use — Tier 1 is the originating task brief / approved plan's `validation` set, Tier 2 is `<PROJECT_ROOT>/.okstra/project.json` under `qaCommands`. Auto-detecting tools from manifest files is forbidden; missing tiers are recorded as `qa-command not configured: <category>` rather than guessed. The `cmd` deny-list (`--fix`, `--write`, ` -w`, ` -u`, `--snapshot-update`, `INSTA_UPDATE=<not-no>`, `cargo update`, `npm install` without `ci`, etc.) is enforced identically. NOTE: runtime fail-fast validation (`okstra_ctl.qa_commands.validate_qa_commands`) only fires at `--task-type implementation` run-prep, so this phase MUST self-check each `qaCommands` entry against the deny-list before executing it — if a denied token is present, skip the command and record it as a `Read-only command log` line `qa-command rejected (denied token: <token>): <label>`.
|
|
40
|
+
- **Tier 3 — stage conformance scripts (whole-task union):** because this phase verifies the **integrated, merged** state, it re-runs conformance against that state rather than per-stage. Read the task-level manifest `<task_root>/qa/conformance-manifest.json` (the directory is the `TASK_QA_PATH` token) and, in **whole-task scope**, run the `runCommand` of **every** `entries[]` item against the merged worktree, refreshing each `<task_root>/qa/result-<stageKey>.json` (`{ "stageKey", "overall": "PASS"|"FAIL"|"MISSING", "ranAt", "requirements" }`). In **single-stage scope**, run only the entry whose `stageKey` matches the verified stage. An entry carrying an `exemption` or user `waiver` is NOT executed — record the skip and reason; a `waiver` becomes a `conditional-accept` condition surfaced in the section 7 Verdict (conformance left unverified by user acknowledgement). Each `runCommand` runs in the worktree cwd with `qaEnv` env (replica DB DSN / app base URL / env file) — **replica / test environment only**, never shared / staging / prod, and the same source/lockfile mutation deny-list applies (a conformance script MAY mutate only its `qaEnv` replica datastore). Interpret each result from the exit code + stdout `QA-RESULT: PASS|FAIL` (last wins) and `REQ <id>: PASS|FAIL: <reason>` lines; no `QA-RESULT` marker → `MISSING`. Any entry whose result is not `PASS` (including `MISSING` or a never-run/missing sidecar) is an **Acceptance Blocker** (`major`+), so the verdict becomes `conditional-accept` / `blocked`. This is the same gate the `validate-run.py` Tier 3 check enforces on the result sidecars.
|
|
41
41
|
- **Routing recommendation**: the next safe phase — one of `release-handoff`, `done`, `error-analysis`, `implementation-planning` — tied to the verdict and blocker list. `release-handoff` is allowed ONLY when the Verdict Token is `accepted`. `release-handoff` is additionally allowed ONLY when the verification scope (the `Verification scope:` line of the injected `VERIFICATION_TARGET` block, recorded as the report's `verificationScope` field) is `whole-task`; a `single-stage` accepted run routes to `release-handoff(stage-group)` (or `implementation` / `done`); plain `release-handoff` remains whole-task-only. Enforcement: `validators/validate-run.py` rejects a `single-stage` report whose routing cites plain `release-handoff`.
|
|
42
42
|
- **Verified-row recording** (single-stage scope only): when the Verdict Token is `accepted`, the lead MUST run `okstra handoff record-verified --plan-run-root <plan-run-root> --stage <N> --report-path <final-report.md path> --data-json <final-report data.json path>` and quote the command + exit code in the report. The helper re-validates taskType/scope/verdict from data.json, so a non-accepted or whole-task report is rejected at the tool layer.
|
|
43
43
|
- Clarification request policy (phase-specific addendum — shared policy is in `_common-contract.md`):
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
{{INCLUDE:_common-contract.md}}
|
|
11
11
|
{{INCLUDE:_stage-discipline.md}}
|
|
12
12
|
- Brief consumption (phase-specific addendum — shared rules live in `_common-contract.md` under "Brief handoff contract"):
|
|
13
|
-
- Apply the shared reporter-confirmation precondition exactly as written. In this phase, unresolved `intent-check:` / `conversion-block:` rows
|
|
14
|
-
- never plan around an unconfirmed `intent-inference` augmentation as if it were a settled requirement.
|
|
13
|
+
- Apply the shared reporter-confirmation precondition exactly as written. In this phase, unresolved `intent-check:` / `conversion-block:` rows carry `Blocks=approval`, so the approval frontmatter stays `approved: false` until they are resolved.
|
|
14
|
+
- never plan around an unconfirmed `intent-inference` augmentation as if it were a settled requirement. Treat the inference as settled ONLY when a `[CONFIRMED …]` marker sits on the matching `intent-check:` row after the precondition runs; absent the marker it stays a `Blocks=approval` clarification item per the precondition's `skipped` branch.
|
|
15
15
|
- `conversion-block:` rows are handled by the precondition; planning around an untranslated reporter phrase is forbidden until it is resolved.
|
|
16
16
|
- Pre-planning context exploration (mandatory before option drafting):
|
|
17
17
|
- read the task brief, related-task briefs, and any cited spec / design doc end-to-end
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
- Cross-verification mode:
|
|
43
43
|
- Phase 5.5 finding convergence runs in **adversarial mode** for this phase (`convergence.adversarial=true`). Verifiers actively try to refute each worker finding (requirement gap / risk / option) by re-inspecting its cited evidence; the burden of proof sits on the claim. See `prompts/lead/convergence.md` §"Adversarial Verification Mode".
|
|
44
44
|
- §5.5.9 plan-body verification runs with an **adversarial posture** (`prompts/lead/convergence.md` §"Adversarial plan-body posture"): verifiers open and confirm every cited path / command and put the burden of proof on the plan. The gate threshold is unchanged — a *majority* `DISAGREE` (`majority-disagree`) is still required to block approval; a single dissent does not.
|
|
45
|
-
|
|
45
|
+
{{INCLUDE:_coverage-critic.md}}
|
|
46
46
|
- Non-goals:
|
|
47
47
|
- code-level micro-optimization unless it changes the implementation approach
|
|
48
48
|
- **source code edits of any kind** — this run produces a plan document only; Edit/Write on project source files is forbidden until the plan is approved and a separate `implementation` run starts
|
|
@@ -51,13 +51,13 @@
|
|
|
51
51
|
- dispatching parallel sub-agents beyond the required worker roster — okstra owns worker fan-out
|
|
52
52
|
- writing artifacts anywhere except `<PROJECT_ROOT>/.okstra/` — the run's `reports/` directory is the canonical location for this phase
|
|
53
53
|
- Clarification request policy (phase-specific addenda — shared policy is in `_common-contract.md`):
|
|
54
|
-
|
|
54
|
+
{{INCLUDE:_clarification-recommendation.md}}
|
|
55
55
|
- **Evidence note required inside `Statement`**: every clarification row includes `Evidence checked: <path:line>` or `Evidence checked: none — <human-only reason>` in the `Statement` cell. `none` is allowed ONLY when the row's nature is "only a human can answer this" (reporter intent, business priority, organisational decision). A row with `none` that *could* have been answered by the codebase is a defect of this phase, restated from the pre-planning rule above.
|
|
56
56
|
- Section heading contract (BLOCKING — validator scans for these literal English substrings):
|
|
57
57
|
- The final report MUST include section headings containing each of the following exact strings: `Option Candidates`, `Trade-off`, `Recommended Option`, `Stage Map`, `Stage Exit Contract`, `Stage Validation`, `Dependency`, `Validation Checklist`, `Rollback`, `Requirement Coverage`. (Approval is no longer a body section — it is the YAML frontmatter `approved` field.)
|
|
58
58
|
- Korean translations are allowed in parentheses (e.g. `### Recommended Option (권장 옵션)`), but the English keyword must be present verbatim in the heading line.
|
|
59
|
-
- The shape and ordering follow `final-report-template.md` sections 5.4 (`Implementation Plan Deliverables`) + 5.5 (`Stage Map`).
|
|
60
|
-
- Beyond substring matching, when the Plan Body Verification gate result is `passed` / `passed-with-dissent`, `validators/validate-run.py` runs the **structural** Stage Map validator (`validators/validate-implementation-plan-stages.py`) at the planning boundary — the exact `## 5.5 Stage Map` heading, each `## 5.5.<i> Stage <i>:` section with its four required subsections, the per-stage effective step count (≤6), the `depends-on` DAG, and the per-stage vertical-slice contract (S10)
|
|
59
|
+
- The shape and ordering follow `final-report-template.md` sections 5.4 (`Implementation Plan Deliverables`) + 5.5 (`Stage Map`). `validators/validate-run.py` substring-matches the raw report text, so a Korean-only heading fails the gate — the cause of repeated observed failures.
|
|
60
|
+
- Beyond substring matching, when the Plan Body Verification gate result is `passed` / `passed-with-dissent`, `validators/validate-run.py` runs the **structural** Stage Map validator (`validators/validate-implementation-plan-stages.py`) at the planning boundary — not deferred to the `implementation` entry gate. It enforces: the exact `## 5.5 Stage Map` heading, each `## 5.5.<i> Stage <i>:` section with its four required subsections, the per-stage effective step count (≤6), the `depends-on` DAG, and the per-stage vertical-slice contract (S10). S10 scans for the literal in-section strings `Slice value:`, `Acceptance:`, the three `Test case (success):` / `Test case (boundary):` / `Test case (failure):` lines (S10d), and the Stepwise `action`-cell prefixes `RED:` / `GREEN:` (or a `TDD exemption:` line, which waives both the test-case lines and the RED/GREEN check) — keep these tokens verbatim for the same reason as the heading keywords above.
|
|
61
61
|
- Required deliverable shape (final report, in addition to the standard sections):
|
|
62
62
|
- at least two implementation options. **Each option must include**:
|
|
63
63
|
- **File Structure**: an explicit list of files to create / modify / delete with each file's responsibility (one-line each). Use the form `Create: path — responsibility` / `Modify: path:line-range — change summary` / `Delete: path — reason`.
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
- **Per-stage conformance declaration (mandatory one line, in the stage section — same placement freedom as `TDD exemption:`):** the stage MUST carry exactly one of:
|
|
83
83
|
- `Conformance tests: stage-<N> — <task_root>/qa/scripts/stage-<N>.<ext> (requires=[db|io|http|external,...])` — a Tier3 verification script that proves this stage's upstream requirements (brief / requirements-discovery / error-analysis / improvement-discovery → this stage's `Acceptance`) hold against **real** DB rows, real endpoints, or the real external API — NOT mocks. When you emit this line you MUST also (a) write the script to `<task_root>/qa/scripts/stage-<N>.<ext>` and (b) add a matching entry to `<task_root>/qa/conformance-manifest.json` with fields `stageKey` (= `<task-id>-stage-<N>`), `script`, `runCommand`, `requirementIds`, `requires` (subset of `{db, io, http, external}`), `passContract`, `exemption: null`, `waiver: null`. The script's standard interface: a `main` that exits `0`=PASS / non-zero=FAIL, and whose stdout ends with `QA-RESULT: PASS|FAIL` followed by one `REQ <id>: PASS|FAIL: <근거>` line per requirement. When the verification body is a test spec, author it with the project's own test framework (devDependency) invoked via a discovery override at `<task_root>/qa/scripts/` (jest: `--config <project config> --roots <task_root>/qa/scripts`) — never hand-roll `describe`/`expect` and never widen the project's own test config; for TypeScript specs also write `<task_root>/qa/scripts/tsconfig.json` extending the project tsconfig with the runner's `types` entry so editors resolve the file.
|
|
84
84
|
- `Conformance exemption: <reason>` — only for stages that touch no db/io/http/external surface, or where unit tests fully cover the increment. (If the eventual `implementation` diff actually touches one of those surfaces, `validate-run.py`'s diff-surface cross-check is BLOCKING — an exemption cannot hide a real db/io/http/external change.)
|
|
85
|
-
The manifest lives at the **task level** (`<task_root>/qa/`, path token `TASK_QA_PATH`) and is shared across planning → implementation → final-verification. Layout split: executable scripts (conformance + any real-IO test) live under `<task_root>/qa/scripts/`; data sidecars (`conformance-manifest.json`, `result-*.json`) stay at the `qa/` root. This declaration is enforced at three layers: `validators/validate-implementation-plan-stages.py` check **S11** forces every stage to carry one of the two lines; the manifest JSON structure — including each entry's `script` living under `qa/scripts/` — is enforced by `validate_conformance_manifest` (run
|
|
85
|
+
The manifest lives at the **task level** (`<task_root>/qa/`, path token `TASK_QA_PATH`) and is shared across planning → implementation → final-verification. Layout split: executable scripts (conformance + any real-IO test) live under `<task_root>/qa/scripts/`; data sidecars (`conformance-manifest.json`, `result-*.json`) stay at the `qa/` root. This declaration is enforced at three layers: `validators/validate-implementation-plan-stages.py` check **S11** forces every stage to carry one of the two lines; the manifest JSON structure — including each entry's `script` living under `qa/scripts/` — is enforced by `validate_conformance_manifest` (called from both the run path and validate-run); and the result gate (each script's `QA-RESULT`) is enforced by the verifier Tier3 + validate-run.
|
|
86
86
|
- `### Stage Exit Contract` — predicted added/modified files, newly exposed identifiers/types/endpoints, downstream-usable resources.
|
|
87
87
|
- `### Stage Validation` — pre / mid / post exact commands or observable outcomes for this stage only.
|
|
88
88
|
- **Vertical-slice-first partition rule (1st-class):** the grouping anchor is a **thin end-to-end vertical slice** — one stage delivers a single user-observable increment, crossing whatever layers are needed (data → service → API → UI) to make that one increment work. File/module proximity is demoted to the **intra-slice grouping rule**: within a slice, keep steps touching the same file/directory/module together so the diff, PR, and rollback unit stay cohesive. **Horizontal layer-splitting is forbidden** — never carve "the DB layer" into one stage and "the service layer" into the next; that produces stages that ship no standalone user value. A stage is split ONLY when (a) a real `depends-on` data/contract dependency exists, (b) effective steps would exceed 6, or (c) it is a distinct vertical slice (a different user-value increment). Maximising the number of parallel stages is NOT a reason to split — parallelism is an emergent property of independent stages, never a partitioning goal.
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
- codex
|
|
8
8
|
- report-writer
|
|
9
9
|
- Optional workers (opt-in via `--workers`):
|
|
10
|
-
- antigravity — when added to the roster it joins the verifier set; when omitted only the Claude+Codex verifiers participate. `--executor antigravity` requires `antigravity` in the roster: the direct CLI demands it explicitly in `--workers`, while the wizard adds it automatically when you pick antigravity as the executor
|
|
10
|
+
- antigravity — when added to the roster it joins the verifier set; when omitted only the Claude+Codex verifiers participate. `--executor antigravity` requires `antigravity` in the roster: the direct CLI demands it explicitly in `--workers`, while the wizard adds it automatically when you pick antigravity as the executor.
|
|
11
11
|
- **Executor binding (resolved at run-prep time, fixed for this run):**
|
|
12
12
|
- Executor display name: `{{EXECUTOR_DISPLAY_NAME}}`
|
|
13
13
|
- Executor provider: `{{EXECUTOR_PROVIDER}}` (one of: `claude` | `codex` | `antigravity`; chosen via `--executor` or `OKSTRA_DEFAULT_EXECUTOR`, default `claude`)
|
|
@@ -18,14 +18,14 @@
|
|
|
18
18
|
{{INCLUDE:_stage-discipline.md}}
|
|
19
19
|
- Pre-implementation gate (mandatory — refuse to start if any item fails):
|
|
20
20
|
- the run brief MUST cite `--approved-plan <path>` pointing to a `final-report.md` produced by a prior `implementation-planning` run located under `runs/implementation-planning/.../reports/final-report.md`
|
|
21
|
-
- that file's YAML frontmatter MUST carry `approved: true`. report-writer emits `approved: false` by default; the user flips it to `true` to authorise this run. Free-form approvals such as "lgtm" / "go ahead" / paraphrased confirmations are NOT accepted;
|
|
21
|
+
- that file's YAML frontmatter MUST carry `approved: true`. report-writer emits `approved: false` by default; the user flips it to `true` to authorise this run. Free-form approvals such as "lgtm" / "go ahead" / paraphrased confirmations are NOT accepted; set the plan file's frontmatter to `approved: true` before invoking implementation, or pass `--approve` so the CLI flips it (`okstra_ctl.run._apply_cli_approval`).
|
|
22
22
|
- The `--approve` flag is meaningful ONLY with `--task-type implementation` and `--approved-plan <path>`; any other use raises `PrepareError`. Idempotent — re-running with `approved: true` already set appends an audit line but does NOT re-toggle.
|
|
23
|
-
- the authoritative scope for this run is the Option Candidate named by the YAML frontmatter `implementation-option:` field. **If `implementation-option:` is empty, fall back to the plan's `Recommended Option`** (this is a soft fallback, not a hard block). The chosen option's
|
|
23
|
+
- the authoritative scope for this run is the Option Candidate named by the YAML frontmatter `implementation-option:` field. **If `implementation-option:` is empty, fall back to the plan's `Recommended Option`** (this is a soft fallback, not a hard block). The chosen option's step list becomes the authoritative scope. Any deviation MUST be justified in the final report AND routed to a new `implementation-planning` run; never silently expand scope. If the chosen option name does not match any heading under `Option Candidates`, record it as a deviation.
|
|
24
24
|
- Stage worktree (provisioned by `okstra-ctl` at this implementation run's prep time):
|
|
25
25
|
- Status: `{{EXECUTOR_WORKTREE_STATUS}}` (one of: `created` | `reused` | `skipped-in-worktree` | `skipped-not-git`)
|
|
26
26
|
- Working tree path: `{{EXECUTOR_WORKTREE_PATH}}` — when status is `created` or `reused`, this is this run's isolated stage worktree rooted at `~/.okstra/worktrees/<project>/<task-group>/<task-id>/stage-<N>/`. When skipped, this is the caller's `project_root`.
|
|
27
27
|
- Branch: `{{EXECUTOR_WORKTREE_BRANCH}}` — empty when status is `skipped-*`. Branch name = `<work-category-prefix>-<task-id-segment>-s<N>`, globally unique via `~/.okstra/worktrees/registry.json`.
|
|
28
|
-
- Base ref: `{{EXECUTOR_WORKTREE_BASE_REF}}` — canonical `<base>` for every `git diff` / `git log` in this run. Independent stages start from the task
|
|
28
|
+
- Base ref: `{{EXECUTOR_WORKTREE_BASE_REF}}` — canonical `<base>` for every `git diff` / `git log` in this run. Independent stages start from the common anchor (the task-key worktree HEAD, fixed once at first stage entry); dependent stages start from the predecessor done commit or the verified merged task worktree head.
|
|
29
29
|
- Provisioning note: `{{EXECUTOR_WORKTREE_NOTE}}`
|
|
30
30
|
- Treat the working-tree path as `project_root` for the duration of this run. Do NOT mutate the caller's original checkout. cwd-sensitive Bash commands MUST be prefixed `cd {{EXECUTOR_WORKTREE_PATH}} && ` in the same Bash invocation (never `bash -lc "..."` wrappers — see executor sidecar for full rules).
|
|
31
31
|
- Lifecycle: kept after the run completes as this stage's evidence worktree. Later stages get their own stage worktrees. Manual cleanup: `git worktree remove <path>` → `git branch -D <branch>` → drop the stage-key registry entry (`<task-key>#stage-<N>`).
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
- Forbidden actions — universal (any occurrence → terminal status `contract-violated`):
|
|
35
35
|
{{PHASE_FORBIDDEN_ACTIONS}}
|
|
36
36
|
- In-phase debugging:
|
|
37
|
-
- isolate root cause before
|
|
37
|
+
- isolate the root cause before applying a fix, but the executor MUST NOT route to a separate `error-analysis` phase mid-run; if a defect blocks plan progress, the executor records findings and routes to a new run after this one ends.
|
|
38
38
|
|
|
39
39
|
## Lazy section pointers (BLOCKING for lead — load at the listed phase, not at Phase 1)
|
|
40
40
|
|
|
@@ -21,12 +21,12 @@
|
|
|
21
21
|
- per-candidate severity / effort / recommended-next-phase
|
|
22
22
|
- convergence classification (full / partial / contested / worker-unique) across workers
|
|
23
23
|
- Worker diversity rule:
|
|
24
|
-
- every analyser inspects every priority lens, but each starts with a different primary pass
|
|
25
|
-
- before broadening to the remaining lenses,
|
|
24
|
+
- every analyser inspects every priority lens, but each starts with a different primary pass. Order lenses exactly as they appear in the brief; `claude` starts at lens 1, `codex` at lens 2, and `antigravity` at lens 3, wrapping around when fewer lenses are present.
|
|
25
|
+
- each worker, before broadening to the remaining lenses, must do one of: (a) produce at least one candidate from its primary pass, or (b) record a no-candidate rationale citing the highest-signal path:line evidence it inspected.
|
|
26
26
|
- two workers' candidates are the same candidate only when they cite the same underlying design/code problem and the same remediation direction. Shared evidence paths alone are not enough to merge; keep distinct failure modes distinct.
|
|
27
|
-
- when a candidate from one worker overlaps another worker's evidence, convergence must
|
|
27
|
+
- when a candidate from one worker overlaps another worker's evidence, convergence must classify the relationship as one of: duplicate, broader/narrower, or conflicting. Do not collapse contested candidates just to meet the candidate cap.
|
|
28
28
|
- Phase 1.5 — Lead reflect-back grilling (runs after Phase 1 context loading and before Phase 4 worker dispatch):
|
|
29
|
-
- Lead inspects scan-scope paths via `ls` / `Grep` / `Read` to map modules, entry points, dependencies, approximate LOC, and recent
|
|
29
|
+
- Lead inspects scan-scope paths via `ls` / `Grep` / `Read` to map modules, entry points, dependencies, and approximate LOC, and reviews recent git history to note which scan-scope files change most.
|
|
30
30
|
- Lead emits a single reflect-back message covering: (a) understood scope per path (one-line summary), (b) understood meaning of each priority lens in this scope, (c) understood out-of-scope rationale, (d) ordered list of N open questions.
|
|
31
31
|
- For each open question Lead asks ONE `AskUserQuestion` with a `(Recommended)` answer drawn from a codebase-first inspection. Budget: at most 12 questions in this phase.
|
|
32
32
|
- Stop conditions (OR): all questions resolved / budget exhausted / user signals proceed.
|
|
@@ -34,14 +34,14 @@
|
|
|
34
34
|
- Decision-tree walk (bounded):
|
|
35
35
|
- When candidates branch on a structural question (e.g. "is module X meant to own this responsibility?"), resolve via `Read` / `Grep` first. Only escalate to the user inside the Phase 1.5 budget.
|
|
36
36
|
- Expected output emphasis:
|
|
37
|
-
- the `## 5.9 Improvement Candidates` table populated with rows that obey the 10-column schema from `validators/
|
|
37
|
+
- the `## 5.9 Improvement Candidates` table populated with rows that obey the 10-column schema from `validators/validate_improvement_report.py` (Cand ID `I-NNN`, Lens from whitelist, Title, Scope ⊆ scan-scope, Severity, Effort, Consensus, Source workers `<worker>:<id>` from {claude, codex, antigravity}, Recommended next-phase ∈ {requirements-discovery, implementation-planning, error-analysis}, Evidence as path:line list)
|
|
38
38
|
- `Consensus` cells in `## 5.9 Improvement Candidates` use the table enum exactly: `full`, `partial`, `contested`, `worker-unique`. Map convergence's `full-consensus` / `partial-consensus` labels to `full` / `partial` before writing the table.
|
|
39
39
|
- `## 7. Final Verdict` Verdict Token ∈ {`candidates-ready`, `no-candidates`, `blocked`}; Direction `routing`; Next Step "사용자에게 후보 K개 선택 의뢰 (## 5.9 표 참조)"
|
|
40
40
|
- `## 3. Recommended Next Steps` first entry summarises per-candidate routing and proposes new task-key names of the form `<task-group>/imp-<Cand-ID>`
|
|
41
41
|
- this report is authored free-form (improvement-discovery is not in the data.json schema enum); after the markdown is written, the report-writer runs `okstra inject-report-index <report.md> --report-language <en|ko>` to add the top-of-report Index + `I-NNN`/`C-NNN` scroll anchors. The run validator fails the report when the Index anchor is missing.
|
|
42
42
|
- Clarification request policy (phase-specific addenda — shared policy is in `_common-contract.md`):
|
|
43
43
|
- if scan-scope or priority-lenses cannot be made concrete during Phase 1.5, end the run with Verdict Token `blocked`, populate `## 1. Clarification Items` with `Blocks=next-phase` rows, and do not run worker dispatch
|
|
44
|
-
|
|
44
|
+
{{INCLUDE:_clarification-recommendation.md}}
|
|
45
45
|
- Non-goals:
|
|
46
46
|
- concrete implementation plans, cost estimates, or code edits for any candidate
|
|
47
47
|
- inventing lenses outside the whitelist
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
1c. **Local checkout execution** (only when the user picked `local checkout`) — confirm with the user that okstra will remove the okstra task worktree and `git checkout <feature branch>` in the MAIN worktree, and that the base branch is never modified. On confirmation run:
|
|
28
28
|
`okstra handoff local-checkout --project-root <project root> --project-id <id> --task-group <g> --task-id <t>`
|
|
29
29
|
Exit 1 means a precondition failed (MAIN worktree dirty, registry entry missing, or checkout failed): show the error verbatim and re-ask the action selection. On success the okstra task worktree no longer exists — the lead's cwd is gone, so EVERY subsequent step (final-report authoring included) MUST use absolute paths or run from the MAIN worktree. Then route to the final-report self-review pass.
|
|
30
|
-
- **stage-group mode order
|
|
30
|
+
- **stage-group mode step order** (overrides the default Q1→Q3 sequence): after Q1 picks `push + PR`, run (1) base-branch selection first — identical to Q2 below, because the dependency-closure check needs `origin/<base>`; (2) G2 stage confirmation (step 1g); (3) assemble (step 2g); then Q2b and Q3 as usual, with the collector branch as the PR head.
|
|
31
31
|
1g. **G2 — stage confirmation**: the stage selection already happened before the run (wizard `handoff_stage_pick`, or the CLI `--stages` flag) and is fixed in `HANDOFF_STAGES`. Display it as a one-line confirmation (`PR 대상 stage: <csv> — 진행합니다`) and proceed; do NOT re-ask the multi-select. Only if `HANDOFF_MODE` is `stage-group` but `HANDOFF_STAGES` is empty (defensive, should not happen) run `okstra handoff eligible --plan-run-root <plan-run-root> --approved-plan <approved plan path>` and ask the user to pick from the eligible stages.
|
|
32
32
|
2g. **assemble**: run `okstra handoff assemble --plan-run-root <...> --approved-plan <...> --project-root <project root> --project-id <id> --task-group <g> --task-id <t> --work-category <c> --stages <csv> --base <chosen-base>`. Exit 2 means a stage-vs-stage merge conflict: show the `conflicts` paths and stop (route: reshape the group or resolve manually). Exit 1 means an eligibility/closure violation: show the error verbatim and re-ask G2. On success the returned `branch` is the PR head branch for every subsequent step.
|
|
33
33
|
2. **PR base branch** (only when the user picked `push + PR`) — present four options and capture exactly one:
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
- `cancel` — end the run without executing push or PR commands; record the cancellation in the final report.
|
|
51
51
|
- Inline drafting rules (Claude lead):
|
|
52
52
|
- read the run brief, the cited final-verification report, `git log --oneline <base>..HEAD`, and `git diff <base>..HEAD --stat` to ground the drafted text in actual committed changes. In stage-group mode the draft is grounded on `git log <implementation_base_commit>..<collector HEAD>` / `git diff <implementation_base_commit>..<collector HEAD> --stat`, with source material = each selected stage's implementation report + its single-stage verification report.
|
|
53
|
-
- **PR body template** — the run context exposes `PR_TEMPLATE_PATH` and `PR_TEMPLATE_SOURCE`. The path MUST be an okstra-owned project artifact under `<PROJECT_ROOT>/.okstra
|
|
53
|
+
- **PR body template** — the run context exposes `PR_TEMPLATE_PATH` and `PR_TEMPLATE_SOURCE`. The path MUST be an okstra-owned project artifact under `<PROJECT_ROOT>/.okstra/**`, or a file the prepare step already materialised into this run's artifact directory. If the resolved file is missing or outside that boundary at draft time, abort with a clear error — do NOT invent a structure. Otherwise the lead MUST `Read` it verbatim, strip HTML comments, and fill in the placeholders, treating the template (never a hard-coded section list) as the source of truth for the structure.
|
|
54
54
|
- produce **two artifacts** before showing them to the user:
|
|
55
55
|
1. **PR title** — by default the subject of the most recent implementation commit, or a concise Conventional Commits-style summary of the committed range.
|
|
56
56
|
2. **PR body** — markdown filled from `PR_TEMPLATE_PATH`. The user-confirmation step's diff (Q3 `edit then proceed`) is computed against the filled template, not against the raw template file.
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
- feature-branch push (only when the user picked `push + PR`): `git push -u origin <current-branch>`. The pushed ref MUST be the feature branch — never the chosen base branch. (stage-group mode: the collector branch returned by assemble)
|
|
61
61
|
- PR creation (only when the user picked `push + PR` AND no PR with the same head already exists on origin): `gh pr create --base <chosen-base> --head <current-branch> --title "<title>" --body "<body>"`. The title and body are the user-confirmed PR draft.
|
|
62
62
|
- PR reuse: if `gh pr list --head <branch> --state open --json url --jq '.[0].url'` returns a URL, treat that PR as already existing — record the URL in the final report and SKIP `gh pr create`.
|
|
63
|
-
- after `gh pr create` succeeds (or an existing PR is reused), the lead MUST run `okstra handoff record-pr --plan-run-root <...> --stages <csv> --branch <head branch> --url <pr url>` and quote the command + exit code in the final report. This applies to BOTH modes — whole-task runs record `--stages` as the full Stage Map list — so duplicate-PR prevention converges on
|
|
63
|
+
- after `gh pr create` succeeds (or an existing PR is reused), the lead MUST run `okstra handoff record-pr --plan-run-root <...> --stages <csv> --branch <head branch> --url <pr url>` and quote the command + exit code in the final report. This applies to BOTH modes — whole-task runs record `--stages` as the full Stage Map list — so duplicate-PR prevention for both modes converges on a single consumers ledger.
|
|
64
64
|
- stage-group helpers: `okstra handoff eligible`, `okstra handoff assemble`, `okstra handoff record-pr`. The assemble step is the ONLY path that may create commits (merge commits on the collector branch) in this phase.
|
|
65
65
|
- Forbidden actions (any occurrence → terminal status `contract-violated`):
|
|
66
66
|
{{PHASE_FORBIDDEN_ACTIONS}}
|
|
@@ -10,12 +10,12 @@
|
|
|
10
10
|
{{INCLUDE:_common-contract.md}}
|
|
11
11
|
- Brief consumption (phase-specific addendum — shared rules live in `_common-contract.md` under "Brief handoff contract"):
|
|
12
12
|
- Apply the shared reporter-confirmation precondition exactly as written. In this phase, unresolved `intent-check:` / `conversion-block:` rows use `Blocks=next-phase`.
|
|
13
|
-
- 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
|
|
13
|
+
- 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`, and resolve OR carry forward each one in this phase.
|
|
14
14
|
- `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.
|
|
15
15
|
- `conversion-block:` rows are explicit "translation failed" signals — never attempt to resolve them by inference here; the precondition above already handled them.
|
|
16
16
|
- Primary focus areas:
|
|
17
17
|
- classify the work as bugfix, feature, improvement, refactor, or ops
|
|
18
|
-
- determine whether `error-analysis` or `implementation-planning` is the next safe step
|
|
18
|
+
- determine whether `error-analysis` or `implementation-planning` is the next safe step. Direct `implementation` handoff is never a valid routing target — implementation requires an approved `implementation-planning` report
|
|
19
19
|
- identify missing materials that block reliable routing
|
|
20
20
|
- define task continuity expectations for long-running work under the same task key
|
|
21
21
|
- capture approval or confirmation points before the next phase starts
|
|
@@ -48,12 +48,12 @@
|
|
|
48
48
|
- Clarification request policy (phase-specific addenda — shared policy is in `_common-contract.md`):
|
|
49
49
|
- if any blocking input is missing at the time of writing the final report, populate `## 1. Clarification Items` in `final-report-template.md` (a single unified table; `Blocks=next-phase` for items the next run cannot start without)
|
|
50
50
|
- 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.
|
|
51
|
-
|
|
51
|
+
{{INCLUDE:_clarification-recommendation.md}}
|
|
52
52
|
- **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.
|
|
53
53
|
- **Evidence note required inside `Statement`**: every clarification row includes `Evidence checked: <path:line>` or `Evidence checked: none — <human-only reason>` in the `Statement` cell. `none` is allowed ONLY when the row's nature is "only a human can answer this" (reporter intent, business priority, external authority). A row with `none` that *could* have been answered by the codebase is a defect.
|
|
54
54
|
- Cross-verification mode:
|
|
55
55
|
- Phase 5.5 convergence runs in **adversarial mode** for this phase (`convergence.adversarial=true`). Verifiers actively try to refute each worker's finding by directly re-inspecting the cited evidence; the burden of proof sits on the claim. See `prompts/lead/convergence.md` §"Adversarial Verification Mode". A single evidence-backed refutation prevents a finding from reaching consensus.
|
|
56
|
-
|
|
56
|
+
{{INCLUDE:_coverage-critic.md}}
|
|
57
57
|
- Non-goals:
|
|
58
58
|
- full implementation design unless it is required to decide the next phase
|
|
59
59
|
- **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
|
|
@@ -138,7 +138,6 @@
|
|
|
138
138
|
"errors": {
|
|
139
139
|
"no_plan": "release-handoff 는 이 task 의 implementation-planning final-report 가 필요합니다 — implementation-planning → implementation → final-verification 을 먼저 진행하세요.",
|
|
140
140
|
"plan_not_approved": "최신 plan 이 approved 상태가 아닙니다: {plan} — implementation 이 완료된 task 에서만 release-handoff 를 시작할 수 있습니다.",
|
|
141
|
-
"no_stage_map": "approved plan 에서 Stage Map 을 읽지 못했습니다: {plan}",
|
|
142
141
|
"nothing_eligible": "PR 로 내보낼 수 있는 범위가 없습니다 — 제외 사유: {blocked}. 단독-stage final-verification 의 accepted 기록(okstra handoff record-verified) 또는 whole-task 검증을 먼저 완료하세요.",
|
|
143
142
|
"none_selected": "최소 1개의 범위를 선택하세요",
|
|
144
143
|
"whole_task_exclusive": "'전체 task' 는 단독 선택만 가능합니다 — stage 묶음을 원하면 stage 번호들만 선택하세요",
|
|
@@ -8,6 +8,7 @@ from __future__ import annotations
|
|
|
8
8
|
|
|
9
9
|
# Public API — keep import order topological (leaves first) to avoid surprises.
|
|
10
10
|
from .ids import (
|
|
11
|
+
build_container_session_name,
|
|
11
12
|
build_run_id,
|
|
12
13
|
parse_run_id,
|
|
13
14
|
run_id_to_session_name,
|
|
@@ -74,7 +75,7 @@ from .backfill import (
|
|
|
74
75
|
discover_project_roots,
|
|
75
76
|
mark_backfilled,
|
|
76
77
|
)
|
|
77
|
-
from .paths import compute_run_paths, next_run_seq
|
|
78
|
+
from .paths import compute_run_paths, next_run_seq, resolve_under_root
|
|
78
79
|
from .run_context import (
|
|
79
80
|
compute_and_write_run_context,
|
|
80
81
|
read_run_context,
|
|
@@ -89,6 +90,7 @@ __all__ = [
|
|
|
89
90
|
"absolute_final_report_path",
|
|
90
91
|
"append_jsonl",
|
|
91
92
|
"backfill_project",
|
|
93
|
+
"build_container_session_name",
|
|
92
94
|
"build_run_id",
|
|
93
95
|
"build_tmux_command",
|
|
94
96
|
"central_lock",
|
|
@@ -124,6 +126,7 @@ __all__ = [
|
|
|
124
126
|
"reserve_run_in_active",
|
|
125
127
|
"resolve_last",
|
|
126
128
|
"resolve_run_id",
|
|
129
|
+
"resolve_under_root",
|
|
127
130
|
"rotate_recent_if_needed",
|
|
128
131
|
"run_id_to_session_name",
|
|
129
132
|
"save_invocation",
|