Skip to content

Commit be30691

Browse files
feat(be38-5524): GREEN — rewrite onboarding skill for auto-detection and Socratic dialogue
Rewrite Phase 1 (Auto-Detection) to read project files (package.json, .husky/, .github/workflows/, pyproject.toml, test dirs) before asking questions. Rewrite Phase 2 (Socratic Dialogue) to replace all 34 rigid multiple-choice menus with open-ended questions and confirmations. Add complete config generation with all 8 required keys (dso.plugin_root as absolute path, format.*, test_gate.test_dirs, commands.validate, tickets.directory, checkpoint.marker_file, review.behavioral_patterns as semicolon-delimited globs). Add fallback behavior, CI workflow filename confirmation, config merge with existing, and Jira bridge project key configuration. 30/30 structural tests pass. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent d25cf48 commit be30691

File tree

2 files changed

+181
-63
lines changed

2 files changed

+181
-63
lines changed

plugins/dso/skills/onboarding/SKILL.md

Lines changed: 180 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -48,16 +48,42 @@ The onboarding session probes seven areas. Track your progress through each:
4848

4949
## Phase 1: Auto-Detection (/dso:onboarding)
5050

51-
**Goal:** Pre-fill as many answers as possible before asking the user anything.
51+
**Goal:** Pre-fill as many answers as possible by reading project files BEFORE asking the user anything.
5252

53-
### Step 1: Run Project Detection
53+
### Step 1: Read Project Files for Auto-Detection
54+
55+
Before asking any questions, scan the project filesystem to gather facts:
5456

5557
```bash
5658
REPO_ROOT=$(git rev-parse --show-toplevel)
5759

58-
# Detect stack and test suites
60+
# 1. Detect stack and test suites via DSO scripts
5961
DETECT_OUT=$(bash "$REPO_ROOT/.claude/scripts/dso project-detect.sh" "$REPO_ROOT" 2>/dev/null || echo "")
6062
STACK_OUT=$(bash "$REPO_ROOT/.claude/scripts/dso detect-stack.sh" "$REPO_ROOT" 2>/dev/null || echo "unknown")
63+
64+
# 2. Read specific project files to fill understanding areas
65+
# Node / JavaScript ecosystem
66+
[ -f "$REPO_ROOT/package.json" ] && PACKAGE_JSON=$(cat "$REPO_ROOT/package.json" 2>/dev/null)
67+
# Python ecosystem
68+
[ -f "$REPO_ROOT/pyproject.toml" ] && PYPROJECT=$(cat "$REPO_ROOT/pyproject.toml" 2>/dev/null)
69+
70+
# 3. Detect pre-commit hooks
71+
HUSKY_HOOK=""
72+
[ -f "$REPO_ROOT/.husky/pre-commit" ] && HUSKY_HOOK=$(cat "$REPO_ROOT/.husky/pre-commit" 2>/dev/null)
73+
[ -f "$REPO_ROOT/.pre-commit-config.yaml" ] && PRECOMMIT_CONFIG=$(cat "$REPO_ROOT/.pre-commit-config.yaml" 2>/dev/null)
74+
75+
# 4. Discover CI workflows — list actual filenames before asking about workflow names
76+
CI_WORKFLOWS=""
77+
if [ -d "$REPO_ROOT/.github/workflows" ]; then
78+
CI_WORKFLOWS=$(ls "$REPO_ROOT/.github/workflows"/*.yml "$REPO_ROOT/.github/workflows"/*.yaml 2>/dev/null | xargs -I{} basename {})
79+
fi
80+
81+
# 5. Discover test directories
82+
TEST_DIRS=""
83+
for candidate in tests test spec __tests__ src/__tests__; do
84+
[ -d "$REPO_ROOT/$candidate" ] && TEST_DIRS="$TEST_DIRS $candidate"
85+
done
86+
TEST_DIRS="${TEST_DIRS# }" # trim leading space
6187
```
6288

6389
Run `project-detect.sh` to discover test suites, CI configuration, and project conventions. Note which understanding areas are already answered by the detection output so you can skip or confirm rather than ask from scratch.
@@ -73,6 +99,11 @@ cat > "$SCRATCHPAD" <<EOF
7399
## Auto-detected
74100
Stack: $STACK_OUT
75101
Detection output: $DETECT_OUT
102+
package.json: ${PACKAGE_JSON:+present}
103+
pyproject.toml: ${PYPROJECT:+present}
104+
.husky/ pre-commit hook: ${HUSKY_HOOK:+present}
105+
CI workflow filenames: ${CI_WORKFLOWS:-none found}
106+
Test directories: ${TEST_DIRS:-none found}
76107
EOF
77108
```
78109

@@ -83,35 +114,43 @@ echo "## $AREA_NAME" >> "$SCRATCHPAD"
83114
echo "$USER_ANSWER" >> "$SCRATCHPAD"
84115
```
85116

86-
### Step 3: Summarize What You Know
117+
### Step 3: Present Detected Configuration for Confirmation
87118

88-
Before asking any questions, present a brief summary of what auto-detection found:
119+
Before asking any questions, present what was found and ask the user to confirm or correct:
89120

90121
```
91122
I've scanned the project and found:
92123
- Stack: [detected stack or "unknown"]
93124
- Test suites: [detected suites or "none detected"]
94-
- CI: [detected CI config or "none detected"]
125+
- Test directories: [TEST_DIRS or "none found"]
126+
- CI workflow filenames: [CI_WORKFLOWS or "none found"]
127+
- Pre-commit hooks: [.husky/ present / .pre-commit-config.yaml present / "none"]
128+
- package.json: [present / not found]
129+
- pyproject.toml: [present / not found]
95130
96-
I'll ask about the areas where I need more context. This should take 5–10 minutes.
131+
Does this look right, or is anything missing?
97132
```
98133

134+
Wait for the user to confirm or correct before continuing. Update the scratchpad with any corrections, then proceed to Phase 2 for areas still needing clarification.
135+
99136
---
100137

101138
## Phase 2: Socratic Dialogue Loop (/dso:onboarding)
102139

103-
**Goal:** Fill gaps in the 7 understanding areas through focused, conversational questions.
140+
**Goal:** Fill gaps in the 7 understanding areas through focused, conversational questions. Present detected configuration for confirmation rather than asking open-ended discovery questions.
104141

105142
### Dialogue Rules
106143

107144
**One question at a time** — never present multiple questions in a single message. Pick the most important unknown and ask about it.
108145

109-
**Prefer multiple-choice questions** over open-ended when possible — they're faster to answer and produce more consistent results.
146+
**Confirmation over discovery** when detection already answered an area, present the detected value and ask the user to confirm or correct it. Do not ask from scratch.
110147

111148
**Skip confirmed areas** — if detection already answered an area with confidence, confirm briefly ("I see you're using pytest — is that the main test runner?") rather than asking from scratch.
112149

113150
**Use "Tell me more about..."** to go deeper when an answer is vague or incomplete.
114151

152+
**No rigid menus** — use open-ended questions with natural follow-ups rather than lettered option lists. Ask what the user does, not which letter they pick.
153+
115154
### Question Guide by Area
116155

117156
Work through each area in the checklist order, but adapt based on what detection already found.
@@ -120,79 +159,68 @@ Work through each area in the checklist order, but adapt based on what detection
120159

121160
Ask about: primary language and version, framework (if any), package manager, runtime target.
122161

123-
Example question:
162+
If `package.json` was found, present the detected Node/JavaScript stack for confirmation:
163+
```
164+
I see a package.json — it looks like this is a [framework] project using Node [version]. Is that right? What version are you targeting, and is there anything about the runtime or package manager I should know?
165+
```
166+
167+
If `pyproject.toml` was found, present the detected Python stack for confirmation:
168+
```
169+
I see a pyproject.toml — it looks like a Python project. What version are you targeting, and are you using poetry, pip, or something else?
170+
```
171+
172+
For unknown stacks, ask openly:
124173
```
125-
I detected this looks like a Python project. Which version are you targeting?
126-
a) Python 3.11
127-
b) Python 3.12
128-
c) Python 3.13
129-
d) Other (please specify)
174+
What language and runtime is this project built on? And what's the primary framework or library, if any?
130175
```
131176

132177
#### 2. commands
133178

134179
Ask about: how to run tests, how to start the dev server, how to lint/format, any project-specific Makefile targets.
135180

136-
Example question:
181+
Present detected test directories for confirmation:
137182
```
138-
How do you run the test suite locally?
139-
a) make test
140-
b) pytest / poetry run pytest
141-
c) npm test / yarn test
142-
d) Other (please describe)
183+
I found these test directories: [TEST_DIRS]. How do you actually run the test suite — is there a make target, a script, or do you run the test runner directly?
143184
```
144185

145186
#### 3. architecture
146187

147188
Ask about: top-level module layout, key service boundaries, any notable design patterns (event sourcing, CQRS, hexagonal, etc.), where the main entry point is.
148189

149-
Example question:
190+
Ask openly:
150191
```
151-
How would you describe the top-level structure?
152-
a) Monolith — single deployable unit
153-
b) Monorepo — multiple packages/services in one repo
154-
c) Microservices — separate repos per service
155-
d) Plugin architecture — core + extension plugins
192+
How would you describe the top-level structure of this project — is it a single deployable unit, a monorepo, or something else? What's the main entry point?
156193
```
157194

158195
#### 4. infrastructure
159196

160197
Ask about: where it runs (cloud provider, on-prem, local-only), databases used, external services or APIs it calls, how secrets are managed.
161198

162-
Example question:
199+
Ask openly:
163200
```
164-
Where does this project run in production?
165-
a) AWS
166-
b) GCP / Google Cloud
167-
c) Azure
168-
d) Local / self-hosted
169-
e) No production deployment yet
201+
Where does this project run in production, and what external services or databases does it depend on? How are secrets managed?
170202
```
171203

172204
#### 5. CI
173205

174-
Ask about: which CI provider, what gates must pass before merge, whether there are separate fast/slow test pipelines, deployment pipeline stages.
206+
List the actual `.github/workflows/*.yml` filenames discovered in Step 1. Use those filenames to confirm the CI workflow name rather than asking the user to type it from memory.
207+
208+
```
209+
I found these workflow filenames: [CI_WORKFLOWS]. Which one is your primary CI gate — the one that runs on pull requests?
210+
```
175211

176-
Example question:
212+
If no workflows were found:
177213
```
178-
Which CI system does this project use?
179-
a) GitHub Actions
180-
b) CircleCI
181-
c) GitLab CI
182-
d) Jenkins
183-
e) No CI configured yet
214+
I don't see any CI workflows yet. What CI system are you planning to use, if any?
184215
```
185216

186217
#### 6. design
187218

188219
Ask about: whether there is a UI layer, which framework/library is used, any established design system, accessibility targets.
189220

190-
Example question:
221+
Ask openly:
191222
```
192-
Does this project have a UI/frontend layer?
193-
a) Yes — web UI (ask follow-up about framework)
194-
b) Yes — native/mobile UI
195-
c) No — it's a backend service or CLI tool
223+
Does this project have a UI or frontend layer? If so, what framework are you using and is there an established design system?
196224
```
197225

198226
##### Design Questions: Conditional Activation (UI Projects Only)
@@ -211,24 +239,30 @@ c) No — it's a backend service or CLI tool
211239

212240
5. **Visual language**: "Describe the intended visual feel in 3 adjectives. (e.g., 'Trustworthy, Dense, Clinical' or 'Playful, Round, Airy')"
213241

214-
6. **Accessibility**: "Is the target accessibility standard WCAG AA or AAA?"
242+
6. **Accessibility**: "What's your target accessibility standard WCAG AA, WCAG AAA, or something else?"
215243

216244
After completing these design questions, append findings to the scratchpad under a `## Design (Extended)` section.
217245

218246
#### 7. enforcement
219247

220248
Ask about: linting tools, commit message conventions, pre-commit hooks in use, code review requirements, test coverage policies.
221249

222-
Example question:
250+
Present detected hooks for confirmation:
223251
```
224-
Which enforcement tools are active?
225-
a) Pre-commit hooks (e.g., ruff, eslint, husky)
226-
b) CI lint gate only
227-
c) Code review required before merge
228-
d) All of the above
229-
e) None / minimal enforcement
252+
I see [.husky/pre-commit present / .pre-commit-config.yaml present / no hooks detected]. What enforcement tools are active — any linters, commit message conventions, or code review requirements a new contributor would need to know?
230253
```
231254

255+
#### 8. Jira Bridge
256+
257+
Ask whether the project uses Jira and, if so, confirm the project key:
258+
259+
```
260+
Does this project use Jira for issue tracking? If so, what's the Jira project key (e.g., "MYAPP" or "DSO")?
261+
Note: credentials (JIRA_URL, JIRA_USER, JIRA_API_TOKEN) stay as environment variables — only the project key goes in config.
262+
```
263+
264+
If the user provides a Jira project key, write `jira.project_key=<KEY>` to `.claude/dso-config.conf`. The Jira Bridge connects DSO to Jira via the `JIRA_URL` environment variable.
265+
232266
### Phase 2 Gate
233267

234268
When all 7 areas have at least a basic answer recorded in the scratchpad, ask:
@@ -374,12 +408,82 @@ This file is intentionally brief — it records what was learned during onboardi
374408

375409
After writing `.claude/project-understanding.md`, generate a starter `.claude/dso-config.conf` from the conversation findings. This file configures DSO for the host project.
376410

377-
**Key categories to populate** (flat `KEY=VALUE` format):
411+
#### Detect and Merge with Existing Config
412+
413+
Before writing any values, check whether a `.claude/dso-config.conf` already exists:
414+
415+
```bash
416+
EXISTING_CONFIG="$REPO_ROOT/.claude/dso-config.conf"
417+
if [ -f "$EXISTING_CONFIG" ]; then
418+
# Detect existing config — merge new keys, do NOT overwrite existing values
419+
EXISTING_CONTENT=$(cat "$EXISTING_CONFIG")
420+
fi
421+
```
422+
423+
If an existing dso-config.conf is found, merge the new keys into it rather than overwriting. Only add keys that are not already present. Existing config values take precedence — do not overwrite them unless the user explicitly confirms the new value.
424+
425+
#### Required Config Keys
426+
427+
Generate all of the following config keys (flat `KEY=VALUE` format). For each key that cannot be auto-detected, apply the fallback behavior described below.
428+
429+
**DSO plugin location** (required):
430+
```
431+
# Absolute path to the DSO plugin directory (resolved via realpath or git rev-parse)
432+
dso.plugin_root=<absolute path — e.g., /Users/name/project/plugins/dso>
433+
```
434+
435+
Resolve to an absolute path using `realpath` or `git rev-parse --show-toplevel` — never a relative path.
436+
437+
**Format settings** (detected from stack):
438+
```
439+
format.extensions=<e.g., .py or .ts,.js>
440+
format.source_dirs=<e.g., src or app,lib>
441+
```
442+
443+
Detect from `package.json` (TypeScript/JavaScript) or `pyproject.toml` (Python) if present.
444+
445+
**Test gate** (detected from test directory scan):
446+
```
447+
test_gate.test_dirs=<e.g., tests or test,spec>
448+
```
449+
450+
Populate from the `$TEST_DIRS` variable discovered in Phase 1 auto-detection.
451+
452+
**Validate command** (composed from detected test/lint/format commands):
453+
```
454+
commands.validate=<e.g., make test || poetry run pytest || npm test>
455+
```
456+
457+
Compose from the test and lint commands confirmed in the commands area of Phase 2.
458+
459+
**Tickets and checkpoints** (use documented defaults):
460+
```
461+
tickets.directory=.tickets-tracker
462+
checkpoint.marker_file=.checkpoint-pending-rollback
463+
```
464+
465+
**Behavioral patterns** (semicolon-delimited globs based on project structure):
466+
```
467+
# Semicolon-delimited glob patterns for review behavioral analysis
468+
review.behavioral_patterns=<e.g., src/**/*.py;tests/**/*.py;*.sh>
469+
```
470+
471+
Generate from the detected source and test directories. The value is semicolon-delimited — multiple glob patterns separated by `;` with no spaces around the semicolons.
472+
473+
**CI workflow name** (confirmed from actual workflow filenames):
474+
475+
Use the workflow filenames discovered in Phase 1 (`$CI_WORKFLOWS`) to confirm the `ci.workflow_name`. Present the actual filenames rather than asking the user to type a name from memory:
476+
```
477+
# CI workflow filename confirmation
478+
ci.workflow_name=<filename confirmed from .github/workflows/ scan>
479+
```
480+
481+
**Additional categories to populate**:
378482

379483
| Category | Keys to set | Source |
380484
|----------|-------------|--------|
381485
| `format` | `format.line_length`, `format.indent` | Enforcement answers |
382-
| `ci` | `ci.workflow_name` | CI area answers |
486+
| `ci` | `ci.workflow_name` | Confirmed from workflow filenames |
383487
| `commands` | `commands.test`, `commands.lint`, `commands.format` | Commands area answers |
384488
| `jira` | `jira.project_key` (if Jira integration desired) | User-stated |
385489
| `design` | `design.system`, `design.tokens_path` | Design area answers |
@@ -388,6 +492,21 @@ After writing `.claude/project-understanding.md`, generate a starter `.claude/ds
388492
| `version` | `version.file_path` | Detected or user-stated |
389493
| `test` | `test.suite.<name>.command`, `test.suite.<name>.speed_class` | Commands + detection |
390494

495+
#### Fallback Behavior for Undetected Config
496+
497+
When a config key cannot be auto-detected and the user does not provide a value, apply this fallback priority:
498+
499+
1. **Prompt user** — ask one focused question to get the value
500+
2. **Documented default** — if a well-known default exists (e.g., `tickets.directory=.tickets-tracker`), use it and note it was defaulted
501+
3. **Omit with explanatory comment** — if no default is safe to assume, omit the key and add an explanatory comment in the config file:
502+
503+
```
504+
# commands.validate — could not be auto-detected; set to your validation command
505+
# Example: commands.validate=make test
506+
```
507+
508+
Never silently skip a required key — always leave a comment so the user knows what to fill in.
509+
391510
#### Ticket prefix derivation
392511

393512
Derive the `tickets.prefix` from the project name by taking the first letter of each hyphen- or underscore-separated word and uppercasing them. For example:
@@ -410,10 +529,9 @@ When the conversation reveals **no `.github/workflows/` files exist**, offer exa
410529
```
411530
I don't see any CI workflows yet. Would you like me to create starter workflows?
412531
I can generate:
413-
a) ci.yml — fast-gate tests on pull requests
414-
b) ci-slow.yml — slow/integration tests on push to main
415-
c) Both
416-
d) Skip — I'll set up CI manually
532+
- ci.yml — fast-gate tests on pull requests
533+
- ci-slow.yml — slow/integration tests on push to main
534+
- both, or skip if you plan to set up CI manually
417535
418536
Accepted examples will be auto-populated into dso-config.conf and generated
419537
via ci-generator.sh using the test suites discovered during onboarding.
@@ -483,5 +601,5 @@ If the user says no or wants to continue manually, summarize what was learned an
483601
| Phase | Goal | Key Activities |
484602
|-------|------|---------------|
485603
| 1: Auto-Detection | Pre-fill answers | Run project-detect.sh, initialize scratchpad temp file, summarize findings |
486-
| 2: Socratic Dialogue | Fill gaps in 7 areas | One question at a time, multiple-choice preferred, skip confirmed areas |
604+
| 2: Socratic Dialogue | Fill gaps in 7 areas | One question at a time, confirmation-based (not rigid menus), skip confirmed areas |
487605
| 3: Completion | Finalize and hand off | Present summary, write .claude/project-understanding.md (detected/user-stated tags), write .claude/design-notes.md (UI projects only: vision, archetypes, golden paths, visual language, accessibility), generate dso-config.conf (ticket prefix, CI workflow examples, ACLI_VERSION), offer /dso:architect-foundation |

tests/skills/test-onboarding-skill.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -536,7 +536,7 @@ test_jira_bridge_project_key() {
536536
test_no_rigid_multiple_choice() {
537537
_snapshot_fail
538538
local rigid_count
539-
rigid_count=$(grep -cE "^\s*(a\)|b\)|c\)|d\)|e\))" "$SKILL_MD" 2>/dev/null || echo "0")
539+
rigid_count=$(grep -cE "^\s*(a\)|b\)|c\)|d\)|e\))" "$SKILL_MD" 2>/dev/null || true)
540540
if [[ "$rigid_count" -eq 0 ]]; then
541541
assert_eq "test_no_rigid_multiple_choice" "found" "found"
542542
else

0 commit comments

Comments
 (0)