@windyroad/architect 0.3.1-preview.75 → 0.3.1-preview.81

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.
package/agents/agent.md CHANGED
@@ -81,6 +81,10 @@ When a change includes a new or modified decision file in `docs/decisions/`:
81
81
  - Does it include reassessment criteria?
82
82
  - If it supersedes another decision, is the old decision properly updated?
83
83
 
84
+ ## Output Formatting
85
+
86
+ When referencing decision IDs (ADR-<NNN>), problem IDs (P<NNN>), or JTBD IDs in prose output, always include the human-readable title on first mention. Use the format `ADR-013 (Skill manifest in package.json)`, not bare `ADR-013`.
87
+
84
88
  ## How to Report
85
89
 
86
90
  If the change is compliant and no new decision is needed:
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env bats
2
+ # Doc-lint guard: architect agent.md must include the output formatting rule
3
+ # requiring human-readable titles alongside bare IDs (P032).
4
+ #
5
+ # Structural assertion — Permitted Exception to the source-grep ban (ADR-005 / P011).
6
+ #
7
+ # Cross-reference:
8
+ # P032 (agent output uses opaque IDs without titles)
9
+ # @jtbd JTBD-001 (enforce governance without slowing down)
10
+
11
+ setup() {
12
+ AGENT_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")/.." && pwd)"
13
+ AGENT_FILE="${AGENT_DIR}/agent.md"
14
+ }
15
+
16
+ @test "agent.md contains output formatting section" {
17
+ run grep -n "## Output Formatting" "$AGENT_FILE"
18
+ [ "$status" -eq 0 ]
19
+ }
20
+
21
+ @test "agent.md output formatting rule requires titles with IDs (P032)" {
22
+ run grep -n "title" "$AGENT_FILE"
23
+ [ "$status" -eq 0 ]
24
+ run grep -n "Output Formatting" "$AGENT_FILE"
25
+ [ "$status" -eq 0 ]
26
+ }
@@ -35,7 +35,11 @@ REQUIRED ACTIONS:
35
35
 
36
36
  SCOPE: All project files including source code, configs, CI, hooks,
37
37
  scripts, and decisions.
38
- Does NOT apply to: CSS/SCSS files, image assets, lockfiles, font files.
38
+ Does NOT apply to: CSS/SCSS files, image assets, lockfiles, font files,
39
+ docs/problems/ (problem tickets), docs/BRIEFING.md, RISK-POLICY.md,
40
+ .risk-reports/, .changeset/, memory files, plan files, docs/jtbd/,
41
+ docs/JOBS_TO_BE_DONE.md, docs/PRODUCT_DISCOVERY.md, docs/VOICE-AND-TONE.md,
42
+ docs/STYLE-GUIDE.md.
39
43
  HOOK_OUTPUT
40
44
  else
41
45
  cat <<'HOOK_OUTPUT'
@@ -0,0 +1,50 @@
1
+ #!/usr/bin/env bats
2
+
3
+ # Tests for architect-detect.sh (UserPromptSubmit) — verifies the injected
4
+ # scope exclusion text lists governance docs that the PreToolUse gate already
5
+ # exempts (P029). Without this, the LLM wastes time delegating to the
6
+ # architect for files the edit gate would allow anyway.
7
+
8
+ setup() {
9
+ SCRIPT_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")/.." && pwd)"
10
+ HOOK="$SCRIPT_DIR/architect-detect.sh"
11
+ ORIG_DIR="$PWD"
12
+ TEST_DIR=$(mktemp -d)
13
+ cd "$TEST_DIR"
14
+ mkdir -p docs/decisions
15
+ }
16
+
17
+ teardown() {
18
+ cd "$ORIG_DIR"
19
+ rm -rf "$TEST_DIR"
20
+ }
21
+
22
+ @test "detect: scope text mentions problem files exemption (P029)" {
23
+ run bash "$HOOK"
24
+ [ "$status" -eq 0 ]
25
+ [[ "$output" == *"docs/problems/"* ]] || [[ "$output" == *"problem tickets"* ]]
26
+ }
27
+
28
+ @test "detect: scope text mentions BRIEFING.md exemption (P029)" {
29
+ run bash "$HOOK"
30
+ [ "$status" -eq 0 ]
31
+ [[ "$output" == *"BRIEFING"* ]]
32
+ }
33
+
34
+ @test "detect: scope text mentions RISK-POLICY exemption (P029)" {
35
+ run bash "$HOOK"
36
+ [ "$status" -eq 0 ]
37
+ [[ "$output" == *"RISK-POLICY"* ]]
38
+ }
39
+
40
+ @test "detect: scope text mentions changeset exemption (P029)" {
41
+ run bash "$HOOK"
42
+ [ "$status" -eq 0 ]
43
+ [[ "$output" == *"changeset"* ]]
44
+ }
45
+
46
+ @test "detect: scope text mentions memory files exemption (P029)" {
47
+ run bash "$HOOK"
48
+ [ "$status" -eq 0 ]
49
+ [[ "$output" == *"memory"* ]] || [[ "$output" == *"MEMORY"* ]]
50
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@windyroad/architect",
3
- "version": "0.3.1-preview.75",
3
+ "version": "0.3.1-preview.81",
4
4
  "description": "Architecture decision enforcement for AI coding agents",
5
5
  "bin": {
6
6
  "windyroad-architect": "./bin/install.mjs"
@@ -32,6 +32,28 @@ Ask the user:
32
32
 
33
33
  If the user has already provided this context in the conversation (e.g., as arguments), use what they've given and only ask about what's missing.
34
34
 
35
+ ### 2b. Decision-boundary analysis (multi-decision check)
36
+
37
+ Before writing the ADR file, perform a decision-boundary analysis on the gathered context to prevent conflated ADRs that block independent status transitions and weaken auditability (P017).
38
+
39
+ **Self-check**: Read the context gathered in step 2. Answer: "How many distinct decisions are present? If each could be independently accepted, rejected, or superseded without affecting the others, they are distinct."
40
+
41
+ - **Single decision** (one coherent question with one chosen option): proceed directly to step 3.
42
+ - **Multiple decisions** (two or more distinct questions, different components, or different decision drivers that do not share the same trade-off): present a split prompt.
43
+
44
+ **Split prompt** — use `AskUserQuestion`:
45
+ - `header: "Multi-decision input"`
46
+ - `multiSelect: false`
47
+ - Options:
48
+ 1. `Split into separate ADRs (Recommended)` — description: "Create one ADR per distinct decision, with consecutive IDs. Each ADR can be accepted, rejected, or superseded independently."
49
+ 2. `Keep as a single ADR` — description: "Create one ADR covering all decisions. Use this only if the decisions are so tightly coupled that they cannot be made independently."
50
+
51
+ **Non-interactive fallback**: When `AskUserQuestion` is unavailable (e.g., non-interactive/AFK mode), automatically split into separate ADRs with consecutive IDs and note the auto-split in output. Do not block creation.
52
+
53
+ **Split implementation**: When splitting, assign consecutive IDs. Cross-reference each ADR in the other's Related section or as a linked decision in the consequences.
54
+
55
+ **Scope**: Scoped to new ADR creation only (steps 2–5). Does not apply to supersession handling (step 6), where the scope of the new decision is already known and bounded.
56
+
35
57
  ### 3. Determine sequence number and filename
36
58
 
37
59
  - Next number = highest existing decision number + 1 (or 001 if none exist)
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/env bats
2
+ # Doc-lint guard: create-adr SKILL.md must include a decision-boundary
3
+ # analysis step for new ADR creation.
4
+ #
5
+ # Structural assertion — Permitted Exception to the source-grep ban (ADR-005 / P011).
6
+ # These tests assert that the skill specification document conforms to the
7
+ # decision-boundary splitting contract introduced by P017.
8
+ #
9
+ # Cross-reference:
10
+ # P017: docs/problems/017-create-adr-should-split-multi-decision-records.open.md
11
+ # ADR-013: docs/decisions/013-structured-user-interaction-for-governance-decisions.proposed.md
12
+ # Sibling: packages/itil/skills/manage-problem/test/manage-problem-concern-boundary.bats (P016)
13
+ # @jtbd JTBD-001 (enforce governance without slowing down)
14
+ # @jtbd JTBD-101 (extend the suite with clear patterns)
15
+
16
+ setup() {
17
+ SKILL_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")/.." && pwd)"
18
+ SKILL_FILE="${SKILL_DIR}/SKILL.md"
19
+ }
20
+
21
+ @test "SKILL.md includes a decision-boundary analysis step for new ADR creation" {
22
+ # P017: Before writing an ADR file, the skill must check whether the input
23
+ # contains multiple distinct decisions, and offer to split if it does.
24
+ # Conflated ADRs damage auditability and block independent status transitions.
25
+ run grep -in "decision.boundary\|decision-boundary\|decision boundary\|boundary.*decision\|split.*decision\|multi.decision\|single.*decision\|distinct.*decision\|decision.*distinct" "$SKILL_FILE"
26
+ [ "$status" -eq 0 ]
27
+ }
28
+
29
+ @test "SKILL.md decision-boundary step uses AskUserQuestion for split decision (ADR-013)" {
30
+ # ADR-013 Rule 1: all branch points must use AskUserQuestion, not prose options.
31
+ # The "split into separate ADRs" option must be presented via AskUserQuestion.
32
+ # Match: AskUserQuestion appearing in context of "split" ADR instruction.
33
+ run grep -in "Split into separate\|split into.*ADR\|ADR.*split\|split.*ADR" "$SKILL_FILE"
34
+ [ "$status" -eq 0 ]
35
+ }
36
+
37
+ @test "SKILL.md decision-boundary step specifies non-interactive auto-split fallback" {
38
+ # ADR-013 Rule 6: non-interactive fail-safe — when AskUserQuestion is unavailable,
39
+ # the skill must auto-split (not block/hang) for creation workflows.
40
+ run grep -in "auto.split\|automatically split" "$SKILL_FILE"
41
+ [ "$status" -eq 0 ]
42
+ }
43
+
44
+ @test "SKILL.md decision-boundary step is scoped to new ADR creation (not supersession)" {
45
+ # P017 fix must only fire during new ADR creation, not during supersession handling.
46
+ # Checks for explicit scope language excluding supersession from the boundary check.
47
+ run grep -in "not.*supersession\|supersession.*not\|new ADR creation only\|creation only\|does not apply.*supersession\|Scoped to" "$SKILL_FILE"
48
+ [ "$status" -eq 0 ]
49
+ }
@@ -17,6 +17,10 @@ This skill is **read-only**. It does not commit, push, or modify files.
17
17
  - When proposing a structural change: get a review before editing architecture-bearing files
18
18
  - Any time the hook gate is not convenient: e.g., planning mode, exploratory spikes
19
19
 
20
+ ## Output Formatting
21
+
22
+ When referencing decision IDs (ADR-<NNN>), problem IDs (P<NNN>), or JTBD IDs in prose output, always include the human-readable title on first mention. Use the format `ADR-013 (Skill manifest in package.json)`, not bare `ADR-013`.
23
+
20
24
  ## Steps
21
25
 
22
26
  ### 1. Parse arguments