diff --git a/Architecture.md b/Architecture.md index a8caf88..56d7da5 100644 --- a/Architecture.md +++ b/Architecture.md @@ -4,7 +4,7 @@ Multiple agents can work on the same repo simultaneously. Two problems must be solved: -**1. Script isolation** — each scope gets its own directory under `.steplock/sessions/`. The dir name is the scope key — session ID for `reset = "session"`, branch name for `reset = "branch"`. `ack.sh` and `preview.sh` live there and read `state.json` from the same dir — no params needed from the agent. +**1. Script isolation** — each scope gets its own directory under `.steplock/sessions/`. The dir name is the scope key — session ID for `reset = "session"`. `ack.sh` and `preview.sh` live there and read `state.json` from the same dir — no params needed from the agent. **2. State races** — `ack.sh` writes `state.json` atomically via temp + `mv`. On POSIX `mv` is atomic same-filesystem — a concurrent reader always sees a complete file. diff --git a/examples/README.md b/examples/README.md index 3561883..7c972fe 100644 --- a/examples/README.md +++ b/examples/README.md @@ -21,9 +21,11 @@ Each state blocks the agent until acknowledged. On the fifth invocation, the pus ``` git-push-quality-gate/ ├── .claude/settings.json ← Claude Code hook registration -└── .steplock/checklists/git-push-quality-gate/ - ├── config.toml ← trigger and behaviour - └── flow.mmd ← checklist items as Mermaid diagram +└── .steplock/ + ├── .gitignore ← excludes sessions/ and audit.log + └── checklists/git-push-quality-gate/ + ├── config.toml ← trigger and behaviour + └── flow.mmd ← checklist items as Mermaid diagram ``` ### Usage diff --git a/examples/git-push-quality-gate/.steplock/.gitignore b/examples/git-push-quality-gate/.steplock/.gitignore new file mode 100644 index 0000000..c3c6f64 --- /dev/null +++ b/examples/git-push-quality-gate/.steplock/.gitignore @@ -0,0 +1,2 @@ +sessions/ +audit.log diff --git a/examples/git-push-quality-gate/.steplock/audit.log b/examples/git-push-quality-gate/.steplock/audit.log deleted file mode 100644 index 9216fc4..0000000 --- a/examples/git-push-quality-gate/.steplock/audit.log +++ /dev/null @@ -1 +0,0 @@ -{"checklist":"git-push-quality-gate","event":"block","session":"s1","state":"clean_code","ts":"2026-06-05T01:24:09.682810+00:00"} diff --git a/examples/git-push-quality-gate/.steplock/sessions/s1/ack.sh b/examples/git-push-quality-gate/.steplock/sessions/s1/ack.sh deleted file mode 100755 index 2b8cbb0..0000000 --- a/examples/git-push-quality-gate/.steplock/sessions/s1/ack.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/sh -DIR="$(cd "$(dirname "$0")" && pwd)" -STATE="$DIR/state.json" -TMP="$STATE.tmp.$$" - -CURRENT=$(jq -r '.current_state' "$STATE") -NEXT=$(jq -r '.next_state // empty' "$STATE") -NEXT="${1:-$NEXT}" - -VALID=$(jq -r '.transitions[]' "$STATE") -MATCHED=$(printf '%s\n' $VALID | grep -Fx "$NEXT") - -if [ -z "$MATCHED" ]; then - echo "steplock: invalid next state '$NEXT'" >&2 - echo "Valid transitions from '$CURRENT':" >&2 - printf '%s\n' $VALID | sed 's/^/ /' >&2 - exit 1 -fi - -jq --arg cur "$CURRENT" --arg next "$NEXT" ' - .visited += [$cur] | - .current_state = $next | - .next_state = null -' "$STATE" > "$TMP" && mv "$TMP" "$STATE" diff --git a/examples/git-push-quality-gate/.steplock/sessions/s1/preview.sh b/examples/git-push-quality-gate/.steplock/sessions/s1/preview.sh deleted file mode 100755 index facae49..0000000 --- a/examples/git-push-quality-gate/.steplock/sessions/s1/preview.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/sh -DIR="$(cd "$(dirname "$0")" && pwd)" -STATE="$DIR/state.json" -VISITED=$(jq -r '.visited[]?' "$STATE" 2>/dev/null) - -echo "Checklist: git-push-quality-gate (4 items)" - -check() { - label="$1"; state="$2" - if printf '%s\n' $VISITED | grep -qxF "$state"; then - printf " [x] %s\n" "$label" - else - printf " [ ] %s\n" "$label" - fi -} - -check 'Did you write clean, readable code?' 'clean_code' -check 'Did you increase test coverage by at least a little?' 'test_coverage' -check 'Did you update relevant documentation?' 'documentation' -check 'Did you check for hardcoded secrets or credentials?' 'no_secrets' diff --git a/examples/git-push-quality-gate/.steplock/sessions/s1/state.json b/examples/git-push-quality-gate/.steplock/sessions/s1/state.json deleted file mode 100644 index a244db6..0000000 --- a/examples/git-push-quality-gate/.steplock/sessions/s1/state.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "checklist": "git-push-quality-gate", - "current_state": "clean_code", - "next_state": "test_coverage", - "transitions": [ - "test_coverage" - ], - "visited": [] -} \ No newline at end of file