sisyphi 1.2.17 → 1.2.19
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/dist/cli.js +165 -158
- package/dist/cli.js.map +1 -1
- package/dist/daemon.js +32 -0
- package/dist/daemon.js.map +1 -1
- package/dist/templates/agent-plugin/agents/CLAUDE.md +1 -1
- package/dist/templates/agent-plugin/agents/operator.md +9 -1
- package/dist/templates/agent-plugin/agents/review/CLAUDE.md +0 -1
- package/dist/templates/agent-plugin/agents/review/compliance.md +4 -0
- package/dist/templates/agent-plugin/agents/review/efficiency.md +4 -0
- package/dist/templates/agent-plugin/agents/review/quality.md +4 -0
- package/dist/templates/agent-plugin/agents/review/reuse.md +4 -0
- package/dist/templates/agent-plugin/agents/review/security.md +4 -0
- package/dist/templates/agent-plugin/agents/review/tests.md +4 -0
- package/dist/templates/agent-plugin/agents/review.md +8 -6
- package/dist/templates/agent-suffix.md +9 -1
- package/dist/templates/orchestrator-base.md +14 -1
- package/dist/templates/orchestrator-plugin/hooks/goal-length-guard.sh +60 -0
- package/dist/templates/orchestrator-plugin/hooks/goal-read-advisory.sh +54 -0
- package/dist/templates/orchestrator-plugin/hooks/hooks.json +20 -0
- package/dist/templates/orchestrator-validation.md +10 -0
- package/package.json +1 -1
- package/templates/agent-plugin/agents/CLAUDE.md +1 -1
- package/templates/agent-plugin/agents/operator.md +9 -1
- package/templates/agent-plugin/agents/review/CLAUDE.md +0 -1
- package/templates/agent-plugin/agents/review/compliance.md +4 -0
- package/templates/agent-plugin/agents/review/efficiency.md +4 -0
- package/templates/agent-plugin/agents/review/quality.md +4 -0
- package/templates/agent-plugin/agents/review/reuse.md +4 -0
- package/templates/agent-plugin/agents/review/security.md +4 -0
- package/templates/agent-plugin/agents/review/tests.md +4 -0
- package/templates/agent-plugin/agents/review.md +8 -6
- package/templates/agent-suffix.md +9 -1
- package/templates/orchestrator-base.md +14 -1
- package/templates/orchestrator-plugin/hooks/goal-length-guard.sh +60 -0
- package/templates/orchestrator-plugin/hooks/goal-read-advisory.sh +54 -0
- package/templates/orchestrator-plugin/hooks/hooks.json +20 -0
- package/templates/orchestrator-validation.md +10 -0
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# PostToolUse(Write|Edit|MultiEdit) hook for the orchestrator: enforce the
|
|
3
|
+
# 100-line cap on goal.md. The edit has already landed (PostToolUse runs after
|
|
4
|
+
# success); if goal.md is now over the cap, emit a decision:block so the
|
|
5
|
+
# orchestrator must trim it and move the detail into context/scope-*.md before
|
|
6
|
+
# proceeding. Under the cap → silent passthrough.
|
|
7
|
+
|
|
8
|
+
if [ -z "$SISYPHUS_SESSION_ID" ] || [ -z "$SISYPHUS_SESSION_DIR" ]; then exit 0; fi
|
|
9
|
+
|
|
10
|
+
STDIN_JSON=$(cat)
|
|
11
|
+
|
|
12
|
+
FP=$(printf '%s' "$STDIN_JSON" | python3 -c "
|
|
13
|
+
import json, sys
|
|
14
|
+
try:
|
|
15
|
+
d = json.load(sys.stdin)
|
|
16
|
+
print((d.get('tool_input') or {}).get('file_path') or '')
|
|
17
|
+
except Exception:
|
|
18
|
+
pass
|
|
19
|
+
" 2>/dev/null)
|
|
20
|
+
|
|
21
|
+
[ -z "$FP" ] && exit 0
|
|
22
|
+
|
|
23
|
+
GOAL_FILE="$SISYPHUS_SESSION_DIR/goal.md"
|
|
24
|
+
|
|
25
|
+
SAME=$(python3 -c "
|
|
26
|
+
import os, sys
|
|
27
|
+
try:
|
|
28
|
+
print('1' if os.path.realpath(sys.argv[1]) == os.path.realpath(sys.argv[2]) else '0')
|
|
29
|
+
except Exception:
|
|
30
|
+
print('0')
|
|
31
|
+
" "$FP" "$GOAL_FILE" 2>/dev/null)
|
|
32
|
+
|
|
33
|
+
[ "$SAME" = "1" ] || exit 0
|
|
34
|
+
[ -f "$GOAL_FILE" ] || exit 0
|
|
35
|
+
|
|
36
|
+
LINES=$(python3 -c "
|
|
37
|
+
import sys
|
|
38
|
+
try:
|
|
39
|
+
with open(sys.argv[1], encoding='utf-8') as f:
|
|
40
|
+
print(sum(1 for _ in f))
|
|
41
|
+
except Exception:
|
|
42
|
+
print(0)
|
|
43
|
+
" "$GOAL_FILE" 2>/dev/null)
|
|
44
|
+
|
|
45
|
+
[ -z "$LINES" ] && exit 0
|
|
46
|
+
if [ "$LINES" -le 100 ]; then exit 0; fi
|
|
47
|
+
|
|
48
|
+
REASON=$(cat <<TXT
|
|
49
|
+
goal.md is now ${LINES} lines — over the 100-line cap. Trim it back to the north-star paragraph plus a "## Scope" reference list before continuing.
|
|
50
|
+
|
|
51
|
+
Move the detail you just added into context/scope-<topic>.md (the maintained home for one slice of the goal) and leave only a one-line pointer in goal.md:
|
|
52
|
+
- context/scope-<topic>.md — one-line description
|
|
53
|
+
|
|
54
|
+
Why the cap: goal.md is inlined into every orchestrator wakeup, so length here taxes every future cycle, even ones working far from this detail. Scope files are read on demand and can be referenced from strategy.md / roadmap.md. Restructure the over-cap detail into scope files rather than deleting still-relevant scope to fit.
|
|
55
|
+
TXT
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
ESCAPED=$(printf '%s' "$REASON" | python3 -c "import json,sys; print(json.dumps(sys.stdin.read()))")
|
|
59
|
+
echo "{\"decision\":\"block\",\"reason\":$ESCAPED,\"hookSpecificOutput\":{\"hookEventName\":\"PostToolUse\"}}"
|
|
60
|
+
exit 0
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# PostToolUse(Read) hook for the orchestrator: when the orchestrator reads
|
|
3
|
+
# goal.md, surface the scope-file convention. goal.md is inlined into every
|
|
4
|
+
# wakeup, so the orchestrator only Reads it when it intends to edit — that's
|
|
5
|
+
# the moment to remind it to push concrete detail into context/scope-*.md
|
|
6
|
+
# rather than into the goal. Neutral guidance (additionalContext), not a block.
|
|
7
|
+
|
|
8
|
+
if [ -z "$SISYPHUS_SESSION_ID" ] || [ -z "$SISYPHUS_SESSION_DIR" ]; then exit 0; fi
|
|
9
|
+
|
|
10
|
+
STDIN_JSON=$(cat)
|
|
11
|
+
|
|
12
|
+
FP=$(printf '%s' "$STDIN_JSON" | python3 -c "
|
|
13
|
+
import json, sys
|
|
14
|
+
try:
|
|
15
|
+
d = json.load(sys.stdin)
|
|
16
|
+
print((d.get('tool_input') or {}).get('file_path') or '')
|
|
17
|
+
except Exception:
|
|
18
|
+
pass
|
|
19
|
+
" 2>/dev/null)
|
|
20
|
+
|
|
21
|
+
[ -z "$FP" ] && exit 0
|
|
22
|
+
|
|
23
|
+
GOAL_FILE="$SISYPHUS_SESSION_DIR/goal.md"
|
|
24
|
+
|
|
25
|
+
# Only fire for the session's own goal.md (compare resolved paths).
|
|
26
|
+
SAME=$(python3 -c "
|
|
27
|
+
import os, sys
|
|
28
|
+
try:
|
|
29
|
+
print('1' if os.path.realpath(sys.argv[1]) == os.path.realpath(sys.argv[2]) else '0')
|
|
30
|
+
except Exception:
|
|
31
|
+
print('0')
|
|
32
|
+
" "$FP" "$GOAL_FILE" 2>/dev/null)
|
|
33
|
+
|
|
34
|
+
[ "$SAME" = "1" ] || exit 0
|
|
35
|
+
|
|
36
|
+
ADVISORY=$(cat <<'TXT'
|
|
37
|
+
Editing goal.md? Keep it to the north-star paragraph plus a `## Scope` list of references — nothing more. Put any concrete detail about one slice of the goal (a subsystem, a workstream, a newly-authorized expansion) in `context/scope-<topic>.md`, and link it from goal.md with a one-liner:
|
|
38
|
+
- context/scope-backend.md — DB + API-layer refactors for X
|
|
39
|
+
- context/scope-frontend.md — render-path cleanup for X
|
|
40
|
+
|
|
41
|
+
Why: goal.md is inlined into every orchestrator wakeup and capped at 100 lines, so per-slice detail here taxes every future cycle — even ones working far from that slice. Routing detail into scope files lets scope grow without rewriting the goal: a mid-session "let's also do the microservices" becomes a new scope file linked from goal.md, never a condensed or deleted goal. Maintain scope files like other context docs (current understanding, not history); they are read on demand, and strategy.md/roadmap.md point at whichever scope a stage is focused on.
|
|
42
|
+
TXT
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
printf '%s' "$ADVISORY" | python3 -c "
|
|
46
|
+
import json, sys
|
|
47
|
+
print(json.dumps({
|
|
48
|
+
'hookSpecificOutput': {
|
|
49
|
+
'hookEventName': 'PostToolUse',
|
|
50
|
+
'additionalContext': sys.stdin.read(),
|
|
51
|
+
}
|
|
52
|
+
}))
|
|
53
|
+
"
|
|
54
|
+
exit 0
|
|
@@ -9,6 +9,26 @@
|
|
|
9
9
|
}
|
|
10
10
|
]
|
|
11
11
|
}
|
|
12
|
+
],
|
|
13
|
+
"PostToolUse": [
|
|
14
|
+
{
|
|
15
|
+
"matcher": "Read",
|
|
16
|
+
"hooks": [
|
|
17
|
+
{
|
|
18
|
+
"type": "command",
|
|
19
|
+
"command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/goal-read-advisory.sh"
|
|
20
|
+
}
|
|
21
|
+
]
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"matcher": "Write|Edit|MultiEdit",
|
|
25
|
+
"hooks": [
|
|
26
|
+
{
|
|
27
|
+
"type": "command",
|
|
28
|
+
"command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/goal-length-guard.sh"
|
|
29
|
+
}
|
|
30
|
+
]
|
|
31
|
+
}
|
|
12
32
|
]
|
|
13
33
|
}
|
|
14
34
|
}
|
|
@@ -53,6 +53,16 @@ Every claim in a validation report must have evidence behind it. The validation
|
|
|
53
53
|
|
|
54
54
|
If a validation agent reports without evidence, their report is incomplete. Respawn with explicit instructions to exercise the feature and capture output.
|
|
55
55
|
|
|
56
|
+
### Shallow checks are not proof
|
|
57
|
+
|
|
58
|
+
Exit criteria and recipe steps can pass without exercising how the code actually runs in production. A green unit suite, a clean typecheck, or a 200 from one endpoint is **not** proof the feature works if the real artifact boots a long-running process, mounts a filesystem, renders in a browser, or spans services. Match validation depth to the runtime:
|
|
59
|
+
|
|
60
|
+
- **Long-running process** (NestJS, a daemon, Electron): boot the actual process and exercise it. Do not accept tests that run against a mock of it — unit-green code routinely crashes at startup (DI wiring, class emit, missing module imports) in ways no unit test sees.
|
|
61
|
+
- **UI / anything rendered**: an operator must drive the real surface (this is the non-optional rule above). A passing component test is not a rendered page.
|
|
62
|
+
- **Spans services or a build/bundle step**: exercise the integrated path end-to-end. Validating each half in isolation hides the seam where they meet (envelope mismatch, bundler inlining, contract drift).
|
|
63
|
+
|
|
64
|
+
When the recipe's checks are shallower than how the code runs in production, the recipe is wrong: deepen it, then validate — don't validate against the shallow version and call it proof. The test: *can this check fail the way production fails?* If not, it proves nothing. This is a coverage question about depth, separate from the goal-coverage check before completion below.
|
|
65
|
+
|
|
56
66
|
## Running Validation
|
|
57
67
|
|
|
58
68
|
Spawn validation agents with clear, specific instructions:
|