Skip to content

Commit 3ff8f1a

Browse files
authored
Restructure softwaredev ways into taxonomy with expanded semantic matching (#30)
* refactor(ways): restructure softwaredev into taxonomy with semantic matching Reorganize flat softwaredev/ ways into five clusters: - architecture/ (adr, adr-context, design) - code/ (errors, performance, quality, security, testing) - delivery/ (commits, github, migrations, patches, release) - environment/ (config, debugging, deps, ssh) - docs/ (docs parent, api child) Add BM25 description + vocabulary to 11 regex-only ways, expanding semantic matching from 7 to 18 ways. Fixture tests: 48/54 (0 FP). Integration tests: 27/31 (0 FP). No regressions from restructure. Fix ADR tool symlink, update all path references in docs, hook comments, test harness, and integration tests. Legacy ADR-013 left untouched as historical record. * test(ways): expand activation test for taxonomy restructure Add steps 4 (newly-semantic way via BM25) and 5 (co-activation of related ways) to the live activation test. Update test README with 18-way corpus baseline and new coverage scenarios. 8 test steps covering: regex, established BM25, new BM25, co-activation, negative control, subagent injection, subagent negative. * fix(test): correct Step 8 expectation for subagent context inheritance The subagent negative test was failing because general-purpose subagents inherit parent conversation context — Performance Way from Step 4 was visible via context sharing, not SubagentStart injection. The injection pipeline correctly produced no stash for an irrelevant prompt. Updated Step 8 to distinguish injection (SubagentStart hook) from context inheritance (Task tool parent sharing).
1 parent 8a0ed83 commit 3ff8f1a

44 files changed

Lines changed: 265 additions & 890 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

commands/test-way.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ Use the `way-match suggest` command:
9797
Output is section-delimited (GAPS, COVERAGE, UNUSED, VOCABULARY). Parse and display in a readable format:
9898

9999
```
100-
=== Vocabulary Analysis: softwaredev/security ===
100+
=== Vocabulary Analysis: softwaredev/code/security ===
101101
102102
Gaps (body terms not in vocabulary, freq >= 2):
103103
parameterized freq=3

docs/governance.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,9 @@ In an enterprise, policy documents and way implementations typically live in sep
157157
```
158158
compliance-repo/ your-claude-config/
159159
├── docs/architecture/ ├── hooks/ways/
160-
│ ├── ADR-150.md │ ├── softwaredev/commits/way.md
160+
│ ├── ADR-150.md │ ├── softwaredev/delivery/commits/way.md
161161
│ └── ADR-200.md │ │ (provenance: → ADR-150)
162-
├── audit-ledger.json │ └── softwaredev/security/way.md
162+
├── audit-ledger.json │ └── softwaredev/code/security/way.md
163163
└── controls.xlsx └── governance/
164164
├── policies/
165165
└── provenance-manifest.json

docs/hooks-and-ways.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -368,9 +368,9 @@ macro: append # macro output after static content
368368
```
369369

370370
Macros generate dynamic content. Examples:
371-
- `softwaredev/adr/macro.sh` - Tri-state detection: no tooling, tooling available, tooling installed
372-
- `softwaredev/quality/macro.sh` - Scans for long files in the project, outputs priority list
373-
- `softwaredev/github/macro.sh` - Detects solo vs team project, adjusts PR guidance
371+
- `softwaredev/architecture/adr/macro.sh` - Tri-state detection: no tooling, tooling available, tooling installed
372+
- `softwaredev/code/quality/macro.sh` - Scans for long files in the project, outputs priority list
373+
- `softwaredev/delivery/github/macro.sh` - Detects solo vs team project, adjusts PR guidance
374374

375375
**Security**: Project-local macros only run if the project is listed in `~/.claude/trusted-project-macros`.
376376

@@ -385,11 +385,11 @@ flowchart TD
385385
classDef marker fill:#00695C,stroke:#004D40,color:#fff
386386
classDef result fill:#2E7D32,stroke:#1B5E20,color:#fff
387387
388-
T["Trigger fires for softwaredev/github"] --> PL
388+
T["Trigger fires for softwaredev/delivery/github"] --> PL
389389
390-
PL{"$PROJECT/.claude/ways/<br/>softwaredev/github/way.md<br/>exists?"}
390+
PL{"$PROJECT/.claude/ways/<br/>softwaredev/delivery/github/way.md<br/>exists?"}
391391
PL -->|yes| USE_P["Use project-local way"]:::project
392-
PL -->|no| GL{"~/.claude/hooks/ways/<br/>softwaredev/github/way.md<br/>exists?"}:::global
392+
PL -->|no| GL{"~/.claude/hooks/ways/<br/>softwaredev/delivery/github/way.md<br/>exists?"}:::global
393393
GL -->|yes| USE_G["Use global way"]:::global
394394
GL -->|no| SKIP["No output"]
395395

docs/hooks-and-ways/extending.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ These are discovered alongside global ways and follow the same matching rules.
101101

102102
A project-local way with the same domain/name path as a global way takes precedence. They share a single marker, so only the project-local version fires.
103103

104-
Example: If a project has `.claude/ways/softwaredev/testing/way.md`, it replaces `~/.claude/hooks/ways/softwaredev/testing/way.md` for that project.
104+
Example: If a project has `.claude/ways/softwaredev/code/testing/way.md`, it replaces `~/.claude/hooks/ways/softwaredev/code/testing/way.md` for that project.
105105

106106
### Macros in project-local ways
107107

docs/hooks-and-ways/provenance.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,9 +131,9 @@ In an enterprise, policy documents and way implementations typically live in sep
131131
```
132132
compliance-repo/ your-claude-config/
133133
├── docs/architecture/ ├── hooks/ways/
134-
│ ├── ADR-150.md │ ├── softwaredev/commits/way.md
134+
│ ├── ADR-150.md │ ├── softwaredev/delivery/commits/way.md
135135
│ └── ADR-200.md │ │ (provenance: → ADR-150)
136-
├── audit-ledger.json │ └── softwaredev/security/way.md
136+
├── audit-ledger.json │ └── softwaredev/code/security/way.md
137137
└── controls.xlsx └── provenance-manifest.json
138138
```
139139

docs/hooks-and-ways/stats.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ You can't manage what you can't see. The ways system logs every firing event and
77
Every time a way fires, `log-event.sh` appends a line to `~/.claude/stats/events.jsonl`:
88

99
```json
10-
{"ts":"2026-02-05T19:00:34Z","event":"way_fired","way":"softwaredev/commits","domain":"softwaredev","trigger":"bash","scope":"agent","project":"/home/you/myproject","session":"abc-123"}
10+
{"ts":"2026-02-05T19:00:34Z","event":"way_fired","way":"softwaredev/delivery/commits","domain":"softwaredev","trigger":"bash","scope":"agent","project":"/home/you/myproject","session":"abc-123"}
1111
```
1212

1313
Session start events are also logged. For teammates, the team name is included:
@@ -39,8 +39,8 @@ Top ways:
3939
meta/todos 96 ████████████████████
4040
meta/memory 96 ████████████████████
4141
meta/knowledge 30 ██████
42-
softwaredev/commits 19 ███
43-
softwaredev/design 18 ███
42+
softwaredev/delivery/commits 19 ███
43+
softwaredev/architecture/design 18 ███
4444
4545
By scope:
4646
agent 319

docs/scripts/adr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
../../hooks/ways/softwaredev/adr/adr-tool
1+
../../hooks/ways/softwaredev/architecture/adr/adr-tool

hooks/ways/check-bash-pre.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
# │ keywords match │
1010
# └─────────────────┘
1111
#
12-
# Ways are nested: domain/wayname/way.md (e.g., softwaredev/github/way.md)
12+
# Ways are nested: domain/wayname/way.md (e.g., softwaredev/delivery/github/way.md)
1313
# Multiple ways can match a single command - CONTEXT accumulates
1414
# all matching way outputs. Markers prevent duplicate content.
1515
# Output is returned as additionalContext JSON for Claude to see.
@@ -33,7 +33,7 @@ scan_ways() {
3333

3434
# Find all way.md files recursively
3535
while IFS= read -r -d '' wayfile; do
36-
# Extract way path relative to ways dir (e.g., "softwaredev/github")
36+
# Extract way path relative to ways dir (e.g., "softwaredev/delivery/github")
3737
waypath="${wayfile#$dir/}"
3838
waypath="${waypath%/way.md}"
3939

hooks/ways/check-file-pre.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
# └───────────────────────┘ │ if files match │ └──────────────┘
99
# └─────────────────┘
1010
#
11-
# Ways are nested: domain/wayname/way.md (e.g., softwaredev/github/way.md)
11+
# Ways are nested: domain/wayname/way.md (e.g., softwaredev/delivery/github/way.md)
1212
# Multiple ways can match a single file path - CONTEXT accumulates
1313
# all matching way outputs. Markers prevent duplicate content.
1414
# Output is returned as additionalContext JSON for Claude to see.
@@ -31,7 +31,7 @@ scan_ways() {
3131

3232
# Find all way.md files recursively
3333
while IFS= read -r -d '' wayfile; do
34-
# Extract way path relative to ways dir (e.g., "softwaredev/github")
34+
# Extract way path relative to ways dir (e.g., "softwaredev/delivery/github")
3535
waypath="${wayfile#$dir/}"
3636
waypath="${waypath%/way.md}"
3737

hooks/ways/check-prompt.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
# │ semantic match │
1010
# └─────────────────┘
1111
#
12-
# Ways are nested: domain/wayname/way.md (e.g., softwaredev/github/way.md)
12+
# Ways are nested: domain/wayname/way.md (e.g., softwaredev/delivery/github/way.md)
1313
# Matching is ADDITIVE: pattern (regex/keyword) and semantic are OR'd.
1414
# Semantic matching degrades: BM25 binary → gzip NCD → skip.
1515
# Project-local ways are scanned first (and take precedence).
@@ -45,7 +45,7 @@ scan_ways() {
4545

4646
# Find all way.md files recursively
4747
while IFS= read -r -d '' wayfile; do
48-
# Extract way path relative to ways dir (e.g., "softwaredev/github")
48+
# Extract way path relative to ways dir (e.g., "softwaredev/delivery/github")
4949
waypath="${wayfile#$dir/}"
5050
waypath="${waypath%/way.md}"
5151

0 commit comments

Comments
 (0)