devflow-kit 3.2.0 → 3.3.0
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/CHANGELOG.md +16 -0
- package/README.md +1 -1
- package/dist/cli/commands/learning.js +25 -5
- package/dist/commands/code-review.md +1 -1
- package/dist/commands/debug.md +1 -1
- package/dist/commands/dynamic-build.md +141 -94
- package/dist/commands/dynamic-plan.md +1 -1
- package/dist/commands/explore.md +1 -1
- package/dist/commands/implement.md +133 -133
- package/dist/commands/resolve.md +27 -16
- package/dist/commands/self-review.md +16 -11
- package/dist/core/agent-models.js +10 -7
- package/dist/core/learning-tuning-config.js +8 -0
- package/dist/core/plugins.js +7 -2
- package/dist/skills/git/references/tracker/github/gather-release-evidence.md +1 -1
- package/dist/skills/git/references/tracker/jira/gather-release-evidence.md +1 -1
- package/dist/skills/git/references/tracker/linear/gather-release-evidence.md +1 -1
- package/package.json +1 -1
- package/src/assets/agents/code.md +71 -18
- package/src/assets/agents/design.md +10 -0
- package/src/assets/agents/diagnose.md +16 -11
- package/src/assets/agents/evaluate.md +14 -25
- package/src/assets/agents/knowledge.md +5 -3
- package/src/assets/agents/learning.md +4 -6
- package/src/assets/agents/research.md +19 -0
- package/src/assets/agents/review.md +10 -0
- package/src/assets/agents/scrutinize.md +34 -10
- package/src/assets/agents/simplify.md +20 -0
- package/src/assets/agents/skim.md +4 -2
- package/src/assets/agents/synthesize.md +12 -0
- package/src/assets/agents/test.md +2 -2
- package/src/assets/agents/triage.md +7 -1
- package/src/assets/agents/validate.md +7 -2
- package/src/assets/commands/_partials/_engine.mds +21 -24
- package/src/assets/commands/_partials/_knowledge.mds +1 -1
- package/src/assets/commands/_partials/_plan_contract.mds +1 -1
- package/src/assets/commands/_partials/_wave.mds +8 -6
- package/src/assets/commands/code-review.mds +1 -1
- package/src/assets/commands/dynamic-build.mds +111 -63
- package/src/assets/commands/implement.mds +132 -132
- package/src/assets/commands/resolve.mds +26 -15
- package/src/assets/commands/self-review.mds +15 -10
- package/src/assets/mds/tracker/_common.mds +1 -1
- package/src/assets/scripts/ci-wait.cjs +636 -0
- package/src/assets/scripts/hooks/assets/orchestrator-charter.md +1 -1
- package/src/assets/scripts/hooks/background-memory-update +290 -9
- package/src/assets/scripts/release-trace.cjs +27 -10
- package/src/assets/skills/accessibility/SKILL.md +1 -1
- package/src/assets/skills/apply-decisions/SKILL.md +12 -82
- package/src/assets/skills/apply-feature-knowledge/SKILL.md +8 -42
- package/src/assets/skills/architecture/SKILL.md +1 -1
- package/src/assets/skills/boundary-validation/SKILL.md +1 -1
- package/src/assets/skills/complexity/SKILL.md +1 -1
- package/src/assets/skills/compliance/SKILL.md +1 -1
- package/src/assets/skills/consistency/SKILL.md +1 -1
- package/src/assets/skills/database/SKILL.md +1 -1
- package/src/assets/skills/dependencies/SKILL.md +1 -1
- package/src/assets/skills/dependency-research/SKILL.md +3 -6
- package/src/assets/skills/design-review/SKILL.md +1 -1
- package/src/assets/skills/docs-framework/SKILL.md +1 -1
- package/src/assets/skills/documentation/SKILL.md +1 -1
- package/src/assets/skills/gap-analysis/SKILL.md +1 -1
- package/src/assets/skills/git/SKILL.md +1 -1
- package/src/assets/skills/go/SKILL.md +1 -1
- package/src/assets/skills/java/SKILL.md +1 -1
- package/src/assets/skills/patterns/SKILL.md +1 -1
- package/src/assets/skills/performance/SKILL.md +1 -1
- package/src/assets/skills/python/SKILL.md +1 -1
- package/src/assets/skills/qa/SKILL.md +1 -3
- package/src/assets/skills/quality-gates/SKILL.md +9 -12
- package/src/assets/skills/quality-gates/references/report-template.md +20 -20
- package/src/assets/skills/react/SKILL.md +1 -1
- package/src/assets/skills/regression/SKILL.md +1 -1
- package/src/assets/skills/reliability/SKILL.md +1 -1
- package/src/assets/skills/research-codebase/SKILL.md +1 -1
- package/src/assets/skills/research-competitor/SKILL.md +1 -1
- package/src/assets/skills/research-external/SKILL.md +1 -1
- package/src/assets/skills/research-technology/SKILL.md +1 -1
- package/src/assets/skills/review-methodology/SKILL.md +1 -1
- package/src/assets/skills/rust/SKILL.md +1 -1
- package/src/assets/skills/security/SKILL.md +1 -1
- package/src/assets/skills/software-design/SKILL.md +1 -1
- package/src/assets/skills/test-driven-development/SKILL.md +9 -29
- package/src/assets/skills/testing/SKILL.md +1 -1
- package/src/assets/skills/typescript/SKILL.md +1 -1
- package/src/assets/skills/ui-design/SKILL.md +1 -1
- package/src/assets/skills/worktree-support/SKILL.md +3 -55
- package/src/assets/skills/worktree-support/references/discovery.md +48 -0
- package/src/assets/skills/worktree-support/references/roots.md +2 -2
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
# background-memory-update — Eager working-memory refresh worker
|
|
4
4
|
# Spawned as a detached background process by memory-worker (Stop hook) after the
|
|
5
|
-
# 120s throttle expires. Drains .pending-turns.jsonl → calls `claude -p`
|
|
5
|
+
# 120s throttle expires. Drains .pending-turns.jsonl → calls `claude -p` on the model
|
|
6
|
+
# and effort the `agents.memory` entry of ~/.devflow/agent-models.json names, else the
|
|
7
|
+
# shipped worker default, in a lean session (D-MEMORY-WORKER-LEAN) →
|
|
6
8
|
# rewrites WORKING-MEMORY.md with a git-reconciliation stamp on line 1.
|
|
7
9
|
#
|
|
8
10
|
# Applies the LLM-vs-plumbing principle: artifact content (WORKING-MEMORY.md) is
|
|
@@ -118,6 +120,92 @@ if ! df_no_symlink_below "$PROJECT_ROOT" "$LOCK_DIR" "$QUEUE_FILE" "$PROCESSING_
|
|
|
118
120
|
exit 0
|
|
119
121
|
fi
|
|
120
122
|
|
|
123
|
+
# --- CLI version probe: choose the argv form (D-MEMORY-WORKER-LEAN) ---
|
|
124
|
+
# The lean argv (--effort, --safe-mode, --max-turns, ...) is verified from
|
|
125
|
+
# MEMORY_MIN_CLAUDE_VERSION up. A CLI older than that, or one whose version cannot be
|
|
126
|
+
# read, gets the legacy argv instead, because one flag a CLI does not know fails every
|
|
127
|
+
# run. The probe runs here, once $CLAUDE_BIN has resolved and the link check has
|
|
128
|
+
# passed, and before the lock is taken, so a slow or hung `--version` can never extend
|
|
129
|
+
# the lock's hold. It is bounded by DEVFLOW_BG_VERSION_PROBE_SECS (default 10, at most
|
|
130
|
+
# 60; tests override it as they do DEVFLOW_BG_WATCHDOG_SECS) with the watchdog's
|
|
131
|
+
# background-and-kill idiom. Its output is parsed, never executed.
|
|
132
|
+
#
|
|
133
|
+
# Errexit safety: the worker runs under `set -e`, and a helper's last non-zero status
|
|
134
|
+
# aborts the caller, so each helper below ends in an explicit return status and is
|
|
135
|
+
# called inside an `if` condition.
|
|
136
|
+
MEMORY_MIN_CLAUDE_VERSION="2.1.286"
|
|
137
|
+
|
|
138
|
+
# Sets CLAUDE_VERSION_TEXT to the first 512 bytes `claude --version` printed ("" on any
|
|
139
|
+
# failure). Returns 0 when it exited 0 inside the bound, else 1. A hung probe gets
|
|
140
|
+
# SIGTERM to its own process group (set -m, as for the spawn below) after the bound
|
|
141
|
+
# and SIGKILL 2s later; the watchdog subshell has its descriptors closed so a sleep it
|
|
142
|
+
# leaves behind holds no pipe open.
|
|
143
|
+
probe_claude_version() {
|
|
144
|
+
local _secs _out _pid _wd_pid _status=1
|
|
145
|
+
CLAUDE_VERSION_TEXT=""
|
|
146
|
+
_secs="${DEVFLOW_BG_VERSION_PROBE_SECS:-10}"
|
|
147
|
+
case "$_secs" in
|
|
148
|
+
''|*[!0123456789]*|????*) _secs=10 ;;
|
|
149
|
+
esac
|
|
150
|
+
if [ "$_secs" -lt 1 ] || [ "$_secs" -gt 60 ]; then _secs=10; fi
|
|
151
|
+
_out=$(mktemp "${TMPDIR:-/tmp}/devflow-claude-version.XXXXXX" 2>/dev/null) || return 1
|
|
152
|
+
set -m
|
|
153
|
+
"$CLAUDE_BIN" --version </dev/null >"$_out" 2>/dev/null &
|
|
154
|
+
_pid=$!
|
|
155
|
+
set +m
|
|
156
|
+
(
|
|
157
|
+
sleep "$_secs"
|
|
158
|
+
kill -TERM -"$_pid" 2>/dev/null || true
|
|
159
|
+
sleep 2
|
|
160
|
+
kill -KILL -"$_pid" 2>/dev/null || true
|
|
161
|
+
) </dev/null >/dev/null 2>&1 &
|
|
162
|
+
_wd_pid=$!
|
|
163
|
+
if wait "$_pid" 2>/dev/null; then _status=0; fi
|
|
164
|
+
kill "$_wd_pid" 2>/dev/null || true
|
|
165
|
+
wait "$_wd_pid" 2>/dev/null || true
|
|
166
|
+
if [ "$_status" -eq 0 ]; then
|
|
167
|
+
CLAUDE_VERSION_TEXT=$(head -c 512 "$_out" 2>/dev/null || true)
|
|
168
|
+
fi
|
|
169
|
+
rm -f "$_out" 2>/dev/null || true
|
|
170
|
+
return "$_status"
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
# Returns 0 when the first X.Y.Z in $1 is at or above the first X.Y.Z in $2, comparing
|
|
174
|
+
# the three components as base-10 numbers left to right (2.10.0 is above 2.1.286, and
|
|
175
|
+
# a leading zero is not octal). Returns 1 when it is below, or when either text holds
|
|
176
|
+
# no X.Y.Z or a component longer than six digits. The digit set is spelled out: a
|
|
177
|
+
# range such as 0-9 collates by locale on bash 3.2.
|
|
178
|
+
claude_version_at_least() {
|
|
179
|
+
local _text="$1" _floor="$2" _re='([0123456789]+)\.([0123456789]+)\.([0123456789]+)'
|
|
180
|
+
local _f1 _f2 _f3 _v1 _v2 _v3
|
|
181
|
+
[[ "$_floor" =~ $_re ]] || return 1
|
|
182
|
+
_f1=${BASH_REMATCH[1]}; _f2=${BASH_REMATCH[2]}; _f3=${BASH_REMATCH[3]}
|
|
183
|
+
[[ "$_text" =~ $_re ]] || return 1
|
|
184
|
+
_v1=${BASH_REMATCH[1]}; _v2=${BASH_REMATCH[2]}; _v3=${BASH_REMATCH[3]}
|
|
185
|
+
if [ "${#_v1}" -gt 6 ] || [ "${#_v2}" -gt 6 ] || [ "${#_v3}" -gt 6 ]; then return 1; fi
|
|
186
|
+
_v1=$((10#$_v1)); _v2=$((10#$_v2)); _v3=$((10#$_v3))
|
|
187
|
+
_f1=$((10#$_f1)); _f2=$((10#$_f2)); _f3=$((10#$_f3))
|
|
188
|
+
if [ "$_v1" -ne "$_f1" ]; then
|
|
189
|
+
if [ "$_v1" -gt "$_f1" ]; then return 0; fi
|
|
190
|
+
return 1
|
|
191
|
+
fi
|
|
192
|
+
if [ "$_v2" -ne "$_f2" ]; then
|
|
193
|
+
if [ "$_v2" -gt "$_f2" ]; then return 0; fi
|
|
194
|
+
return 1
|
|
195
|
+
fi
|
|
196
|
+
if [ "$_v3" -ge "$_f3" ]; then return 0; fi
|
|
197
|
+
return 1
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
CLAUDE_ARGV_FORM="legacy"
|
|
201
|
+
if ! probe_claude_version; then
|
|
202
|
+
log "claude --version probe failed or timed out — using the legacy argv"
|
|
203
|
+
elif claude_version_at_least "$CLAUDE_VERSION_TEXT" "$MEMORY_MIN_CLAUDE_VERSION"; then
|
|
204
|
+
CLAUDE_ARGV_FORM="lean"
|
|
205
|
+
else
|
|
206
|
+
log "claude --version is below ${MEMORY_MIN_CLAUDE_VERSION} or unparseable — using the legacy argv"
|
|
207
|
+
fi
|
|
208
|
+
|
|
121
209
|
# --- Worker-level lock (300s stale-break — much longer than learning-lock's 30s) ---
|
|
122
210
|
# This prevents a second worker (spawned 121s later) from double-writing WORKING-MEMORY.md
|
|
123
211
|
# while the first worker's claude -p call (up to 120s) is still in flight.
|
|
@@ -171,7 +259,20 @@ fi
|
|
|
171
259
|
# Clean up any staged file left by a watchdog-killed prior run.
|
|
172
260
|
# Without this, a stale staged file with a valid stamp would be mistakenly
|
|
173
261
|
# mv-ed to the real path on the NEXT run's CAS check (D-MEMORY-STAGED-CAS).
|
|
262
|
+
#
|
|
263
|
+
# D-MEMORY-WORKER-LEAN: the removal is also a CHECKED precondition. The model gets the
|
|
264
|
+
# Write tool alone, and Write refuses a file that exists and has not been read, which
|
|
265
|
+
# is how an earlier Write-only worker failed silently: every Write errored while the
|
|
266
|
+
# run exited 0. Once nothing stands at the staged path, the one Write is always a
|
|
267
|
+
# create, so Write-only is safe. A path `rm -f` cannot clear (a directory, say) would
|
|
268
|
+
# make every Write fail, so the run stops here instead: no LLM call, the batch and
|
|
269
|
+
# the queue untouched (nothing has been claimed yet), the lock released by the EXIT
|
|
270
|
+
# trap. `-e` or `-L`, so a link there counts as present.
|
|
174
271
|
rm -f "$STAGED_FILE" 2>/dev/null || true
|
|
272
|
+
if [ -e "$STAGED_FILE" ] || [ -L "$STAGED_FILE" ]; then
|
|
273
|
+
log "SKIP: $STAGED_FILE could not be removed — a Write to it would fail, so no LLM run; the batch and the queue are left as they are"
|
|
274
|
+
exit 0
|
|
275
|
+
fi
|
|
175
276
|
|
|
176
277
|
# --- Orphan-only skip: if queue has no assistant/qa turn, exit and leave the queue ---
|
|
177
278
|
# This prevents fabrication-prone LLM runs with only user turns in the queue.
|
|
@@ -500,7 +601,107 @@ Instructions:
|
|
|
500
601
|
EOF
|
|
501
602
|
)
|
|
502
603
|
|
|
503
|
-
|
|
604
|
+
# --- Model and effort (D-MEMORY-WORKER-LEAN) ---
|
|
605
|
+
# One authority: WORKER_AGENTS.memory in src/core/agent-models.ts, which `devflow
|
|
606
|
+
# agents` shows as the worker's default. The two defaults below are that row spelled
|
|
607
|
+
# out for bash, held equal to it by tests/agent-models-worker.test.ts, as are the
|
|
608
|
+
# alias and effort lists and the name rules. A personal `agents.memory` entry in
|
|
609
|
+
# $HOME/.devflow/agent-models.json (the machine root; nothing relocates it) overrides
|
|
610
|
+
# them. Each field is validated on its own against the worker domain, so a bad model
|
|
611
|
+
# keeps a good effort and the reverse:
|
|
612
|
+
# model = `default` (the shipped one), one of the aliases, or a `claude-` name;
|
|
613
|
+
# a name starts with a letter or digit, continues with those and . _ -,
|
|
614
|
+
# and is 64 characters at most (MODEL_NAME_RE in src/core/agent-frontmatter.ts)
|
|
615
|
+
# effort = `default` (the shipped one) or one of the levels
|
|
616
|
+
# `inherit` is outside both, since a background worker has no session to inherit from.
|
|
617
|
+
# Only a value that passed its match reaches argv. A value that is absent, empty or
|
|
618
|
+
# not a JSON string reads as absent and takes the shipped one silently; a string that
|
|
619
|
+
# fails its match takes it with one log line naming the field, never the value.
|
|
620
|
+
# The character sets are spelled out because a range such as A-Za-z matches accented
|
|
621
|
+
# letters in a UTF-8 locale on bash 3.2.
|
|
622
|
+
MEMORY_MODEL_DEFAULT="claude-sonnet-5-5"
|
|
623
|
+
MEMORY_EFFORT_DEFAULT="high"
|
|
624
|
+
MEMORY_MODEL_ALIASES="haiku sonnet opus fable"
|
|
625
|
+
MEMORY_MODEL_PREFIX="claude-"
|
|
626
|
+
MEMORY_MODEL_MAX_LEN=64
|
|
627
|
+
MEMORY_EFFORT_LEVELS="low medium high xhigh max"
|
|
628
|
+
MEMORY_NAME_HEAD="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
|
|
629
|
+
MEMORY_EFFORT_CHARS="abcdefghijklmnopqrstuvwxyz"
|
|
630
|
+
|
|
631
|
+
# Prints the string value of agents.memory.<field> followed by one `x` (the caller strips
|
|
632
|
+
# it, so a value's own trailing newline survives the command substitution). Prints just
|
|
633
|
+
# the `x` when the file, the field or a string there is missing. Always returns 0.
|
|
634
|
+
memory_agent_field() {
|
|
635
|
+
local _file="$HOME/.devflow/agent-models.json"
|
|
636
|
+
if [ "$_JSON_AVAILABLE" = "true" ] && [ -f "$_file" ]; then
|
|
637
|
+
json_string_field_file "$_file" "agents.memory.$1" 2>/dev/null || true
|
|
638
|
+
fi
|
|
639
|
+
printf x
|
|
640
|
+
return 0
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
# Sets MEMORY_MODEL. Always returns 0.
|
|
644
|
+
resolve_memory_model() {
|
|
645
|
+
local _raw _tail="${MEMORY_NAME_HEAD}._-" _ok=""
|
|
646
|
+
MEMORY_MODEL="$MEMORY_MODEL_DEFAULT"
|
|
647
|
+
_raw=$(memory_agent_field model)
|
|
648
|
+
_raw=${_raw%x}
|
|
649
|
+
case "$_raw" in
|
|
650
|
+
''|default) return 0 ;;
|
|
651
|
+
[!$MEMORY_NAME_HEAD]*|*[!$_tail]*) ;;
|
|
652
|
+
*)
|
|
653
|
+
if [ "${#_raw}" -le "$MEMORY_MODEL_MAX_LEN" ]; then
|
|
654
|
+
case " $MEMORY_MODEL_ALIASES " in
|
|
655
|
+
*" $_raw "*) _ok="yes" ;;
|
|
656
|
+
esac
|
|
657
|
+
case "$_raw" in
|
|
658
|
+
"$MEMORY_MODEL_PREFIX"?*) _ok="yes" ;;
|
|
659
|
+
esac
|
|
660
|
+
fi
|
|
661
|
+
;;
|
|
662
|
+
esac
|
|
663
|
+
if [ -n "$_ok" ]; then
|
|
664
|
+
MEMORY_MODEL="$_raw"
|
|
665
|
+
else
|
|
666
|
+
log "agents.memory.model: not a model the worker accepts (default, an alias or a ${MEMORY_MODEL_PREFIX} name) — using the shipped model"
|
|
667
|
+
fi
|
|
668
|
+
return 0
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
# Sets MEMORY_EFFORT. Always returns 0.
|
|
672
|
+
resolve_memory_effort() {
|
|
673
|
+
local _raw _ok=""
|
|
674
|
+
MEMORY_EFFORT="$MEMORY_EFFORT_DEFAULT"
|
|
675
|
+
_raw=$(memory_agent_field effort)
|
|
676
|
+
_raw=${_raw%x}
|
|
677
|
+
case "$_raw" in
|
|
678
|
+
''|default) return 0 ;;
|
|
679
|
+
*[!$MEMORY_EFFORT_CHARS]*) ;;
|
|
680
|
+
*)
|
|
681
|
+
case " $MEMORY_EFFORT_LEVELS " in
|
|
682
|
+
*" $_raw "*) _ok="yes" ;;
|
|
683
|
+
esac
|
|
684
|
+
;;
|
|
685
|
+
esac
|
|
686
|
+
if [ -n "$_ok" ]; then
|
|
687
|
+
MEMORY_EFFORT="$_raw"
|
|
688
|
+
else
|
|
689
|
+
log "agents.memory.effort: not an effort level the worker accepts (default or a level) — using the shipped effort"
|
|
690
|
+
fi
|
|
691
|
+
return 0
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
resolve_memory_model
|
|
695
|
+
resolve_memory_effort
|
|
696
|
+
|
|
697
|
+
if [ "$CLAUDE_ARGV_FORM" = "lean" ]; then
|
|
698
|
+
EFFORT_LOG="effort ${MEMORY_EFFORT}"
|
|
699
|
+
ARGV_LOG="lean argv"
|
|
700
|
+
else
|
|
701
|
+
EFFORT_LOG="no effort passed"
|
|
702
|
+
ARGV_LOG="legacy argv"
|
|
703
|
+
fi
|
|
704
|
+
log "Spawning claude -p (model ${MEMORY_MODEL}, ${EFFORT_LOG}, ${ARGV_LOG}, ${TURN_COUNT} turns)"
|
|
504
705
|
# SECURITY: never log PROMPT — it contains turn content which may include secrets
|
|
505
706
|
|
|
506
707
|
# --- Watchdog timeout (overridable for tests: DEVFLOW_BG_WATCHDOG_SECS=2) ---
|
|
@@ -537,14 +738,94 @@ fi
|
|
|
537
738
|
# Restore set +m immediately after capturing CLAUDE_PID so the watchdog subshell and
|
|
538
739
|
# other subsequent background operations stay in the worker's group.
|
|
539
740
|
# Job-control notifications go to stderr which is redirected to the log — suppress them.
|
|
741
|
+
#
|
|
742
|
+
# D-MEMORY-WORKER-LEAN — the spawn. The worker opens a headless session to make one
|
|
743
|
+
# Write, so the session is cut to what that Write needs. Prompt on stdin, output and
|
|
744
|
+
# errors to the log, as before. Two argv forms, chosen by the version probe above:
|
|
745
|
+
#
|
|
746
|
+
# lean (CLI at or above MEMORY_MIN_CLAUDE_VERSION):
|
|
747
|
+
# -p --model M --effort E --safe-mode --tools Write --disable-slash-commands \
|
|
748
|
+
# --strict-mcp-config --mcp-config '{"mcpServers":{}}' --max-turns 3 \
|
|
749
|
+
# --dangerously-skip-permissions --output-format text
|
|
750
|
+
# legacy (older, unreadable or timed-out probe):
|
|
751
|
+
# -p --model M --tools Write --dangerously-skip-permissions --output-format text
|
|
752
|
+
#
|
|
753
|
+
# What each flag is for:
|
|
754
|
+
# --model, --effort the resolved agents.memory values above. --effort is the only
|
|
755
|
+
# effort source: an inherited CLAUDE_CODE_EFFORT_LEVEL beats the
|
|
756
|
+
# flag (measured on 2026-10-09), so it is unset below, for both
|
|
757
|
+
# forms, and the log's "no effort passed" is then true.
|
|
758
|
+
# --safe-mode starts with the user's customisations off: instruction files,
|
|
759
|
+
# skills, plugins, hooks, MCP servers, custom commands and agents.
|
|
760
|
+
# Auth, model selection and built-in tools work as usual, and
|
|
761
|
+
# settings `env` (the provider URL and key) still applies under
|
|
762
|
+
# it (measured on 2026-10-09), so a routed or keyed install works.
|
|
763
|
+
# --tools Write Write is the only tool. `--allowedTools` only pre-approves, it
|
|
764
|
+
# leaves every tool, listing and MCP server loaded.
|
|
765
|
+
# --disable-slash-commands, --strict-mcp-config with an empty --mcp-config
|
|
766
|
+
# no slash-command or skill listing, no MCP server and none of the
|
|
767
|
+
# instructions they add to the context.
|
|
768
|
+
# --max-turns 3 the worker's own pattern is one Write and then the end of the
|
|
769
|
+
# turn, two requests; the third is margin. A run that reaches the
|
|
770
|
+
# cap exits non-zero, so its batch stays for the retry; the Write
|
|
771
|
+
# on the capped turn still runs. 3 was verified on claude 2.1.294
|
|
772
|
+
# on 2026-10-09 (cap 1 exits 1, caps 2 and 3 exit 0 on that
|
|
773
|
+
# pattern). `--max-turns` is not listed in `claude --help` there
|
|
774
|
+
# but is registered (`--max-turns abc` errors "must be a number"),
|
|
775
|
+
# which is why it was exercised rather than read off the help.
|
|
776
|
+
# --dangerously-skip-permissions headless: nothing could answer a prompt.
|
|
777
|
+
# --output-format text
|
|
778
|
+
# DEVFLOW_BG_UPDATER=1 the recursion guard stays on both forms, though --safe-mode
|
|
779
|
+
# also disables hooks. CLAUDE_CODE_DISABLE_CLAUDE_MDS=1 and
|
|
780
|
+
# CLAUDE_CODE_DISABLE_AUTO_MEMORY=1 keep the instruction files and
|
|
781
|
+
# auto-memory out on both forms, including the legacy one.
|
|
782
|
+
#
|
|
783
|
+
# Why Write-only is safe: the staged path is empty before every run (the removal and
|
|
784
|
+
# the checked precondition after the lock above), so the one Write is always a create.
|
|
785
|
+
# Write refuses an existing file that has not been read, and that is the whole history
|
|
786
|
+
# of this flag set:
|
|
787
|
+
# a472a490 passed `--tools "Write"` with `--allowedTools` for two memory files;
|
|
788
|
+
# e701cecc widened the tools to `Read,Write,Bash` after counting the silent
|
|
789
|
+
# read-before-write failures (the run exited 0 while every Write errored);
|
|
790
|
+
# baf02265 removed both flags, with no reason in its message;
|
|
791
|
+
# 6186645f raised the worker's model and kept `--allowedTools 'Read,Write'`.
|
|
792
|
+
#
|
|
793
|
+
# The version floor is 2.1.286, the lowest CLI on which the whole lean argv was run
|
|
794
|
+
# and its flags, the settings `env` under --safe-mode and the effort override were
|
|
795
|
+
# checked (2.1.286 and 2.1.292 to 2.1.294 behave identically; 2026-10-09, recorded in
|
|
796
|
+
# docs/reference/platform-assumptions.md). The legacy form carries no --effort,
|
|
797
|
+
# --safe-mode, --max-turns, --disable-slash-commands, --strict-mcp-config or
|
|
798
|
+
# --mcp-config, none of which is verified on older CLIs, so on it effort is not
|
|
799
|
+
# applied, MCP servers stay loaded and there is no turn cap.
|
|
800
|
+
#
|
|
801
|
+
# The turns input has no byte cap: the queue holds every turn whole by design, and the
|
|
802
|
+
# prompt is bounded by the newest-20-rows window above and the 64 KB existing-memory
|
|
803
|
+
# cap, not by cutting a turn.
|
|
804
|
+
unset CLAUDE_CODE_EFFORT_LEVEL
|
|
540
805
|
set -m
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
806
|
+
if [ "$CLAUDE_ARGV_FORM" = "lean" ]; then
|
|
807
|
+
DEVFLOW_BG_UPDATER=1 CLAUDE_CODE_DISABLE_CLAUDE_MDS=1 CLAUDE_CODE_DISABLE_AUTO_MEMORY=1 "$CLAUDE_BIN" -p \
|
|
808
|
+
--model "$MEMORY_MODEL" \
|
|
809
|
+
--effort "$MEMORY_EFFORT" \
|
|
810
|
+
--safe-mode \
|
|
811
|
+
--tools Write \
|
|
812
|
+
--disable-slash-commands \
|
|
813
|
+
--strict-mcp-config \
|
|
814
|
+
--mcp-config '{"mcpServers":{}}' \
|
|
815
|
+
--max-turns 3 \
|
|
816
|
+
--dangerously-skip-permissions \
|
|
817
|
+
--output-format text \
|
|
818
|
+
<<< "$PROMPT" \
|
|
819
|
+
>> "$LOG_FILE" 2>&1 &
|
|
820
|
+
else
|
|
821
|
+
DEVFLOW_BG_UPDATER=1 CLAUDE_CODE_DISABLE_CLAUDE_MDS=1 CLAUDE_CODE_DISABLE_AUTO_MEMORY=1 "$CLAUDE_BIN" -p \
|
|
822
|
+
--model "$MEMORY_MODEL" \
|
|
823
|
+
--tools Write \
|
|
824
|
+
--dangerously-skip-permissions \
|
|
825
|
+
--output-format text \
|
|
826
|
+
<<< "$PROMPT" \
|
|
827
|
+
>> "$LOG_FILE" 2>&1 &
|
|
828
|
+
fi
|
|
548
829
|
CLAUDE_PID=$!
|
|
549
830
|
set +m
|
|
550
831
|
|
|
@@ -113,12 +113,28 @@ const FULL_SHA_RE = /^[0-9a-f]{40}$/;
|
|
|
113
113
|
const KEY_RE = /^[A-Z][A-Z0-9_]{1,9}$/;
|
|
114
114
|
|
|
115
115
|
/**
|
|
116
|
-
*
|
|
117
|
-
*
|
|
118
|
-
*
|
|
119
|
-
*
|
|
116
|
+
* D-TRACE-KEYWORDS: two keyword sets, deliberately unequal, because they answer
|
|
117
|
+
* two different questions.
|
|
118
|
+
*
|
|
119
|
+
* CLOSING_KEYWORD_RE is step 3a's closing-keyword regex, byte-for-byte the literal
|
|
120
|
+
* the built `gather-release-evidence` references state: a commit that carries one
|
|
121
|
+
* of these keywords ships the issue it names. `Refs #N` only mentions an issue, so
|
|
122
|
+
* `refs` is not a closing keyword and the prompt never lets such a commit reach
|
|
123
|
+
* SHIPPED_ISSUES. The script itself classifies with TRACE_KEYWORD_RE; this regex
|
|
124
|
+
* is exported so a parity test can pin the prompt's rule to a literal.
|
|
125
|
+
*
|
|
126
|
+
* TRACE_KEYWORD_RE is the closing set plus `refs`. The trace map asks the weaker
|
|
127
|
+
* question "does this commit name an issue at all?", and a `Refs #N` commit does,
|
|
128
|
+
* so it is `traced` and not `untraced`. Narrowing the closing set must not turn
|
|
129
|
+
* those commits into traceability gaps in the release confirm.
|
|
130
|
+
*
|
|
131
|
+
* Both apply case-insensitively WITHOUT the `u` flag — so a non-ASCII letter
|
|
132
|
+
* (`ſ`, the Kelvin sign) never folds onto an ASCII keyword letter. A parity test
|
|
133
|
+
* pins CLOSING_KEYWORD_RE's `.source` and `.flags` to the built text, and
|
|
134
|
+
* TRACE_KEYWORD_RE to the closing set plus `refs`.
|
|
120
135
|
*/
|
|
121
|
-
const
|
|
136
|
+
const CLOSING_KEYWORD_RE = /^\(?(close[sd]?|fix(e[sd])?|resolve[sd]?):?$/i;
|
|
137
|
+
const TRACE_KEYWORD_RE = /^\(?(close[sd]?|fix(e[sd])?|resolve[sd]?|refs):?$/i;
|
|
122
138
|
|
|
123
139
|
/** Step 3a's trailing-strip class, byte-for-byte the built literal (parity-pinned). */
|
|
124
140
|
const TRAILING_CLASS = '[.,;:)\\]!?]';
|
|
@@ -377,11 +393,11 @@ function gateCandidate(candidate, grammar, key) {
|
|
|
377
393
|
|
|
378
394
|
/**
|
|
379
395
|
* Step 3a, executed, then the grammar's gate: the first reference `message`
|
|
380
|
-
* yields, or null. Per line, a whitespace token matching
|
|
381
|
-
* the next token, plus each further token while the previous one ends in `,`.
|
|
396
|
+
* yields, or null. Per line, a whitespace token matching TRACE_KEYWORD_RE opens a
|
|
397
|
+
* run: the next token, plus each further token while the previous one ends in `,`.
|
|
382
398
|
* Each run token splits on `,`, is stripped, and non-empty parts are gated.
|
|
383
399
|
*
|
|
384
|
-
* Linear in the message: a keyword token never ends in `,` (
|
|
400
|
+
* Linear in the message: a keyword token never ends in `,` (TRACE_KEYWORD_RE is
|
|
385
401
|
* anchored), so every comma run is walked by at most the one keyword before it.
|
|
386
402
|
*
|
|
387
403
|
* @param {string} message
|
|
@@ -393,7 +409,7 @@ function findReference(message, grammar, key) {
|
|
|
393
409
|
for (const line of message.split('\n')) {
|
|
394
410
|
const tokens = line.split(/\s+/).filter(t => t !== '');
|
|
395
411
|
for (let i = 0; i < tokens.length; i++) {
|
|
396
|
-
if (!
|
|
412
|
+
if (!TRACE_KEYWORD_RE.test(tokens[i])) continue;
|
|
397
413
|
for (let j = i + 1; j < tokens.length; j++) {
|
|
398
414
|
for (const part of tokens[j].split(',')) {
|
|
399
415
|
const stripped = stripCandidate(part);
|
|
@@ -1117,7 +1133,8 @@ module.exports = Object.freeze({
|
|
|
1117
1133
|
EXIT_CODES,
|
|
1118
1134
|
LIMITS,
|
|
1119
1135
|
RELEASE_TAG_RE,
|
|
1120
|
-
|
|
1136
|
+
CLOSING_KEYWORD_RE,
|
|
1137
|
+
TRACE_KEYWORD_RE,
|
|
1121
1138
|
TRAILING_CLASS,
|
|
1122
1139
|
GRAMMARS,
|
|
1123
1140
|
GRAMMAR_RULES,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: accessibility
|
|
3
|
-
description: This skill should be used when the user asks to "add accessibility", "check ARIA", "handle keyboard navigation",
|
|
3
|
+
description: This skill should be used when the user asks to "add accessibility", "check ARIA", "handle keyboard navigation", or creates UI components, forms, or interactive elements.
|
|
4
4
|
user-invocable: false
|
|
5
5
|
allowed-tools: Read, Grep, Glob
|
|
6
6
|
activation:
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: apply-decisions
|
|
3
|
-
description:
|
|
3
|
+
description: Consume the DECISIONS_CONTEXT index; cite IDs in-session only
|
|
4
4
|
user-invocable: false
|
|
5
|
-
allowed-tools: Read
|
|
5
|
+
allowed-tools: Read, Bash
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Apply Decisions
|
|
9
9
|
|
|
10
|
-
Canonical consumer algorithm for the `DECISIONS_CONTEXT` index passed by orchestrators. The index lists each active ADR/PF entry with its ID and title — plus a status tag and an area on a v1 line, or the entry's scope on a v2 line — not the full body. Use this skill to surface the right decisions and pitfalls for your task without loading the entire corpus.
|
|
11
|
-
|
|
12
10
|
## Iron Law
|
|
13
11
|
|
|
14
12
|
> **VERBATIM IDs ONLY — NEVER FABRICATE**
|
|
@@ -17,104 +15,36 @@ Canonical consumer algorithm for the `DECISIONS_CONTEXT` index passed by orchest
|
|
|
17
15
|
> in the index, do not cite it. If an entry looks relevant but you haven't Read its
|
|
18
16
|
> full body, do not cite it. Fabricated citations are worse than no citations.
|
|
19
17
|
|
|
20
|
-
---
|
|
21
|
-
|
|
22
18
|
## 5-Step Algorithm
|
|
23
19
|
|
|
24
20
|
### Step 1: Scan the index
|
|
25
21
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
```
|
|
29
|
-
Decisions (N):
|
|
30
|
-
ADR-NNN Return Result types from every fallible operation [Accepted]
|
|
31
|
-
ADR-NNN Claim the learning queue with an op, never with mv — src/assets/scripts/hooks/**, area:learning
|
|
32
|
-
|
|
33
|
-
Pitfalls (M):
|
|
34
|
-
PF-NNN Background hook god scripts [Active] — src/assets/scripts/hooks/foo.cjs
|
|
35
|
-
PF-NNN A rename claims a shared file only while nothing re-creates it — area:hooks
|
|
36
|
-
|
|
37
|
-
ADR-NNN entries live in {worktree}/.devflow/learning/decisions.md
|
|
38
|
-
PF-NNN entries live in {worktree}/.devflow/learning/pitfalls.md
|
|
39
|
-
Read the relevant file and locate the matching `## ADR-NNN:` or `## PF-NNN:` heading for the full body.
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
- **A v1 line** ends in a status tag — `[Accepted]` on a decision, `[Active]` on a pitfall — after a title cut to 60 characters, and a pitfall adds its area after `—`.
|
|
43
|
-
- **A v2 line** has no tag. Its title is whole, and after `—` comes its scope: the globs and `area:` tags the rule governs, cut to 80 characters.
|
|
22
|
+
One line per active entry: its ID (`ADR-NNN` or `PF-NNN`), a title, then a status tag and/or, after `—`, its area or scope. The footer names the decisions and pitfalls files.
|
|
44
23
|
|
|
45
24
|
### Step 2: Identify plausibly-relevant entries
|
|
46
25
|
|
|
47
|
-
|
|
48
|
-
- The files you are modifying or reviewing — a v2 scope glob that matches one of them is a strong signal
|
|
49
|
-
- The category of issue you are addressing (e.g., error handling, hook scripts, JSON parsing)
|
|
50
|
-
- The architectural area of your change
|
|
51
|
-
|
|
52
|
-
A v1 title may be cut short — if a truncated title looks relevant, proceed to Step 3.
|
|
26
|
+
Pick entries whose title, area or scope overlaps the files you touch (a matching scope glob is a strong signal), the kind of issue or the architectural area. Follow up a cut-short title that looks relevant.
|
|
53
27
|
|
|
54
28
|
### Step 3: Read the full body
|
|
55
29
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
A v2 body reads:
|
|
30
|
+
Find the entry's heading line in the file the footer names, then Read only that section:
|
|
59
31
|
|
|
32
|
+
```bash
|
|
33
|
+
command grep -nF '## ADR-NNN:' "{worktree-from-footer}/.devflow/learning/decisions.md"
|
|
60
34
|
```
|
|
61
|
-
## ADR-NNN: {title}
|
|
62
35
|
|
|
63
|
-
-
|
|
64
|
-
- **Scope**: `{glob}`, `area:{tag}`
|
|
65
|
-
- **Decision**: {the rule}
|
|
66
|
-
- **Why**: {why it holds}
|
|
67
|
-
- **Source**: {where it was learned}
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
A pitfall's Status is `Active` and its rule line is labelled `**Rule**`. The verified date is the day the entry was last confirmed true; a body without one has not been confirmed since it was written. A v1 body carries `**Date**`, `**Status**`, `**Context**`, `**Decision**` and `**Consequences**` for a decision, or `**Area**`, `**Issue**`, `**Impact**`, `**Resolution**` and `**Status**` for a pitfall.
|
|
71
|
-
|
|
72
|
-
**The footer is the single source of truth for file paths.** Never substitute hardcoded paths — the footer resolves to the correct worktree, which may differ from your cwd in multi-worktree flows.
|
|
73
|
-
|
|
74
|
-
```
|
|
75
|
-
Use the exact paths from the DECISIONS_CONTEXT footer, e.g.:
|
|
76
|
-
{worktree-from-footer}/.devflow/learning/decisions.md → find ## ADR-NNN: heading
|
|
77
|
-
{worktree-from-footer}/.devflow/learning/pitfalls.md → find ## PF-NNN: heading
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
Only cite an entry after you have read its full body and confirmed it applies.
|
|
36
|
+
For a pitfall use `## PF-NNN:` and `pitfalls.md`. Read with `offset` at the printed line and a `limit` of about 25, stopping at the next `## `. The footer is the single source of truth for paths; the ledger is git-ignored, so only a shell search finds the line. A `verified` date is when the entry was last confirmed true; none means unconfirmed. Cite only after reading the body and confirming it applies.
|
|
81
37
|
|
|
82
38
|
### Step 4: Cite inline — in-session handoffs only
|
|
83
39
|
|
|
84
|
-
|
|
40
|
+
Cite `applies ADR-NNN` or `avoids PF-NNN` in-session only: your reasoning, prompts to downstream agents, your report back.
|
|
85
41
|
|
|
86
|
-
Anything committed, pushed or posted states the rule in words, never its ID
|
|
42
|
+
Anything committed, pushed or posted states the rule in words, never its ID (code, comments, tests, docs, commit messages, PR and issue text, review comments, and any report copied into those). IDs are numbered per machine, so no other clone can resolve one.
|
|
87
43
|
|
|
88
44
|
### Step 5: Use verbatim IDs only
|
|
89
45
|
|
|
90
|
-
Cite only IDs
|
|
91
|
-
|
|
92
|
-
---
|
|
93
|
-
|
|
94
|
-
## Worked Example
|
|
95
|
-
|
|
96
|
-
**Scenario**: Reviewing `src/assets/scripts/hooks/background-learning` for issues.
|
|
97
|
-
|
|
98
|
-
1. **Scan** — Index shows `PF-NNN Background hook god scripts [Active] — src/assets/scripts/hooks/foo.cjs`
|
|
99
|
-
2. **Identify** — Area field includes `src/assets/scripts/hooks/` which overlaps with the file under review
|
|
100
|
-
3. **Read** — Open the pitfalls file at the path given in the DECISIONS_CONTEXT footer (e.g., `<worktree>/.devflow/learning/pitfalls.md`), find `## PF-NNN:` section, read full body
|
|
101
|
-
4. **Cite** — If the file shows signs of the god-script pattern, note `avoids PF-NNN` in reasoning; a comment you commit for the fix says why in words ("hooks stay thin dispatchers"), never the ID
|
|
102
|
-
5. **Verbatim** — ID `PF-NNN` appeared in the index; citation is valid
|
|
103
|
-
|
|
104
|
-
---
|
|
46
|
+
Cite only IDs in `DECISIONS_CONTEXT`; never guess or rebuild one. When nothing clearly applies, cite nothing.
|
|
105
47
|
|
|
106
48
|
## Skip Guard
|
|
107
49
|
|
|
108
|
-
When `DECISIONS_CONTEXT` is empty, `(none)
|
|
109
|
-
|
|
110
|
-
---
|
|
111
|
-
|
|
112
|
-
## Citation Format Reference
|
|
113
|
-
|
|
114
|
-
| Situation | Citation |
|
|
115
|
-
|-----------|----------|
|
|
116
|
-
| Applying a prior architectural decision | `applies ADR-NNN` |
|
|
117
|
-
| Avoiding a known pitfall | `avoids PF-NNN` |
|
|
118
|
-
| Entry not in index | (no citation — silence is correct) |
|
|
119
|
-
| Entry in index but not read yet | (no citation — read first) |
|
|
120
|
-
| Text that is committed, pushed or posted | (no ID — state the rule in words) |
|
|
50
|
+
When `DECISIONS_CONTEXT` is empty, `(none)` or not provided, skip this skill — unless your instructions tell you to read the decisions index yourself; that index is then your `DECISIONS_CONTEXT`. Never load decisions files otherwise.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: apply-feature-knowledge
|
|
3
|
-
description:
|
|
3
|
+
description: Consume FEATURE_KNOWLEDGE, the pre-computed feature context
|
|
4
4
|
user-invocable: false
|
|
5
5
|
allowed-tools: Read
|
|
6
6
|
---
|
|
@@ -11,37 +11,17 @@ allowed-tools: Read
|
|
|
11
11
|
|
|
12
12
|
> **Pre-computed context, not a cage. Verify against current code — always.**
|
|
13
13
|
>
|
|
14
|
-
> A feature knowledge captures patterns AS THEY WERE when last written.
|
|
15
|
-
>
|
|
16
|
-
>
|
|
14
|
+
> A feature knowledge captures patterns AS THEY WERE when last written. Use it as a
|
|
15
|
+
> starting point, not gospel truth; when something feels off, Read the actual files.
|
|
16
|
+
> Code is authoritative.
|
|
17
17
|
|
|
18
18
|
---
|
|
19
19
|
|
|
20
20
|
## 3-Step Algorithm
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
1. Read each feature knowledge section (separated by `--- Feature knowledge: {slug} ---` headers)
|
|
27
|
-
2. Absorb: architecture, data flow, key patterns, anti-patterns, gotchas
|
|
28
|
-
3. Note integration points that relate to your current task
|
|
29
|
-
|
|
30
|
-
### Step 2: Apply to Current Task
|
|
31
|
-
|
|
32
|
-
1. **Patterns as defaults**: Follow documented patterns unless you have a specific reason not to
|
|
33
|
-
2. **Anti-patterns as warnings**: Check your work against documented anti-patterns
|
|
34
|
-
3. **Gotchas as checklists**: Verify each gotcha doesn't apply to your changes
|
|
35
|
-
4. **Integration points**: Ensure your changes respect documented boundaries
|
|
36
|
-
5. **Key files**: Use as starting points for exploration
|
|
37
|
-
|
|
38
|
-
### Step 3: Verify Against Current Code
|
|
39
|
-
|
|
40
|
-
The feature knowledge may not reflect recent changes:
|
|
41
|
-
- If the feature knowledge doesn't address your specific area, explore further
|
|
42
|
-
- **When an assertion seems outdated**: Read the relevant source files to confirm — code wins
|
|
43
|
-
- When you find a contradiction between the KB and actual code, trust the code
|
|
44
|
-
- Note discrepancies in your output when they matter for the task
|
|
22
|
+
1. **Read** each section of `FEATURE_KNOWLEDGE` (headed `--- Feature knowledge: {slug} ---`) for architecture, data flow, patterns, anti-patterns, gotchas and the integration points your task touches.
|
|
23
|
+
2. **Apply** it: follow documented patterns unless you have a specific reason not to; check your work against each anti-pattern and gotcha; respect documented integration boundaries; start exploring from the key files.
|
|
24
|
+
3. **Verify** against current code: it may not reflect recent changes. Where it is silent on your area, explore further. Where an assertion seems outdated or contradicts the code, Read the source and trust it. Note a discrepancy in your output when it matters for the task.
|
|
45
25
|
|
|
46
26
|
---
|
|
47
27
|
|
|
@@ -52,18 +32,4 @@ Do not mention feature knowledge or its absence in your output.
|
|
|
52
32
|
|
|
53
33
|
## Freshness Model
|
|
54
34
|
|
|
55
|
-
Feature knowledge
|
|
56
|
-
- KBs are written at the point a documented area changes (not on a background schedule)
|
|
57
|
-
- Readers verify key assertions against current code rather than relying on staleness markers
|
|
58
|
-
- When in doubt, Read the file — that resolves any uncertainty immediately
|
|
59
|
-
|
|
60
|
-
## Concatenation Format
|
|
61
|
-
|
|
62
|
-
Multiple feature knowledge entries are concatenated with slug headers:
|
|
63
|
-
```
|
|
64
|
-
--- Feature knowledge: payments ---
|
|
65
|
-
[full KNOWLEDGE.md content]
|
|
66
|
-
|
|
67
|
-
--- Feature knowledge: auth ---
|
|
68
|
-
[full KNOWLEDGE.md content]
|
|
69
|
-
```
|
|
35
|
+
Feature knowledge is **verify-on-read**: check key assertions against current code, not staleness markers, and when in doubt Read the file.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: architecture
|
|
3
|
-
description: This skill should be used when reviewing code for SOLID
|
|
3
|
+
description: This skill should be used when reviewing code for SOLID or layering issues.
|
|
4
4
|
user-invocable: false
|
|
5
5
|
allowed-tools: Read, Grep, Glob
|
|
6
6
|
---
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: boundary-validation
|
|
3
|
-
description: This skill should be used when the user asks to "validate input", "parse request data", "
|
|
3
|
+
description: This skill should be used when the user asks to "validate input", "parse request data", "add Zod schema", or creates API endpoints and system boundaries.
|
|
4
4
|
user-invocable: false
|
|
5
5
|
allowed-tools: Read, Grep, Glob, AskUserQuestion
|
|
6
6
|
---
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: complexity
|
|
3
|
-
description: This skill should be used when reviewing code for
|
|
3
|
+
description: This skill should be used when reviewing code for deep nesting or long functions.
|
|
4
4
|
user-invocable: false
|
|
5
5
|
allowed-tools: Read, Grep, Glob
|
|
6
6
|
---
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: compliance
|
|
3
|
-
description: This skill should be used when reviewing code
|
|
3
|
+
description: This skill should be used when reviewing code that handles PII, payments or health data.
|
|
4
4
|
user-invocable: false
|
|
5
5
|
allowed-tools: Read, Grep, Glob
|
|
6
6
|
---
|