okstra 0.201.3 → 0.204.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.md +3 -3
- package/dist/cli-registry.mjs +7 -7
- package/dist/cli-registry.mjs.map +1 -1
- package/dist/commands/lifecycle/install.mjs +50 -124
- package/dist/commands/lifecycle/install.mjs.map +1 -1
- package/dist/commands/lifecycle/setup.mjs +15 -0
- package/dist/commands/lifecycle/setup.mjs.map +1 -1
- package/dist/commands/memory/memory.mjs +41 -8
- package/dist/commands/memory/memory.mjs.map +1 -1
- package/dist/lib/citation-guidance.d.mts +21 -0
- package/dist/lib/citation-guidance.mjs +79 -0
- package/dist/lib/citation-guidance.mjs.map +1 -0
- package/dist/lib/install-assets.mjs +3 -0
- package/dist/lib/install-assets.mjs.map +1 -1
- package/dist/lib/runtime-manifest.mjs +2 -1
- package/dist/lib/runtime-manifest.mjs.map +1 -1
- package/dist/lib/types.d.mts +2 -1
- package/docs/architecture/storage-model.md +17 -10
- package/docs/architecture.md +26 -20
- package/docs/cli.md +16 -13
- package/docs/contributor-change-matrix.md +3 -2
- package/docs/performance-improvement-plan-v2.md +2 -3
- package/docs/project-structure-overview.md +38 -9
- package/docs/task-process/README.md +1 -1
- package/docs/task-process/common-flow.md +1 -1
- package/docs/task-process/final-verification.md +3 -1
- package/docs/task-process/implementation.md +1 -1
- package/docs/task-process/release-handoff.md +36 -39
- package/package.json +1 -2
- package/runtime/BUILD.json +2 -2
- package/runtime/agents/common.json +28 -0
- package/runtime/agents/operations/code-review.json +6 -0
- package/runtime/agents/operations/report-translation.json +6 -0
- package/runtime/agents/operations/schedule-verification.json +6 -0
- package/runtime/agents/roles/analyser.json +18 -0
- package/runtime/agents/roles/critic.json +18 -0
- package/runtime/agents/roles/designer.json +18 -0
- package/runtime/agents/roles/implementer.json +20 -0
- package/runtime/agents/roles/leader.json +20 -0
- package/runtime/agents/roles/planner.json +18 -0
- package/runtime/agents/roles/report-writer.json +19 -0
- package/runtime/agents/roles/translator.json +19 -0
- package/runtime/agents/roles/verifier.json +18 -0
- package/runtime/bin/lib/okstra/usage.sh +5 -5
- package/runtime/prompts/duties/acceptance-critic.json +32 -0
- package/runtime/prompts/duties/acceptance-verifier.json +32 -0
- package/runtime/prompts/duties/analysis-worker.json +32 -0
- package/runtime/prompts/duties/code-reviewer.json +32 -0
- package/runtime/prompts/duties/diagnosis-worker.json +32 -0
- package/runtime/prompts/duties/direction-selection-worker.json +32 -0
- package/runtime/prompts/duties/discovery-worker.json +32 -0
- package/runtime/prompts/duties/implementation-executor.json +32 -0
- package/runtime/prompts/duties/implementation-verifier.json +32 -0
- package/runtime/prompts/duties/lead.json +32 -0
- package/runtime/prompts/duties/planning-worker.json +36 -0
- package/runtime/prompts/duties/report-writer.json +32 -0
- package/runtime/prompts/duties/reverification-worker.json +32 -0
- package/runtime/prompts/duties/schedule-verifier.json +32 -0
- package/runtime/prompts/duties/scope-critic.json +32 -0
- package/runtime/prompts/duties/technical-verification-worker.json +32 -0
- package/runtime/prompts/duties/translator.json +32 -0
- package/runtime/prompts/launch.template.md +3 -2
- package/runtime/prompts/lead/adapters/cmux.md +1 -1
- package/runtime/prompts/lead/convergence.md +4 -4
- package/runtime/prompts/lead/okstra-lead-contract.md +115 -6
- package/runtime/prompts/lead/plan-body-verification.md +6 -6
- package/runtime/prompts/lead/report-writer.md +3 -3
- package/runtime/prompts/profiles/_common-contract.md +2 -2
- package/runtime/prompts/profiles/_implementation-executor.md +4 -1
- package/runtime/prompts/profiles/_implementation-verifier.md +3 -3
- package/runtime/prompts/profiles/change-impact-analysis.json +31 -0
- package/runtime/prompts/profiles/change-impact-analysis.md +0 -20
- package/runtime/prompts/profiles/error-analysis.json +39 -0
- package/runtime/prompts/profiles/error-analysis.md +0 -25
- package/runtime/prompts/profiles/feature-analysis.json +31 -0
- package/runtime/prompts/profiles/feature-analysis.md +0 -20
- package/runtime/prompts/profiles/final-verification.json +30 -0
- package/runtime/prompts/profiles/final-verification.md +3 -22
- package/runtime/prompts/profiles/forbidden-actions.json +4 -3
- package/runtime/prompts/profiles/implementation-option-selection.json +31 -0
- package/runtime/prompts/profiles/implementation-option-selection.md +0 -20
- package/runtime/prompts/profiles/implementation-planning.json +40 -0
- package/runtime/prompts/profiles/implementation-planning.md +6 -29
- package/runtime/prompts/profiles/implementation.json +30 -0
- package/runtime/prompts/profiles/implementation.md +1 -20
- package/runtime/prompts/profiles/improvement-discovery.json +31 -0
- package/runtime/prompts/profiles/improvement-discovery.md +0 -20
- package/runtime/prompts/profiles/project-analysis.json +31 -0
- package/runtime/prompts/profiles/project-analysis.md +0 -20
- package/runtime/prompts/profiles/release-handoff.json +5 -0
- package/runtime/prompts/profiles/release-handoff.md +71 -73
- package/runtime/prompts/profiles/requirements-discovery.json +39 -0
- package/runtime/prompts/profiles/requirements-discovery.md +0 -25
- package/runtime/prompts/profiles/technical-verification.json +39 -0
- package/runtime/prompts/profiles/technical-verification.md +0 -25
- package/runtime/prompts/wizard/prompts.ko.json +12 -17
- package/runtime/python/okstra_ctl/adapters/hosts/antigravity/relay.md +1 -0
- package/runtime/python/okstra_ctl/adapters/hosts/claude-code/adapter.py +3 -0
- package/runtime/python/okstra_ctl/adapters/hosts/claude-code/manifest.json +1 -1
- package/runtime/python/okstra_ctl/adapters/hosts/claude-code/relay.md +4 -3
- package/runtime/python/okstra_ctl/adapters/hosts/claude-code/worker-session.md +108 -0
- package/runtime/python/okstra_ctl/adapters/hosts/codex/relay.md +1 -0
- package/runtime/python/okstra_ctl/adapters/hosts/grok/relay.md +2 -0
- package/runtime/python/okstra_ctl/adapters/hosts/kimi/relay.md +2 -0
- package/runtime/python/okstra_ctl/adapters/providers/antigravity/adapter.py +8 -1
- package/runtime/python/okstra_ctl/adapters/providers/claude/adapter.py +8 -0
- package/runtime/python/okstra_ctl/adapters/providers/codex/adapter.py +23 -6
- package/runtime/python/okstra_ctl/adapters/providers/grok/adapter.py +6 -2
- package/runtime/python/okstra_ctl/agent/invocation.py +168 -113
- package/runtime/python/okstra_ctl/agent/prompt_cli/cli.py +120 -0
- package/runtime/python/okstra_ctl/agent/prompt_cli/materialize.py +107 -2
- package/runtime/python/okstra_ctl/agent/prompt_cli/run_identity.py +0 -49
- package/runtime/python/okstra_ctl/analysis_packet.py +4 -1
- package/runtime/python/okstra_ctl/application/open_worker.py +6 -1
- package/runtime/python/okstra_ctl/assignment_resolver.py +16 -5
- package/runtime/python/okstra_ctl/cmux.py +69 -20
- package/runtime/python/okstra_ctl/code_review_target.py +16 -8
- package/runtime/python/okstra_ctl/conformance.py +43 -0
- package/runtime/python/okstra_ctl/consumers.py +6 -3
- package/runtime/python/okstra_ctl/container.py +31 -8
- package/runtime/python/okstra_ctl/context_cost.py +11 -15
- package/runtime/python/okstra_ctl/contract_refreeze.py +156 -0
- package/runtime/python/okstra_ctl/convergence_critic_prompt.py +4 -6
- package/runtime/python/okstra_ctl/convergence_provenance.py +81 -18
- package/runtime/python/okstra_ctl/design_prep.py +34 -1
- package/runtime/python/okstra_ctl/dispatch_core.py +53 -27
- package/runtime/python/okstra_ctl/domain/host.py +5 -0
- package/runtime/python/okstra_ctl/domain/worker_runtime.py +10 -0
- package/runtime/python/okstra_ctl/error_report.py +4 -3
- package/runtime/python/okstra_ctl/execution_manifest.py +71 -18
- package/runtime/python/okstra_ctl/execution_mutation_audit.py +21 -21
- package/runtime/python/okstra_ctl/handoff.py +167 -277
- package/runtime/python/okstra_ctl/implementation_stage.py +9 -0
- package/runtime/python/okstra_ctl/initial_prompt_materialization.py +113 -0
- package/runtime/python/okstra_ctl/lead_progress.py +1 -1
- package/runtime/python/okstra_ctl/legacy_model_selection.py +2 -2
- package/runtime/python/okstra_ctl/manager_cli.py +175 -14
- package/runtime/python/okstra_ctl/manager_launch.py +41 -19
- package/runtime/python/okstra_ctl/manager_paths.py +22 -3
- package/runtime/python/okstra_ctl/manager_split.py +474 -0
- package/runtime/python/okstra_ctl/manager_store.py +331 -21
- package/runtime/python/okstra_ctl/manager_sync.py +37 -16
- package/runtime/python/okstra_ctl/manager_view.py +217 -0
- package/runtime/python/okstra_ctl/model_discovery.py +30 -0
- package/runtime/python/okstra_ctl/model_io/lines.py +14 -1
- package/runtime/python/okstra_ctl/model_io/renderers.py +4 -3
- package/runtime/python/okstra_ctl/models.py +1 -1
- package/runtime/python/okstra_ctl/next_phase.py +16 -6
- package/runtime/python/okstra_ctl/operation_invocation.py +86 -0
- package/runtime/python/okstra_ctl/option_comparison.py +168 -0
- package/runtime/python/okstra_ctl/path_hints.py +9 -0
- package/runtime/python/okstra_ctl/paths.py +3 -0
- package/runtime/python/okstra_ctl/plan_items_cli.py +6 -1
- package/runtime/python/okstra_ctl/profile_show.py +42 -1
- package/runtime/python/okstra_ctl/qa_commands.py +15 -0
- package/runtime/python/okstra_ctl/registry/host_discovery.py +20 -12
- package/runtime/python/okstra_ctl/registry/host_registry.py +11 -0
- package/runtime/python/okstra_ctl/render.py +50 -0
- package/runtime/python/okstra_ctl/report_contract.py +1 -1
- package/runtime/python/okstra_ctl/report_finalize.py +13 -6
- package/runtime/python/okstra_ctl/report_html/view_models/final_verification.py +2 -21
- package/runtime/python/okstra_ctl/report_html/view_models/release_handoff.py +21 -3
- package/runtime/python/okstra_ctl/report_html/visualizations.py +0 -5
- package/runtime/python/okstra_ctl/report_synthesis_packet.py +177 -17
- package/runtime/python/okstra_ctl/report_translation.py +2 -1
- package/runtime/python/okstra_ctl/report_translation_dispatch.py +69 -9
- package/runtime/python/okstra_ctl/role_requirements.py +142 -129
- package/runtime/python/okstra_ctl/rollup.py +3 -1
- package/runtime/python/okstra_ctl/run.py +76 -29
- package/runtime/python/okstra_ctl/schedule_semantics.py +17 -6
- package/runtime/python/okstra_ctl/stage_fix_carry.py +23 -4
- package/runtime/python/okstra_ctl/stage_integrate.py +178 -18
- package/runtime/python/okstra_ctl/stage_map.py +16 -2
- package/runtime/python/okstra_ctl/stage_targets.py +209 -43
- package/runtime/python/okstra_ctl/team.py +22 -13
- package/runtime/python/okstra_ctl/time_report.py +2 -1
- package/runtime/python/okstra_ctl/usage_report.py +3 -1
- package/runtime/python/okstra_ctl/verification_target.py +13 -2
- package/runtime/python/okstra_ctl/wizard/confirmation.py +3 -9
- package/runtime/python/okstra_ctl/wizard/ids.py +1 -1
- package/runtime/python/okstra_ctl/wizard/registry.py +1 -1
- package/runtime/python/okstra_ctl/wizard/state.py +3 -5
- package/runtime/python/okstra_ctl/wizard/steps_plan.py +3 -23
- package/runtime/python/okstra_ctl/worker_prompt_contract.py +5 -1
- package/runtime/python/okstra_ctl/worker_prompt_headers.py +35 -7
- package/runtime/python/okstra_ctl/worker_prompt_policy.py +66 -48
- package/runtime/python/okstra_ctl/workflow.py +1 -1
- package/runtime/python/okstra_ctl/worktree/__init__.py +3 -1
- package/runtime/python/okstra_ctl/worktree/naming.py +9 -0
- package/runtime/python/okstra_ctl/worktree_registry.py +38 -9
- package/runtime/python/okstra_token_usage/pricing.py +6 -4
- package/runtime/schemas/agent-common-v1.schema.json +34 -0
- package/runtime/schemas/agent-duty-v1.schema.json +38 -0
- package/runtime/schemas/agent-operation-v1.schema.json +11 -0
- package/runtime/schemas/agent-profile-v1.schema.json +46 -0
- package/runtime/schemas/agent-role-v1.schema.json +29 -0
- package/runtime/schemas/final-report-v2.0.schema.json +118 -97
- package/runtime/schemas/final-report-v3.0.schema.json +118 -97
- package/runtime/skills/okstra-brief-gen/SKILL.md +84 -4
- package/runtime/skills/okstra-chat/SKILL.md +2 -2
- package/runtime/skills/okstra-code-review/SKILL.md +23 -9
- package/runtime/skills/okstra-container-build/SKILL.md +10 -10
- package/runtime/skills/okstra-inspect/SKILL.md +1 -1
- package/runtime/skills/okstra-inspect/facets/cost.md +1 -1
- package/runtime/skills/okstra-inspect/facets/error-zip.md +9 -9
- package/runtime/skills/okstra-inspect/facets/errors.md +16 -16
- package/runtime/skills/okstra-inspect/facets/logs.md +7 -7
- package/runtime/skills/okstra-inspect/facets/recap.md +2 -2
- package/runtime/skills/okstra-inspect/facets/report.md +1 -1
- package/runtime/skills/okstra-inspect/facets/status.md +4 -3
- package/runtime/skills/okstra-inspect/facets/time.md +11 -10
- package/runtime/skills/okstra-manager/SKILL.md +70 -5
- package/runtime/skills/okstra-pr-gen/SKILL.md +6 -5
- package/runtime/skills/okstra-rollup/SKILL.md +5 -5
- package/runtime/skills/okstra-run/SKILL.md +32 -13
- package/runtime/skills/okstra-schedule-gen/SKILL.md +19 -14
- package/runtime/skills/okstra-setup/SKILL.md +21 -10
- package/runtime/skills/okstra-setup/references/project-config.md +7 -6
- package/runtime/skills/okstra-usage/SKILL.md +1 -1
- package/runtime/skills/okstra-user-response/SKILL.md +1 -1
- package/runtime/templates/manager/view.template.html +109 -0
- package/runtime/templates/report-writer-prompt-preamble.md +8 -0
- package/runtime/templates/reports/brief.template.md +14 -4
- package/runtime/templates/reports/html/i18n/en.json +7 -4
- package/runtime/templates/reports/html/i18n/ko.json +7 -4
- package/runtime/templates/reports/html/tasks/final-verification.template.html +2 -2
- package/runtime/templates/reports/html/tasks/release-handoff.template.html +8 -5
- package/runtime/templates/reports/i18n/en.json +1 -1
- package/runtime/templates/reports/md/tasks/release-handoff.template.md +1 -1
- package/runtime/templates/reports/release-handoff-input.template.md +6 -4
- package/runtime/templates/translator-prompt-preamble.md +36 -0
- package/runtime/validators/checks/validate-assets-01.py +7 -8
- package/runtime/validators/validate-brief.py +77 -2
- package/runtime/validators/validate-implementation-plan-stages.py +2 -1
- package/runtime/validators/validate-run.py +59 -9
- package/runtime/validators/validate-schedule.py +9 -0
- package/docs/for-ai/README.md +0 -68
- package/docs/for-ai/skills/okstra-brief-gen.md +0 -262
- package/docs/for-ai/skills/okstra-chat.md +0 -34
- package/docs/for-ai/skills/okstra-code-review.md +0 -57
- package/docs/for-ai/skills/okstra-container-build.md +0 -129
- package/docs/for-ai/skills/okstra-inspect.md +0 -262
- package/docs/for-ai/skills/okstra-manager.md +0 -69
- package/docs/for-ai/skills/okstra-memory.md +0 -126
- package/docs/for-ai/skills/okstra-pr-gen.md +0 -49
- package/docs/for-ai/skills/okstra-rollup.md +0 -114
- package/docs/for-ai/skills/okstra-run.md +0 -250
- package/docs/for-ai/skills/okstra-schedule-gen.md +0 -240
- package/docs/for-ai/skills/okstra-setup.md +0 -158
- package/docs/for-ai/skills/okstra-usage.md +0 -29
- package/docs/for-ai/skills/okstra-user-response.md +0 -72
- package/runtime/agents/workers/claude-worker.md +0 -128
- package/runtime/agents/workers/report-writer-worker.md +0 -37
- package/runtime/agents/workers/translator-worker.md +0 -63
- package/runtime/prompts/duties/acceptance-critic.md +0 -44
- package/runtime/prompts/duties/acceptance-verifier.md +0 -44
- package/runtime/prompts/duties/analysis-worker.md +0 -44
- package/runtime/prompts/duties/code-reviewer.md +0 -44
- package/runtime/prompts/duties/common.md +0 -39
- package/runtime/prompts/duties/diagnosis-worker.md +0 -44
- package/runtime/prompts/duties/direction-selection-worker.md +0 -44
- package/runtime/prompts/duties/discovery-worker.md +0 -44
- package/runtime/prompts/duties/implementation-executor.md +0 -44
- package/runtime/prompts/duties/implementation-verifier.md +0 -44
- package/runtime/prompts/duties/lead.md +0 -44
- package/runtime/prompts/duties/planning-worker.md +0 -52
- package/runtime/prompts/duties/report-writer.md +0 -44
- package/runtime/prompts/duties/reverification-worker.md +0 -44
- package/runtime/prompts/duties/schedule-verifier.md +0 -44
- package/runtime/prompts/duties/scope-critic.md +0 -44
- package/runtime/prompts/duties/technical-verification-worker.md +0 -44
- package/runtime/prompts/duties/translator.md +0 -44
- package/runtime/python/okstra_ctl/pane_title.py +0 -154
|
@@ -47,6 +47,10 @@ Checks performed per brief file:
|
|
|
47
47
|
it is checked by `okstra_ctl.group_context.validate_group_context` (four
|
|
48
48
|
required sections, no template placeholder left, directory slug matches
|
|
49
49
|
the frontmatter `task-group`). Any other `type` is a failure.
|
|
50
|
+
16. No required section except `## Source Material` still carries the
|
|
51
|
+
template's `<...>` scaffolding — a paragraph wrapped in angle brackets,
|
|
52
|
+
a `- <...>` bullet, or a `> augmented: <label>` line. Source Material is
|
|
53
|
+
exempt because it holds the reporter's words verbatim.
|
|
50
54
|
|
|
51
55
|
Exit code 0 on PASS, 1 on FAIL.
|
|
52
56
|
"""
|
|
@@ -104,6 +108,10 @@ AUGMENTATION_LABELS = {
|
|
|
104
108
|
|
|
105
109
|
REPORTER_CONFIRMATION_VALUES = {"complete", "partial", "pending", "skipped"}
|
|
106
110
|
|
|
111
|
+
# okstra-manager `task split` renders the same brief contract for each project
|
|
112
|
+
# it splits a tracker issue into.
|
|
113
|
+
GENERATORS = {"okstra-brief-gen", "okstra-manager"}
|
|
114
|
+
|
|
107
115
|
SCOPE_VALUES = {"reporter-input", "codebase"}
|
|
108
116
|
|
|
109
117
|
TASK_GRAPH_HEADER = ["From", "Relation", "To", "Direction", "Source", "Impact"]
|
|
@@ -652,6 +660,71 @@ def check_variant_required_sections(
|
|
|
652
660
|
)
|
|
653
661
|
|
|
654
662
|
|
|
663
|
+
# 템플릿의 `<...>` 문구는 작성자가 바꿔 쓸 자리다. 그대로 남으면 다음 phase 가
|
|
664
|
+
# 그 문구를 제보 내용으로 읽는다. 문구는 여러 줄에 걸친 한 문단이라 줄 단위
|
|
665
|
+
# `is_template_example` 만으로는 잡히지 않는다 — 문단을 합쳐서 본다.
|
|
666
|
+
_AUGMENTED_LABEL_SCAFFOLD_RE = re.compile(r"^>\s*augmented:\s*<label>")
|
|
667
|
+
|
|
668
|
+
|
|
669
|
+
def _paragraphs_outside_fences(body: str) -> Iterable[list[str]]:
|
|
670
|
+
paragraph: list[str] = []
|
|
671
|
+
in_fence = False
|
|
672
|
+
for line in body.splitlines():
|
|
673
|
+
stripped = line.strip()
|
|
674
|
+
if stripped.startswith("```"):
|
|
675
|
+
in_fence = not in_fence
|
|
676
|
+
if in_fence or stripped.startswith("```") or not stripped:
|
|
677
|
+
if paragraph:
|
|
678
|
+
yield paragraph
|
|
679
|
+
paragraph = []
|
|
680
|
+
continue
|
|
681
|
+
paragraph.append(stripped)
|
|
682
|
+
if paragraph:
|
|
683
|
+
yield paragraph
|
|
684
|
+
|
|
685
|
+
|
|
686
|
+
def template_scaffold(body: str) -> list[str]:
|
|
687
|
+
"""Template scaffolding left in a section body, one entry per leftover."""
|
|
688
|
+
found: list[str] = []
|
|
689
|
+
for paragraph in _paragraphs_outside_fences(body):
|
|
690
|
+
joined = " ".join(paragraph)
|
|
691
|
+
if joined.startswith("<") and joined.endswith(">"):
|
|
692
|
+
found.append(joined)
|
|
693
|
+
continue
|
|
694
|
+
found.extend(
|
|
695
|
+
line
|
|
696
|
+
for line in paragraph
|
|
697
|
+
if is_template_example(line) or _AUGMENTED_LABEL_SCAFFOLD_RE.match(line)
|
|
698
|
+
)
|
|
699
|
+
return found
|
|
700
|
+
|
|
701
|
+
|
|
702
|
+
def check_template_scaffold(text: str, scope: str, errors: list[str]) -> None:
|
|
703
|
+
"""Required sections must not keep the template's `<...>` scaffolding.
|
|
704
|
+
|
|
705
|
+
`## Source Material` is exempt: it holds the reporter's words verbatim,
|
|
706
|
+
and those can legitimately contain angle-bracketed text.
|
|
707
|
+
"""
|
|
708
|
+
headings = [
|
|
709
|
+
REQUIREMENT_SECTION,
|
|
710
|
+
*ALWAYS_REQUIRED_SECTIONS,
|
|
711
|
+
_GATE_SECTION,
|
|
712
|
+
*(heading for heading, _prefix in _END_STATE_SECTIONS),
|
|
713
|
+
]
|
|
714
|
+
if scope == "codebase":
|
|
715
|
+
headings += ["Scan Scope", "Priority Lenses"]
|
|
716
|
+
else:
|
|
717
|
+
headings.append("Problem / Symptom")
|
|
718
|
+
for heading in headings:
|
|
719
|
+
leftover = template_scaffold(section_body(text, heading))
|
|
720
|
+
if leftover:
|
|
721
|
+
errors.append(
|
|
722
|
+
f"'## {heading}' still carries template text {leftover[0][:60]!r} — "
|
|
723
|
+
"replace it with the brief's content, or _(none)_ when the section "
|
|
724
|
+
"is deliberately empty. Downstream phases read this section as written"
|
|
725
|
+
)
|
|
726
|
+
|
|
727
|
+
|
|
655
728
|
def check_reporter_confirmations(
|
|
656
729
|
rc_status: str | None, reporter_rows: list[str], errors: list[str]
|
|
657
730
|
) -> None:
|
|
@@ -693,9 +766,10 @@ def validate_brief(path: Path, briefs_root: Path) -> list[str]:
|
|
|
693
766
|
if fm.get("type") != "brief":
|
|
694
767
|
errors.append(f"frontmatter type must be 'brief', got {fm.get('type')!r}")
|
|
695
768
|
|
|
696
|
-
if fm.get("generator")
|
|
769
|
+
if fm.get("generator") not in GENERATORS:
|
|
697
770
|
errors.append(
|
|
698
|
-
f"frontmatter generator must be
|
|
771
|
+
f"frontmatter generator must be one of {sorted(GENERATORS)}, "
|
|
772
|
+
f"got {fm.get('generator')!r}"
|
|
699
773
|
)
|
|
700
774
|
|
|
701
775
|
if fm.get("reporter-confirmations") not in REPORTER_CONFIRMATION_VALUES:
|
|
@@ -719,6 +793,7 @@ def validate_brief(path: Path, briefs_root: Path) -> list[str]:
|
|
|
719
793
|
check_requirement_section(text, errors)
|
|
720
794
|
check_end_state_sections(text, scope, errors)
|
|
721
795
|
check_variant_required_sections(text, scope, errors)
|
|
796
|
+
check_template_scaffold(text, scope, errors)
|
|
722
797
|
|
|
723
798
|
# 2. brief-id matches filename stem
|
|
724
799
|
stem = path.stem
|
|
@@ -34,6 +34,7 @@ from okstra_ctl.stage_map import ( # noqa: E402
|
|
|
34
34
|
parse_stage_dependencies,
|
|
35
35
|
parse_stage_map_text,
|
|
36
36
|
schema_v2_report,
|
|
37
|
+
stage_number_gap_message,
|
|
37
38
|
)
|
|
38
39
|
|
|
39
40
|
HARD_STEP_CAP = 8
|
|
@@ -86,7 +87,7 @@ def _stage_numbers_monotonic(
|
|
|
86
87
|
) -> List[ValidationError]:
|
|
87
88
|
return [
|
|
88
89
|
ValidationError("S2", r.stage_number,
|
|
89
|
-
|
|
90
|
+
stage_number_gap_message(r.stage_number, i))
|
|
90
91
|
for i, r in enumerate(stages, start=1)
|
|
91
92
|
if r.stage_number != i
|
|
92
93
|
]
|
|
@@ -43,6 +43,7 @@ from okstra_project.resolver import resolve_architecture # noqa: E402
|
|
|
43
43
|
from okstra_ctl.conformance import ( # noqa: E402
|
|
44
44
|
conformance_result_file,
|
|
45
45
|
detect_surfaces,
|
|
46
|
+
declared_stage_surface_gaps,
|
|
46
47
|
exempt_stage_surface_conflicts,
|
|
47
48
|
evaluate_conformance,
|
|
48
49
|
manifest_required_surfaces,
|
|
@@ -2120,7 +2121,13 @@ def _declared_conformance_errors(
|
|
|
2120
2121
|
and all(isinstance(value, str) for value in actual_requires)
|
|
2121
2122
|
else None
|
|
2122
2123
|
)
|
|
2123
|
-
|
|
2124
|
+
# 넓히는 것만 허용한다 — 선언보다 많은 capability 는 더 엄격한 검증이다.
|
|
2125
|
+
# 승인된 계획이 `requires` 를 좁게 적고 그 stage 의 diff 가 다른 표면을
|
|
2126
|
+
# 건드리면, diff-surface 대조는 넓힐 것을 요구하는데 정확 일치는 그것을
|
|
2127
|
+
# 거절해 같은 계획으로는 통과할 입력이 없었다(2026-09-22 dev-10860
|
|
2128
|
+
# Stage 1). 좁히는 것은 선언한 검증을 빼는 것이므로 여전히 불일치다.
|
|
2129
|
+
declared_capabilities = frozenset(declaration.get("requires") or [])
|
|
2130
|
+
if actual_capabilities is None or not actual_capabilities >= declared_capabilities:
|
|
2124
2131
|
errors.append(f"stage {stage_number} requires mismatch")
|
|
2125
2132
|
# 계획이 면제한 stage 에 구현이 실제 Tier 3 항목을 붙이는 것은 허용한다 —
|
|
2126
2133
|
# 면제 stage 의 diff 가 db/io/http/external 표면을 건드려 diff-surface 대조에
|
|
@@ -2183,6 +2190,24 @@ def _project_surface_patterns(project_root: Path) -> object:
|
|
|
2183
2190
|
return None
|
|
2184
2191
|
|
|
2185
2192
|
|
|
2193
|
+
def _implemented_stages(data_path: Path) -> frozenset[int]:
|
|
2194
|
+
"""이 태스크에서 구현이 끝난 stage. 원장을 못 읽으면 빈 집합이다."""
|
|
2195
|
+
from okstra_ctl.consumers import read_stage_consumer_state
|
|
2196
|
+
|
|
2197
|
+
try:
|
|
2198
|
+
state = read_stage_consumer_state(data_path.parent.parent)
|
|
2199
|
+
except (OSError, UnicodeError, ValueError):
|
|
2200
|
+
return frozenset()
|
|
2201
|
+
return frozenset(state.done_stages)
|
|
2202
|
+
|
|
2203
|
+
|
|
2204
|
+
def _is_implemented_stage(stage: object, implemented: frozenset[int]) -> bool:
|
|
2205
|
+
number = stage.get("stage") if isinstance(stage, dict) else None
|
|
2206
|
+
return isinstance(number, int) and not isinstance(number, bool) and (
|
|
2207
|
+
number in implemented
|
|
2208
|
+
)
|
|
2209
|
+
|
|
2210
|
+
|
|
2186
2211
|
def _validate_planning_conformance_declared(
|
|
2187
2212
|
report_path: Path,
|
|
2188
2213
|
failures: list[str],
|
|
@@ -2209,7 +2234,17 @@ def _validate_planning_conformance_declared(
|
|
|
2209
2234
|
ip = data.get("implementationPlanning")
|
|
2210
2235
|
if not isinstance(ip, dict):
|
|
2211
2236
|
return
|
|
2212
|
-
|
|
2237
|
+
# 구현이 끝난 stage 는 이 게이트의 대상이 아니다. 그 본문은 다음 계획 run 에
|
|
2238
|
+
# 그대로 이월되고(ADR-0015), 이월된 본문은 고칠 수 없다 — 규칙이 그 사이에
|
|
2239
|
+
# 넓어졌다면 통과 가능한 값이 없는 요구가 된다(2026-09-24, dev-10860: 이월된
|
|
2240
|
+
# stage 2·3·5 가 오늘의 표면 패턴으로 `requires` 누락 판정).
|
|
2241
|
+
implemented = _implemented_stages(data_path)
|
|
2242
|
+
stages = [
|
|
2243
|
+
stage
|
|
2244
|
+
for stage in ip.get("stages") or ()
|
|
2245
|
+
if not _is_implemented_stage(stage, implemented)
|
|
2246
|
+
]
|
|
2247
|
+
_planning_conformance_declarations(stages, failures)
|
|
2213
2248
|
if ip.get("planningContract") != "selected-direction":
|
|
2214
2249
|
from okstra_ctl.implementation_direction import (
|
|
2215
2250
|
stage_validation_executability_errors,
|
|
@@ -2217,6 +2252,8 @@ def _validate_planning_conformance_declared(
|
|
|
2217
2252
|
|
|
2218
2253
|
failures.extend(stage_validation_executability_errors(ip))
|
|
2219
2254
|
for conflict in exempt_stage_surface_conflicts(data, surface_patterns):
|
|
2255
|
+
if conflict["stage"] in implemented:
|
|
2256
|
+
continue
|
|
2220
2257
|
failures.append(
|
|
2221
2258
|
"conformance gate BLOCKING: stage "
|
|
2222
2259
|
f"{conflict['stage']} declares `Conformance exemption:` but its "
|
|
@@ -2229,6 +2266,19 @@ def _validate_planning_conformance_declared(
|
|
|
2229
2266
|
"blocks the same stage after the work is done, where the approved "
|
|
2230
2267
|
"plan can no longer be corrected."
|
|
2231
2268
|
)
|
|
2269
|
+
for gap in declared_stage_surface_gaps(data, surface_patterns):
|
|
2270
|
+
if gap["stage"] in implemented:
|
|
2271
|
+
continue
|
|
2272
|
+
failures.append(
|
|
2273
|
+
"conformance gate BLOCKING: stage "
|
|
2274
|
+
f"{gap['stage']} declares `Conformance tests:` with "
|
|
2275
|
+
f"requires={gap['requires']} but its planned paths touch surface(s) "
|
|
2276
|
+
f"{gap['surfaces']}: {', '.join(gap['paths'])} — add "
|
|
2277
|
+
f"{gap['surfaces']} to that stage's `requires`, or move those paths "
|
|
2278
|
+
"out of it. The implementation run's diff-surface check demands "
|
|
2279
|
+
"the wider set after the work is done, where the approved plan can "
|
|
2280
|
+
"no longer be corrected."
|
|
2281
|
+
)
|
|
2232
2282
|
|
|
2233
2283
|
|
|
2234
2284
|
def _validate_conformance_surfaces(
|
|
@@ -8065,19 +8115,19 @@ def _validate_final_verification_consistency(data: dict, failures: list[str]) ->
|
|
|
8065
8115
|
"`blocksReleaseHandoff: false`."
|
|
8066
8116
|
)
|
|
8067
8117
|
|
|
8118
|
+
if routing_token == "final-verification" and token == "accepted":
|
|
8119
|
+
failures.append(
|
|
8120
|
+
"final-verification: routingRecommendation cites `final-verification` "
|
|
8121
|
+
"but the verdict is `accepted` — an accepted verdict carries no blocker "
|
|
8122
|
+
"to re-verify. Route to release-handoff or done."
|
|
8123
|
+
)
|
|
8124
|
+
|
|
8068
8125
|
scope = data.get("verificationScope", "whole-task")
|
|
8069
8126
|
if scope not in ("whole-task", "single-stage"):
|
|
8070
8127
|
failures.append(
|
|
8071
8128
|
f"final-verification: verificationScope must be `whole-task` or "
|
|
8072
8129
|
f"`single-stage`, got {scope!r}."
|
|
8073
8130
|
)
|
|
8074
|
-
if scope == "single-stage" and routing_token == "release-handoff":
|
|
8075
|
-
failures.append(
|
|
8076
|
-
"final-verification: verificationScope `single-stage` cannot recommend "
|
|
8077
|
-
"plain release-handoff routing — a single-stage accepted verdict may "
|
|
8078
|
-
"only route to `release-handoff(stage-group)` (partial-PR mode); "
|
|
8079
|
-
"whole-task release-handoff requires whole-task verification."
|
|
8080
|
-
)
|
|
8081
8131
|
|
|
8082
8132
|
|
|
8083
8133
|
def validate_report_views(report_path: Path, failures: list[str]) -> None:
|
|
@@ -441,6 +441,15 @@ def _validate_format(path: Path) -> list[str]:
|
|
|
441
441
|
f"{why}; a stage block is Steps plus Exit criteria"
|
|
442
442
|
)
|
|
443
443
|
|
|
444
|
+
# 9b. The At a Glance work column is titled in the schedule's language.
|
|
445
|
+
glance_header = (
|
|
446
|
+
f"| # | {labels['glance_work_column']} | Category | Priority | Effort | Days | Risk |"
|
|
447
|
+
)
|
|
448
|
+
if "## At a Glance" in section_positions and glance_header not in text:
|
|
449
|
+
violations.append(
|
|
450
|
+
f"`## At a Glance` requires the header literal {glance_header!r}"
|
|
451
|
+
)
|
|
452
|
+
|
|
444
453
|
# 10. Days total format inside At a Glance: `**N tasks total / estimated effort: X.X ~ Y.Y days (Effort sum)**`
|
|
445
454
|
if "## At a Glance" in section_positions:
|
|
446
455
|
start = section_positions["## At a Glance"]
|
package/docs/for-ai/README.md
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
# Okstra Skills AI Manuals
|
|
2
|
-
|
|
3
|
-
This directory is a compressed manual for an AI to quickly select and precisely run okstra public skills. The authoritative contract is `skills/*/SKILL.md`; this document is the operational guide for the AI. When the source skills, templates, validators, or CLI registry conflict, prefer the source skills and the actual validator/CLI implementation.
|
|
4
|
-
|
|
5
|
-
## Verified Sources
|
|
6
|
-
|
|
7
|
-
- Public skill list: [`src/lib/skill-catalog.mjs`](../../src/lib/skill-catalog.mjs)
|
|
8
|
-
- Skill sources: [`skills/`](../../skills/)
|
|
9
|
-
- CLI command surface: [`src/cli-registry.mjs`](../../src/cli-registry.mjs)
|
|
10
|
-
- brief template: [`templates/reports/brief.template.md`](../../templates/reports/brief.template.md)
|
|
11
|
-
- schedule template: [`templates/reports/schedule.template.md`](../../templates/reports/schedule.template.md)
|
|
12
|
-
- brief validator: [`validators/validate-brief.py`](../../validators/validate-brief.py)
|
|
13
|
-
- schedule validator: [`validators/validate-schedule.py`](../../validators/validate-schedule.py)
|
|
14
|
-
|
|
15
|
-
## Skill Routing
|
|
16
|
-
|
|
17
|
-
| User intent | Skill to use | Manual |
|
|
18
|
-
|---|---|---|
|
|
19
|
-
| Install/initialize okstra on a new project or a new machine | `okstra-setup` | [`skills/okstra-setup.md`](skills/okstra-setup.md) |
|
|
20
|
-
| Turn requirements, tickets, links, a codebase scan, or an error-zip into an okstra input brief | `okstra-brief-gen` | [`skills/okstra-brief-gen.md`](skills/okstra-brief-gen.md) |
|
|
21
|
-
| Start an okstra run or execute the next phase in the current Claude Code session | `okstra-run` | [`skills/okstra-run.md`](skills/okstra-run.md) |
|
|
22
|
-
| Manage okstra tasks across multiple projects — bundling, assignment, sync snapshots, child launch packets | `okstra-manager` | [`skills/okstra-manager.md`](skills/okstra-manager.md) |
|
|
23
|
-
| Check status, history, report, time, logs, cost, errors, error-zip, run-audit, recap | `okstra-inspect` | [`skills/okstra-inspect.md`](skills/okstra-inspect.md) |
|
|
24
|
-
| Collect and aggregate the results of multiple task runs across a task-group (or the whole project) into a synthesized summary | `okstra-rollup` | [`skills/okstra-rollup.md`](skills/okstra-rollup.md) |
|
|
25
|
-
| Project-wide recent run coverage, tokens, known cost, CPU, and wall-clock usage by task type | `okstra-usage` | [`skills/okstra-usage.md`](skills/okstra-usage.md) |
|
|
26
|
-
| Generate a client-facing work schedule for a whole task-group | `okstra-schedule-gen` | [`skills/okstra-schedule-gen.md`](skills/okstra-schedule-gen.md) |
|
|
27
|
-
| Store or search conversations/decisions/preferences/requirements in the global Memory Book | `okstra-memory` | [`skills/okstra-memory.md`](skills/okstra-memory.md) |
|
|
28
|
-
| Create or join a global room and send or read addressed messages across host sessions | `okstra-chat` | [`skills/okstra-chat.md`](skills/okstra-chat.md) |
|
|
29
|
-
| Manage the implementation-task worktree-based docker compose user-test environment | `okstra-container-build` | [`skills/okstra-container-build.md`](skills/okstra-container-build.md) |
|
|
30
|
-
| Answer the unresolved clarification questions an okstra run left behind in-session and record the approval gate | `okstra-user-response` | [`skills/okstra-user-response.md`](skills/okstra-user-response.md) |
|
|
31
|
-
| Register a PR body template or generate a PR description from a branch diff (global, git repository) | `okstra-pr-gen` | [`skills/okstra-pr-gen.md`](skills/okstra-pr-gen.md) |
|
|
32
|
-
| Review the changed code of one okstra `implementation` stage or of any branch against the coding-preflight rules, and write the result to a file | `okstra-code-review` | [`skills/okstra-code-review.md`](skills/okstra-code-review.md) |
|
|
33
|
-
|
|
34
|
-
## Shared Execution Rules
|
|
35
|
-
|
|
36
|
-
1. Run commands as separate Bash calls whenever the source skill requires it. In particular, do not wrap `okstra preflight --runtime claude-code`, `okstra wizard ...`, or `okstra container ...` calls in `&&`, `||`, `$(...)`, a leading variable assignment, `eval`, or `export`.
|
|
37
|
-
2. An `okstra <subcmd>` call bootstraps its own Python path. Unless a skill states otherwise, do not build `okstra paths --shell` or `export PYTHONPATH=...`.
|
|
38
|
-
3. Most skills except `okstra-setup` do not use an `npx` fallback. If the runtime is missing, tell the user to run `/okstra-setup` and stop. But if it fails with `unknown command: <cmd>`, the `okstra` binary on PATH is older than the skill — point the user to `npm i -g okstra@latest` rather than `/okstra-setup`, and stop.
|
|
39
|
-
4. Project artifacts go under `<PROJECT_ROOT>/.okstra/` by default. The exceptions are `okstra-memory` (`~/.okstra/memory-book/`) and `okstra-chat` (`~/.okstra/chat/`).
|
|
40
|
-
5. `runtime/` is build output. When fixing a source skill or template, edit the source under `skills/`, `templates/`, `validators/`, `scripts/`, `src/` and apply it via a build.
|
|
41
|
-
6. Do not guess the contents of a tracker, URL, file, report, log, zip, template, or validator. Use only what you have confirmed by reading or running with a tool.
|
|
42
|
-
7. Read-side skills also produce some artifacts. `okstra-inspect errors` produces an error report Markdown and `okstra-inspect error-zip` produces an anonymized zip. Even in these cases, keep the purpose-specific fixed CLI fields as the source of truth.
|
|
43
|
-
|
|
44
|
-
## The Order the AI Reads In
|
|
45
|
-
|
|
46
|
-
1. Pick a skill in this file.
|
|
47
|
-
2. Read only the matching `docs/for-ai/skills/<skill>.md`.
|
|
48
|
-
3. If the skill requires actual execution, confirm the relevant step in the source [`skills/<skill>/SKILL.md`](../../skills/).
|
|
49
|
-
4. When writing a brief or schedule, also confirm the template and the validator.
|
|
50
|
-
|
|
51
|
-
## Public Skill List
|
|
52
|
-
|
|
53
|
-
The public skills listed in this AI manual are the following 14:
|
|
54
|
-
|
|
55
|
-
- `okstra-setup`
|
|
56
|
-
- `okstra-brief-gen`
|
|
57
|
-
- `okstra-run`
|
|
58
|
-
- `okstra-manager`
|
|
59
|
-
- `okstra-memory`
|
|
60
|
-
- `okstra-chat`
|
|
61
|
-
- `okstra-inspect`
|
|
62
|
-
- `okstra-rollup`
|
|
63
|
-
- `okstra-usage`
|
|
64
|
-
- `okstra-schedule-gen`
|
|
65
|
-
- `okstra-container-build`
|
|
66
|
-
- `okstra-user-response`
|
|
67
|
-
- `okstra-pr-gen`
|
|
68
|
-
- `okstra-code-review`
|
|
@@ -1,262 +0,0 @@
|
|
|
1
|
-
# okstra-brief-gen AI Manual
|
|
2
|
-
|
|
3
|
-
## Source
|
|
4
|
-
|
|
5
|
-
- Skill source: [`skills/okstra-brief-gen/SKILL.md`](../../../skills/okstra-brief-gen/SKILL.md)
|
|
6
|
-
- brief template: [`templates/reports/brief.template.md`](../../../templates/reports/brief.template.md)
|
|
7
|
-
- brief validator: [`validators/validate-brief.py`](../../../validators/validate-brief.py)
|
|
8
|
-
- lens enum SSOT: [`scripts/okstra_ctl/improvement_lenses.py`](../../../scripts/okstra_ctl/improvement_lenses.py)
|
|
9
|
-
|
|
10
|
-
## Purpose
|
|
11
|
-
|
|
12
|
-
`okstra-brief-gen` produces a task brief to feed into the okstra pipeline. A brief is a pre-discovery artifact. It is not a document that turns requirements into an implementation plan; it is a handoff document that separates the reporter's verbatim material from the AI-verified evidence/interpretation using labels, so the next phase can start without questions.
|
|
13
|
-
|
|
14
|
-
Output location:
|
|
15
|
-
|
|
16
|
-
```text
|
|
17
|
-
<PROJECT_ROOT>/.okstra/briefs/<task-group>/<brief-id>.md
|
|
18
|
-
<PROJECT_ROOT>/.okstra/briefs/<task-group>/sub/.../<brief-id>.md
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
## Three variants
|
|
22
|
-
|
|
23
|
-
| Variant | Input | Recommended next phase |
|
|
24
|
-
|---|---|---|
|
|
25
|
-
| Reporter input | files, tickets, URLs, conversation/free text | `requirements-discovery` or `error-analysis` |
|
|
26
|
-
| Codebase scan | scan scope, priority lenses, candidate cap, context | `improvement-discovery` |
|
|
27
|
-
| Error feedback | a single error cluster from the zip produced by `okstra error-zip` | `error-analysis` |
|
|
28
|
-
|
|
29
|
-
## Core invariants
|
|
30
|
-
|
|
31
|
-
1. Source Material is a verbatim-preservation area. Do not paraphrase, summarize, or reorder.
|
|
32
|
-
2. The AI's interpretation, file links, terminology mapping, and format conversion all go under `Augmentation` or a `> augmented:` blockquote.
|
|
33
|
-
3. An augmentation carries one of four labels: `evidence-link`, `format-conversion`, `terminology-mapping`, `intent-inference`.
|
|
34
|
-
4. `intent-inference` is paired with `intent-check:` in `Open Questions`. This relationship is checked by `validators/validate-brief.py`.
|
|
35
|
-
5. A `terminology-mapping` augmentation is paired with `terminology:` in `Open Questions` (validator-checked). Exception: the Step 4.5 result markers `applied glossary:` / `skipped glossary:` need no paired row.
|
|
36
|
-
6. Questions only the reporter can answer are collected in Step 6.5 and recorded verbatim under `## Reporter Confirmations`.
|
|
37
|
-
7. Ticket split/link/order relations go in the structured table of `## Related Task Graph`. Do not infer work order from parent-id alone.
|
|
38
|
-
8. Every okstra-owned write stays inside `<PROJECT_ROOT>/.okstra/`. External files are read only when the reporter explicitly cited them as source.
|
|
39
|
-
9. Every row in `Open Questions` starts with one of five prefixes: `general:`, `terminology:`, `intent-check:`, `conversion-block:`, `adr-candidate:` (validator-enforced). `adr-candidate:` is only a signal — the decision file is written by `implementation-planning` into `<PROJECT_ROOT>/.okstra/decisions/`.
|
|
40
|
-
|
|
41
|
-
## Preflight
|
|
42
|
-
|
|
43
|
-
Run as a single call.
|
|
44
|
-
|
|
45
|
-
```bash
|
|
46
|
-
okstra preflight --runtime claude-code
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
On `Okstra preflight: ready`, carry the fixed `Project root` line. On
|
|
50
|
-
`Okstra preflight: failed`, show `Reason` and `Recovery`, then stop. This skill
|
|
51
|
-
does not use an `npx` fallback.
|
|
52
|
-
|
|
53
|
-
## Input collection
|
|
54
|
-
|
|
55
|
-
### Reporter input
|
|
56
|
-
|
|
57
|
-
More than one source type is allowed, but each source is stored as a separate block under `Source Material`.
|
|
58
|
-
|
|
59
|
-
- File: read the entire file and insert it as-is.
|
|
60
|
-
- Issue tracker ticket: detect Linear/Jira/GitHub/Notion and use MCP or the `gh` CLI. If no access tool is available, ask the user to paste the body or skip.
|
|
61
|
-
- Link URL: fetch it. On failure / login wall / body truncation, ask the user to paste.
|
|
62
|
-
- User input: if conversation context is sufficient, use conversation synthesis; if thin, take a single free-text input.
|
|
63
|
-
|
|
64
|
-
If a ticket has children/sub-tasks, ask once at the parent how to handle the tree.
|
|
65
|
-
|
|
66
|
-
- Full tree: generate a brief per descendant.
|
|
67
|
-
- Parent only: put child keys/URLs in Related Artifacts and leave a `parent-of` edge in `Related Task Graph`.
|
|
68
|
-
- Selected: recurse only into the chosen direct-child branch.
|
|
69
|
-
|
|
70
|
-
During recursion, manage the visited set as `<tracker>:<ticket-id>`, and on re-run reseed from the existing brief frontmatter's `ticket-id` + `source-type`.
|
|
71
|
-
When Full tree or Selected produces multiple briefs, copy the same `Related Task Graph` into every generated brief. That way, even if only one child brief is passed to a downstream phase, the split topology, predecessor/successor relations, and de-duplication signals are preserved.
|
|
72
|
-
|
|
73
|
-
`Related Task Graph` table schema:
|
|
74
|
-
|
|
75
|
-
| Column | Meaning |
|
|
76
|
-
|---|---|
|
|
77
|
-
| From | task key, brief id, tracker id, or URL |
|
|
78
|
-
| Relation | `parent-of`, `child-of`, `depends-on`, `blocks`, `blocked-by`, `follow-up-of`, `split-from`, `duplicates`, `related-to` |
|
|
79
|
-
| To | task key, brief id, tracker id, or URL |
|
|
80
|
-
| Direction | `directed` or `undirected` |
|
|
81
|
-
| Source | tracker linked issue, task-list checkbox, reporter statement, manual split, prior okstra task |
|
|
82
|
-
| Impact | meaning the downstream phase must preserve |
|
|
83
|
-
|
|
84
|
-
`depends-on`, `blocks`, parent/child, follow-up, and split relations are `directed`. `duplicates` and `related-to` are `undirected`. Do not create a relation with no source.
|
|
85
|
-
|
|
86
|
-
### Codebase scan
|
|
87
|
-
|
|
88
|
-
Collected values:
|
|
89
|
-
|
|
90
|
-
- `scan_scope`: a list of real paths inside the project.
|
|
91
|
-
- `priority_lenses`: 1–4 of the `LENSES` enum.
|
|
92
|
-
- `out_of_scope`: optional.
|
|
93
|
-
- `candidate_cap`: 1–12, default 8.
|
|
94
|
-
- context, desired outcome, constraints.
|
|
95
|
-
|
|
96
|
-
Verify path existence, the lens enum subset, and the candidate-cap range before writing. Final validation is done by `validate-brief.py`, which checks `scope: codebase`, `Scan Scope`, and `Priority Lenses`.
|
|
97
|
-
|
|
98
|
-
### Error feedback
|
|
99
|
-
|
|
100
|
-
The input is the zip produced by `okstra error-zip --out <path>`.
|
|
101
|
-
|
|
102
|
-
Processing:
|
|
103
|
-
|
|
104
|
-
1. Confirm the zip contains `report.md` and `errors/anonymized.jsonl`.
|
|
105
|
-
2. Pick exactly one cluster from the frequent-cluster table.
|
|
106
|
-
3. Move only the chosen cluster's anonymized records into Source Material.
|
|
107
|
-
4. Do not mix different errorTypes into one brief.
|
|
108
|
-
5. Set the next-step guidance to `error-analysis`.
|
|
109
|
-
|
|
110
|
-
## task-group and filename
|
|
111
|
-
|
|
112
|
-
For task-group, show existing-group recommendations first. Call `okstra task-list --text`, read the distinct fixed `Task group` values in `Updated at` order, and offer the 2 most recent + enter-directly. If `Status` is `error`, report `Failure stage` and `Failure reason`, then stop. If `Task count` is `0`, ask for free text. In tracker recursion, task-group must be obtained before building any child path.
|
|
113
|
-
|
|
114
|
-
File path rule:
|
|
115
|
-
|
|
116
|
-
```text
|
|
117
|
-
depth 0: .okstra/briefs/<task-group>/<ticket-id>-<file-title>.md
|
|
118
|
-
depth 1: .okstra/briefs/<task-group>/sub/<ticket-id>-<file-title>.md
|
|
119
|
-
depth N: .okstra/briefs/<task-group>/<sub/ repeated N>/<ticket-id>-<file-title>.md
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
The frontmatter's `depth` must equal the number of `sub/` segments in the path. The validator checks this.
|
|
123
|
-
|
|
124
|
-
On collision, the default is Skip. You may offer Append suffix or Overwrite. Do not silently perform a bulk overwrite in tracker multi-generation.
|
|
125
|
-
|
|
126
|
-
## Domain alignment
|
|
127
|
-
|
|
128
|
-
First look at okstra's internal memory.
|
|
129
|
-
|
|
130
|
-
- `<PROJECT_ROOT>/.okstra/glossary.md`
|
|
131
|
-
- `<PROJECT_ROOT>/.okstra/decisions/`
|
|
132
|
-
- the related task's `history/fix-cycles.jsonl`
|
|
133
|
-
|
|
134
|
-
Read external domain docs only when the reporter explicitly cited them as source material. Record conflicting/ambiguous terms under `Augmentation > Domain alignment` with `terminology-mapping`, and put a `terminology:` row in `Open Questions`.
|
|
135
|
-
|
|
136
|
-
When a file path or symbol is mentioned, find the actual in-repo reference with `Read`/`Grep` and record it as `evidence-link`. If it cannot be mapped, do not guess — leave a `conversion-block:` row.
|
|
137
|
-
|
|
138
|
-
## Sharpening pass
|
|
139
|
-
|
|
140
|
-
Do not run a full interview. Ask only about gaps that source and codebase cannot fill.
|
|
141
|
-
|
|
142
|
-
Default budget:
|
|
143
|
-
|
|
144
|
-
- at most 1 question per section the source skill designates as fill-in.
|
|
145
|
-
- at most 2 questions for terminology/fuzzy disambiguation.
|
|
146
|
-
- at most 6 questions overall.
|
|
147
|
-
- codebase-scan up to 8 questions.
|
|
148
|
-
|
|
149
|
-
Prefer codebase-first checks over questions. Put remaining gaps in `_(none)_` or `Open Questions`.
|
|
150
|
-
|
|
151
|
-
## template writing rules
|
|
152
|
-
|
|
153
|
-
The template `templates/reports/brief.template.md` is the SSOT. Follow the section order, frontmatter keys, top blockquote shape, and HTML comment guidance.
|
|
154
|
-
|
|
155
|
-
Reporter input and Error feedback:
|
|
156
|
-
|
|
157
|
-
- keep `## Source Material`.
|
|
158
|
-
- keep `## Problem / Symptom`.
|
|
159
|
-
- omit `## Scan Scope`, `## Priority Lenses`.
|
|
160
|
-
|
|
161
|
-
Codebase scan:
|
|
162
|
-
|
|
163
|
-
- `scope: codebase` in frontmatter.
|
|
164
|
-
- omit `## Source Material`, `## Problem / Symptom`.
|
|
165
|
-
- keep `## Scan Scope`, `## Priority Lenses`.
|
|
166
|
-
|
|
167
|
-
Do not fabricate empty sections. When there is no value, use `_(none)_`.
|
|
168
|
-
|
|
169
|
-
## frontmatter key
|
|
170
|
-
|
|
171
|
-
Every brief carries the following keys. The key set is checked by `validate-brief.py`.
|
|
172
|
-
|
|
173
|
-
- `type`
|
|
174
|
-
- `brief-id`
|
|
175
|
-
- `parent-id`
|
|
176
|
-
- `ticket-id`
|
|
177
|
-
- `source-type`
|
|
178
|
-
- `task-group`
|
|
179
|
-
- `depth`
|
|
180
|
-
- `created`
|
|
181
|
-
- `generator`
|
|
182
|
-
- `reporter-confirmations`
|
|
183
|
-
|
|
184
|
-
`brief-id` must equal the filename stem. At depth 0 the `parent-id` is `self`; a descendant's `parent-id` is its direct parent's `brief-id`.
|
|
185
|
-
|
|
186
|
-
## Recommended next phase
|
|
187
|
-
|
|
188
|
-
Write it into the `Recommended next phase:` of the brief body's top blockquote.
|
|
189
|
-
|
|
190
|
-
- observable error, repro, stack trace, error-zip record: `error-analysis`
|
|
191
|
-
- a requirement with ambiguity or large Open Questions: `requirements-discovery`
|
|
192
|
-
- `scope: codebase`: `improvement-discovery`
|
|
193
|
-
- if ambiguous: `requirements-discovery`
|
|
194
|
-
|
|
195
|
-
Do not auto-start `okstra-run`.
|
|
196
|
-
|
|
197
|
-
## Reporter Confirmations
|
|
198
|
-
|
|
199
|
-
Collect the rows in `Open Questions` that only the reporter can answer.
|
|
200
|
-
|
|
201
|
-
- `intent-check:`
|
|
202
|
-
- `conversion-block:`
|
|
203
|
-
|
|
204
|
-
If a `[CONFIRMED <date> → RC-N]` marker already exists, exclude it from pending. Ask the user whether to answer now; if they answer, record it verbatim under `## Reporter Confirmations`. Do not delete the row — attach a marker.
|
|
205
|
-
|
|
206
|
-
At most 12 questions per run. If pending exceeds 12, ask only the top 12 in `conversion-block:` → `intent-check:` order, leave the rest as `partial`, then tell the user which rows remain.
|
|
207
|
-
|
|
208
|
-
Status values:
|
|
209
|
-
|
|
210
|
-
- `complete`: all pending reporter-only rows are answered. The validator checks that every `intent-check:`/`conversion-block:` row has a `[CONFIRMED …]` marker.
|
|
211
|
-
- `partial`: only some are answered. The validator checks that at least one row has a `[CONFIRMED …]` marker (if nothing was received, `skipped`).
|
|
212
|
-
- `skipped`: the user chose to defer to a downstream phase.
|
|
213
|
-
- `pending`: treated as a pre-handoff state; do not proceed.
|
|
214
|
-
|
|
215
|
-
## Validation
|
|
216
|
-
|
|
217
|
-
After writing, run the validator before emitting the handoff message.
|
|
218
|
-
|
|
219
|
-
Installed copy:
|
|
220
|
-
|
|
221
|
-
```bash
|
|
222
|
-
~/.okstra/lib/validators/validate-brief.sh "<PROJECT_ROOT>/.okstra/briefs" --briefs-root "<PROJECT_ROOT>/.okstra/briefs"
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
repo checkout:
|
|
226
|
-
|
|
227
|
-
```bash
|
|
228
|
-
validators/validate-brief.sh "<PROJECT_ROOT>/.okstra/briefs" --briefs-root "<PROJECT_ROOT>/.okstra/briefs"
|
|
229
|
-
```
|
|
230
|
-
|
|
231
|
-
On failure, fix the cited brief and re-run. Fall back to a manual checklist only when the validator is absent.
|
|
232
|
-
When a `Related Task Graph` is present, the validator also checks the table header, relation enum, direction enum, and directed/undirected mismatch.
|
|
233
|
-
|
|
234
|
-
## Completion message
|
|
235
|
-
|
|
236
|
-
Single brief:
|
|
237
|
-
|
|
238
|
-
```text
|
|
239
|
-
brief saved: <abs-path>
|
|
240
|
-
next: /okstra-run (recommended task-type: <phase>)
|
|
241
|
-
```
|
|
242
|
-
|
|
243
|
-
Multi-brief:
|
|
244
|
-
|
|
245
|
-
```text
|
|
246
|
-
briefs saved (N):
|
|
247
|
-
- <abs>/<task-group>/<brief>.md (depth 0, parent, recommended: <phase>)
|
|
248
|
-
- <abs>/<task-group>/sub/<brief>.md (depth 1, child, recommended: <phase>)
|
|
249
|
-
next: /okstra-run
|
|
250
|
-
```
|
|
251
|
-
|
|
252
|
-
Before the hand-off block, once per task-group (Step 7a): if `<PROJECT_ROOT>/.okstra/briefs/<task-group>/group-context.md` is absent, ask whether to create the skeleton (`okstra group-context init --project-root <PROJECT_ROOT> --task-group <task-group>`; recommended for a new group) or skip. Never fill it from the tickets. When created, add `group context skeleton: <abs>/<task-group>/group-context.md (fill before /okstra-run)` to the block — preparation refuses the group's tasks while a `<...>` placeholder line remains. The file's trailing `## Task Memory` region is okstra's (rewritten by `report-finalize` with the group's start order and each task's latest conclusion); `init` inserts the human sections above an existing region. Brief ordinals (`<TICKET>-<n>-<slug>`) are the start order okstra reads; `Related Task Graph` edges are quoted beside it as `waits for`.
|
|
253
|
-
|
|
254
|
-
## Forbidden patterns
|
|
255
|
-
|
|
256
|
-
- Summarizing or tidying Source Material before inserting it.
|
|
257
|
-
- Guessing tracker/URL content without tool verification.
|
|
258
|
-
- Writing unlabelled augmentation.
|
|
259
|
-
- Leaving `intent-inference` without `intent-check:`.
|
|
260
|
-
- Writing a decision file into external docs/ADR. okstra decisions belong only in `<PROJECT_ROOT>/.okstra/decisions/`.
|
|
261
|
-
- Silently overwriting an entire child tree.
|
|
262
|
-
- Auto-starting `okstra-run` right after brief generation.
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
# okstra-chat AI Manual
|
|
2
|
-
|
|
3
|
-
## Source
|
|
4
|
-
|
|
5
|
-
- Skill source: [`skills/okstra-chat/SKILL.md`](../../../skills/okstra-chat/SKILL.md)
|
|
6
|
-
- CLI: [`src/commands/chat/chat.mts`](../../../src/commands/chat/chat.mts)
|
|
7
|
-
|
|
8
|
-
## Purpose
|
|
9
|
-
|
|
10
|
-
Global rooms under the okstra home so host sessions from different providers can send and read messages. Not a project `.okstra/` artifact.
|
|
11
|
-
|
|
12
|
-
## CLI
|
|
13
|
-
|
|
14
|
-
```bash
|
|
15
|
-
okstra chat rooms
|
|
16
|
-
okstra chat create --room <name>
|
|
17
|
-
okstra chat join --room <name> --name <display>
|
|
18
|
-
okstra chat members --room <name>
|
|
19
|
-
okstra chat send --room <name> --as <display> (--to <all|name> | --reply-to <id>) (--body <text> | --body-file <path>)
|
|
20
|
-
okstra chat unread --room <name> --as <display>
|
|
21
|
-
okstra chat inbox --room <name> --as <display>
|
|
22
|
-
okstra chat log --room <name> --as <display>
|
|
23
|
-
okstra chat ack --room <name> --as <display> --through <id>
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
Display names are typed. The CLI does not generate them.
|
|
27
|
-
|
|
28
|
-
Unread is the inbox after the read cursor minus messages whose `from` equals `--as`. It does not move the cursor. `inbox` and `log` keep those messages. Rows are `id @from YYYY-MM-DD HH:MM body`. A reply inserts `↑parentId` after the time. Recipient is not on the line. A body with several lines continues on rows indented by two spaces; those rows carry no id.
|
|
29
|
-
|
|
30
|
-
`send --to` may equal `--as`. `--to` and `--reply-to` are exactly one. `--body` and `--body-file` are exactly one; either may hold several lines, and only an all-blank body is rejected. A reply inherits `to` from the parent. `members` is the full roster. `ack --through` rejects an id behind the current cursor. `.` and `..` are reserved names. A stale `.lock` (dead owner pid, or older than 5 s) is reclaimed by the next writer.
|
|
31
|
-
|
|
32
|
-
The skill picker is `all` plus `members` minus the current display name. Skill send and reply use `--body`, not `--body-file`. Before joining an existing room the skill runs `members`; if the typed display name is already listed, it asks whether this session is already in the room under that name (a re-entry after context loss) and, if so, continues with `--as` without joining. After showing unread rows, the skill runs `ack --through` with the id of the last row that starts with an id, unless the output is `no unread`. The Step 3 menu is send, unread, inbox, log, reply, done. Reply takes a free-input id and body; there is no recipient picker and no `okstra chat reply` subcommand.
|
|
33
|
-
|
|
34
|
-
Read the fixed text rows. Do not parse JSON.
|