devcouncil 0.1.0 → 0.2.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/LICENSE +201 -201
- package/README.md +197 -494
- package/package.json +9 -2
- package/pyproject.toml +62 -27
- package/src/devcouncil/__main__.py +4 -4
- package/src/devcouncil/app/__init__.py +28 -28
- package/src/devcouncil/app/config.py +297 -108
- package/src/devcouncil/app/errors.py +23 -23
- package/src/devcouncil/app/events.py +44 -44
- package/src/devcouncil/app/orchestrator.py +67 -67
- package/src/devcouncil/app/project_status.py +29 -0
- package/src/devcouncil/app/run_context.py +39 -39
- package/src/devcouncil/app/state_machine.py +108 -108
- package/src/devcouncil/artifacts/__init__.py +1 -1
- package/src/devcouncil/artifacts/coverage.py +96 -96
- package/src/devcouncil/artifacts/graph.py +163 -143
- package/src/devcouncil/artifacts/migrations.py +20 -20
- package/src/devcouncil/artifacts/schemas.py +23 -23
- package/src/devcouncil/artifacts/serializer.py +21 -21
- package/src/devcouncil/artifacts/validators.py +27 -27
- package/src/devcouncil/assets/__init__.py +1 -0
- package/src/devcouncil/assets/devcouncil-logo.svg +60 -0
- package/src/devcouncil/assets/devcouncil_logo_premium.png +0 -0
- package/src/devcouncil/cli/commands/agents.py +292 -0
- package/src/devcouncil/cli/commands/artifacts.py +54 -48
- package/src/devcouncil/cli/commands/ast.py +22 -0
- package/src/devcouncil/cli/commands/baseline.py +35 -32
- package/src/devcouncil/cli/commands/check.py +209 -0
- package/src/devcouncil/cli/commands/config.py +115 -54
- package/src/devcouncil/cli/commands/cost.py +57 -0
- package/src/devcouncil/cli/commands/dashboard.py +31 -0
- package/src/devcouncil/cli/commands/doctor.py +291 -47
- package/src/devcouncil/cli/commands/evidence.py +48 -0
- package/src/devcouncil/cli/commands/go.py +656 -0
- package/src/devcouncil/cli/commands/handoff.py +69 -0
- package/src/devcouncil/cli/commands/hook.py +209 -33
- package/src/devcouncil/cli/commands/init.py +204 -57
- package/src/devcouncil/cli/commands/integrate.py +1171 -76
- package/src/devcouncil/cli/commands/lsp.py +20 -0
- package/src/devcouncil/cli/commands/map.py +96 -22
- package/src/devcouncil/cli/commands/plan.py +422 -210
- package/src/devcouncil/cli/commands/prompt.py +48 -34
- package/src/devcouncil/cli/commands/repair.py +89 -69
- package/src/devcouncil/cli/commands/report.py +120 -54
- package/src/devcouncil/cli/commands/reset_demo_state.py +33 -28
- package/src/devcouncil/cli/commands/rollback.py +55 -54
- package/src/devcouncil/cli/commands/run.py +285 -220
- package/src/devcouncil/cli/commands/runs.py +223 -0
- package/src/devcouncil/cli/commands/scaffold.py +32 -0
- package/src/devcouncil/cli/commands/semantic.py +47 -0
- package/src/devcouncil/cli/commands/setup.py +300 -20
- package/src/devcouncil/cli/commands/shell.py +73 -0
- package/src/devcouncil/cli/commands/show.py +76 -57
- package/src/devcouncil/cli/commands/skills.py +88 -0
- package/src/devcouncil/cli/commands/status.py +141 -105
- package/src/devcouncil/cli/commands/tasks.py +55 -41
- package/src/devcouncil/cli/commands/trace.py +49 -4
- package/src/devcouncil/cli/commands/verify.py +293 -128
- package/src/devcouncil/cli/commands/version.py +20 -20
- package/src/devcouncil/cli/commands/watch.py +574 -0
- package/src/devcouncil/cli/commands/watch_fs.py +40 -0
- package/src/devcouncil/cli/main.py +92 -25
- package/src/devcouncil/council/prompts/arbiter.md +19 -19
- package/src/devcouncil/council/prompts/critic_a.md +10 -10
- package/src/devcouncil/council/prompts/critic_b.md +10 -10
- package/src/devcouncil/council/prompts/implementation_reviewer.md +16 -16
- package/src/devcouncil/council/prompts/planner_a.md +16 -16
- package/src/devcouncil/council/prompts/planner_b.md +16 -16
- package/src/devcouncil/council/prompts/rebuttal.md +10 -10
- package/src/devcouncil/council/prompts/spec_writer.md +12 -12
- package/src/devcouncil/domain/assumption.py +17 -17
- package/src/devcouncil/domain/critique.py +32 -32
- package/src/devcouncil/domain/evidence.py +47 -27
- package/src/devcouncil/domain/gap.py +52 -26
- package/src/devcouncil/domain/requirement.py +22 -22
- package/src/devcouncil/domain/task.py +55 -26
- package/src/devcouncil/execution/__init__.py +1 -1
- package/src/devcouncil/execution/checkpoints.py +246 -0
- package/src/devcouncil/execution/context_builder.py +54 -54
- package/src/devcouncil/execution/executor.py +15 -15
- package/src/devcouncil/execution/fs_watcher.py +180 -0
- package/src/devcouncil/execution/handoff.py +102 -0
- package/src/devcouncil/execution/hook_policy.py +186 -77
- package/src/devcouncil/execution/patch.py +77 -28
- package/src/devcouncil/execution/permissions.py +52 -59
- package/src/devcouncil/execution/policy_engine.py +343 -0
- package/src/devcouncil/execution/prompt_builder.py +650 -38
- package/src/devcouncil/execution/shell_session.py +225 -0
- package/src/devcouncil/execution/task_runner.py +68 -64
- package/src/devcouncil/executors/__init__.py +1 -1
- package/src/devcouncil/executors/agent_registry.py +575 -0
- package/src/devcouncil/executors/coding_cli.py +736 -0
- package/src/devcouncil/executors/mini_swe.py +63 -63
- package/src/devcouncil/executors/native/agent.py +186 -85
- package/src/devcouncil/executors/openhands.py +56 -56
- package/src/devcouncil/gating/__init__.py +1 -1
- package/src/devcouncil/gating/checks/clean_git.py +52 -45
- package/src/devcouncil/gating/checks/planned_files_check.py +32 -32
- package/src/devcouncil/gating/checks/requirement_coverage.py +26 -26
- package/src/devcouncil/gating/checks/secret_scan_check.py +53 -34
- package/src/devcouncil/gating/policy.py +315 -167
- package/src/devcouncil/hardware.py +184 -0
- package/src/devcouncil/indexing/__init__.py +1 -1
- package/src/devcouncil/indexing/ast_matcher.py +168 -0
- package/src/devcouncil/indexing/graph_index.py +48 -48
- package/src/devcouncil/indexing/lsp.py +161 -0
- package/src/devcouncil/indexing/repo_mapper.py +1455 -204
- package/src/devcouncil/indexing/semantic_index.py +205 -0
- package/src/devcouncil/integrations/actions.py +146 -0
- package/src/devcouncil/integrations/check.py +423 -0
- package/src/devcouncil/integrations/github.py +35 -35
- package/src/devcouncil/integrations/github_intent.py +142 -0
- package/src/devcouncil/integrations/gitnexus.py +62 -27
- package/src/devcouncil/integrations/graphify.py +34 -34
- package/src/devcouncil/integrations/mcp/server.py +2072 -96
- package/src/devcouncil/integrations/opencode_devcouncil_plugin.mjs +24 -0
- package/src/devcouncil/integrations/pr_comments.py +62 -0
- package/src/devcouncil/live/__init__.py +2 -0
- package/src/devcouncil/live/cards.py +349 -0
- package/src/devcouncil/live/models.py +63 -0
- package/src/devcouncil/live/repair_prompt.py +83 -0
- package/src/devcouncil/live/reviewer.py +70 -0
- package/src/devcouncil/live/signals.py +135 -0
- package/src/devcouncil/live/summary.py +34 -0
- package/src/devcouncil/live/tasks.py +18 -0
- package/src/devcouncil/live/transcripts.py +141 -0
- package/src/devcouncil/llm/__init__.py +1 -1
- package/src/devcouncil/llm/cache.py +42 -38
- package/src/devcouncil/llm/model_defaults.yaml +44 -0
- package/src/devcouncil/llm/provider.py +627 -125
- package/src/devcouncil/llm/router.py +303 -118
- package/src/devcouncil/optimization/__init__.py +1 -0
- package/src/devcouncil/optimization/gepa_agent.py +318 -0
- package/src/devcouncil/planning/__init__.py +1 -1
- package/src/devcouncil/planning/arbiter_service.py +57 -57
- package/src/devcouncil/planning/correction_manifest.py +303 -0
- package/src/devcouncil/planning/critique_service.py +71 -66
- package/src/devcouncil/planning/plan_service.py +60 -46
- package/src/devcouncil/planning/prompt_enhancer_service.py +167 -0
- package/src/devcouncil/planning/repair_service.py +39 -39
- package/src/devcouncil/planning/spec_service.py +70 -44
- package/src/devcouncil/repo/ci_scaffold.py +157 -0
- package/src/devcouncil/repo/gitignore.py +123 -0
- package/src/devcouncil/repo/sca.py +374 -0
- package/src/devcouncil/reporting/github_check.py +32 -32
- package/src/devcouncil/reporting/json_report.py +30 -17
- package/src/devcouncil/reporting/markdown_report.py +83 -46
- package/src/devcouncil/reporting/report_builder.py +14 -14
- package/src/devcouncil/skills/__init__.py +19 -0
- package/src/devcouncil/skills/library/README.md +46 -0
- package/src/devcouncil/skills/library/ai-training.md +50 -0
- package/src/devcouncil/skills/library/android.md +50 -0
- package/src/devcouncil/skills/library/backend.md +52 -0
- package/src/devcouncil/skills/library/core-engineering.md +95 -0
- package/src/devcouncil/skills/library/data-engineering.md +47 -0
- package/src/devcouncil/skills/library/desktop.md +46 -0
- package/src/devcouncil/skills/library/devops.md +48 -0
- package/src/devcouncil/skills/library/game-dev.md +46 -0
- package/src/devcouncil/skills/library/ios.md +48 -0
- package/src/devcouncil/skills/library/mobile-cross-platform.md +46 -0
- package/src/devcouncil/skills/library/security.md +48 -0
- package/src/devcouncil/skills/library/systems.md +48 -0
- package/src/devcouncil/skills/library/web.md +47 -0
- package/src/devcouncil/skills/library/windows.md +47 -0
- package/src/devcouncil/skills/registry.py +330 -0
- package/src/devcouncil/storage/db.py +147 -66
- package/src/devcouncil/storage/models.py +204 -83
- package/src/devcouncil/storage/native.py +557 -0
- package/src/devcouncil/storage/repositories.py +388 -249
- package/src/devcouncil/telemetry/cost.py +140 -34
- package/src/devcouncil/telemetry/model_pricing.yaml +48 -0
- package/src/devcouncil/telemetry/pricing.py +28 -0
- package/src/devcouncil/telemetry/traces.py +62 -7
- package/src/devcouncil/telemetry/tracker.py +52 -49
- package/src/devcouncil/ui/__init__.py +1 -0
- package/src/devcouncil/ui/dashboard.py +423 -0
- package/src/devcouncil/utils/__init__.py +1 -1
- package/src/devcouncil/utils/redaction.py +147 -141
- package/src/devcouncil/utils/subprocess_env.py +69 -0
- package/src/devcouncil/verification/__init__.py +1 -1
- package/src/devcouncil/verification/acceptance_compiler.py +125 -0
- package/src/devcouncil/verification/ad_hoc_check.py +129 -0
- package/src/devcouncil/verification/diff_coverage.py +353 -0
- package/src/devcouncil/verification/implementation_reviewer.py +55 -55
- package/src/devcouncil/verification/next_actions.py +189 -0
- package/src/devcouncil/verification/sandbox.py +178 -0
- package/src/devcouncil/verification/test_resolver.py +91 -0
- package/src/devcouncil/verification/verifier.py +1342 -307
- package/uv.lock +205 -64
- package/src/devcouncil/indexing/symbol_index.py +0 -0
|
@@ -1,12 +1,48 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
|
|
1
3
|
import typer
|
|
2
|
-
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def _configure_stdio() -> None:
|
|
7
|
+
"""Make stdout/stderr resilient to non-cp1252 characters.
|
|
8
|
+
|
|
9
|
+
Coding agents and rich output emit Unicode such as ``✓``. On Windows the
|
|
10
|
+
default console / redirected-pipe encoding is cp1252, where an un-encodable
|
|
11
|
+
character raises UnicodeEncodeError mid-write. Because Rich buffers output,
|
|
12
|
+
that error can surface during an unrelated later write — which previously
|
|
13
|
+
got misreported as a coding agent "failing to start". Reconfigure both
|
|
14
|
+
streams to UTF-8 with replacement so output can never crash the process.
|
|
15
|
+
"""
|
|
16
|
+
for stream in (sys.stdout, sys.stderr):
|
|
17
|
+
reconfigure = getattr(stream, "reconfigure", None)
|
|
18
|
+
if reconfigure is None:
|
|
19
|
+
continue
|
|
20
|
+
try:
|
|
21
|
+
reconfigure(encoding="utf-8", errors="replace")
|
|
22
|
+
except (ValueError, OSError):
|
|
23
|
+
try:
|
|
24
|
+
reconfigure(errors="replace")
|
|
25
|
+
except (ValueError, OSError):
|
|
26
|
+
pass
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
_configure_stdio()
|
|
30
|
+
|
|
31
|
+
from devcouncil.cli.commands import ( # noqa: E402 - imports follow stdio reconfiguration
|
|
3
32
|
artifacts,
|
|
33
|
+
agents,
|
|
4
34
|
baseline,
|
|
35
|
+
check,
|
|
5
36
|
config,
|
|
37
|
+
cost,
|
|
38
|
+
ast,
|
|
39
|
+
dashboard,
|
|
6
40
|
doctor,
|
|
41
|
+
go,
|
|
7
42
|
hook,
|
|
8
43
|
init,
|
|
9
44
|
integrate,
|
|
45
|
+
lsp,
|
|
10
46
|
map,
|
|
11
47
|
mcp_server,
|
|
12
48
|
plan,
|
|
@@ -16,6 +52,7 @@ from devcouncil.cli.commands import (
|
|
|
16
52
|
reset_demo_state,
|
|
17
53
|
rollback,
|
|
18
54
|
run,
|
|
55
|
+
runs,
|
|
19
56
|
setup,
|
|
20
57
|
show,
|
|
21
58
|
status,
|
|
@@ -23,48 +60,78 @@ from devcouncil.cli.commands import (
|
|
|
23
60
|
trace,
|
|
24
61
|
verify,
|
|
25
62
|
version,
|
|
63
|
+
watch,
|
|
64
|
+
shell,
|
|
65
|
+
semantic,
|
|
66
|
+
evidence,
|
|
67
|
+
handoff,
|
|
68
|
+
skills,
|
|
69
|
+
scaffold,
|
|
70
|
+
)
|
|
71
|
+
from devcouncil.cli.commands.watch_fs import watch_fs # noqa: E402 - imports follow stdio reconfiguration
|
|
72
|
+
|
|
73
|
+
app = typer.Typer(
|
|
74
|
+
name="dev",
|
|
75
|
+
help="DevCouncil: Gated orchestrator for AI-assisted software development.",
|
|
76
|
+
add_completion=False,
|
|
26
77
|
)
|
|
27
|
-
|
|
28
|
-
app =
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
)
|
|
33
|
-
|
|
34
|
-
# Typer subcommands (those using app = Typer())
|
|
35
|
-
app.add_typer(init.app, name="init")
|
|
36
|
-
app.add_typer(doctor.app, name="doctor")
|
|
37
|
-
app.add_typer(prompt.app, name="prompt")
|
|
38
|
-
app.add_typer(tasks.app, name="tasks")
|
|
39
|
-
app.add_typer(show.app, name="show")
|
|
78
|
+
|
|
79
|
+
# Typer subcommands (those using app = Typer())
|
|
80
|
+
app.add_typer(init.app, name="init")
|
|
81
|
+
app.add_typer(doctor.app, name="doctor")
|
|
82
|
+
app.add_typer(tasks.app, name="tasks")
|
|
40
83
|
app.add_typer(report.app, name="report")
|
|
41
84
|
app.add_typer(rollback.app, name="rollback")
|
|
42
85
|
app.add_typer(config.app, name="config")
|
|
43
86
|
app.add_typer(artifacts.app, name="artifacts")
|
|
87
|
+
app.add_typer(agents.app, name="agents")
|
|
44
88
|
app.add_typer(hook.app, name="hook")
|
|
45
89
|
app.add_typer(version.app, name="version")
|
|
46
90
|
app.add_typer(mcp_server.app, name="mcp-server")
|
|
47
91
|
app.add_typer(integrate.app, name="integrate")
|
|
48
92
|
app.add_typer(integrate.app, name="integrations")
|
|
49
93
|
app.add_typer(trace.app, name="trace")
|
|
94
|
+
app.add_typer(cost.app, name="cost")
|
|
95
|
+
app.add_typer(runs.app, name="runs")
|
|
50
96
|
app.add_typer(setup.app, name="setup")
|
|
97
|
+
app.add_typer(lsp.app, name="lsp")
|
|
98
|
+
app.add_typer(ast.app, name="ast")
|
|
99
|
+
app.add_typer(dashboard.app, name="dashboard")
|
|
100
|
+
app.add_typer(watch.app, name="watch")
|
|
101
|
+
app.add_typer(semantic.app, name="semantic")
|
|
102
|
+
app.add_typer(evidence.app, name="evidence")
|
|
103
|
+
app.add_typer(skills.app, name="skills")
|
|
104
|
+
watch.app.command("fs")(watch_fs)
|
|
51
105
|
|
|
52
106
|
# Direct command registrations (those defined as def cmd())
|
|
53
107
|
app.command(name="baseline")(baseline.baseline)
|
|
108
|
+
app.command(name="e2e")(go.go)
|
|
109
|
+
app.command(name="go")(go.go)
|
|
54
110
|
app.command(name="map")(map.map_repo)
|
|
111
|
+
app.command(name="scaffold-ci")(scaffold.scaffold_ci_command)
|
|
55
112
|
app.command(name="plan")(plan.plan)
|
|
113
|
+
app.command(name="approve")(plan.approve)
|
|
114
|
+
app.command(name="prompt")(prompt.prompt)
|
|
56
115
|
app.command(name="reset-demo-state")(reset_demo_state.reset_demo_state)
|
|
57
116
|
app.command(name="run")(run.run)
|
|
117
|
+
# shell/handoff take a positional TASK_ID followed by options, so they must be
|
|
118
|
+
# plain commands — as typer sub-apps (click groups) the documented
|
|
119
|
+
# `dev shell TASK-001 --command ...` form fails to parse.
|
|
120
|
+
app.command(name="shell")(shell.shell)
|
|
121
|
+
app.command(name="handoff")(handoff.handoff)
|
|
122
|
+
app.command(name="show")(show.show)
|
|
58
123
|
app.command(name="verify")(verify.verify)
|
|
124
|
+
app.command(name="check")(check.check)
|
|
59
125
|
app.command(name="repair")(repair.repair)
|
|
60
|
-
app.command(name="status")(status.status)
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
126
|
+
app.command(name="status")(status.status)
|
|
127
|
+
app.command(name="optimize")(agents.optimize_agent)
|
|
128
|
+
|
|
129
|
+
@app.callback()
|
|
130
|
+
def main(ctx: typer.Context):
|
|
131
|
+
"""
|
|
132
|
+
DevCouncil: Gated orchestrator for AI-assisted software development.
|
|
133
|
+
"""
|
|
134
|
+
return
|
|
135
|
+
|
|
136
|
+
if __name__ == "__main__":
|
|
137
|
+
app()
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
Goal: {goal}
|
|
2
|
-
|
|
3
|
-
Initial Requirements:
|
|
4
|
-
{requirements_json}
|
|
5
|
-
|
|
6
|
-
Plan A: {plan_a_json}
|
|
7
|
-
Plan B: {plan_b_json}
|
|
8
|
-
|
|
9
|
-
Critique of Plan B by Critic A: {critique_a_json}
|
|
10
|
-
Critique of Plan A by Critic B: {critique_b_json}
|
|
11
|
-
|
|
12
|
-
Rebuttal of Critic B by Planner A: {rebuttal_a_json}
|
|
13
|
-
Rebuttal of Critic A by Planner B: {rebuttal_b_json}
|
|
14
|
-
|
|
15
|
-
You are the arbiter engineering manager. Your goal is to produce the final, definitive set of requirements and tasks.
|
|
16
|
-
- You do not decide by vibes.
|
|
17
|
-
- High-severity unrefuted findings from critics must be incorporated into the final requirements or tasks.
|
|
18
|
-
- If a planner successfully rebutted a finding, you may skip it.
|
|
19
|
-
- Produce a single, coherent task graph.
|
|
1
|
+
Goal: {goal}
|
|
2
|
+
|
|
3
|
+
Initial Requirements:
|
|
4
|
+
{requirements_json}
|
|
5
|
+
|
|
6
|
+
Plan A: {plan_a_json}
|
|
7
|
+
Plan B: {plan_b_json}
|
|
8
|
+
|
|
9
|
+
Critique of Plan B by Critic A: {critique_a_json}
|
|
10
|
+
Critique of Plan A by Critic B: {critique_b_json}
|
|
11
|
+
|
|
12
|
+
Rebuttal of Critic B by Planner A: {rebuttal_a_json}
|
|
13
|
+
Rebuttal of Critic A by Planner B: {rebuttal_b_json}
|
|
14
|
+
|
|
15
|
+
You are the arbiter engineering manager. Your goal is to produce the final, definitive set of requirements and tasks.
|
|
16
|
+
- You do not decide by vibes.
|
|
17
|
+
- High-severity unrefuted findings from critics must be incorporated into the final requirements or tasks.
|
|
18
|
+
- If a planner successfully rebutted a finding, you may skip it.
|
|
19
|
+
- Produce a single, coherent task graph.
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
Requirements:
|
|
2
|
-
{requirements_json}
|
|
3
|
-
|
|
4
|
-
Target Plan:
|
|
5
|
-
{target_plan_json}
|
|
6
|
-
|
|
7
|
-
You are a hostile staff engineer reviewing another team's implementation plan.
|
|
8
|
-
Find missing requirements, bad assumptions, missing tests, security risks, migration risks, and unverifiable claims.
|
|
9
|
-
Do not praise. Do not rewrite the plan.
|
|
10
|
-
Every finding must include a falsifiable_check.
|
|
1
|
+
Requirements:
|
|
2
|
+
{requirements_json}
|
|
3
|
+
|
|
4
|
+
Target Plan:
|
|
5
|
+
{target_plan_json}
|
|
6
|
+
|
|
7
|
+
You are a hostile staff engineer reviewing another team's implementation plan.
|
|
8
|
+
Find missing requirements, bad assumptions, missing tests, security risks, migration risks, and unverifiable claims.
|
|
9
|
+
Do not praise. Do not rewrite the plan.
|
|
10
|
+
Every finding must include a falsifiable_check.
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
Requirements:
|
|
2
|
-
{requirements_json}
|
|
3
|
-
|
|
4
|
-
Target Plan:
|
|
5
|
-
{target_plan_json}
|
|
6
|
-
|
|
7
|
-
You are a hostile staff engineer reviewing another team's implementation plan.
|
|
8
|
-
Find missing requirements, bad assumptions, missing tests, security risks, migration risks, and unverifiable claims.
|
|
9
|
-
Do not praise. Do not rewrite the plan.
|
|
10
|
-
Every finding must include a falsifiable_check.
|
|
1
|
+
Requirements:
|
|
2
|
+
{requirements_json}
|
|
3
|
+
|
|
4
|
+
Target Plan:
|
|
5
|
+
{target_plan_json}
|
|
6
|
+
|
|
7
|
+
You are a hostile staff engineer reviewing another team's implementation plan.
|
|
8
|
+
Find missing requirements, bad assumptions, missing tests, security risks, migration risks, and unverifiable claims.
|
|
9
|
+
Do not praise. Do not rewrite the plan.
|
|
10
|
+
Every finding must include a falsifiable_check.
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
You are an expert software reviewer. Review the following code changes against the task requirements.
|
|
2
|
-
Task: {task.title}
|
|
3
|
-
Description: {task.description}
|
|
4
|
-
|
|
5
|
-
Requirements:
|
|
6
|
-
{requirements_json}
|
|
7
|
-
|
|
8
|
-
Code Diff:
|
|
9
|
-
{diff}
|
|
10
|
-
|
|
11
|
-
Your task is to identify if the implementation is complete, correct, and follows best practices.
|
|
12
|
-
- Identify missing edge cases.
|
|
13
|
-
- Identify architectural drift.
|
|
14
|
-
- Identify security risks not caught by static scans.
|
|
15
|
-
|
|
16
|
-
Return a JSON object with 'is_satisfactory' and a list of 'findings' (as Gap objects).
|
|
1
|
+
You are an expert software reviewer. Review the following code changes against the task requirements.
|
|
2
|
+
Task: {task.title}
|
|
3
|
+
Description: {task.description}
|
|
4
|
+
|
|
5
|
+
Requirements:
|
|
6
|
+
{requirements_json}
|
|
7
|
+
|
|
8
|
+
Code Diff:
|
|
9
|
+
{diff}
|
|
10
|
+
|
|
11
|
+
Your task is to identify if the implementation is complete, correct, and follows best practices.
|
|
12
|
+
- Identify missing edge cases.
|
|
13
|
+
- Identify architectural drift.
|
|
14
|
+
- Identify security risks not caught by static scans.
|
|
15
|
+
|
|
16
|
+
Return a JSON object with 'is_satisfactory' and a list of 'findings' (as Gap objects).
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
Goal: {goal}
|
|
2
|
-
|
|
3
|
-
Requirements:
|
|
4
|
-
{requirements_json}
|
|
5
|
-
|
|
6
|
-
Repository Map:
|
|
7
|
-
{repo_map_json}
|
|
8
|
-
|
|
9
|
-
Your task is to create a detailed implementation plan.
|
|
10
|
-
- Break down the requirements into atomic implementation tasks.
|
|
11
|
-
- For each task, specify which files will be created or modified.
|
|
12
|
-
- Specify which tests are expected to verify the task.
|
|
13
|
-
- Ensure each task maps back to at least one requirement.
|
|
14
|
-
|
|
15
|
-
Role-specific instructions:
|
|
16
|
-
You are the pragmatic tech lead. Optimize for simplicity and minimal dependencies.
|
|
1
|
+
Goal: {goal}
|
|
2
|
+
|
|
3
|
+
Requirements:
|
|
4
|
+
{requirements_json}
|
|
5
|
+
|
|
6
|
+
Repository Map:
|
|
7
|
+
{repo_map_json}
|
|
8
|
+
|
|
9
|
+
Your task is to create a detailed implementation plan.
|
|
10
|
+
- Break down the requirements into atomic implementation tasks.
|
|
11
|
+
- For each task, specify which files will be created or modified.
|
|
12
|
+
- Specify which tests are expected to verify the task.
|
|
13
|
+
- Ensure each task maps back to at least one requirement.
|
|
14
|
+
|
|
15
|
+
Role-specific instructions:
|
|
16
|
+
You are the pragmatic tech lead. Optimize for simplicity and minimal dependencies.
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
Goal: {goal}
|
|
2
|
-
|
|
3
|
-
Requirements:
|
|
4
|
-
{requirements_json}
|
|
5
|
-
|
|
6
|
-
Repository Map:
|
|
7
|
-
{repo_map_json}
|
|
8
|
-
|
|
9
|
-
Your task is to create a detailed implementation plan.
|
|
10
|
-
- Break down the requirements into atomic implementation tasks.
|
|
11
|
-
- For each task, specify which files will be created or modified.
|
|
12
|
-
- Specify which tests are expected to verify the task.
|
|
13
|
-
- Ensure each task maps back to at least one requirement.
|
|
14
|
-
|
|
15
|
-
Role-specific instructions:
|
|
16
|
-
You are the production-readiness architect. Optimize for security, performance, edge cases, failure modes, and maintainability. Assume the first plan will miss subtle requirements.
|
|
1
|
+
Goal: {goal}
|
|
2
|
+
|
|
3
|
+
Requirements:
|
|
4
|
+
{requirements_json}
|
|
5
|
+
|
|
6
|
+
Repository Map:
|
|
7
|
+
{repo_map_json}
|
|
8
|
+
|
|
9
|
+
Your task is to create a detailed implementation plan.
|
|
10
|
+
- Break down the requirements into atomic implementation tasks.
|
|
11
|
+
- For each task, specify which files will be created or modified.
|
|
12
|
+
- Specify which tests are expected to verify the task.
|
|
13
|
+
- Ensure each task maps back to at least one requirement.
|
|
14
|
+
|
|
15
|
+
Role-specific instructions:
|
|
16
|
+
You are the production-readiness architect. Optimize for security, performance, edge cases, failure modes, and maintainability. Assume the first plan will miss subtle requirements.
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
Original Plan:
|
|
2
|
-
{original_plan_json}
|
|
3
|
-
|
|
4
|
-
Critique Findings:
|
|
5
|
-
{findings_json}
|
|
6
|
-
|
|
7
|
-
You are the planner who created the original plan. Review the critique findings.
|
|
8
|
-
- A finding can be rejected only with artifact evidence or strong justification.
|
|
9
|
-
- A finding can be accepted and converted into a requirement/task/test.
|
|
10
|
-
- No hand-wavy rebuttals.
|
|
1
|
+
Original Plan:
|
|
2
|
+
{original_plan_json}
|
|
3
|
+
|
|
4
|
+
Critique Findings:
|
|
5
|
+
{findings_json}
|
|
6
|
+
|
|
7
|
+
You are the planner who created the original plan. Review the critique findings.
|
|
8
|
+
- A finding can be rejected only with artifact evidence or strong justification.
|
|
9
|
+
- A finding can be accepted and converted into a requirement/task/test.
|
|
10
|
+
- No hand-wavy rebuttals.
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
Goal: {goal}
|
|
2
|
-
|
|
3
|
-
Repository Map:
|
|
4
|
-
{repo_map_json}
|
|
5
|
-
|
|
6
|
-
Your task is to draft the initial software specification for this goal.
|
|
7
|
-
1. Identify functional and non-functional requirements.
|
|
8
|
-
2. Extract any assumptions you are making about the codebase or architecture.
|
|
9
|
-
3. List any blocking questions that the user must answer before implementation can proceed.
|
|
10
|
-
|
|
11
|
-
Each requirement MUST have clear acceptance criteria with verification methods.
|
|
12
|
-
Each assumption MUST have a confidence and impact level.
|
|
1
|
+
Goal: {goal}
|
|
2
|
+
|
|
3
|
+
Repository Map:
|
|
4
|
+
{repo_map_json}
|
|
5
|
+
|
|
6
|
+
Your task is to draft the initial software specification for this goal.
|
|
7
|
+
1. Identify functional and non-functional requirements.
|
|
8
|
+
2. Extract any assumptions you are making about the codebase or architecture.
|
|
9
|
+
3. List any blocking questions that the user must answer before implementation can proceed.
|
|
10
|
+
|
|
11
|
+
Each requirement MUST have clear acceptance criteria with verification methods.
|
|
12
|
+
Each assumption MUST have a confidence and impact level.
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
from pydantic import BaseModel, Field
|
|
2
|
-
from typing import Literal, List
|
|
3
|
-
|
|
4
|
-
class Assumption(BaseModel):
|
|
5
|
-
id: str
|
|
6
|
-
statement: str
|
|
7
|
-
confidence: Literal["low", "medium", "high"]
|
|
8
|
-
impact: Literal["low", "medium", "high"]
|
|
9
|
-
reversible: bool
|
|
10
|
-
requires_user_confirmation: bool
|
|
11
|
-
linked_requirement_ids: List[str] = Field(default_factory=list)
|
|
12
|
-
status: Literal[
|
|
13
|
-
"open",
|
|
14
|
-
"confirmed",
|
|
15
|
-
"rejected",
|
|
16
|
-
"converted_to_requirement"
|
|
17
|
-
] = "open"
|
|
1
|
+
from pydantic import BaseModel, Field
|
|
2
|
+
from typing import Literal, List
|
|
3
|
+
|
|
4
|
+
class Assumption(BaseModel):
|
|
5
|
+
id: str
|
|
6
|
+
statement: str
|
|
7
|
+
confidence: Literal["low", "medium", "high"]
|
|
8
|
+
impact: Literal["low", "medium", "high"]
|
|
9
|
+
reversible: bool
|
|
10
|
+
requires_user_confirmation: bool
|
|
11
|
+
linked_requirement_ids: List[str] = Field(default_factory=list)
|
|
12
|
+
status: Literal[
|
|
13
|
+
"open",
|
|
14
|
+
"confirmed",
|
|
15
|
+
"rejected",
|
|
16
|
+
"converted_to_requirement"
|
|
17
|
+
] = "open"
|
|
@@ -1,32 +1,32 @@
|
|
|
1
|
-
from pydantic import BaseModel
|
|
2
|
-
from typing import Literal, Optional
|
|
3
|
-
|
|
4
|
-
class CritiqueFinding(BaseModel):
|
|
5
|
-
id: str
|
|
6
|
-
source_agent: str
|
|
7
|
-
target_plan_id: str
|
|
8
|
-
severity: Literal["low", "medium", "high", "critical"]
|
|
9
|
-
finding_type: Literal[
|
|
10
|
-
"missing_requirement",
|
|
11
|
-
"missing_task",
|
|
12
|
-
"missing_test",
|
|
13
|
-
"bad_assumption",
|
|
14
|
-
"architecture_risk",
|
|
15
|
-
"security_risk",
|
|
16
|
-
"performance_risk",
|
|
17
|
-
"dependency_risk",
|
|
18
|
-
"migration_risk",
|
|
19
|
-
"unverifiable_acceptance_criteria"
|
|
20
|
-
]
|
|
21
|
-
claim: str
|
|
22
|
-
linked_requirement_id: Optional[str] = None
|
|
23
|
-
suggested_requirement: Optional[str] = None
|
|
24
|
-
suggested_task: Optional[str] = None
|
|
25
|
-
falsifiable_check: str
|
|
26
|
-
status: Literal[
|
|
27
|
-
"open",
|
|
28
|
-
"accepted",
|
|
29
|
-
"rejected",
|
|
30
|
-
"converted",
|
|
31
|
-
"needs_user"
|
|
32
|
-
] = "open"
|
|
1
|
+
from pydantic import BaseModel
|
|
2
|
+
from typing import Literal, Optional
|
|
3
|
+
|
|
4
|
+
class CritiqueFinding(BaseModel):
|
|
5
|
+
id: str
|
|
6
|
+
source_agent: str
|
|
7
|
+
target_plan_id: str
|
|
8
|
+
severity: Literal["low", "medium", "high", "critical"]
|
|
9
|
+
finding_type: Literal[
|
|
10
|
+
"missing_requirement",
|
|
11
|
+
"missing_task",
|
|
12
|
+
"missing_test",
|
|
13
|
+
"bad_assumption",
|
|
14
|
+
"architecture_risk",
|
|
15
|
+
"security_risk",
|
|
16
|
+
"performance_risk",
|
|
17
|
+
"dependency_risk",
|
|
18
|
+
"migration_risk",
|
|
19
|
+
"unverifiable_acceptance_criteria"
|
|
20
|
+
]
|
|
21
|
+
claim: str
|
|
22
|
+
linked_requirement_id: Optional[str] = None
|
|
23
|
+
suggested_requirement: Optional[str] = None
|
|
24
|
+
suggested_task: Optional[str] = None
|
|
25
|
+
falsifiable_check: str
|
|
26
|
+
status: Literal[
|
|
27
|
+
"open",
|
|
28
|
+
"accepted",
|
|
29
|
+
"rejected",
|
|
30
|
+
"converted",
|
|
31
|
+
"needs_user"
|
|
32
|
+
] = "open"
|
|
@@ -1,27 +1,47 @@
|
|
|
1
|
-
from pydantic import BaseModel
|
|
2
|
-
from typing import Literal, List
|
|
3
|
-
|
|
4
|
-
class CommandResult(BaseModel):
|
|
5
|
-
command: str
|
|
6
|
-
exit_code: int
|
|
7
|
-
stdout_path: str
|
|
8
|
-
stderr_path: str
|
|
9
|
-
summary: str
|
|
10
|
-
|
|
11
|
-
class DiffEvidence(BaseModel):
|
|
12
|
-
task_id: str
|
|
13
|
-
changed_files: List[str]
|
|
14
|
-
added_files: List[str]
|
|
15
|
-
deleted_files: List[str]
|
|
16
|
-
diff_summary: str
|
|
17
|
-
|
|
18
|
-
class
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
1
|
+
from pydantic import BaseModel, Field
|
|
2
|
+
from typing import Literal, List, Dict
|
|
3
|
+
|
|
4
|
+
class CommandResult(BaseModel):
|
|
5
|
+
command: str
|
|
6
|
+
exit_code: int
|
|
7
|
+
stdout_path: str
|
|
8
|
+
stderr_path: str
|
|
9
|
+
summary: str
|
|
10
|
+
|
|
11
|
+
class DiffEvidence(BaseModel):
|
|
12
|
+
task_id: str
|
|
13
|
+
changed_files: List[str]
|
|
14
|
+
added_files: List[str]
|
|
15
|
+
deleted_files: List[str]
|
|
16
|
+
diff_summary: str
|
|
17
|
+
|
|
18
|
+
class DiffCoverageEvidence(BaseModel):
|
|
19
|
+
"""Proof that the changed lines were (or were not) exercised by the tests.
|
|
20
|
+
|
|
21
|
+
This is the executable evidence behind DevCouncil's core promise: a passing
|
|
22
|
+
suite is only acceptance evidence if the lines the diff changed were actually
|
|
23
|
+
run. ``measured`` is False when no reliable signal could be computed (no
|
|
24
|
+
coverage tool, no instrumentable test command, or no changed executable
|
|
25
|
+
lines), in which case it must never be read as a defect.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
task_id: str
|
|
29
|
+
tool: str = ""
|
|
30
|
+
measured: bool = False
|
|
31
|
+
changed_lines: int = 0
|
|
32
|
+
covered_lines: int = 0
|
|
33
|
+
coverage_ratio: float = 0.0
|
|
34
|
+
uncovered_by_file: Dict[str, List[int]] = Field(default_factory=dict)
|
|
35
|
+
absent_files: List[str] = Field(default_factory=list)
|
|
36
|
+
summary: str = ""
|
|
37
|
+
|
|
38
|
+
class VerificationEvidence(BaseModel):
|
|
39
|
+
__test__ = False # Prevent pytest from collecting this as a test class
|
|
40
|
+
requirement_id: str
|
|
41
|
+
acceptance_criterion_id: str
|
|
42
|
+
command: str
|
|
43
|
+
status: Literal["passed", "failed", "not_run"]
|
|
44
|
+
evidence_summary: str
|
|
45
|
+
|
|
46
|
+
# Backward-compatible alias
|
|
47
|
+
TestEvidence = VerificationEvidence
|
|
@@ -1,26 +1,52 @@
|
|
|
1
|
-
from pydantic import BaseModel, Field
|
|
2
|
-
from typing import Literal, List, Optional
|
|
3
|
-
|
|
4
|
-
class Gap(BaseModel):
|
|
5
|
-
id: str
|
|
6
|
-
severity: Literal["low", "medium", "high", "critical"]
|
|
7
|
-
gap_type: Literal[
|
|
8
|
-
"requirement_not_planned",
|
|
9
|
-
"task_not_implemented",
|
|
10
|
-
"planned_file_not_changed",
|
|
11
|
-
"orphan_diff",
|
|
12
|
-
"missing_test",
|
|
13
|
-
"test_failed",
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
1
|
+
from pydantic import BaseModel, Field
|
|
2
|
+
from typing import Literal, List, Optional
|
|
3
|
+
|
|
4
|
+
class Gap(BaseModel):
|
|
5
|
+
id: str
|
|
6
|
+
severity: Literal["low", "medium", "high", "critical"]
|
|
7
|
+
gap_type: Literal[
|
|
8
|
+
"requirement_not_planned",
|
|
9
|
+
"task_not_implemented",
|
|
10
|
+
"planned_file_not_changed",
|
|
11
|
+
"orphan_diff",
|
|
12
|
+
"missing_test",
|
|
13
|
+
"test_failed",
|
|
14
|
+
"invalid_verification_command",
|
|
15
|
+
"acceptance_criteria_unproven",
|
|
16
|
+
"diff_not_exercised",
|
|
17
|
+
"assumption_violated",
|
|
18
|
+
"architecture_drift",
|
|
19
|
+
"security_risk",
|
|
20
|
+
"dependency_risk",
|
|
21
|
+
"migration_gap",
|
|
22
|
+
"quality_gate_failed",
|
|
23
|
+
"skipped_verification_command",
|
|
24
|
+
"coarse_acceptance_proof",
|
|
25
|
+
]
|
|
26
|
+
requirement_id: Optional[str] = None
|
|
27
|
+
task_id: Optional[str] = None
|
|
28
|
+
description: str
|
|
29
|
+
evidence: List[str] = Field(default_factory=list)
|
|
30
|
+
recommended_fix: str
|
|
31
|
+
blocking: bool
|
|
32
|
+
# Machine-actionable hints for the agent self-repair loop. Populated at gap
|
|
33
|
+
# creation where known; consumed by the typed next-actions contract (see
|
|
34
|
+
# devcouncil.verification.next_actions). As of schema v4 these are persisted by
|
|
35
|
+
# the gap store and round-tripped on reload, so a reconnecting agent gets the
|
|
36
|
+
# full repair contract rather than a heuristic reconstruction.
|
|
37
|
+
file: Optional[str] = None
|
|
38
|
+
line: Optional[int] = None
|
|
39
|
+
suggested_command: Optional[str] = None
|
|
40
|
+
# The acceptance criterion this gap is about (when applicable), so the agent can
|
|
41
|
+
# tie a failure straight back to the criterion it must satisfy.
|
|
42
|
+
acceptance_criterion_id: Optional[str] = None
|
|
43
|
+
# Paths to the captured stdout/stderr logs (written under .devcouncil/logs) for the
|
|
44
|
+
# failing command behind this gap, so the agent can open the FULL failure output
|
|
45
|
+
# without re-running. Optional and defaulted for backward compatibility; the gap
|
|
46
|
+
# store does not persist these, so they are only present on a fresh verify run.
|
|
47
|
+
stdout_path: Optional[str] = None
|
|
48
|
+
stderr_path: Optional[str] = None
|
|
49
|
+
# Expected verification method (e.g. "unit_test"/"static_check") for an unproven
|
|
50
|
+
# acceptance criterion, so missing-evidence routing is concrete rather than a
|
|
51
|
+
# restatement of the description.
|
|
52
|
+
expected_verification_method: Optional[str] = None
|