Skip to content

Commit d3673cb

Browse files
chore(sprint): add implementation tasks for dso-0y9j, dso-r9fa, dso-2x3c
Create TDD task breakdowns for Batch 3 stories: - dso-0y9j: 2 tasks (--lib mode RED/GREEN) - dso-r9fa: 3 tasks (setup RED/GREEN/self-apply) - dso-2x3c: 2 tasks (doc migration RED/GREEN) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent cfd9efa commit d3673cb

File tree

9 files changed

+388
-1
lines changed

9 files changed

+388
-1
lines changed

.tickets/dso-02wk.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
---
2+
id: dso-02wk
3+
status: open
4+
deps: []
5+
links: []
6+
created: 2026-03-17T21:06:26Z
7+
type: task
8+
priority: 0
9+
assignee: Joe Oakhart
10+
parent: dso-0y9j
11+
---
12+
# Write failing tests for shim --lib mode (RED)
13+
14+
## TDD Requirement (RED phase)
15+
16+
Add 4 failing test functions to tests/scripts/test-shim-smoke.sh. All FAIL until --lib is implemented.
17+
18+
**test_lib_mode_exports_dso_root**: helper sh-c sources shim --lib; assert DSO_ROOT equals PLUGIN_ROOT and starts with '/'
19+
**test_lib_mode_produces_no_stdout**: helper sources (not exec) shim --lib; capture stdout; assert empty
20+
**test_lib_mode_does_not_dispatch**: helper sources shim --lib then exit 0; assert exit 0 (no dispatch attempted)
21+
**test_lib_mode_exec_exits_zero**: CLAUDE_PLUGIN_ROOT=PLUGIN_ROOT bash shim --lib; assert exit 0
22+
23+
RED: shim treats '--lib' as script name, exits 127. All 4 FAIL.
24+
25+
## Acceptance Criteria
26+
27+
- [ ] run-all.sh exits with failures (confirming RED phase)
28+
Verify: bash $(git rev-parse --show-toplevel)/tests/run-all.sh 2>&1 | grep -q 'FAILED: [^0]'
29+
- [ ] ruff check passes
30+
Verify: ruff check scripts/*.py tests/**/*.py
31+
- [ ] ruff format --check passes
32+
Verify: ruff format --check scripts/*.py tests/**/*.py
33+
- [ ] test-shim-smoke.sh contains at least 4 lib-mode test functions
34+
Verify: grep -c '^test_lib_mode_' $(git rev-parse --show-toplevel)/tests/scripts/test-shim-smoke.sh | awk '{exit ($1 < 4)}'
35+
- [ ] New lib-mode tests FAIL before --lib implementation
36+
Verify: bash $(git rev-parse --show-toplevel)/tests/scripts/test-shim-smoke.sh 2>&1 | grep 'FAIL' | grep -q 'lib_mode'
37+

.tickets/dso-0sjt.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
---
2+
id: dso-0sjt
3+
status: open
4+
deps: [dso-jl2z]
5+
links: []
6+
created: 2026-03-17T21:07:16Z
7+
type: task
8+
priority: 0
9+
assignee: Joe Oakhart
10+
parent: dso-r9fa
11+
---
12+
# Self-apply dso-setup.sh to plugin repo
13+
14+
## TDD Requirement
15+
16+
Run dso-setup.sh in this repo to bootstrap the plugin repo's own shim. Creates .claude/scripts/dso and writes dso.plugin_root to workflow-config.conf.
17+
18+
## Implementation Steps
19+
20+
1. Run: bash $(git rev-parse --show-toplevel)/scripts/dso-setup.sh
21+
(TARGET_REPO and PLUGIN_ROOT both default to this repo root)
22+
2. Verify .claude/scripts/dso was created and is executable
23+
3. Verify workflow-config.conf has exactly one dso.plugin_root entry
24+
4. Verify dso tk --help exits 0 without CLAUDE_PLUGIN_ROOT set
25+
26+
## Acceptance Criteria
27+
28+
- [ ] bash tests/run-all.sh passes
29+
Verify: bash $(git rev-parse --show-toplevel)/tests/run-all.sh 2>&1 | grep -q 'FAILED: 0'
30+
- [ ] ruff check passes
31+
Verify: ruff check scripts/*.py tests/**/*.py
32+
- [ ] ruff format --check passes
33+
Verify: ruff format --check scripts/*.py tests/**/*.py
34+
- [ ] .claude/scripts/dso exists and is executable
35+
Verify: test -x $(git rev-parse --show-toplevel)/.claude/scripts/dso
36+
- [ ] workflow-config.conf has exactly one dso.plugin_root entry
37+
Verify: grep -c '^dso.plugin_root=' $(git rev-parse --show-toplevel)/workflow-config.conf | awk '{exit ($1 != 1)}'
38+
- [ ] dso tk --help exits 0 without CLAUDE_PLUGIN_ROOT
39+
Verify: (cd $(git rev-parse --show-toplevel) && unset CLAUDE_PLUGIN_ROOT && ./.claude/scripts/dso tk --help)
40+

.tickets/dso-2rts.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
---
2+
id: dso-2rts
3+
status: open
4+
deps: [dso-02wk]
5+
links: []
6+
created: 2026-03-17T21:06:39Z
7+
type: task
8+
priority: 0
9+
assignee: Joe Oakhart
10+
parent: dso-0y9j
11+
---
12+
# Add --lib flag to shim template (GREEN)
13+
14+
## TDD Requirement (GREEN phase)
15+
16+
Modify templates/host-project/dso to add --lib flag handling. All 4 lib-mode tests pass.
17+
18+
## Implementation Steps
19+
20+
After DSO_ROOT is resolved (before dispatch section), add:
21+
22+
```sh
23+
# Library mode: export DSO_ROOT and return without dispatching
24+
if [ "${1:-}" = "--lib" ]; then
25+
export DSO_ROOT="$DSO_ROOT"
26+
return 0 2>/dev/null || exit 0
27+
fi
28+
```
29+
30+
The `return 0 2>/dev/null || exit 0` idiom handles both sourced and exec invocations.
31+
32+
## Acceptance Criteria
33+
34+
- [ ] bash tests/run-all.sh passes
35+
Verify: bash $(git rev-parse --show-toplevel)/tests/run-all.sh 2>&1 | grep -q 'FAILED: 0'
36+
- [ ] ruff check passes
37+
Verify: ruff check scripts/*.py tests/**/*.py
38+
- [ ] ruff format --check passes
39+
Verify: ruff format --check scripts/*.py tests/**/*.py
40+
- [ ] templates/host-project/dso contains --lib handling
41+
Verify: grep -q -- '--lib' $(git rev-parse --show-toplevel)/templates/host-project/dso
42+
- [ ] DSO_ROOT is absolute path after sourcing the shim template
43+
Verify: PLUGIN_ROOT=$(git rev-parse --show-toplevel); out=$(CLAUDE_PLUGIN_ROOT="$PLUGIN_ROOT" sh -c ". '$PLUGIN_ROOT/templates/host-project/dso' --lib 2>/dev/null; echo DSO_ROOT=$DSO_ROOT"); echo "$out" | grep '^DSO_ROOT=/' | grep -q .
44+
- [ ] Exec mode exits 0
45+
Verify: CLAUDE_PLUGIN_ROOT=$(git rev-parse --show-toplevel) bash $(git rev-parse --show-toplevel)/templates/host-project/dso --lib; test $? -eq 0
46+
- [ ] All lib-mode tests pass
47+
Verify: bash $(git rev-parse --show-toplevel)/tests/scripts/test-shim-smoke.sh 2>&1 | grep -q 'FAILED: 0'
48+

.tickets/dso-5l1c.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
---
2+
id: dso-5l1c
3+
status: open
4+
deps: []
5+
links: []
6+
created: 2026-03-17T21:06:55Z
7+
type: task
8+
priority: 0
9+
assignee: Joe Oakhart
10+
parent: dso-r9fa
11+
---
12+
# Write failing tests for dso-setup command (RED)
13+
14+
## TDD Requirement (RED phase)
15+
16+
Create tests/scripts/test-dso-setup.sh with 5 failing tests. All FAIL because scripts/dso-setup.sh does not exist yet.
17+
18+
## Implementation Steps
19+
20+
1. Create tests/scripts/test-dso-setup.sh
21+
2. Source $PLUGIN_ROOT/tests/lib/assert.sh
22+
3. Define SETUP_SCRIPT=$(git rev-parse --show-toplevel)/scripts/dso-setup.sh
23+
4. Each test creates its own TMPDIR=$(mktemp -d) with trap 'rm -rf $TMPDIR' EXIT
24+
25+
## Tests to write:
26+
27+
**test_setup_creates_shim**
28+
- bash "$SETUP_SCRIPT" "$TMPDIR" "$PLUGIN_ROOT"
29+
- Assert: test -f "$TMPDIR/.claude/scripts/dso"
30+
31+
**test_setup_shim_executable**
32+
- bash "$SETUP_SCRIPT" "$TMPDIR" "$PLUGIN_ROOT"
33+
- Assert: test -x "$TMPDIR/.claude/scripts/dso"
34+
35+
**test_setup_writes_plugin_root**
36+
- bash "$SETUP_SCRIPT" "$TMPDIR" "$PLUGIN_ROOT"
37+
- Assert: grep -q '^dso.plugin_root=' "$TMPDIR/workflow-config.conf" (use absolute path to tmpdir file)
38+
39+
**test_setup_is_idempotent**
40+
- Run setup twice on empty config; grep -c '^dso.plugin_root=' must equal 1
41+
- Also: pre-populate config with existing entry, run once, assert count still 1
42+
43+
**test_setup_dso_tk_help_works**
44+
- bash "$SETUP_SCRIPT" "$TMPDIR" "$PLUGIN_ROOT"
45+
- Then: (cd "$TMPDIR" && unset CLAUDE_PLUGIN_ROOT && "./.claude/scripts/dso" tk --help)
46+
- Assert exit 0
47+
48+
5. chmod +x tests/scripts/test-dso-setup.sh
49+
50+
## Acceptance Criteria
51+
52+
- [ ] run-all.sh exits with failures (confirming RED)
53+
Verify: bash $(git rev-parse --show-toplevel)/tests/run-all.sh 2>&1 | grep -q 'FAILED: [^0]'
54+
- [ ] ruff check passes
55+
Verify: ruff check scripts/*.py tests/**/*.py
56+
- [ ] ruff format --check passes
57+
Verify: ruff format --check scripts/*.py tests/**/*.py
58+
- [ ] test-dso-setup.sh exists and is executable
59+
Verify: test -x $(git rev-parse --show-toplevel)/tests/scripts/test-dso-setup.sh
60+
- [ ] Contains at least 5 test functions
61+
Verify: grep -c '^test_setup_' $(git rev-parse --show-toplevel)/tests/scripts/test-dso-setup.sh | awk '{exit ($1 < 5)}'
62+
- [ ] Tests fail before setup script exists
63+
Verify: bash $(git rev-parse --show-toplevel)/tests/scripts/test-dso-setup.sh 2>&1 | grep -q 'FAIL'
64+

.tickets/dso-awoz.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
id: dso-awoz
3-
status: open
3+
status: closed
44
deps: []
55
links: []
66
created: 2026-03-17T19:51:47Z

.tickets/dso-j3gm.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
---
2+
id: dso-j3gm
3+
status: closed
4+
deps: []
5+
links: []
6+
created: 2026-03-17T21:06:10Z
7+
type: task
8+
priority: 0
9+
assignee: Joe Oakhart
10+
---
11+
# Write failing tests for shim --lib mode (RED)
12+
13+
## TDD Requirement (RED phase)
14+
15+
Add 4 failing test functions to tests/scripts/test-shim-smoke.sh. All FAIL until --lib is implemented.
16+
17+
Tests to add:
18+
- test_lib_mode_exports_dso_root: helper subscript sources shim --lib; assert DSO_ROOT == PLUGIN_ROOT and starts with '/'
19+
- test_lib_mode_produces_no_stdout: helper subscript SOURCES shim --lib; capture stdout; assert empty
20+
- test_lib_mode_does_not_dispatch: helper subscript sources shim --lib then exit 0; assert exit 0 (no dispatch)
21+
- test_lib_mode_exec_exits_zero: bash shim --lib; assert exit 0
22+
23+
RED: shim treats '--lib' as script name → exits 127 → all FAIL
24+
25+
26+
## Notes
27+
28+
**2026-03-17T21:06:26Z**
29+
30+
parent: dso-0y9j

.tickets/dso-jl2z.md

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
---
2+
id: dso-jl2z
3+
status: open
4+
deps: [dso-5l1c]
5+
links: []
6+
created: 2026-03-17T21:07:07Z
7+
type: task
8+
priority: 0
9+
assignee: Joe Oakhart
10+
parent: dso-r9fa
11+
---
12+
# Create scripts/dso-setup.sh (GREEN)
13+
14+
## TDD Requirement (GREEN phase)
15+
16+
Create scripts/dso-setup.sh. All 5 setup tests pass.
17+
18+
## Interface
19+
20+
```
21+
dso-setup.sh [TARGET_REPO [PLUGIN_ROOT]]
22+
```
23+
24+
- TARGET_REPO: directory to install shim into; defaults to $(git rev-parse --show-toplevel)
25+
- PLUGIN_ROOT: plugin directory; defaults to parent of this script's directory (scripts/../)
26+
27+
## Implementation (POSIX sh)
28+
29+
```sh
30+
#!/bin/sh
31+
TARGET_REPO="${1:-$(git rev-parse --show-toplevel)}"
32+
PLUGIN_ROOT="${2:-$(cd "$(dirname "$0")/.." && pwd)}"
33+
34+
mkdir -p "$TARGET_REPO/.claude/scripts/"
35+
cp "$PLUGIN_ROOT/templates/host-project/dso" "$TARGET_REPO/.claude/scripts/dso"
36+
chmod +x "$TARGET_REPO/.claude/scripts/dso"
37+
38+
CONFIG="$TARGET_REPO/workflow-config.conf"
39+
if grep -q '^dso\.plugin_root=' "$CONFIG" 2>/dev/null; then
40+
# Update existing entry (idempotent)
41+
sed -i.bak "s|^dso\.plugin_root=.*|dso.plugin_root=$PLUGIN_ROOT|" "$CONFIG" && rm -f "$CONFIG.bak"
42+
else
43+
printf 'dso.plugin_root=%s\n' "$PLUGIN_ROOT" >> "$CONFIG"
44+
fi
45+
```
46+
47+
chmod +x scripts/dso-setup.sh
48+
49+
## Acceptance Criteria
50+
51+
- [ ] bash tests/run-all.sh passes
52+
Verify: bash $(git rev-parse --show-toplevel)/tests/run-all.sh 2>&1 | grep -q 'FAILED: 0'
53+
- [ ] ruff check passes
54+
Verify: ruff check scripts/*.py tests/**/*.py
55+
- [ ] ruff format --check passes
56+
Verify: ruff format --check scripts/*.py tests/**/*.py
57+
- [ ] scripts/dso-setup.sh exists and is executable
58+
Verify: test -x $(git rev-parse --show-toplevel)/scripts/dso-setup.sh
59+
- [ ] All setup tests pass
60+
Verify: bash $(git rev-parse --show-toplevel)/tests/scripts/test-dso-setup.sh 2>&1 | grep -q 'FAILED: 0'
61+

.tickets/dso-ku5i.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
---
2+
id: dso-ku5i
3+
status: open
4+
deps: []
5+
links: []
6+
created: 2026-03-17T21:07:32Z
7+
type: task
8+
priority: 1
9+
assignee: Joe Oakhart
10+
parent: dso-2x3c
11+
---
12+
# Write failing doc migration completeness test (RED)
13+
14+
## TDD Requirement (RED phase)
15+
16+
Create tests/scripts/test-doc-migration.sh with test that verifies zero legacy ${CLAUDE_PLUGIN_ROOT}/scripts/ invocations remain. FAILS because 57 lines exist.
17+
18+
## Implementation Steps
19+
20+
1. Create tests/scripts/test-doc-migration.sh
21+
2. Source $PLUGIN_ROOT/tests/lib/assert.sh
22+
3. Implement test_no_legacy_plugin_root_refs:
23+
24+
```bash
25+
test_no_legacy_plugin_root_refs() {
26+
REPO_ROOT=$(git rev-parse --show-toplevel)
27+
# Count legacy invocations, excluding known-good lines:
28+
# - PLUGIN_SCRIPTS= variable assignments (10 lines, config-resolution internal)
29+
# - ls directory listings like: ls "${CLAUDE_PLUGIN_ROOT}/scripts/"*.sh
30+
COUNT=$(grep -r '${CLAUDE_PLUGIN_ROOT}/scripts/' "$REPO_ROOT/skills" "$REPO_ROOT/docs/workflows" "$REPO_ROOT/CLAUDE.md" 2>/dev/null | grep -v 'PLUGIN_SCRIPTS=' | grep -v 'ls.*CLAUDE_PLUGIN_ROOT.*scripts/"' | wc -l | tr -d ' ')
31+
assert_eq "test_no_legacy_plugin_root_refs" "0" "$COUNT"
32+
}
33+
```
34+
35+
4. chmod +x tests/scripts/test-doc-migration.sh
36+
37+
## Notes
38+
- 57 invocation lines currently exist → test FAILS (RED confirmed)
39+
- Exclusions: 10 PLUGIN_SCRIPTS= lines + 1 ls directory listing in skills/dev-onboarding/SKILL.md:121
40+
41+
## Acceptance Criteria
42+
43+
- [ ] run-all.sh exits with failures (confirming RED)
44+
Verify: bash $(git rev-parse --show-toplevel)/tests/run-all.sh 2>&1 | grep -q 'FAILED: [^0]'
45+
- [ ] ruff check passes
46+
Verify: ruff check scripts/*.py tests/**/*.py
47+
- [ ] ruff format --check passes
48+
Verify: ruff format --check scripts/*.py tests/**/*.py
49+
- [ ] test-doc-migration.sh exists and is executable
50+
Verify: test -x $(git rev-parse --show-toplevel)/tests/scripts/test-doc-migration.sh
51+
- [ ] Test FAILS while legacy refs exist
52+
Verify: bash $(git rev-parse --show-toplevel)/tests/scripts/test-doc-migration.sh 2>&1 | grep -q 'FAIL'
53+

0 commit comments

Comments
 (0)