okstra 0.201.3 → 0.202.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/dist/commands/lifecycle/setup.mjs +15 -0
- package/dist/commands/lifecycle/setup.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/docs/architecture/storage-model.md +4 -0
- package/docs/architecture.md +1 -1
- package/docs/cli.md +2 -2
- package/docs/for-ai/skills/okstra-manager.md +21 -4
- package/docs/for-ai/skills/okstra-setup.md +9 -0
- package/docs/project-structure-overview.md +4 -1
- package/package.json +1 -1
- package/runtime/BUILD.json +2 -2
- package/runtime/prompts/launch.template.md +1 -1
- package/runtime/prompts/lead/okstra-lead-contract.md +2 -2
- package/runtime/prompts/profiles/_implementation-verifier.md +1 -1
- package/runtime/prompts/profiles/implementation-planning.md +2 -0
- package/runtime/python/okstra_ctl/convergence_critic_prompt.py +4 -6
- package/runtime/python/okstra_ctl/convergence_provenance.py +75 -18
- package/runtime/python/okstra_ctl/execution_mutation_audit.py +21 -21
- package/runtime/python/okstra_ctl/manager_cli.py +85 -12
- package/runtime/python/okstra_ctl/manager_launch.py +40 -18
- package/runtime/python/okstra_ctl/manager_paths.py +8 -0
- package/runtime/python/okstra_ctl/manager_split.py +474 -0
- package/runtime/python/okstra_ctl/manager_store.py +121 -18
- package/runtime/python/okstra_ctl/manager_sync.py +33 -15
- package/runtime/python/okstra_ctl/manager_view.py +216 -0
- package/runtime/python/okstra_ctl/plan_items_cli.py +6 -1
- package/runtime/python/okstra_ctl/qa_commands.py +15 -0
- 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/visualizations.py +0 -5
- package/runtime/python/okstra_ctl/verification_target.py +13 -2
- package/runtime/skills/okstra-manager/SKILL.md +53 -4
- package/runtime/skills/okstra-run/SKILL.md +1 -1
- package/runtime/skills/okstra-setup/SKILL.md +9 -0
- package/runtime/templates/manager/view.template.html +108 -0
- package/runtime/templates/reports/html/i18n/en.json +2 -0
- package/runtime/templates/reports/html/i18n/ko.json +2 -0
- package/runtime/templates/reports/html/tasks/final-verification.template.html +2 -2
- package/runtime/validators/validate-brief.py +7 -2
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
+
<title>{{TITLE}}</title>
|
|
7
|
+
<style>
|
|
8
|
+
:root {
|
|
9
|
+
--bg: #f7f7f5;
|
|
10
|
+
--panel: #ffffff;
|
|
11
|
+
--text: #1f2328;
|
|
12
|
+
--muted: #5f6670;
|
|
13
|
+
--line: #d9dbde;
|
|
14
|
+
--planned: #6e7781;
|
|
15
|
+
--missing: #9a6700;
|
|
16
|
+
--running: #0969da;
|
|
17
|
+
--done: #1a7f37;
|
|
18
|
+
--blocked: #cf222e;
|
|
19
|
+
}
|
|
20
|
+
@media (prefers-color-scheme: dark) {
|
|
21
|
+
:root {
|
|
22
|
+
--bg: #111418;
|
|
23
|
+
--panel: #1a1f25;
|
|
24
|
+
--text: #e6e8eb;
|
|
25
|
+
--muted: #9aa3ad;
|
|
26
|
+
--line: #2f363e;
|
|
27
|
+
--planned: #8b949e;
|
|
28
|
+
--missing: #d29922;
|
|
29
|
+
--running: #58a6ff;
|
|
30
|
+
--done: #3fb950;
|
|
31
|
+
--blocked: #f85149;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
* { box-sizing: border-box; }
|
|
35
|
+
body {
|
|
36
|
+
margin: 0;
|
|
37
|
+
background: var(--bg);
|
|
38
|
+
color: var(--text);
|
|
39
|
+
font: 14px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", "Apple SD Gothic Neo", "Noto Sans KR", sans-serif;
|
|
40
|
+
}
|
|
41
|
+
main { max-width: 1200px; margin: 0 auto; padding: 24px 16px 48px; }
|
|
42
|
+
header h1 { margin: 0 0 4px; font-size: 22px; }
|
|
43
|
+
.meta { color: var(--muted); font-size: 13px; }
|
|
44
|
+
section { margin-top: 28px; }
|
|
45
|
+
h2 { font-size: 17px; margin: 0 0 10px; }
|
|
46
|
+
h3 { font-size: 15px; margin: 0; }
|
|
47
|
+
.panel {
|
|
48
|
+
background: var(--panel);
|
|
49
|
+
border: 1px solid var(--line);
|
|
50
|
+
border-radius: 8px;
|
|
51
|
+
padding: 16px;
|
|
52
|
+
margin-bottom: 16px;
|
|
53
|
+
}
|
|
54
|
+
.tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 10px; }
|
|
55
|
+
.tile { background: var(--panel); border: 1px solid var(--line); border-radius: 8px; padding: 10px 12px; }
|
|
56
|
+
.tile .count { font-size: 24px; font-weight: 600; }
|
|
57
|
+
.tile .label { color: var(--muted); font-size: 12px; text-transform: uppercase; letter-spacing: 0.04em; }
|
|
58
|
+
.scroll { overflow-x: auto; }
|
|
59
|
+
table { width: 100%; border-collapse: collapse; }
|
|
60
|
+
th, td { text-align: left; padding: 7px 10px; border-bottom: 1px solid var(--line); vertical-align: top; }
|
|
61
|
+
th { color: var(--muted); font-weight: 600; font-size: 12px; white-space: nowrap; }
|
|
62
|
+
.wrap { display: inline-block; min-width: 220px; }
|
|
63
|
+
code.id { white-space: nowrap; word-break: normal; }
|
|
64
|
+
code { font: 12px/1.4 ui-monospace, SFMono-Regular, Menlo, monospace; word-break: break-all; }
|
|
65
|
+
.chip {
|
|
66
|
+
display: inline-block;
|
|
67
|
+
padding: 1px 8px;
|
|
68
|
+
border-radius: 999px;
|
|
69
|
+
border: 1px solid currentColor;
|
|
70
|
+
font-size: 12px;
|
|
71
|
+
white-space: nowrap;
|
|
72
|
+
}
|
|
73
|
+
.chip.planned { color: var(--planned); }
|
|
74
|
+
.chip.missing { color: var(--missing); }
|
|
75
|
+
.chip.running { color: var(--running); }
|
|
76
|
+
.chip.done { color: var(--done); }
|
|
77
|
+
.chip.blocked { color: var(--blocked); }
|
|
78
|
+
.task-head { display: flex; flex-wrap: wrap; gap: 8px 16px; align-items: baseline; margin-bottom: 8px; }
|
|
79
|
+
.counts { display: flex; flex-wrap: wrap; gap: 6px; }
|
|
80
|
+
.hint { color: var(--muted); font-size: 12px; margin: 6px 0 12px; }
|
|
81
|
+
details { margin-top: 10px; }
|
|
82
|
+
summary { cursor: pointer; color: var(--muted); }
|
|
83
|
+
ul.plain { margin: 6px 0 0; padding-left: 18px; }
|
|
84
|
+
.empty { color: var(--muted); }
|
|
85
|
+
a { color: var(--running); }
|
|
86
|
+
</style>
|
|
87
|
+
</head>
|
|
88
|
+
<body>
|
|
89
|
+
<main>
|
|
90
|
+
<header>
|
|
91
|
+
<h1>{{TITLE}}</h1>
|
|
92
|
+
<div class="meta">{{META}}</div>
|
|
93
|
+
</header>
|
|
94
|
+
<section>
|
|
95
|
+
<h2>Summary</h2>
|
|
96
|
+
{{SUMMARY}}
|
|
97
|
+
</section>
|
|
98
|
+
<section>
|
|
99
|
+
<h2>Projects</h2>
|
|
100
|
+
{{PROJECTS}}
|
|
101
|
+
</section>
|
|
102
|
+
<section>
|
|
103
|
+
<h2>Manager tasks</h2>
|
|
104
|
+
{{TASKS}}
|
|
105
|
+
</section>
|
|
106
|
+
</main>
|
|
107
|
+
</body>
|
|
108
|
+
</html>
|
|
@@ -371,6 +371,8 @@
|
|
|
371
371
|
"final-verification": {
|
|
372
372
|
"verification-verdict": "Verification verdict",
|
|
373
373
|
"result-per-requirement": "Result per requirement",
|
|
374
|
+
"requirement": "Requirement",
|
|
375
|
+
"evidence": "Evidence",
|
|
374
376
|
"what-the-change-added": "What the change added",
|
|
375
377
|
"traced-to": "Serves",
|
|
376
378
|
"callers": "Callers",
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
{% extends "html/base.template.html" %}
|
|
2
2
|
{% from "html/macros/layout.html" import narrative as render_narrative, row_key %}
|
|
3
|
-
{% from "html/macros/visualizations.html" import figure %}
|
|
4
3
|
|
|
5
4
|
{% block human_content %}
|
|
6
5
|
<section data-report-section="verification-verdict">
|
|
@@ -22,7 +21,8 @@
|
|
|
22
21
|
<section data-report-section="requirement-results" data-report-field="finalVerification.validationEvidence">
|
|
23
22
|
<h2>{{ t('tasks.final-verification.result-per-requirement') }}</h2>
|
|
24
23
|
{{ render_narrative(narrative.coverageExplanation, "finalVerification.userNarrative.coverageExplanation") }}
|
|
25
|
-
{{
|
|
24
|
+
<div class="table-scroll"><table><thead><tr><th>{{ t('macros.layout.id') }}</th><th>{{ t('tasks.final-verification.requirement') }}</th><th>{{ t('macros.layout.status') }}</th><th>{{ t('tasks.final-verification.evidence') }}</th></tr></thead>
|
|
25
|
+
<tbody>{% for row in final.validationEvidence %}<tr id="id-{{ row.id }}"><td>{{ row.id | inline_code }}</td><td>{{ row.requirement | inline_code }}</td><td><span class="status status-{{ row.status }}">{{ row.status }}</span></td><td>{{ row.artifact | inline_code }}</td></tr>{% endfor %}</tbody></table></div>
|
|
26
26
|
</section>
|
|
27
27
|
|
|
28
28
|
<section data-report-section="added-surface" data-report-field="finalVerification.addedSurfaceAudit">
|
|
@@ -104,6 +104,10 @@ AUGMENTATION_LABELS = {
|
|
|
104
104
|
|
|
105
105
|
REPORTER_CONFIRMATION_VALUES = {"complete", "partial", "pending", "skipped"}
|
|
106
106
|
|
|
107
|
+
# okstra-manager `task split` renders the same brief contract for each project
|
|
108
|
+
# it splits a tracker issue into.
|
|
109
|
+
GENERATORS = {"okstra-brief-gen", "okstra-manager"}
|
|
110
|
+
|
|
107
111
|
SCOPE_VALUES = {"reporter-input", "codebase"}
|
|
108
112
|
|
|
109
113
|
TASK_GRAPH_HEADER = ["From", "Relation", "To", "Direction", "Source", "Impact"]
|
|
@@ -693,9 +697,10 @@ def validate_brief(path: Path, briefs_root: Path) -> list[str]:
|
|
|
693
697
|
if fm.get("type") != "brief":
|
|
694
698
|
errors.append(f"frontmatter type must be 'brief', got {fm.get('type')!r}")
|
|
695
699
|
|
|
696
|
-
if fm.get("generator")
|
|
700
|
+
if fm.get("generator") not in GENERATORS:
|
|
697
701
|
errors.append(
|
|
698
|
-
f"frontmatter generator must be
|
|
702
|
+
f"frontmatter generator must be one of {sorted(GENERATORS)}, "
|
|
703
|
+
f"got {fm.get('generator')!r}"
|
|
699
704
|
)
|
|
700
705
|
|
|
701
706
|
if fm.get("reporter-confirmations") not in REPORTER_CONFIRMATION_VALUES:
|