solo-sdd 0.2.0__py3-none-any.whl
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.
- solo_sdd/__init__.py +1 -0
- solo_sdd/__main__.py +5 -0
- solo_sdd/cli.py +204 -0
- solo_sdd/data/ALGORITHM.md +211 -0
- solo_sdd/data/global/AGENTS.md +132 -0
- solo_sdd/data/global/model-policy.json +14 -0
- solo_sdd/data/global/process-guard.py +294 -0
- solo_sdd/data/global/sdd_dispatch.py +524 -0
- solo_sdd/data/global/sdd_dispatch_plan.py +650 -0
- solo_sdd/data/global/sdd_eval.py +1001 -0
- solo_sdd/data/global/sdd_pr.py +956 -0
- solo_sdd/data/global/sdd_worktree.py +846 -0
- solo_sdd/data/global/work_hooks.py +2536 -0
- solo_sdd/data/global/work_hooks_settings.py +7 -0
- solo_sdd/data/integrations/antislop/LICENSE +21 -0
- solo_sdd/data/integrations/antislop/README.md +11 -0
- solo_sdd/data/integrations/antislop/VERSION +2 -0
- solo_sdd/data/integrations/antislop/antislop.md +745 -0
- solo_sdd/data/integrations/antislop/integration +6 -0
- solo_sdd/data/integrations/antislop/skills/antislop-copywriting/SKILL.md +372 -0
- solo_sdd/data/integrations/antislop/skills/antislop-human/LICENSE-web-quality-skills +21 -0
- solo_sdd/data/integrations/antislop/skills/antislop-human/SKILL.md +204 -0
- solo_sdd/data/integrations/antislop/skills/antislop-human/contrast-check.py +168 -0
- solo_sdd/data/integrations/antislop/skills/antislop-human/references/A11Y-PATTERNS.md +249 -0
- solo_sdd/data/integrations/antislop/skills/antislop-human/references/WCAG.md +127 -0
- solo_sdd/data/integrations/antislop/skills/antislop-layoutmobile/SKILL.md +170 -0
- solo_sdd/data/integrations/antislop/skills/antislop-ui/LICENSE-web-quality-skills +21 -0
- solo_sdd/data/integrations/antislop/skills/antislop-ui/SKILL.md +344 -0
- solo_sdd/data/integrations/antislop/skills/antislop-ui/references/CORE-WEB-VITALS.md +181 -0
- solo_sdd/data/integrations/antislop/skills/antislop-ui/references/WEB-BASELINE.md +28 -0
- solo_sdd/data/integrations/security-audit/LICENSE +21 -0
- solo_sdd/data/integrations/security-audit/README.md +106 -0
- solo_sdd/data/integrations/security-audit/VERSION +21 -0
- solo_sdd/data/integrations/security-audit/integration +6 -0
- solo_sdd/data/integrations/security-audit/skills/security-audit/AI-AND-LLM.md +83 -0
- solo_sdd/data/integrations/security-audit/skills/security-audit/ATTACK-CLASSES.md +130 -0
- solo_sdd/data/integrations/security-audit/skills/security-audit/CLIENT-SIDE.md +83 -0
- solo_sdd/data/integrations/security-audit/skills/security-audit/CLOUD-AND-DEPLOYMENT.md +86 -0
- solo_sdd/data/integrations/security-audit/skills/security-audit/DATA-ISOLATION-AND-LIFECYCLE.md +84 -0
- solo_sdd/data/integrations/security-audit/skills/security-audit/DESKTOP-MOBILE-AND-LOCAL-IPC.md +89 -0
- solo_sdd/data/integrations/security-audit/skills/security-audit/HUNTING.md +251 -0
- solo_sdd/data/integrations/security-audit/skills/security-audit/MEMORY-SAFETY-AND-BINARY.md +101 -0
- solo_sdd/data/integrations/security-audit/skills/security-audit/PROTOCOLS-RPC-AND-MESSAGING.md +81 -0
- solo_sdd/data/integrations/security-audit/skills/security-audit/RECONNAISSANCE.md +156 -0
- solo_sdd/data/integrations/security-audit/skills/security-audit/RESOURCE-EXHAUSTION-AND-AVAILABILITY.md +78 -0
- solo_sdd/data/integrations/security-audit/skills/security-audit/SKILL.md +192 -0
- solo_sdd/data/integrations/security-audit/skills/security-audit/SUPPLY-CHAIN-AND-RELEASE.md +73 -0
- solo_sdd/data/integrations/security-audit/skills/security-audit/VALIDATION-AND-REPORTING.md +186 -0
- solo_sdd/data/integrations/security-audit/skills/security-audit/WEB-PROTOCOL-AND-AUTH.md +105 -0
- solo_sdd/data/integrations/security-audit/skills/security-audit/report-schema.json +461 -0
- solo_sdd/data/integrations/security-audit/skills/security-audit/validate-coverage-ledger.cjs +872 -0
- solo_sdd/data/integrations/security-audit/skills/security-audit/validate-findings.cjs +773 -0
- solo_sdd/data/skills/agent-quality/SKILL.md +52 -0
- solo_sdd/data/skills/blockers/SKILL.md +29 -0
- solo_sdd/data/skills/changes/SKILL.md +31 -0
- solo_sdd/data/skills/codex-orchestration/SKILL.md +161 -0
- solo_sdd/data/skills/context-resume/SKILL.md +50 -0
- solo_sdd/data/skills/copy-check/SKILL.md +109 -0
- solo_sdd/data/skills/debug-profile/SKILL.md +73 -0
- solo_sdd/data/skills/evidence-research/SKILL.md +43 -0
- solo_sdd/data/skills/health/SKILL.md +38 -0
- solo_sdd/data/skills/project-init/SKILL.md +96 -0
- solo_sdd/data/skills/relay/SKILL.md +31 -0
- solo_sdd/data/skills/report/SKILL.md +30 -0
- solo_sdd/data/skills/ship/SKILL.md +55 -0
- solo_sdd/data/skills/spec-analyze/SKILL.md +116 -0
- solo_sdd/data/skills/spec-audit/SKILL.md +53 -0
- solo_sdd/data/skills/spec-dispatch/SKILL.md +239 -0
- solo_sdd/data/skills/spec-next/SKILL.md +118 -0
- solo_sdd/data/skills/spec-plan/SKILL.md +149 -0
- solo_sdd/data/skills/ui-check/SKILL.md +106 -0
- solo_sdd/data/skills/work-status/SKILL.md +26 -0
- solo_sdd/data/sync.py +9 -0
- solo_sdd/data/targets.json +66 -0
- solo_sdd/data/templates/DESIGN.md +21 -0
- solo_sdd/data/templates/docs/waiting.md +7 -0
- solo_sdd/data/templates/solo-sdd/analyze.md +21 -0
- solo_sdd/data/templates/solo-sdd/change/proposal.md +33 -0
- solo_sdd/data/templates/solo-sdd/change/spec.md +17 -0
- solo_sdd/data/templates/solo-sdd/change/tasks.md +8 -0
- solo_sdd/data/templates/solo-sdd/change/verification.md +23 -0
- solo_sdd/data/templates/solo-sdd/project.md +12 -0
- solo_sdd/doctor.py +338 -0
- solo_sdd/hooks.py +297 -0
- solo_sdd/import_openspec.py +164 -0
- solo_sdd/init.py +293 -0
- solo_sdd/integration_run.py +532 -0
- solo_sdd/integrations.py +351 -0
- solo_sdd/keywords.py +65 -0
- solo_sdd/layout.py +820 -0
- solo_sdd/process_cli.py +378 -0
- solo_sdd/process_format.py +444 -0
- solo_sdd/providers.py +116 -0
- solo_sdd/resources.py +6 -0
- solo_sdd/rules_block.py +56 -0
- solo_sdd/settings.py +248 -0
- solo_sdd/setup_detect.py +71 -0
- solo_sdd-0.2.0.dist-info/METADATA +496 -0
- solo_sdd-0.2.0.dist-info/RECORD +102 -0
- solo_sdd-0.2.0.dist-info/WHEEL +4 -0
- solo_sdd-0.2.0.dist-info/entry_points.txt +2 -0
- solo_sdd-0.2.0.dist-info/licenses/LICENSE +21 -0
solo_sdd/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.2.0"
|
solo_sdd/__main__.py
ADDED
solo_sdd/cli.py
ADDED
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
"""solo-sdd entry point: command parsing."""
|
|
2
|
+
import difflib, os, sys
|
|
3
|
+
|
|
4
|
+
from solo_sdd import __version__, doctor, hooks, import_openspec, integration_run, integrations, keywords, layout, process_cli, process_format, providers, settings
|
|
5
|
+
from solo_sdd import init as project_init
|
|
6
|
+
|
|
7
|
+
layout.PULL_HINT = "solo-sdd sync pull"
|
|
8
|
+
|
|
9
|
+
COMMANDS = """solo-sdd commands:
|
|
10
|
+
--version version
|
|
11
|
+
status state of every copy
|
|
12
|
+
install [--agents a,b] [--hooks] [--global-rules] [--replace-foreign]
|
|
13
|
+
lay out skills, scripts and templates for the agents (default: the last choice, else
|
|
14
|
+
the detected ones; other always); --hooks connects the hooks in settings.json;
|
|
15
|
+
--global-rules also writes the rules block into ~/AGENTS.md, ~/.codex/AGENTS.md and
|
|
16
|
+
~/.claude/CLAUDE.md (a home that has the block from an earlier version keeps it);
|
|
17
|
+
a file solo-sdd did not lay out is kept, --replace-foreign replaces it with a backup
|
|
18
|
+
uninstall [--purge | --global-rules]
|
|
19
|
+
remove copies and hooks; --purge also removes solo-sdd data and a solo schema left by an
|
|
20
|
+
old version; --global-rules removes only the global rules block
|
|
21
|
+
init [folder] [--yes] [--solo|--team] [--agents a,b] [--delivery local|pr] [--set key=value]... [--reconfigure]
|
|
22
|
+
prepare a project git repository: solo-sdd/ (project.md, analyze.md, specs/, changes/,
|
|
23
|
+
config from the detected authors, CODEOWNERS, branch protection, remote and agents;
|
|
24
|
+
asks on a terminal), docs/waiting.md, the rules block in AGENTS.md and CLAUDE.md
|
|
25
|
+
(rules.scope: global writes none); --reconfigure asks again for every setting
|
|
26
|
+
doctor check the environment: python, copies, hooks, agents and their gaps, gh, AGENTS.md keywords
|
|
27
|
+
update [--replace-foreign] repeat the layout, suggest a package upgrade
|
|
28
|
+
sync pull <name> [--from <place>] take an edit made in place back into the repository
|
|
29
|
+
migrate-agents [folder] [--write] rename pre-English AGENTS.md headings and items to English; without --write only the diff
|
|
30
|
+
validate [<id>] [--all] [--json] check the solo-sdd/ process tree (one change or all), no external program
|
|
31
|
+
list [--specs] [--json] open changes with task progress and CLAIM/WAITING, or main specs with requirement counts
|
|
32
|
+
new <id> create solo-sdd/changes/<id>/ from the templates
|
|
33
|
+
archive <id> [--yes] [--force] apply the change's deltas to the main specs and move it to changes/archive/
|
|
34
|
+
config list|get <key>|set <key> <value>|unset <key>
|
|
35
|
+
project settings in solo-sdd/config: every key with its value and source, one value, change one line
|
|
36
|
+
integrations list|enable <name>|disable <name>
|
|
37
|
+
integrations of solo-sdd/integrations/, ~/.local/share/solo-sdd/integrations/ and
|
|
38
|
+
the bundled ones with their source and state; enable or disable one by the integrations
|
|
39
|
+
line of solo-sdd/config (integrations.off for a bundled one, enabled unless it names it)
|
|
40
|
+
and rewrite the AGENTS.md block with the rules.md of the enabled ones
|
|
41
|
+
check --point checks|ship [--changed] [--change <id>]
|
|
42
|
+
run the enabled integrations of the point (--changed: those whose applies matches a
|
|
43
|
+
changed file), one PASS|FAIL|SKIP line each; the result is recorded by the working
|
|
44
|
+
tree under ~/.local/share/solo-sdd/checks/ and reused on the same tree; --change
|
|
45
|
+
puts one Integrations line of the point into the change's verification.md Result
|
|
46
|
+
check --point review|audit [--changed] [--tag <tag>]
|
|
47
|
+
run nothing: one MATERIAL <name>: <path> line per enabled integration of the point;
|
|
48
|
+
--tag: per enabled one with the tag, the bundled ones included, also outside a project
|
|
49
|
+
import openspec [folder] [--write] plan of converting openspec/ into solo-sdd/; --write creates solo-sdd/, openspec/ stays"""
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def upgrade_hint(prefix, root):
|
|
53
|
+
if "/uv/tools/" in prefix:
|
|
54
|
+
return "uv tool upgrade solo-sdd"
|
|
55
|
+
if "/pipx/venvs/" in prefix:
|
|
56
|
+
return "pipx upgrade solo-sdd"
|
|
57
|
+
if "node_modules" in root:
|
|
58
|
+
return "npm update -g solo-sdd"
|
|
59
|
+
if os.path.exists(os.path.join(root, ".git")):
|
|
60
|
+
return f"git pull in {root}"
|
|
61
|
+
return "python3 -m pip install --upgrade solo-sdd"
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def install(with_hooks=False, agents=None, rules=False, replace_foreign=False):
|
|
65
|
+
if agents is not None:
|
|
66
|
+
try:
|
|
67
|
+
agents = providers.parse(agents)
|
|
68
|
+
except ValueError as e:
|
|
69
|
+
print(e)
|
|
70
|
+
return 1
|
|
71
|
+
state = layout.load_state()
|
|
72
|
+
if "claude" not in (agents or layout.chosen(state)) and (with_hooks or state.get("_hooks")):
|
|
73
|
+
print("hooks need claude among the agents: solo-sdd install --agents claude,... --hooks"
|
|
74
|
+
+ ("; the connected hooks go with solo-sdd uninstall" if state.get("_hooks") else ""))
|
|
75
|
+
return 1
|
|
76
|
+
problems = layout.push(agents=agents, rules=rules, replace_foreign=replace_foreign)
|
|
77
|
+
for name in agents or layout.chosen(layout.load_state()):
|
|
78
|
+
if not providers.probed(name):
|
|
79
|
+
print("%s: %s" % (name, providers.unprobed()))
|
|
80
|
+
connected = hooks.setup() if with_hooks else 0
|
|
81
|
+
return 1 if problems or connected else 0
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def uninstall(purge=False):
|
|
85
|
+
layout.load_targets() # a bad map stops before the hooks are restored, not halfway
|
|
86
|
+
steps = layout.load_state().get("_hooks")
|
|
87
|
+
code = hooks.restore(steps) if steps else 0
|
|
88
|
+
if code == 0:
|
|
89
|
+
state = layout.load_state()
|
|
90
|
+
if state.pop("_hooks", None) is not None:
|
|
91
|
+
layout.save_state(state)
|
|
92
|
+
return 1 if layout.uninstall(purge) or code else 0
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def update(replace_foreign=False):
|
|
96
|
+
problems = layout.push(replace_foreign=replace_foreign)
|
|
97
|
+
print(upgrade_hint(sys.prefix, layout.REPO))
|
|
98
|
+
return 1 if problems else 0
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def status():
|
|
102
|
+
state = layout.load_state()
|
|
103
|
+
print(f"source: {state.get('_source', layout.REPO)} {state.get('_version', __version__)}")
|
|
104
|
+
layout.status()
|
|
105
|
+
return 0
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def migrate_agents(folder=".", write=False):
|
|
109
|
+
"""Diff of AGENTS.md with the pre-English headings and items renamed; --write applies it."""
|
|
110
|
+
path = os.path.join(folder, "AGENTS.md")
|
|
111
|
+
try:
|
|
112
|
+
with open(path, encoding="utf-8", newline="") as f:
|
|
113
|
+
old = f.read()
|
|
114
|
+
except OSError as e:
|
|
115
|
+
print(f"no AGENTS.md: {path}: {e.strerror}")
|
|
116
|
+
return 1
|
|
117
|
+
new, found = keywords.migrate_agents(old)
|
|
118
|
+
if new == old:
|
|
119
|
+
print(f"{path}: nothing to change")
|
|
120
|
+
return 0
|
|
121
|
+
sys.stdout.writelines(difflib.unified_diff(old.splitlines(True), new.splitlines(True), "a/AGENTS.md", "b/AGENTS.md"))
|
|
122
|
+
if write:
|
|
123
|
+
with open(path, "w", encoding="utf-8", newline="") as f:
|
|
124
|
+
f.write(new)
|
|
125
|
+
print(f"{path}: rewritten ({', '.join(found)})")
|
|
126
|
+
else:
|
|
127
|
+
print(f"{path}: not changed; apply with: solo-sdd migrate-agents {folder} --write")
|
|
128
|
+
return 0
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def main(argv=None):
|
|
132
|
+
try:
|
|
133
|
+
return _main(argv)
|
|
134
|
+
except layout.BrokenState as e:
|
|
135
|
+
print(f"fail state: {e}")
|
|
136
|
+
return 1
|
|
137
|
+
except layout.BadTargets as e:
|
|
138
|
+
print(f"fail {e}")
|
|
139
|
+
return 1
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def _main(argv=None):
|
|
143
|
+
argv = sys.argv[1:] if argv is None else list(argv)
|
|
144
|
+
if argv == ["--version"]:
|
|
145
|
+
print(__version__)
|
|
146
|
+
return 0
|
|
147
|
+
if argv in (["status"], ["update"], ["doctor"]):
|
|
148
|
+
return {"status": status, "update": update, "doctor": doctor.run}[argv[0]]()
|
|
149
|
+
if argv == ["update", "--replace-foreign"]:
|
|
150
|
+
return update(replace_foreign=True)
|
|
151
|
+
if argv and argv[0] == "init":
|
|
152
|
+
code = project_init.main(argv[1:])
|
|
153
|
+
if code is not None:
|
|
154
|
+
return code
|
|
155
|
+
if argv and argv[0] == "install":
|
|
156
|
+
flags = [a for a in argv[1:] if a in ("--hooks", "--global-rules", "--replace-foreign")]
|
|
157
|
+
rest = [a for a in argv[1:] if a not in flags]
|
|
158
|
+
if len(set(flags)) == len(flags) and (rest == [] or (len(rest) == 2 and rest[0] == "--agents")):
|
|
159
|
+
return install("--hooks" in flags, rest[1] if rest else None, "--global-rules" in flags,
|
|
160
|
+
"--replace-foreign" in flags)
|
|
161
|
+
if argv and argv[0] == "uninstall" and argv[1:] in ([], ["--purge"]):
|
|
162
|
+
return uninstall(bool(argv[1:]))
|
|
163
|
+
if argv == ["uninstall", "--global-rules"]:
|
|
164
|
+
return layout.uninstall_rules()
|
|
165
|
+
if argv and argv[0] == "migrate-agents":
|
|
166
|
+
rest = [a for a in argv[1:] if a != "--write"]
|
|
167
|
+
if len(rest) <= 1 and len(argv) - len(rest) <= 2:
|
|
168
|
+
return migrate_agents(*rest, write="--write" in argv[1:])
|
|
169
|
+
if argv and argv[0] == "validate":
|
|
170
|
+
code = process_format.run(argv[1:])
|
|
171
|
+
if code is not None:
|
|
172
|
+
return code
|
|
173
|
+
if argv and argv[0] in ("list", "new", "archive"):
|
|
174
|
+
code = process_cli.run(argv)
|
|
175
|
+
if code is not None:
|
|
176
|
+
return code
|
|
177
|
+
if argv and argv[0] == "config":
|
|
178
|
+
code = settings.run(argv[1:])
|
|
179
|
+
if code is not None:
|
|
180
|
+
return code
|
|
181
|
+
if argv and argv[0] == "integrations":
|
|
182
|
+
code = integrations.run(argv[1:])
|
|
183
|
+
if code is not None:
|
|
184
|
+
return code
|
|
185
|
+
if argv and argv[0] == "check":
|
|
186
|
+
code = integration_run.run(argv[1:])
|
|
187
|
+
if code is not None:
|
|
188
|
+
return code
|
|
189
|
+
if argv and argv[0] == "import":
|
|
190
|
+
code = import_openspec.main(argv[1:])
|
|
191
|
+
if code is not None:
|
|
192
|
+
return code
|
|
193
|
+
if argv[:2] == ["sync", "pull"]:
|
|
194
|
+
code = layout.main(argv[1:])
|
|
195
|
+
if not os.path.exists(os.path.join(layout.REPO, ".git")):
|
|
196
|
+
print("source is the installed package: the edit is lost on upgrade, move it to a clone")
|
|
197
|
+
return code
|
|
198
|
+
if argv[:1] in (["-h"], ["--help"], ["help"]) or argv[1:2] in (["-h"], ["--help"]):
|
|
199
|
+
print(COMMANDS)
|
|
200
|
+
return 0
|
|
201
|
+
if argv:
|
|
202
|
+
print("solo-sdd: wrong command or arguments: " + " ".join(argv), file=sys.stderr)
|
|
203
|
+
print(COMMANDS)
|
|
204
|
+
return 2
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
# Solo SDD: the algorithm
|
|
2
|
+
|
|
3
|
+
Spec-driven development for one person or a team, with any coding agent (Claude Code and Codex today). The user sets the goal and accepts the result. The agents run the work themselves: from the plan to code merged into main, without questions along the way. The base is solo-sdd's own process tree `solo-sdd/` and its commands (`solo-sdd new`, `validate`, `list`, `archive`); the skills from `skills/` work on top of them. A project still on `openspec/` moves with `solo-sdd import openspec`.
|
|
4
|
+
|
|
5
|
+
How the repository is organised and how to deploy it is in [README.md](README.md). The third-party files the repository ships are listed in [SOURCES.md](SOURCES.md). Why the rules are worded the way they are is in [LESSONS.md](LESSONS.md).
|
|
6
|
+
|
|
7
|
+
## Principles
|
|
8
|
+
|
|
9
|
+
1. **The specification is the source of truth.** Behaviour changes together with the spec, in one change. Code that diverges from the spec counts as a defect, even if the tests are green.
|
|
10
|
+
2. **A small change.** One result the user can check themselves, one area of code, at most 10 tasks. If it comes out bigger, it is several changes linked through `Depends On`.
|
|
11
|
+
3. **A property, not a method.** The spec says what must be true ("git history does not change"), not how to check it ("look for the substring push"). The implementer chooses the method.
|
|
12
|
+
4. **Proof, not a report.** Readiness is confirmed by observations: a test that fails on the previous code, and a live scenario in what a person sees. Green tests, a report by the author or a subagent, "the function was called" do not count as proof.
|
|
13
|
+
5. **No questions along the way.** The agent resolves an ambiguity itself and records the decision. Asking is allowed only before three things: a paid call, deleting or overwriting data, an action on prod. The question names what will happen, how many calls and what amount.
|
|
14
|
+
6. **A blocker does not stop the work.** First look for a workaround: mocks, old data, `.env`, a neighbouring service. No workaround: what is unchecked goes into `verification.md` and `docs/waiting.md`, the rest gets closed.
|
|
15
|
+
7. **Code is written by whoever holds the plan.** Every handoff between agents loses precision, so the lead agent writes the code itself. Subagents are for independent acceptance and heavy reading. Review is done by an agent that did not write this code.
|
|
16
|
+
8. **Nothing is invented.** Values the source knows (CLI, API, database) are asked from the source. An honest "could not determine" is better than a plausible value.
|
|
17
|
+
9. **Cheap where a mistake is easy to notice.** Search, reading logs and test output run on cheap models; code, review and acceptance on the main one. First the effort changes (medium by default, low for mechanics, higher if stuck), the model only when effort did not help. Paid calls to the product model in tests and runs go to the cheapest models and with consent. Heavy reading goes to a search subagent (Explore), so the lead's context does not get compacted.
|
|
18
|
+
10. **"Done" = archived, checked live, merged.** If any of the three is missing, the status is "not done" with what is missing.
|
|
19
|
+
|
|
20
|
+
## Cycle
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
0 project-init ─► 1 context-resume ─► 2 evidence-research (when needed)
|
|
24
|
+
│
|
|
25
|
+
9 spec-audit ◄─ 8 ship ◄─ 7 closing ◄─ 6 proof ◄─ 5 spec-next ◄─ 4 spec-analyze ◄─ 3 spec-plan
|
|
26
|
+
(every 5 archives) ▲
|
|
27
|
+
debug-profile, ui-check, agent-quality
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Cross-cutting skills at any stage: `work-status` (five lines about the state), `context-resume` (after a pause, a context compaction or an agent switch).
|
|
31
|
+
|
|
32
|
+
### 0. The project is ready for agents: `project-init`
|
|
33
|
+
|
|
34
|
+
Once per project. It creates `AGENTS.md` (project rules: commands, map, boundaries and invariants, checks), `CLAUDE.md` with the line `@AGENTS.md`, the process tree `solo-sdd/` by `solo-sdd init` with `solo-sdd/project.md` (language, mode and an "Intent"), `.env.example`, README.
|
|
35
|
+
|
|
36
|
+
In a repository that already has code it also writes the codebase map `docs/codebase/` (`STACK.md`, `ARCHITECTURE.md`, `CONVENTIONS.md`, `CONCERNS.md`): four cheap subagents, every statement names a path, each file stamped with the commit; the `CONCERNS.md` items are candidates for `spec-plan`. `/project-init map` refreshes it.
|
|
37
|
+
|
|
38
|
+
**Gate G0:** `solo-sdd validate --all` passes; every command from the `AGENTS.md` table actually runs; the project comes up by the README in a clean shell.
|
|
39
|
+
|
|
40
|
+
### 1. Context: `context-resume`
|
|
41
|
+
|
|
42
|
+
When returning to a project, after a context compaction or on an agent switch. It reads the project rules, `handoff.md`, `verification.md` of open changes, `git status` and the history by the words of the task. The output is a map: the goal, the source of truth, the last confirmed state, the user's decisions, blockers, the next step. A fact from history is checked against files and the service. If they diverge, the current state counts as right.
|
|
43
|
+
|
|
44
|
+
### 2. Research and decision: `evidence-research`
|
|
45
|
+
|
|
46
|
+
Only when the plan cannot be written without it: choosing a technology, a service or an approach. `evidence-research` gives a table of options by the user's constraints, every fact with a source and a date. A disputed decision goes the same way: the options side by side on checked facts, the choice and its reason. The result goes into `spec-plan` as input.
|
|
47
|
+
|
|
48
|
+
### Light path: no change
|
|
49
|
+
|
|
50
|
+
A code edit takes the light path when it changes no behaviour a main spec describes, adds no dependency, touches no data, migration or deploy, and changes at most `process.light-path.max-files` files (default 3); `process.light-path: off` forbids it. The edit, the project's tests, a live check of the edited place and one commit `light: <the request>` are the whole record; `spec-plan` coverage names such an item with its commit, `work-status` and `report` count these commits apart from changes. Anything outside the bounds, and a bug in behaviour a spec describes, goes through a change.
|
|
51
|
+
|
|
52
|
+
### 3. Plan: `spec-plan`
|
|
53
|
+
|
|
54
|
+
Input: a plan, a bug list, the result of a discussion. Output: a queue of small changes. No code is written, except the light path items, after the plan commit.
|
|
55
|
+
|
|
56
|
+
- A unit fits if it has one checkable result, one area of code, at most 10 tasks and a live check scenario. Bugs are grouped by a common cause, not "one bug, one change".
|
|
57
|
+
- A unit that leads away from the "Intent" of `solo-sdd/project.md` does not become a change and goes into the report.
|
|
58
|
+
- `solo-sdd new <id>` lays out the change; the artifacts are written in the order proposal → specs → verification → tasks by the "Writing rules" of `spec-plan` (see "Change artifacts").
|
|
59
|
+
- Whatever waits for a person, access or paid consent does not become a task. It is `Needs` in `verification.md`. A change made up entirely of such conditions gets a `WAITING` file.
|
|
60
|
+
- Every input item is matched with a change or the light path. Any other item without a change counts as an error.
|
|
61
|
+
- A bug with a found cause takes the short track (the "Bug fix" section in `spec-plan`): the reproduction and the place of the cause in the proposal, the bug scenario is added to the spec, the first task is a failing test for this scenario, at most 5 tasks, side edits in Out of Scope. Cause not found: `debug-profile` first.
|
|
62
|
+
- A UI change starts What Changes with a Design Read line from `DESIGN.md` (no `Dial` line with three numbers means dials 1/1/1 and "draft without direction"); the Live Scenario is a list "element → action → result"; the user's business facts (numbers, reviews, customers) are placeholders `[data needed: …]`.
|
|
63
|
+
|
|
64
|
+
**Gate G1:** `solo-sdd validate --all`; then `spec-analyze` on every created change (stage 4); full coverage of the input.
|
|
65
|
+
|
|
66
|
+
After G1 the folders of created and changed changes go in one commit `change: <id>, …`, without other edits. If `solo-sdd/changes` is ignored, there is no commit, and the report says "plan outside git".
|
|
67
|
+
|
|
68
|
+
### 4. Check before code: `spec-analyze`
|
|
69
|
+
|
|
70
|
+
Before the first task of every change. The spec is checked against itself while there is no code: a hole in `tasks.md` costs one line, after implementation a rework.
|
|
71
|
+
|
|
72
|
+
Passes:
|
|
73
|
+
|
|
74
|
+
| # | Pass | What it looks for |
|
|
75
|
+
|---|---|---|
|
|
76
|
+
| 1 | Coverage | A requirement or scenario without a task and a test; a task without a requirement |
|
|
77
|
+
| 2 | Solo frame | An empty Out of Scope; an unarchived Depends On; a retelling instead of a quote in Source; more than 10 tasks; waiting for a person in tasks; a Live Scenario that does not reach what the user sees |
|
|
78
|
+
| 3 | Checkability | A task without an observable criterion |
|
|
79
|
+
| 3a | Executable properties | An invariant, round trip or idempotence checked only by examples |
|
|
80
|
+
| 4 | Consumer | A new field, module or value that nobody reads |
|
|
81
|
+
| 5 | Ambiguities | Empty, erroneous and partial cases; "no data" versus "not read"; a repeat; what the user sees in each outcome; term drift; `TBD` |
|
|
82
|
+
| 6 | Wording | A method instead of a property; line numbers instead of structure; hard-coded values; words without a measure |
|
|
83
|
+
| 7 | Consistency | A contradiction with the main spec; a decision in design without a task; a task uses what appears later; drifting from the intent |
|
|
84
|
+
| 7a | Requirement compatibility | Requirements that are true one by one and unsatisfiable together; incompatible constraints; an undescribed combination of conditions; a hidden assumption |
|
|
85
|
+
|
|
86
|
+
Checks derived from the defects of a specific project live in its `solo-sdd/analyze.md` (laid out by `solo-sdd init`). The skill picks them up itself.
|
|
87
|
+
|
|
88
|
+
The agent fixes CRITICAL and HIGH findings in the artifacts and writes the decisions into `Decisions Without Owner`. Code does not change in this pass.
|
|
89
|
+
|
|
90
|
+
**Gate G2:** no open CRITICAL and HIGH; everything from `Depends On` is archived. Otherwise the change is not ready, and `spec-next` takes another.
|
|
91
|
+
|
|
92
|
+
### 5. Implementation: `spec-next`
|
|
93
|
+
|
|
94
|
+
One run closes one change, from selection to archive.
|
|
95
|
+
|
|
96
|
+
1. Step 0: a project with `openspec/` and no `solo-sdd/` stops here with the next step `solo-sdd import openspec`; the skills never import by themselves.
|
|
97
|
+
2. Selection: the named change; else the one with the most done; else the next one with closed dependencies. A change with a `CLAIM` file (taken by another agent) or `WAITING` is skipped.
|
|
98
|
+
3. Claim: `solo-sdd/changes/<id>/CLAIM` in the main project folder with the line `<agent> <date>`; Claude adds `session=<session id>` (`$CLAUDE_CODE_SESSION_ID`), by which the write hook recognises its own `CLAIM`. The hook itself places the marker only on a `tasks.md` edit that checks a new task: analysis and audit that edit artifacts do not take the change.
|
|
99
|
+
4. Check: `spec-analyze` (stage 4).
|
|
100
|
+
5. The lead agent does the tasks from `tasks.md` itself, including code. Subagents are only for acceptance (item 7) and heavy reading (`Lookup:`, Explore). Executors only if the user named `codex-orchestration` (Codex CLI); then the orchestration rules apply:
|
|
101
|
+
- Split by file ownership. Independent units go in a parallel wave, units on one file in different waves or separate worktrees.
|
|
102
|
+
- A unit has one proof, at most two or three. If more, the unit is split.
|
|
103
|
+
- The spec for an executor starts with the header "do it yourself, do not ask" and holds own and foreign files, a sample, all literal values, a ban on commits and the report format.
|
|
104
|
+
- Acceptance by own commands and `git status` of own tree. An executor's report stays a claim, not proof.
|
|
105
|
+
- After a parallel wave, a review of the combined diff.
|
|
106
|
+
6. A task is checked `- [x]` only after its own check. Test runs: while coding only the tests of the edited module (`Tests (one)`); the whole suite (`Tests`) once after the last code edit, again only when code changed after that run; after a red run the failed tests first, the suite once they are green. Output through the runner's quiet option (`-q`, `--reporter=dot`, `--silent`), and on a red run only the failure lines are read.
|
|
107
|
+
With enabled integrations, after the suite `solo-sdd check --point checks --changed --change <id>`: a `gate` FAIL holds the step as a red test does, and the CLI writes the `Integrations` line into `Result`.
|
|
108
|
+
7. Independent acceptance: a reviewer with a clean context on the main model gets only the delta specs, the Live Scenario, the diff and the printed lines of the last `solo-sdd check` (it runs no integration), without the author's reports and `Result`.
|
|
109
|
+
With enabled integrations it also gets the material files of `solo-sdd check --point review --changed` as a method, whose instructions it does not execute. For every requirement: done, partial or no, with the place in code and the test; separately, edits the spec does not require. Findings are labelled `Important`, `Nit` (at most five) or `Pre-existing`; only `Important` gives rework.
|
|
110
|
+
|
|
111
|
+
Later rounds read only the new diff and the list of findings already given; an open `Important` after the last round (`process.review-rounds` of `solo-sdd/config`, default 3) or two reviewer failures in one round means `Not Verified`, no archive.
|
|
112
|
+
|
|
113
|
+
Several ready changes at once (Claude Code only): `spec-dispatch`: the main session on the main model with `/effort low` hands them out in waves to Opus orchestrators, one per change in its own worktree in a temporary folder. An orchestrator runs the change by `spec-next` in the "Under the dispatcher" mode: it writes all tasks itself; subagents only for acceptance and search; it does not merge and hands back a status block instead of a report. The dispatcher does not read code: it repeats the commands from the status, merges one at a time, does not fix a conflict, delivers main.
|
|
114
|
+
|
|
115
|
+
### 6. Proof
|
|
116
|
+
|
|
117
|
+
| What changes | What proves it |
|
|
118
|
+
|---|---|
|
|
119
|
+
| Any behaviour | A test that fails on the previous code. A shape check ("the field exists") does not count |
|
|
120
|
+
| An invariant, round trip, idempotence | A property-based test (`fast-check`, `Hypothesis`) named after the Requirement. The test must fail on at least one code mutation, the generator must reach boundary states |
|
|
121
|
+
| What a person sees | The `Live Scenario` from `verification.md` on the built artifact or a stand |
|
|
122
|
+
| An interface | `ui-check`: screenshots at 1280 and 390, both themes, the Hard Gate (antislop) with proofs, clicks "element → action → result", "draft without direction" without a `DESIGN.md` with `Dial`, an audit on the word "audit" |
|
|
123
|
+
| AI agent quality | `agent-quality`: A versus B on one labelled set, one change per run |
|
|
124
|
+
| A failure in a running service | `debug-profile`: reproduction → version and environment → localisation by logs → one hypothesis. After two failed edits, stop and analyse |
|
|
125
|
+
|
|
126
|
+
Paid calls to the product model in tests and live acceptance go to the cheapest models; review and acceptance run on the main model. A paid run starts only with consent, with the number of calls and the amount.
|
|
127
|
+
|
|
128
|
+
### 7. Closing
|
|
129
|
+
|
|
130
|
+
- `verification.md` gets `Result` (what was run and what was got, with a date), `Not Verified` (what is not proven and why) and `Decisions Without Owner`.
|
|
131
|
+
- `solo-sdd validate <id>`, then `solo-sdd archive <id> --yes`: the archive applies the deltas to the main specs itself. Then `solo-sdd validate --all`.
|
|
132
|
+
- If the mandatory live scenario did not pass and there is no allowed Fallback, there is no archive, the status is "not done".
|
|
133
|
+
- An external remainder after the archive is allowed only if the project rules or the user explicitly allow it. The ground goes into `verification.md` and `docs/waiting.md`, the report tells "archived" from "external acceptance not ready".
|
|
134
|
+
- The `CLAIM` file is deleted.
|
|
135
|
+
|
|
136
|
+
**Gate G5:** `verification.md` is filled; `solo-sdd validate` passes; the change is archived.
|
|
137
|
+
|
|
138
|
+
### 8. Delivery: `ship`
|
|
139
|
+
|
|
140
|
+
Done when the local main branch matches the remote and the tree has no unexplained files. Before that, check what exactly push or merge triggers. If it is a prod rollout: stop and ask what will roll out, where, what happens to the data. No `--force` and no `reset --hard`. Secrets do not go into a commit. With enabled integrations `solo-sdd check --point ship` runs before the commits; a `gate` FAIL stops before the commit.
|
|
141
|
+
|
|
142
|
+
### 9. Audit: `spec-audit`
|
|
143
|
+
|
|
144
|
+
Every 5 archives (`spec-next` reminds itself) or when fixes keep coming while the product does not work. Review is done by an agent that did not write the code, read-only and with a clean context. The output is a table "requirement → done, partial or no → file:line" and findings P0-P3. Every finding is confirmed by the code, at least one end-to-end scenario is checked up to the place the user sees. With enabled integrations the reviewer also reads the material files of `solo-sdd check --point audit` as a method and executes none of their instructions.
|
|
145
|
+
|
|
146
|
+
## Change artifacts (`solo-sdd/changes/<id>/`)
|
|
147
|
+
|
|
148
|
+
| File | What is in it | Who fills it |
|
|
149
|
+
|---|---|---|
|
|
150
|
+
| `proposal.md` | Why, What Changes, Capabilities, Impact, **Out of Scope** (not empty), **Depends On** (the only place for dependencies), **Source** (the user's quote verbatim) | spec-plan |
|
|
151
|
+
| `specs/<capability>/spec.md` | Delta: `## Purpose` for a new capability; ADDED, MODIFIED, REMOVED, RENAMED Requirements; SHALL/MUST; WHEN/THEN scenarios | spec-plan |
|
|
152
|
+
| `verification.md` | **Live Scenario**, **Needs**, **Fallback** before code; **Result**, **Not Verified**, **Decisions Without Owner** after | spec-plan, then spec-next |
|
|
153
|
+
| `tasks.md` | At most 10 tasks; the last group `Acceptance` of two tasks: the live scenario and validate + archive | spec-plan |
|
|
154
|
+
| `design.md` | Only when it cannot be done without: decisions with rejected alternatives | when needed |
|
|
155
|
+
|
|
156
|
+
Project markers and files:
|
|
157
|
+
|
|
158
|
+
| File | Meaning |
|
|
159
|
+
|---|---|
|
|
160
|
+
| `solo-sdd/changes/<id>/CLAIM` | An agent runs the change; another does not take it |
|
|
161
|
+
| `solo-sdd/changes/<id>/WAITING` | The change waits for an external condition; a line in `docs/waiting.md` |
|
|
162
|
+
| `docs/waiting.md` | The waiting table: what, from whom, since when (template: `templates/docs/waiting.md`) |
|
|
163
|
+
| `handoff.md` | Handoff between sessions and agents: the five `work-status` lines and decisions |
|
|
164
|
+
| `docs/debug-profile.md` | What runs where, logs, config, what must not be touched without consent |
|
|
165
|
+
| `solo-sdd/analyze.md` | `spec-analyze` checks derived from the defects of this project |
|
|
166
|
+
|
|
167
|
+
## Gates
|
|
168
|
+
|
|
169
|
+
| Gate | When | Who checks | What | On failure |
|
|
170
|
+
|---|---|---|---|---|
|
|
171
|
+
| G0 | After `project-init` | The lead agent | validate, the commands from AGENTS.md run, the project comes up by the README | Fix the project or the README |
|
|
172
|
+
| G1 | After `spec-plan` | The lead agent | validate, analyze, input coverage | Split or complete the changes |
|
|
173
|
+
| G2 | Before code | `spec-analyze` | No CRITICAL and HIGH, dependencies archived | Fix the artifacts; the change is not taken |
|
|
174
|
+
| G3 | After every task | The lead agent, by own commands | The diff, the task's checks, `git status` of own tree | Rework until the checks are green |
|
|
175
|
+
| G4 | Before closing | The lead agent and an independent reviewer | The test failed on the previous code; the property test catches a mutation; the Live Scenario passed; the reviewer has no open `Important` | "Not done", Not Verified |
|
|
176
|
+
| G5 | Closing | The lead agent | verification.md, `solo-sdd validate`, archive | Do not archive |
|
|
177
|
+
| G6 | Delivery | `ship` | main = origin/main; deploy only with consent | Stop before the deploy |
|
|
178
|
+
| G7 | Every 5 archives | An agent that did not write the code | Requirement ↔ code, an end-to-end scenario | P0 and P1 are fixed if the task allows the fix; otherwise a report to the user, who can pass it to `spec-plan` |
|
|
179
|
+
|
|
180
|
+
## Roles
|
|
181
|
+
|
|
182
|
+
| Role | Does | Does not |
|
|
183
|
+
|---|---|---|
|
|
184
|
+
| User | Gives the goal, Source and Intent; accepts the result; agrees to money, deletion and prod | Does not carry context between agents, does not answer technical questions along the way |
|
|
185
|
+
| Lead agent | Plans, writes code, keeps the artifacts, closes the change | Does not accept own work; does not trust reports |
|
|
186
|
+
| Executor (Codex, by the user's choice) | Does one unit in its own files and reports in the given form | Does not touch foreign files, does not commit, does not invent values |
|
|
187
|
+
| Reviewer | Reads code and spec with a clean context, read-only | Does not edit what it found |
|
|
188
|
+
| Search (Explore) | Reads many files and returns a digest | Does not edit and does not make decisions |
|
|
189
|
+
|
|
190
|
+
Claude Code and Codex are equal: both work by the same rules (`~/AGENTS.md` = `~/.codex/AGENTS.md` = `~/.claude/CLAUDE.md`) and the same skills. They differ only in the tool for subagents and orchestration.
|
|
191
|
+
|
|
192
|
+
## When to run what
|
|
193
|
+
|
|
194
|
+
| Situation | Skill |
|
|
195
|
+
|---|---|
|
|
196
|
+
| A new folder or a repository without rules | `project-init` |
|
|
197
|
+
| "Let's continue", after a pause or an agent switch | `context-resume` |
|
|
198
|
+
| "What to choose", comparing technologies or services | `evidence-research` |
|
|
199
|
+
| A disputed decision between options | `evidence-research` |
|
|
200
|
+
| A plan, a bug list, the result of a discussion → into work | `spec-plan` |
|
|
201
|
+
| A bug with a found cause | `spec-plan`, the "Bug fix" section; cause not found: `debug-profile` first |
|
|
202
|
+
| Before the code of a change | `spec-analyze` |
|
|
203
|
+
| "Implement the next spec", "finish the change" | `spec-next` |
|
|
204
|
+
| Several ready changes, "hand them to orchestrators", the main session only accepts statuses (Claude Code) | `spec-dispatch` |
|
|
205
|
+
| The interface changed | `ui-check` |
|
|
206
|
+
| Text for people in the product | `copy-check` |
|
|
207
|
+
| A prompt, model or retrieval of an AI agent changes | `agent-quality` |
|
|
208
|
+
| A service does not work, the cause is not obvious | `debug-profile` |
|
|
209
|
+
| Commit, push, PR, merge | `ship` |
|
|
210
|
+
| "Status?" | `work-status` |
|
|
211
|
+
| Review, audit, "why does nothing work" | `spec-audit` |
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# Global work rules: `~/AGENTS.md`, `~/.codex/AGENTS.md`, `~/.claude/CLAUDE.md`
|
|
2
|
+
|
|
3
|
+
Shared by Claude Code and Codex. The three copies above are deployed from the solo-sdd repository (`global/AGENTS.md`): edit in the source that `solo-sdd status` names (the `source:` line), and run `solo-sdd install` (from a clone, `python3 sync.py push`). Pull an edit made in one of the copies with `solo-sdd sync pull global/AGENTS.md`.
|
|
4
|
+
|
|
5
|
+
## 0. Rule order
|
|
6
|
+
|
|
7
|
+
1. At the start of work in any folder, find the local project rules: `AGENTS.md` and `CLAUDE.md` in the current folder and above up to the repository root, `solo-sdd/project.md` (a project with only `openspec/` moves by `solo-sdd import openspec`), `docs/status.md`. Read them yourself, without a reminder. Claude does not pick up `AGENTS.md` automatically, Codex does not pick up `CLAUDE.md`, so read both.
|
|
8
|
+
2. Local rules exist: on any divergence they apply. This file covers only what the local rules are silent about.
|
|
9
|
+
3. No local rules: work entirely by this file. If the work in the folder is more than a one-off edit, suggest `/project-init` in one line.
|
|
10
|
+
4. A direct instruction of the user in the current chat wins over both the local and the global rules.
|
|
11
|
+
|
|
12
|
+
## 1. Communication
|
|
13
|
+
|
|
14
|
+
- Reply in the language the user writes in, including the final report and comments for the user.
|
|
15
|
+
- Briefly. The result first, then the details. Asked for "briefly": 2-3 sentences.
|
|
16
|
+
- Instructions for the user: numbered steps, with the exact name of the button or field ("where to click").
|
|
17
|
+
- Terminal commands: one block that can be pasted whole; with `cd` to a full path; no comments on the same line as a command.
|
|
18
|
+
- Before asking or saying "this does not exist", reread the chat and the project folder: the user may have given it already. When returning to a project or switching agents: `/context-resume`.
|
|
19
|
+
|
|
20
|
+
## 2. Autonomy
|
|
21
|
+
|
|
22
|
+
- Do not ask clarifying questions during the work. Make a reasoned decision and list the decisions made in the report.
|
|
23
|
+
- Ask only before: paid requests, deleting or overwriting data, actions on prod. The question names what exactly will happen, the number of requests and the amount.
|
|
24
|
+
- Whatever you can do yourself, do yourself: running, checking, clicks in the browser, reading logs. Hand manual steps to the user only when you have no access, and say which access exactly.
|
|
25
|
+
- Do not stop while there are unfinished items and no real blocker.
|
|
26
|
+
|
|
27
|
+
### Commands and stopping processes
|
|
28
|
+
|
|
29
|
+
- If a command must not get input, close stdin with `< /dev/null`. Keep pipes, heredocs and intended input; do not run bare `cat`, `read` or interactive interpreters without an input source.
|
|
30
|
+
- Run servers and other long-lived processes as managed background tasks and keep their id. Run ordinary builds and tests with a bounded timeout.
|
|
31
|
+
- After a timeout, first check the task's state with the standard tool. Do not assume all child processes have ended, and do not "clean them up" by name.
|
|
32
|
+
- Do not use `pkill`, `killall`, an arbitrary `kill` (including a numeric PID), `osascript`, `launchctl` or `shutdown` to stop things. Use the built-in stop of the specific task by its id. Managing its processes is the job of the launch environment, which knows what processes it created.
|
|
33
|
+
- Do not force a sandbox on all projects: check that the sandbox is compatible with the project's tests before changing the mode. If the sandbox is on for a project on macOS, dev ports need `sandbox.network.allowLocalBinding: true`. Do not install a build into `/Applications` without separate consent.
|
|
34
|
+
|
|
35
|
+
## 3. What "done" means
|
|
36
|
+
|
|
37
|
+
- "Done" depends on the kind of work:
|
|
38
|
+
- code: done + checked by tests + checked live on a real scenario + recorded by the project rules (changes: validate, archive; git: commit, push, merge);
|
|
39
|
+
- analysis or research: a conclusion, sources with dates, separately what is not confirmed; files do not change;
|
|
40
|
+
- text: facts checked, form and length fit the reader, one ready version;
|
|
41
|
+
- prod: the change is rolled out with consent and checked by the same scenario on prod.
|
|
42
|
+
- Git and the change cycle (`solo-sdd/`) are mandatory where the project and the task provide for them. A one-off text or analysis does not need their cycle.
|
|
43
|
+
- Light path: a code edit needs no change when it changes no behaviour a main spec in `solo-sdd/specs/` describes, adds no dependency, touches no data, migration or deploy, and changes at most `process.light-path.max-files` files. Read `solo-sdd config get process.light-path` and `solo-sdd config get process.light-path.max-files`; no `solo-sdd/` tree or no command: on and 3. Then: the edit, the tests of the edited module, the suite once after the edit, a live check of the edited place, one commit `light: <the request>` (under `delivery.mode: pr` the PR title starts with `light:`). Outside the bounds, a bug in behaviour a spec describes, or `off`: a change.
|
|
44
|
+
- Test runs: while coding only the tests of the edited module (`Tests (one)`); the whole suite (`Tests`) once after the last code edit, again only when code changed after that run; after a red run the failed tests first, the suite once they are green. Quiet output (`-q`, `--reporter=dot`, `--silent`); on a red run read only the failure lines.
|
|
45
|
+
- Tests prove behaviour: a behaviour a live stand proves gets no second test (a required property test and a bug's regression test excepted); a new case is a row of the existing test; no tests for getters, DTOs, configuration, thin wrappers, private functions a scenario test reaches, one-off scripts or what a CI step checks. Doubles only for external I/O (the network, paid APIs) and the clock; own storage gets a temporary real one or an in-memory fake; the module under test is never mocked. An existing assertion changes or goes only when the behaviour it checks changes on purpose (a MODIFIED or REMOVED requirement); a change of setup, cost or layout keeps every assertion.
|
|
46
|
+
- If any of this is missing: write "not done" and what is missing. Green tests by themselves do not mean "done".
|
|
47
|
+
- The report names the checks done and, separately, the ones not done with the reason.
|
|
48
|
+
- The same edit did not help twice: stop and find the cause instead of a third attempt the same way.
|
|
49
|
+
|
|
50
|
+
## 4. Blockers
|
|
51
|
+
|
|
52
|
+
- No key, access or data: first look for a workaround: mocks, old project data, `.env`, neighbouring services, documentation.
|
|
53
|
+
- No workaround: record what stayed unchecked and what is needed for it (in a change, `verification.md` and `docs/waiting.md`), and close everything else.
|
|
54
|
+
|
|
55
|
+
## 5. Status and waiting
|
|
56
|
+
|
|
57
|
+
- Before waiting longer than 2 minutes, say what you wait for and how long.
|
|
58
|
+
- In long work, give a status line after every stage.
|
|
59
|
+
- Answer a status question with the `/work-status` skill.
|
|
60
|
+
|
|
61
|
+
## 6. Task boundaries
|
|
62
|
+
|
|
63
|
+
- Asked to analyse, describe or assess: change nothing.
|
|
64
|
+
- Asked to fix: change only the named places. Do not rewrite from scratch and do not delete previous versions.
|
|
65
|
+
- Work outside the current task becomes a separate task, not done along the way.
|
|
66
|
+
- Do not hard-code lists and values that can be got from the source. Temporary hard-coding only on a direct request.
|
|
67
|
+
|
|
68
|
+
## 7. Money and resources
|
|
69
|
+
|
|
70
|
+
- Search, logs and test output run on cheap models; code, review and acceptance on the main one. Effort first, then the model.
|
|
71
|
+
- Paid calls to the product model in tests, acceptance and experiments run on the cheapest models.
|
|
72
|
+
- Do not start paid requests without approval.
|
|
73
|
+
- An external service is needed: free options and free tiers first.
|
|
74
|
+
- Watch the context: hand heavy reading to a search subagent (Explore), write code yourself.
|
|
75
|
+
|
|
76
|
+
## 8. Secrets and data
|
|
77
|
+
|
|
78
|
+
- Secrets live only in `.env`. Do not print them and do not ask to send them in chat: create an empty field and name it.
|
|
79
|
+
- Keys, certificates and personal data do not go into git or logs.
|
|
80
|
+
- Before an operation on a database or a server, say what will happen to the existing data.
|
|
81
|
+
- Use a fact about experience, a metric or a number from history together with its source, date or period and status: confirmed | from an old record | not checked. Apply new calculation rules to new records; recalculating accumulated data only on a direct request.
|
|
82
|
+
- All project files are kept inside the project folder.
|
|
83
|
+
|
|
84
|
+
## 9. Two agents in one project
|
|
85
|
+
|
|
86
|
+
- The project has one working folder. Create your copies and worktrees in the built-in Claude Code worktree (`claude --worktree <name>`, `EnterWorktree`, `isolation: "worktree"` of a subagent: the copy goes into the project's `.claude/worktrees`; this folder must be in `.gitignore`) or in a temporary folder (`git worktree add "${TMPDIR:-/tmp}/wt-<name>"`) and delete them after yourself. Codex uses only a temporary folder: `codex --worktree`, `/worktree` and the `create_worktree` tool put the copy into `~/.codex/worktrees`.
|
|
87
|
+
- Before an edit, check `git status`: another agent may be working next to you. Do not roll back others' changes.
|
|
88
|
+
- Before taking a change, check for `CLAIM` (taken by another agent) and `WAITING` (waits for an external condition) files in its folder. If either is there, take another.
|
|
89
|
+
- An independent review is done by the agent that did not write the code.
|
|
90
|
+
|
|
91
|
+
## 10. Orchestration
|
|
92
|
+
|
|
93
|
+
- You write the code yourself: every handoff between agents loses precision. Subagents are only for independent acceptance and heavy reading (Explore). Independent changes run in parallel through `spec-dispatch`.
|
|
94
|
+
- Codex executors only when the user named the skill `codex-orchestration`.
|
|
95
|
+
- Plan through `/spec-plan`, debug through `/debug-profile`. In a project with `solo-sdd/` a plugin's own cycle of tests, verification, per-task subagents and code review is not used: `spec-next` and `ship` set the cycle.
|
|
96
|
+
|
|
97
|
+
## 11. Project mode
|
|
98
|
+
|
|
99
|
+
- The mode is set in the local rules: `demo` or `prod`. If not set, decide by the task: a demo, a defence, a prototype, an MVP mean `demo`.
|
|
100
|
+
- `demo`: no docker and no deploy, invented data, one demo script, the run command as the first line of the README.
|
|
101
|
+
- `prod`: logs cover every stage so that the cause of a failure can be found from them; there is a deploy instruction.
|
|
102
|
+
|
|
103
|
+
## 12. Interface
|
|
104
|
+
|
|
105
|
+
- A product interface is handed over after checking it against the mockup and clicking every changed element in the browser, on desktop and on a phone. Skill `/ui-check`.
|
|
106
|
+
- `/ui-check` passes the Hard Gate (antislop rules) with a proof in every line. No `DESIGN.md` with a `Dial` line: the interface is marked "draft without direction".
|
|
107
|
+
- A personal HTML report without a request for external publication: check display and clicks on desktop; an adaptive check is not required.
|
|
108
|
+
|
|
109
|
+
## 13. Git, if the local rules are silent
|
|
110
|
+
|
|
111
|
+
- After checked work: commit and push. Merge an open PR yourself only when the project's settings let the agent merge (`solo-sdd config get delivery.merge-by` is `agent`, or no `solo-sdd/` tree), then update the local main branch; with `human` stop at a green PR: a person merges.
|
|
112
|
+
- No `--force` and no `git reset --hard`.
|
|
113
|
+
- If push or merge triggers a prod deploy (CI, a hook, hosting autodeploy), stop before them and ask. An open PR does not mean a checked prod.
|
|
114
|
+
- Skill `/ship`.
|
|
115
|
+
|
|
116
|
+
## 14. Skills
|
|
117
|
+
|
|
118
|
+
`/spec-plan`: a plan or a bug list into a queue of small changes · `/spec-analyze`: a check of a change before code · `/spec-next`: a change from selection to archive · `/ship`: commit, push, PR, merge · `/work-status`: five lines about the state · `/spec-audit`: an independent check of code against the spec · `/ui-check`: a check of the interface against the mockup · `/copy-check`: product texts for people without AI signs or invented facts · `/project-init`: preparing a new project · `/context-resume`: restore the context before work · `/debug-profile`: debugging a service or a bug in code · `/agent-quality`: AI agent quality by comparison on a set of cases · `/evidence-research`: comparison and choice on checked facts
|
|
119
|
+
|
|
120
|
+
Manual commands, only when the user calls them: `/relay`: another agent's report into work · `/blockers`: blockers and findings into separate changes · `/report`: a summary for a period · `/health`: whether the project's integrations are alive · `/changes`: a table of change states
|
|
121
|
+
|
|
122
|
+
Choose a skill by the goal and the expected result, not by a matching word: "analyse" can be about code, logs or a text. If a tool a skill refers to is not in the current environment, take a fallback source (local history, project files, a notes vault) and do not pass off missing data as a fact.
|
|
123
|
+
|
|
124
|
+
The whole algorithm, with all stages and gates: `~/.local/share/solo-sdd/ALGORITHM.md`. The skills of this algorithm are edited in the source from `solo-sdd status`, in `skills/`, not in the agent folders: `solo-sdd install` deploys them and does not overwrite an edit made in place, but shows it.
|
|
125
|
+
|
|
126
|
+
## 15. Lessons
|
|
127
|
+
|
|
128
|
+
- The user corrected you in a way that applies beyond the current task, or you fixed a bug and found its cause: without asking, write one imperative sentence about the class of cause, not the symptom, with no file or line ("Every async call in a handler is awaited", not "add await in api.py"), into the `## Lessons` section at the end of the project's `AGENTS.md`, creating the section if it is missing. This is part of any task, also under "change nothing" or "only the named places"; if the user forbade edits, the report gives it as `Lesson (not written): <sentence>`. A remark about the current diff only ("rename this variable") is not a lesson.
|
|
129
|
+
- First search `## Lessons` and the rest of that `AGENTS.md`: a lesson an existing line covers refines that line instead of adding one. The section holds at most 20 lines; a 21st means merging or generalising the closest lines in the same edit, also without asking.
|
|
130
|
+
- No `AGENTS.md` in the project: create none; the report gives the lesson as `Lesson (no AGENTS.md): <sentence>`.
|
|
131
|
+
- Never write a lesson into the installed global rules (`~/AGENTS.md`, `~/.codex/AGENTS.md`, `~/.claude/CLAUDE.md`); a lesson about the solo-sdd process itself goes only into the report as `Lesson for solo-sdd: <sentence>`.
|
|
132
|
+
- The report names every line written or refined in `## Lessons` and its file.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_comment": "Model policy for the work_hooks.py guard and stop hooks. Source of the list: ~/.codex/models_cache.json (affordable/fast descriptions) on 2026-10-15. Subagent roles (review, orchestrator, implement, lookup) are taken from an explicit tag at the start of the description (case-insensitive; the orchestrator tag is the word followed by a space or a colon). A reviewer (review) runs without model or on a model from main: review and acceptance are judgement, they run on the main model. Only the owner allows bypassing the model rules: SOLO_SDD_EXPENSIVE_OK=1 in the Claude Code environment. test_markers keeps Russian test words as \\u escapes: prompts may be Russian, the repository holds no Cyrillic. The deployed copy ~/.claude/hooks/model-policy.json is yours: edit the model lists and the browser key there. browser.tools (tool name prefixes), browser.skills (skill names) and browser.bash (plain substrings of a Bash command) add to the hook's built-in browser signs of the stop interface check and cannot remove one; a part that is not a list of non-empty strings adds nothing and writes an errors.log line. install, update and sync.py push skip an edited copy (skipped ... edited in place) and sync.py status shows it as drift, so a newer shipped list is not taken while it is drift. To take it: from a clone, python3 sync.py push --force (the old copy is saved under ~/.local/share/solo-sdd/backup/); from the package, move the copy aside, run solo-sdd update (created) and carry your edits over.",
|
|
3
|
+
"cheap": ["luna", "terra", "reserve", "haiku"],
|
|
4
|
+
"expensive_always": ["astra"],
|
|
5
|
+
"expensive": ["astra", "sol", "opus", "fable"],
|
|
6
|
+
"main": ["opus", "fable"],
|
|
7
|
+
"roles": {"review": ["Review:"], "orchestrator": ["Orchestrator ", "Orchestrator:"], "implement": ["Implement:"], "lookup": ["Lookup:"]},
|
|
8
|
+
"browser": {
|
|
9
|
+
"tools": ["mcp__claude-in-chrome__", "mcp__agent-browser__", "mcp__peekaboo__"],
|
|
10
|
+
"skills": ["ui-check", "agent-browser", "claude-in-chrome", "webapp-testing", "run", "web-perf"],
|
|
11
|
+
"bash": ["agent-browser", "playwright", "puppeteer", "--headless", "chrome-devtools", "screencapture", "--remote-debugging-port", "json/version", "webSocketDebuggerUrl"]
|
|
12
|
+
},
|
|
13
|
+
"test_markers": "(?i)(\\btests?\\b|pytest|vitest|jest|node --test|acceptance|e2e|smoke|eval\\b|benchmark|probe|\u043f\u0440\u0438\u0451\u043c\u043a|\u043f\u0440\u0438\u0435\u043c\u043a|\u043f\u0440\u043e\u0433\u043e\u043d|\u0442\u0435\u0441\u0442)"
|
|
14
|
+
}
|