@windyroad/architect 0.1.2 → 0.1.3-preview.27

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/README.md ADDED
@@ -0,0 +1,66 @@
1
+ # @windyroad/architect
2
+
3
+ **Architecture decision enforcement for Claude Code.** Ensures every code change is reviewed against your project's architecture decisions before it lands.
4
+
5
+ Part of [Windy Road Agent Plugins](../../README.md).
6
+
7
+ ## What It Does
8
+
9
+ The architect plugin prevents architectural drift by gating edits behind an architecture review. When you have a `docs/decisions/` directory, the plugin:
10
+
11
+ 1. **Detects** your architecture decisions on every prompt
12
+ 2. **Blocks** edits to project files until the architect agent has reviewed the proposed changes
13
+ 3. **Reviews** changes against your existing ADRs (Architecture Decision Records) and flags conflicts
14
+ 4. **Flags** when a new decision should be documented
15
+
16
+ No decisions directory yet? The plugin stays silent until you create one.
17
+
18
+ ## Install
19
+
20
+ ```bash
21
+ npx @windyroad/architect
22
+ ```
23
+
24
+ Restart Claude Code after installing.
25
+
26
+ ## Usage
27
+
28
+ Once installed, the plugin works automatically. You don't need to invoke it -- it intercepts edits and runs the review before allowing changes through.
29
+
30
+ **Create a new Architecture Decision Record:**
31
+
32
+ ```
33
+ /wr-architect:create-adr
34
+ ```
35
+
36
+ This walks you through creating an ADR in [MADR 4.0](https://adr.github.io/madr/) format. It examines your existing decisions, asks about the problem and options, and writes a properly formatted record to `docs/decisions/`.
37
+
38
+ ## How It Works
39
+
40
+ | Hook | Trigger | What it does |
41
+ |------|---------|-------------|
42
+ | `architect-detect.sh` | Every prompt | Checks for `docs/decisions/` and injects the review instruction |
43
+ | `architect-enforce-edit.sh` | Edit or Write | Blocks the edit if the architect hasn't reviewed yet |
44
+ | `architect-plan-enforce.sh` | ExitPlanMode | Ensures plans are reviewed before execution |
45
+ | `architect-mark-reviewed.sh` | Agent completes | Marks the review as done (TTL: 1800s) |
46
+ | `architect-refresh-hash.sh` | After edit | Refreshes the content hash so the next edit triggers a fresh review |
47
+ | `architect-reset-marker.sh` | Session end | Cleans up review markers |
48
+
49
+ ## Agent
50
+
51
+ The `wr-architect:agent` reviews proposed changes against existing decisions in `docs/decisions/` and reports:
52
+
53
+ - Whether changes comply with or violate existing decisions
54
+ - Whether a new ADR should be created
55
+ - Whether existing decisions are stale and need reassessment
56
+
57
+ ## Updating and Uninstalling
58
+
59
+ ```bash
60
+ npx @windyroad/architect --update
61
+ npx @windyroad/architect --uninstall
62
+ ```
63
+
64
+ ## Licence
65
+
66
+ [MIT](../../LICENSE)
package/agents/agent.md CHANGED
@@ -10,7 +10,6 @@ tools:
10
10
  - Read
11
11
  - Glob
12
12
  - Grep
13
- - Bash
14
13
  model: inherit
15
14
  ---
16
15
 
@@ -107,20 +106,9 @@ Issue types:
107
106
  - **[Missing Supersession]**: A new decision should supersede an old one but doesn't
108
107
  - **[Confirmation Violation]**: New code violates a confirmation criterion of an existing decision
109
108
 
110
- ## Verdict File
111
-
112
- After completing your review, you MUST write a verdict file so the hook system knows the outcome:
113
-
114
- - After **PASS**: `echo "PASS" > /tmp/architect-verdict`
115
- - After **ISSUES FOUND**: `echo "FAIL" > /tmp/architect-verdict`
116
-
117
- Advisory items (staleness flags) do NOT count as FAIL. Only write FAIL when there are actionable issues (Decision Conflict, Undocumented Decision, Decision Format, Missing Supersession, Confirmation Violation).
118
-
119
- You MUST NOT use Bash for anything other than writing the verdict file.
120
-
121
109
  ## Constraints
122
110
 
123
- - You are read-only. You do not edit files (the only exception is writing the verdict file via Bash).
111
+ - You are read-only. You do not edit files.
124
112
  - You review all project files: source code, configuration, CI workflows, hook scripts, build scripts, and decision files. The only exclusions are stylesheets, images, lockfiles, and font files.
125
113
  - If the change is purely cosmetic (comments, formatting, whitespace), report PASS.
126
114
  - Do not block changes that are clearly within the scope of an existing accepted decision.
@@ -1,17 +1,19 @@
1
1
  #!/bin/bash
2
2
  # Architecture - PostToolUse hook for Agent tool
3
3
  # Creates a session marker when architect has been consulted.
4
+ # Parses verdict from agent output text (session-safe, no temp files).
4
5
  # This marker unlocks the architect-enforce-edit.sh PreToolUse block.
5
- # Mirrors: voice-tone-mark-reviewed.sh
6
6
 
7
- # Source shared portable helpers (_mtime, _hashcmd)
8
7
  SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
9
8
  source "$SCRIPT_DIR/lib/gate-helpers.sh"
10
9
 
11
- INPUT=$(cat)
10
+ _parse_input
12
11
 
13
- SUBAGENT=$(echo "$INPUT" | jq -r '.tool_input.subagent_type // empty') || true
14
- SESSION_ID=$(echo "$INPUT" | jq -r '.session_id // empty') || true
12
+ TOOL_NAME=$(_get_tool_name)
13
+ [ "$TOOL_NAME" = "Agent" ] || exit 0
14
+
15
+ SUBAGENT=$(_get_subagent_type)
16
+ SESSION_ID=$(_get_session_id)
15
17
 
16
18
  if [ -z "$SESSION_ID" ]; then
17
19
  exit 0
@@ -19,25 +21,24 @@ fi
19
21
 
20
22
  case "$SUBAGENT" in
21
23
  *architect*)
22
- # Check verdict file from architect agent
23
- VERDICT_FILE="/tmp/architect-verdict"
24
+ # Parse verdict from agent output text (no temp file needed)
25
+ AGENT_OUTPUT=$(_get_tool_output)
24
26
  VERDICT=""
25
- if [ -f "$VERDICT_FILE" ]; then
26
- VERDICT=$(cat "$VERDICT_FILE")
27
- rm -f "$VERDICT_FILE"
27
+ if echo "$AGENT_OUTPUT" | grep -q "Architecture Review: PASS"; then
28
+ VERDICT="PASS"
29
+ elif echo "$AGENT_OUTPUT" | grep -q "ISSUES FOUND"; then
30
+ VERDICT="FAIL"
28
31
  fi
29
32
 
30
33
  case "$VERDICT" in
31
34
  PASS)
32
- # Architect explicitly passed, create marker
33
35
  touch "/tmp/architect-reviewed-${SESSION_ID}"
34
36
  ;;
35
37
  FAIL)
36
- # Architect found issues, do NOT create marker
38
+ # Do NOT create marker review found issues
37
39
  ;;
38
40
  *)
39
- # No verdict file (agent error or old agent version)
40
- # Allow with warning to avoid permanent lockout
41
+ # Could not parse verdict allow with marker to avoid lockout
41
42
  touch "/tmp/architect-reviewed-${SESSION_ID}"
42
43
  ;;
43
44
  esac
@@ -52,6 +53,8 @@ case "$SUBAGENT" in
52
53
  echo "$HASH" > "/tmp/architect-reviewed-${SESSION_ID}.hash"
53
54
  fi
54
55
 
56
+ # Plan review marker
57
+ touch "/tmp/architect-plan-reviewed-${SESSION_ID}"
55
58
  ;;
56
59
  esac
57
60
 
@@ -12,7 +12,7 @@ source "$_ARCHITECT_GATE_DIR/gate-helpers.sh"
12
12
  check_architect_gate() {
13
13
  local SESSION_ID="$1"
14
14
  local MARKER="/tmp/architect-reviewed-${SESSION_ID}"
15
- local TTL_SECONDS="${ARCHITECT_TTL:-600}"
15
+ local TTL_SECONDS="${ARCHITECT_TTL:-1800}"
16
16
 
17
17
  if [ -n "$SESSION_ID" ] && [ -f "$MARKER" ]; then
18
18
  local NOW=$(date +%s)
@@ -0,0 +1,32 @@
1
+ #!/usr/bin/env bats
2
+
3
+ # Tests for architect-gate.sh (TTL, drift, marker)
4
+
5
+ setup() {
6
+ SCRIPT_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")/.." && pwd)"
7
+ source "$SCRIPT_DIR/lib/architect-gate.sh"
8
+ TEST_SESSION="test-$$-$BATS_TEST_NUMBER"
9
+ }
10
+
11
+ teardown() {
12
+ rm -f "/tmp/architect-reviewed-${TEST_SESSION}"
13
+ rm -f "/tmp/architect-reviewed-${TEST_SESSION}.hash"
14
+ }
15
+
16
+ @test "gate denies when no marker exists" {
17
+ run check_architect_gate "$TEST_SESSION"
18
+ [ "$status" -ne 0 ]
19
+ }
20
+
21
+ @test "gate allows when marker exists and is fresh" {
22
+ touch "/tmp/architect-reviewed-${TEST_SESSION}"
23
+ run check_architect_gate "$TEST_SESSION"
24
+ [ "$status" -eq 0 ]
25
+ }
26
+
27
+ @test "gate denies when marker is expired" {
28
+ touch "/tmp/architect-reviewed-${TEST_SESSION}"
29
+ # Set TTL to 0 to force expiry
30
+ ARCHITECT_TTL=0 run check_architect_gate "$TEST_SESSION"
31
+ [ "$status" -ne 0 ]
32
+ }
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env bats
2
+
3
+ # Tests for architect verdict parsing from output text
4
+
5
+ @test "grep matches 'Architecture Review: PASS'" {
6
+ output="Some preamble text\n\n**Architecture Review: PASS**\n\nNo conflicts."
7
+ echo -e "$output" | grep -q "Architecture Review: PASS"
8
+ }
9
+
10
+ @test "grep matches 'ISSUES FOUND'" {
11
+ output="**Architecture Review: ISSUES FOUND**\n\n1. [Decision Conflict]"
12
+ echo -e "$output" | grep -q "ISSUES FOUND"
13
+ }
14
+
15
+ @test "grep does NOT match unrelated text" {
16
+ output="The review is complete. Everything looks good."
17
+ ! echo -e "$output" | grep -q "Architecture Review: PASS"
18
+ }
19
+
20
+ @test "subagent pattern matches wr-architect:agent" {
21
+ SUBAGENT="wr-architect:agent"
22
+ case "$SUBAGENT" in
23
+ *architect*) true ;;
24
+ *) false ;;
25
+ esac
26
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@windyroad/architect",
3
- "version": "0.1.2",
3
+ "version": "0.1.3-preview.27",
4
4
  "description": "Architecture decision enforcement for AI coding agents",
5
5
  "bin": {
6
6
  "windyroad-architect": "./bin/install.mjs"
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: wr:adr
2
+ name: wr-architect:create-adr
3
3
  description: Create a new Architecture Decision Record (MADR 4.0) in docs/decisions/. Examines existing decisions, asks about the problem and options, and writes a properly formatted ADR.
4
4
  allowed-tools: Read, Write, Edit, Bash, Glob, Grep, AskUserQuestion
5
5
  ---