deepflow 0.1.111 → 0.1.113

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.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: df:discover
3
3
  description: Explore a problem space deeply through structured questioning to surface requirements and constraints
4
- allowed-tools: [AskUserQuestion, Read, Agent]
4
+ allowed-tools: [AskUserQuestion, Agent]
5
5
  ---
6
6
 
7
7
  # /df:discover — Deep Problem Exploration
@@ -148,7 +148,7 @@ Context ≥50% → checkpoint and exit. Before spawning: `TaskUpdate(status: "in
148
148
 
149
149
  **Token tracking start:** Store `start_percentage` (from context.json) and `start_timestamp` (ISO 8601) keyed by task_id. Omit if unavailable.
150
150
 
151
- **NEVER use `isolation: "worktree"`.** Deepflow manages one worktree **per spec** (§1.5). Tasks from the same spec commit to the same branch so wave 2 sees wave 1 commits; tasks from different specs commit to different branches and never interleave. **Spawn ALL ready tasks in ONE message** except file conflicts.
151
+ **Intra-wave isolation:** Each task in a wave runs with `isolation: "worktree"` tasks from the same spec share that spec's worktree branch so wave 2 sees wave 1 commits; tasks from different specs run in different worktrees and never interleave. **Spawn ALL ready tasks in ONE message** except file conflicts.
152
152
 
153
153
  **Per-spec routing (CRITICAL):** Each task in `WAVE_JSON` carries a `spec` field (from `bin/wave-runner.js`). When building the agent prompt (§6), you MUST set `Working directory: ${SPEC_WORKTREES[task.spec].path}` — the worktree for that task's spec, NOT the first spec in the map. Cross-spec contamination (spawning a task from spec B into spec A's worktree) corrupts branch history and breaks `/df:verify`. If `task.spec` is absent from the JSON, fall back to deriving it from the task's mini-plan file `.deepflow/plans/doing-{specName}.md`; if still unresolvable, defer the task and log `"⚠ T{N} deferred — cannot resolve spec"`.
154
154
 
@@ -156,11 +156,26 @@ Context ≥50% → checkpoint and exit. Before spawning: `TaskUpdate(status: "in
156
156
 
157
157
  **≥2 [SPIKE] tasks same problem →** Parallel Spike Probes (§5.7). **[OPTIMIZE] tasks →** Optimize Cycle (§5.9), one at a time. **[INTEGRATION] tasks** (`task.isIntegration === true` in WAVE_JSON) **→** use the Integration Task prompt template (§6 Integration Task), not the Standard Task template. Integration tasks always land in the final wave via `Blocked by:` — wave-runner guarantees this, so they execute after all producer/consumer implementation tasks have committed. Route them to the **consumer spec's** worktree via `SPEC_WORKTREES[task.spec].path` (plan.md §4.8.2 places the integration task under the consumer's section header, so `task.spec` is already the consumer).
158
158
 
159
+ ### 5.1. INTRA-WAVE CHERRY-PICK MERGE
160
+
161
+ After ALL wave-N agents complete, cherry-pick each wave-N commit back to the main branch BEFORE wave N+1 begins. This ensures wave N+1 agents see all wave-N changes regardless of which worktree they run in.
162
+
163
+ **Wave gate:** Wave N+1 MUST NOT start until all wave-N cherry-picks complete.
164
+
165
+ **Ordering:** Apply cherry-picks in ascending task-number order (e.g., T1 before T2 before T3) for determinism.
166
+
167
+ **Steps (per wave completion):**
168
+ 1. Collect all task commits from wave N (from ratchet PASS records).
169
+ 2. Sort commits by ascending task-number order.
170
+ 3. For each commit, spawn haiku context-fork (§5.8): `git cherry-pick {sha}`. Receive one-line summary.
171
+ 4. On conflict: log `"⚠ cherry-pick conflict: {sha} — {file}"`, abort cherry-pick, mark task as needing manual resolution.
172
+ 5. Only after all wave-N cherry-picks finish → proceed to spawn wave N+1 agents.
173
+
159
174
  ### 5.5. RATCHET CHECK
160
175
 
161
- Run `node "${HOME}/.claude/bin/ratchet.js"` in the **task's spec worktree** after each agent completes, using that spec's snapshot file:
176
+ Run `node bin/ratchet.js` in the **task's spec worktree** after each agent completes, using that spec's snapshot file:
162
177
  ```bash
163
- node "${HOME}/.claude/bin/ratchet.js" --worktree ${SPEC_WORKTREES[task.spec].path} --snapshot .deepflow/auto-snapshot-{task.spec}.txt --task T{N}
178
+ node bin/ratchet.js --worktree ${SPEC_WORKTREES[task.spec].path} --snapshot .deepflow/auto-snapshot-{task.spec}.txt --task T{N}
164
179
  ```
165
180
 
166
181
  The script handles all health checks internally and outputs structured JSON:
@@ -187,7 +202,7 @@ The script handles all health checks internally and outputs structured JSON:
187
202
  ```
188
203
  (Fall back to text mode if `--json` is unavailable: `node "${HOME}/.claude/bin/wave-runner.js" --plan PLAN.md --recalc --failed T{N}`)
189
204
  Report: `"✗ T{n}: reverted"`.
190
- - **Exit 2 (SALVAGEABLE):** Spawn `Agent(model="sonnet")` to fix lint/typecheck issues. Re-run `node "${HOME}/.claude/bin/ratchet.js"`. If still non-zero → revert both commits, set status pending.
205
+ - **Exit 2 (SALVAGEABLE):** Spawn `Agent(model="sonnet")` to fix lint/typecheck issues. Re-run `node bin/ratchet.js`. If still non-zero → revert both commits, set status pending.
191
206
 
192
207
  #### 5.5.1. AC COVERAGE CHECK (after ratchet pass)
193
208
 
@@ -207,11 +222,12 @@ where `{spec_path}` is the path to `specs/doing-{spec_name}.md` and `{agent_outp
207
222
 
208
223
  Parse the agent's response for `DECISIONS:` line. If present:
209
224
  1. Split by ` | ` to get individual decisions
210
- 2. Each decision has format `[TAG] description — rationale` where TAG ∈ {APPROACH, PROVISIONAL, ASSUMPTION, FUTURE, UPDATE}
211
- 3. Append to `.deepflow/decisions.md` under `### {date}{spec_name}` header (create header if first decision for this spec today, reuse if exists)
212
- 4. Format: `- [TAG] descriptionrationale`
225
+ 2. If any entry does not start with `[TAG]` where TAG ∈ {APPROACH, PROVISIONAL, ASSUMPTION, FUTURE, UPDATE}, emit SALVAGEABLE and skip writing that entry to decisions.md (valid entries still get written).
226
+ 3. Each decision has format `[TAG] descriptionrationale` where TAG {APPROACH, PROVISIONAL, ASSUMPTION, FUTURE, UPDATE}
227
+ 4. Append to `.deepflow/decisions.md` under `### {date} {spec_name}` header (create header if first decision for this spec today, reuse if exists)
228
+ 5. Format: `- [TAG] description — rationale`
213
229
 
214
- If no `DECISIONS:` line in agent output → skip silently (mechanical tasks don't produce decisions).
230
+ If no `DECISIONS:` line in agent output and the task effort is not `low` emit SALVAGEABLE (non-trivial tasks without a decision line may indicate the agent skipped documenting architectural choices). For tasks with effort `low`, skip silently (mechanical tasks don't produce decisions).
215
231
 
216
232
  **This runs on every ratchet pass, not just at verify time.** Decisions are captured incrementally as tasks complete, so they're never lost even if verify fails or merge is manual.
217
233
 
@@ -232,6 +248,20 @@ tokens:
232
248
  ```
233
249
  Omit if context.json/token-history.jsonl/awk unavailable. Never fail ratchet for tracking errors.
234
250
 
251
+ ### 5.6. WAVE TEST AGENT
252
+
253
+ Trigger: task type is [TEST] or orchestrator spawns a dedicated test-writing agent for a wave.
254
+
255
+ Before spawning the test agent, collect context:
256
+ ```bash
257
+ SNAPSHOT_FILES=!`cat .deepflow/auto-snapshot.txt 2>/dev/null || echo ''`
258
+ EXISTING_TEST_NAMES=!`grep -h -E "^\s*(it|test|describe)\(" ${SNAPSHOT_FILES} 2>/dev/null | sed "s/^[[:space:]]*//" || echo ''`
259
+ ```
260
+
261
+ Pass `SNAPSHOT_FILES` and `EXISTING_TEST_NAMES` into the agent prompt so it can avoid duplication.
262
+
263
+ **Implementation diff:** The wave test agent reads the implementation diff itself using the `Read` tool or `git diff` — do NOT capture or pass the raw diff to the wave test prompt inline. Injecting large diffs inflates context and causes rot.
264
+
235
265
  ### 5.7. PARALLEL SPIKE PROBES
236
266
 
237
267
  Trigger: ≥2 [SPIKE] tasks with same blocker or identical hypothesis.
@@ -399,7 +429,7 @@ Success criteria: {ACs from spec relevant to this task}
399
429
  {If spec contains ## Domain Model section:
400
430
  --- CONTEXT: Domain Model ---
401
431
  {Domain Model section content from doing-*.md, extracted via shell injection:
402
- DOMAIN_MODEL=!`sed -n '/^## Domain Model$/,/^## [^D]/p' specs/doing-{spec_name}.md | head -n -1 2>/dev/null || echo 'NOT_FOUND'`
432
+ DOMAIN_MODEL=!`sed -n '/^## Domain Model$/,/^## /p' specs/doing-{spec_name}.md | head -n -1 2>/dev/null || echo 'NOT_FOUND'`
403
433
  }
404
434
  }
405
435
  {If EXISTING_TYPES is non-empty:
@@ -421,7 +451,7 @@ AC-2:skip:reason here (if applicable)
421
451
  AC_COVERAGE_END
422
452
  ```
423
453
  Format: one line per AC with either `AC-N:done` or `AC-N:skip:reason`. Omit this block if the spec has no acceptance criteria.
424
- DECISIONS: If you made non-obvious choices, append to the LAST LINE BEFORE TASK_STATUS:
454
+ DECISIONS: If you made non-obvious choices, cite with [APPROACH]. Append to the LAST LINE BEFORE TASK_STATUS:
425
455
  DECISIONS: [TAG] {decision} — {rationale} | [TAG] {decision2} — {rationale2}
426
456
  Tags:
427
457
  [APPROACH] — chose X over Y (architectural/design choice)
@@ -430,6 +460,7 @@ Tags:
430
460
  [FUTURE] — deferred X because Y; revisit when Z
431
461
  [UPDATE] — changed prior decision from X to Y because Z
432
462
  Skip for trivial/mechanical changes.
463
+ Files: List every file you modified or created, one per line, in the format `Files: path/to/file.ts, path/to/other.ts`. This is required so the orchestrator can detect file conflicts across concurrent tasks.
433
464
  Last line of your response MUST be: TASK_STATUS:pass (if successful) or TASK_STATUS:fail (if failed) or TASK_STATUS:revert (if reverted)
434
465
  ```
435
466
 
@@ -442,6 +473,7 @@ Integration ACs: {list from PLAN.md}
442
473
  Specs involved: {spec file paths}
443
474
  Interface Map: {from integration task detail}
444
475
  Contract Risks: {from integration task detail}
476
+ LSP documentSymbol on Impact files → Read with offset/limit on relevant ranges only (never read full files)
445
477
  --- END ---
446
478
  RULES:
447
479
  - Fix the CONSUMER to match the PRODUCER's declared interface. Never weaken the producer.
@@ -464,7 +496,28 @@ Last line: TASK_STATUS:pass or TASK_STATUS:fail
464
496
 
465
497
  **Bootstrap:** `BOOTSTRAP: Write tests for edit_scope files. Do NOT change implementation. Commit as test({spec}): bootstrap. Last line: TASK_STATUS:pass or TASK_STATUS:fail`
466
498
 
467
- **Spike:** `{task_id} [SPIKE]: {hypothesis}. Files+Spec. {reverted warnings}. Minimal spike. Commit as spike({spec}): {desc}. If you discovered constraints, rejected approaches, or made assumptions, report: DECISIONS: [TAG] {finding} — {why it matters} (use PROVISIONAL for "works but needs revisit", ASSUMPTION for "assumed X; if wrong Y breaks", APPROACH for definitive choices). Last line: TASK_STATUS:pass or TASK_STATUS:fail`
499
+ **Wave Test** (`Agent(model="sonnet")`):
500
+ ```
501
+ --- START ---
502
+ {task_id} [TEST]: Write tests for {spec_name}. Files+Spec.
503
+ Pre-existing test files:
504
+ {SNAPSHOT_FILES}
505
+
506
+ Existing test function names (do NOT duplicate these):
507
+ {EXISTING_TEST_NAMES}
508
+ --- MIDDLE ---
509
+ Spec: {spec_path}
510
+ Edit scope: {edit_scope}
511
+ --- END ---
512
+ RULES:
513
+ - Use the `Read` tool (or `git diff HEAD~1`) to inspect what the implementation changed before writing tests.
514
+ - Do not duplicate tests that already exist in the pre-existing test files listed above.
515
+ - Do not modify pre-existing test files — write new test files only.
516
+ - Commit as test({spec}): {description}.
517
+ Last line of your response MUST be: TASK_STATUS:pass (if successful) or TASK_STATUS:fail (if failed)
518
+ ```
519
+
520
+ **Spike**: `{task_id} [SPIKE]: {hypothesis}. Files+Spec. {reverted warnings}. Minimal spike. Commit as spike({spec}): {desc}. If you discovered constraints, rejected approaches, or made assumptions, report: DECISIONS: [TAG] {finding} — {why it matters} (use PROVISIONAL for "works but needs revisit", ASSUMPTION for "assumed X; if wrong Y breaks", APPROACH for definitive choices). Last line: TASK_STATUS:pass or TASK_STATUS:fail`
468
521
 
469
522
  **Optimize Task** (`Agent(model="opus")`):
470
523
  ```
@@ -474,6 +527,7 @@ Current: {val} (baseline: {b}, best: {best}). Target: {t} ({dir}). Metric: {cmd}
474
527
  CONSTRAINT: ONE atomic change.
475
528
  --- MIDDLE ---
476
529
  Last 5 cycles + failed hypotheses + Impact/deps.
530
+ LSP documentSymbol on Impact files → Read with offset/limit on relevant ranges only (never read full files)
477
531
  --- END ---
478
532
  {Learnings}. ONE change + commit. No metric run, no multiple changes.
479
533
  Last line of your response MUST be: TASK_STATUS:pass or TASK_STATUS:fail or TASK_STATUS:revert
@@ -489,6 +543,7 @@ Current/Target. Role instruction:
489
543
  ingenua: "Ignore prior. Fresh approach."
490
544
  --- MIDDLE ---
491
545
  Full history + all failed hypotheses.
546
+ LSP documentSymbol on Impact files → Read with offset/limit on relevant ranges only (never read full files)
492
547
  --- END ---
493
548
  ONE atomic change. Commit. STOP.
494
549
  Last line of your response MUST be: TASK_STATUS:pass or TASK_STATUS:fail or TASK_STATUS:revert
@@ -230,7 +230,7 @@ You are a spec planner. Your job is to independently analyze a spec and produce
230
230
  2. **Compute spec layer** — determine L0–L3 based on sections present (see layer rules below)
231
231
  3. **Check experiments** — glob `.deepflow/experiments/{topic}--*` for past spikes
232
232
  4. **Explore the codebase** — detect code style, patterns, integration points relevant to this spec
233
- 5. **Impact analysis** (L3 only) — LSP-first blast radius for files in scope
233
+ 5. **Impact analysis** (L3 only) — LSP documentSymbol on impact files Read with offset/limit on relevant ranges only (never read full files)
234
234
  6. **Targeted exploration** — follow `templates/explore-agent.md` spawn rules for post-LSP gaps
235
235
  7. **Generate tasks** — produce a mini-plan following the output format below
236
236
 
@@ -402,10 +402,9 @@ The reasoner prompt:
402
402
  ```
403
403
  You are the plan reasoner. Analyze this spec and produce a prioritized task plan.
404
404
 
405
- ## Spec file path
406
- {spec_path}
407
-
408
- Read the spec using the Read tool on the path above. Do NOT read any implementation files.
405
+ ## Spec content
406
+ <!-- {spec_content} — injected by orchestrator before spawning; do NOT use Read tool on the spec -->
407
+ {spec_content}
409
408
 
410
409
  ## Agent summaries (from §3 parallel agents)
411
410
 
@@ -55,6 +55,7 @@ Spawn reasoner agent (`subagent_type: "reasoner"`, `model: "opus"`). The reasone
55
55
  - Flags conflicts with existing code
56
56
  - Verifies every REQ-N has a corresponding AC; flags uncovered requirements
57
57
  - Flags vague/untestable requirements (e.g., "should be fast" without a metric)
58
+ - If Explore agents found type definitions or interfaces relevant to this spec, include a ## Domain Model section with Key Types (signatures only) and Ubiquitous Language (domain terms). Omit if no relevant types found.
58
59
 
59
60
  ### 4. GENERATE SPEC
60
61
 
@@ -0,0 +1,205 @@
1
+ ---
2
+ name: repo-inspect
3
+ description: Produces structured JSON intelligence for a remote GitHub repo — fetches metadata and file tree via gh api, reads key files via WebFetch. No local clone. Use when evaluating an unfamiliar repo before planning integration work.
4
+ context: fork
5
+ allowed-tools: [Bash, WebFetch]
6
+ ---
7
+
8
+ # Repo-Inspect
9
+
10
+ Inspect a GitHub repository and emit a single JSON object describing its architecture. No clones, no tmpdir, no local filesystem writes.
11
+
12
+ **Input:** `{owner}/{repo}` or a full GitHub URL (e.g., `https://github.com/owner/repo`).
13
+ **Output:** Raw JSON only — no markdown, no commentary.
14
+
15
+ ---
16
+
17
+ ## Protocol
18
+
19
+ ### Step 0 — Parse Input
20
+
21
+ Strip `https://github.com/` prefix if present. Extract `{owner}` and `{repo}` from the remaining `owner/repo` string.
22
+
23
+ ### Step 1 — Fetch Repo Metadata (1 Bash call)
24
+
25
+ ```bash
26
+ gh api repos/{owner}/{repo}
27
+ ```
28
+
29
+ Extract: `description`, `language`, `topics`, `default_branch`, `stargazers_count`, `forks_count`.
30
+
31
+ On error (non-zero exit or JSON with `message` field indicating 404/403):
32
+ ```json
33
+ {"error": "api_failed", "message": "<gh api error text>"}
34
+ ```
35
+ Stop and return this error JSON immediately.
36
+
37
+ ### Step 2 — Fetch Full File Tree (1 Bash call)
38
+
39
+ ```bash
40
+ gh api "repos/{owner}/{repo}/git/trees/{default_branch}?recursive=1"
41
+ ```
42
+
43
+ Parse `tree[]` array. Each item has: `path`, `type` (`blob`|`tree`), `size`.
44
+
45
+ If tree is truncated (`truncated: true`), note it but proceed — the tree API returns up to ~100K entries which covers virtually all repos.
46
+
47
+ ### Step 3 — Language Detection
48
+
49
+ Scan tree paths for manifest files in priority order:
50
+
51
+ | Manifest | Language |
52
+ |---|---|
53
+ | `Cargo.toml` | Rust |
54
+ | `package.json` | JavaScript/TypeScript |
55
+ | `pyproject.toml` or `setup.py` or `requirements.txt` | Python |
56
+ | `go.mod` | Go |
57
+ | `pom.xml` or `build.gradle` | Java |
58
+ | `mix.exs` | Elixir |
59
+ | `Gemfile` | Ruby |
60
+ | `build.zig` | Zig |
61
+ | `CMakeLists.txt` | C/C++ |
62
+
63
+ Use the **first match** (highest priority). If no manifest found, fall back to `language` field from Step 1 metadata.
64
+
65
+ Record: `detected_language`, `manifest_path` (path of matched manifest, or null).
66
+
67
+ ### Step 4 — File Selection (3–6 files)
68
+
69
+ Build a prioritized list of files to fetch. Select 3–6 total:
70
+
71
+ 1. **README** — find `README.md` or `README.rst` or `README` in tree root (depth 0). Always include if present.
72
+ 2. **Manifest** — the manifest file detected in Step 3. Always include if present.
73
+ 3. **Primary entry point** — search tree for (in order): `src/main.*`, `src/lib.*`, `src/index.*`, `index.*`, `app.*`, `main.*`. Pick the first match at the shallowest depth.
74
+ 4. **Supplemental files** — from remaining blobs: prefer shallowest paths, then largest `size`. Pick source files (`.rs`, `.ts`, `.js`, `.py`, `.go`, `.java`, `.ex`, `.rb`, `.zig`, `.c`, `.cpp`, `.h`). Fill up to 6 total.
75
+
76
+ For monorepos (detected when tree contains `packages/*/`, `crates/*/`, `apps/*/` directories, or manifest workspace field): select 1-2 representative sub-package manifests/entry points instead of generic supplemental files.
77
+
78
+ ### Step 5 — Fetch File Contents (3–6 WebFetch calls)
79
+
80
+ For each selected file path, fetch:
81
+
82
+ ```
83
+ https://raw.githubusercontent.com/{owner}/{repo}/{default_branch}/{path}
84
+ ```
85
+
86
+ Use WebFetch. If a fetch fails (404 or network error), skip that file and note it. Do not retry.
87
+
88
+ Collect: list of `{path, content}` pairs for all successfully fetched files.
89
+
90
+ ### Step 6 — Extract Intelligence from Fetched Content
91
+
92
+ From manifest content (if fetched):
93
+
94
+ - **dependency_count**: Count entries in `[dependencies]` (Cargo.toml), `dependencies` + `devDependencies` keys (package.json), `[tool.poetry.dependencies]` (pyproject.toml), `require` directives (go.mod/Gemfile), `<dependency>` tags (pom.xml). Use 0 if manifest not fetched.
95
+ - **test_framework**: Check dev-dependencies for known test frameworks:
96
+ - JS/TS: `jest`, `vitest`, `mocha`, `jasmine`, `tap`, `ava`
97
+ - Python: `pytest`, `unittest` (stdlib), `nose`
98
+ - Rust: built-in (`#[test]`), `rstest`, `proptest`
99
+ - Go: built-in (`testing` package)
100
+ - Java: `junit`, `testng`
101
+ - Ruby: `rspec`, `minitest`
102
+ - Elixir: built-in (`ExUnit`)
103
+ Also check tree for `test/`, `tests/`, `spec/`, `__tests__/` directories as corroboration.
104
+ - **monorepo**: true if tree contains at least 2 of `packages/`, `crates/`, `apps/`, `libs/` top-level dirs, OR if manifest has workspace/workspaces field.
105
+
106
+ From README content (if fetched):
107
+ - Extract the first non-heading paragraph as a candidate for `purpose`. Trim to ≤ 200 chars.
108
+
109
+ Fallback for `purpose`: use repo `description` from Step 1 metadata.
110
+
111
+ ### Step 7 — Derive key_modules
112
+
113
+ From the tree blob paths, identify directories containing 2+ source files (files with extensions `.rs`, `.ts`, `.js`, `.tsx`, `.jsx`, `.py`, `.go`, `.java`, `.ex`, `.rb`, `.zig`, `.c`, `.cpp`, `.h`, `.swift`, `.kt`).
114
+
115
+ Algorithm:
116
+ 1. For each blob, extract parent directory path.
117
+ 2. Count source files per directory.
118
+ 3. Keep directories with count >= 2.
119
+ 4. Sort by file count descending, then by path depth ascending (shallower = more significant).
120
+ 5. Take up to 10 modules.
121
+ 6. Strip common prefixes (e.g., if all modules share `src/`, keep `src/` as a module too).
122
+
123
+ Return directory names (last path segment) for the `key_modules` array. If fewer than 3 candidate directories exist, include directories with 1 source file to reach 3, or return what's available.
124
+
125
+ ### Step 8 — Derive concepts_applicable
126
+
127
+ Based on language, test framework, monorepo status, and key module names, suggest applicable engineering concepts. Examples:
128
+
129
+ - Monorepo → `"workspace-management"`, `"cross-package-testing"`
130
+ - Rust → `"ownership-model"`, `"cargo-workspace"` (if monorepo)
131
+ - TypeScript → `"type-safety"`, `"module-resolution"`
132
+ - Has `auth` module → `"authentication-patterns"`
133
+ - Has `db` or `models` module → `"data-modeling"`
134
+ - Has `api` or `routes` module → `"rest-api-design"`
135
+ - Has tests → `"tdd"` or `"bdd"` (if rspec/jasmine)
136
+
137
+ Limit to 3–7 concepts. These are suggestions for the caller — not exhaustive.
138
+
139
+ ### Step 9 — Confidence Score
140
+
141
+ Set `confidence` based on data quality:
142
+
143
+ | Condition | Confidence |
144
+ |---|---|
145
+ | README + manifest + entry point all fetched | `high` |
146
+ | README or manifest fetched, but not both | `medium` |
147
+ | Neither README nor manifest fetched | `low` |
148
+
149
+ ### Step 10 — Emit JSON Output
150
+
151
+ Output **exactly one JSON object** with no surrounding text, no markdown code fences, no comments:
152
+
153
+ ```json
154
+ {
155
+ "repo": "{owner}/{repo}",
156
+ "purpose": "<first non-heading README paragraph or repo description, ≤200 chars>",
157
+ "architecture": {
158
+ "language": "<detected language>",
159
+ "entry_points": ["<relative paths of main/lib/index files>"],
160
+ "key_modules": ["<directory names with 2+ source files>"],
161
+ "dependencies_count": 0,
162
+ "test_framework": "<framework name or 'unknown'>"
163
+ },
164
+ "concepts_applicable": ["<concept1>", "<concept2>"],
165
+ "files_inspected": ["<path1>", "<path2>"],
166
+ "confidence": "high|medium|low"
167
+ }
168
+ ```
169
+
170
+ **Critical:** The very last thing you output must be this JSON object and nothing else. Do not wrap in code blocks. Do not add explanation.
171
+
172
+ ---
173
+
174
+ ## Error Handling
175
+
176
+ | Scenario | Action |
177
+ |---|---|
178
+ | `gh api` returns non-zero exit for metadata | Return `{"error": "api_failed", "message": "<stderr>"}` and stop |
179
+ | `gh api` returns 404 JSON | Return `{"error": "api_failed", "message": "Repository not found or not accessible"}` |
180
+ | Tree fetch fails | Return `{"error": "tree_failed", "message": "<stderr>"}` and stop |
181
+ | All WebFetch calls fail | Set confidence to "low", proceed with tree-only analysis |
182
+ | Single WebFetch fails | Skip file, continue |
183
+
184
+ ---
185
+
186
+ ## Efficiency Budget
187
+
188
+ - `gh api` calls: exactly 2 (metadata + tree)
189
+ - WebFetch calls: 3–6 (selected files)
190
+ - Analysis steps: ~5 (no extra Bash calls needed)
191
+ - **Total tool calls: ≤ 20**
192
+ - **Wall time: ≤ 60s**
193
+ - **Tokens: ≤ 30K**
194
+
195
+ Do not make extra `gh api` calls. Do not fetch files not in the selection list. The tree endpoint returns all paths in one call — no Glob, no Read, no additional listing needed.
196
+
197
+ ---
198
+
199
+ ## Rules
200
+
201
+ - Never write to local filesystem (no `> file`, no `mktemp`, no `git clone`).
202
+ - Never use Read, Glob, or Grep tools — this skill operates on remote data only.
203
+ - Output raw JSON only — the caller parses it, not reads it as prose.
204
+ - Private repos work automatically via `gh auth` stored token.
205
+ - Strip `context: fork` means this skill's token usage doesn't pollute the caller's context.
@@ -96,6 +96,9 @@ quality:
96
96
  # Timeout in seconds to wait for the dev server to become ready (default: 30)
97
97
  browser_timeout: 30
98
98
 
99
+ # Minimum quality score threshold for harness verification (0.0-1.0, default: 0.6)
100
+ harness_min_score: 0.6
101
+
99
102
  # Ratchet configuration for /df:verify health gate
100
103
  # Ratchet snapshots baseline metrics (tests passing, coverage, type checks) before execution
101
104
  # and ensures subsequent runs don't regress. These overrides control which commands ratchet monitors.
@@ -43,6 +43,23 @@
43
43
 
44
44
  - [Explicitly excluded: e.g., "Video upload is NOT included"]
45
45
 
46
+ ## Domain Model
47
+
48
+ <!-- Optional. Define the core entities and vocabulary. -->
49
+
50
+ ### Key Types
51
+
52
+ ```typescript
53
+ // Core domain types and entities
54
+ ```
55
+
56
+ ### Ubiquitous Language
57
+
58
+ - **Term**: Definition
59
+ - **Term**: Definition
60
+
61
+ _Note: Keep to max 15 terms for clarity._
62
+
46
63
  ## Acceptance Criteria
47
64
 
48
65
  - [ ] [Testable criterion: e.g., "User can upload jpg/png/webp files"]