devlyn-cli 2.7.0 → 2.8.1
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.md +9 -1
- package/CLAUDE.md +30 -11
- package/README.md +14 -2
- package/benchmark/auto-resolve/fixtures/F1-cli-trivial-flag/task.ko.txt +8 -0
- package/benchmark/auto-resolve/fixtures/retired/F34-cli-settle-inflight/NOTES.md +28 -0
- package/benchmark/auto-resolve/fixtures/retired/F34-cli-settle-inflight/RETIRED.md +15 -0
- package/benchmark/auto-resolve/fixtures/retired/F34-cli-settle-inflight/expected.json +57 -0
- package/benchmark/auto-resolve/fixtures/retired/F34-cli-settle-inflight/metadata.json +10 -0
- package/benchmark/auto-resolve/fixtures/retired/F34-cli-settle-inflight/setup.sh +50 -0
- package/benchmark/auto-resolve/fixtures/retired/F34-cli-settle-inflight/spec.md +59 -0
- package/benchmark/auto-resolve/fixtures/retired/F34-cli-settle-inflight/task.txt +9 -0
- package/benchmark/auto-resolve/fixtures/retired/F34-cli-settle-inflight/verifiers/ordered-settlement.js +88 -0
- package/benchmark/auto-resolve/fixtures/retired/F34-cli-settle-inflight/verifiers/reject-invalid.js +45 -0
- package/benchmark/auto-resolve/fixtures/retired/F35-cli-apply-journal/NOTES.md +30 -0
- package/benchmark/auto-resolve/fixtures/retired/F35-cli-apply-journal/RETIRED.md +16 -0
- package/benchmark/auto-resolve/fixtures/retired/F35-cli-apply-journal/expected.json +64 -0
- package/benchmark/auto-resolve/fixtures/retired/F35-cli-apply-journal/metadata.json +10 -0
- package/benchmark/auto-resolve/fixtures/retired/F35-cli-apply-journal/setup.sh +21 -0
- package/benchmark/auto-resolve/fixtures/retired/F35-cli-apply-journal/spec.md +58 -0
- package/benchmark/auto-resolve/fixtures/retired/F35-cli-apply-journal/task.txt +9 -0
- package/benchmark/auto-resolve/fixtures/retired/F35-cli-apply-journal/verifiers/dup-op.js +54 -0
- package/benchmark/auto-resolve/fixtures/retired/F35-cli-apply-journal/verifiers/priority-apply.js +82 -0
- package/benchmark/auto-resolve/fixtures/retired/F35-cli-apply-journal/verifiers/rollback.js +77 -0
- package/benchmark/auto-resolve/fixtures/retired/F36-cli-session-admission/NOTES.md +99 -0
- package/benchmark/auto-resolve/fixtures/retired/F36-cli-session-admission/RETIRED.md +18 -0
- package/benchmark/auto-resolve/fixtures/retired/F36-cli-session-admission/expected.json +64 -0
- package/benchmark/auto-resolve/fixtures/retired/F36-cli-session-admission/metadata.json +10 -0
- package/benchmark/auto-resolve/fixtures/retired/F36-cli-session-admission/setup.sh +4 -0
- package/benchmark/auto-resolve/fixtures/retired/F36-cli-session-admission/spec.md +61 -0
- package/benchmark/auto-resolve/fixtures/retired/F36-cli-session-admission/task.txt +9 -0
- package/benchmark/auto-resolve/fixtures/retired/F36-cli-session-admission/verifiers/correctness-small.js +135 -0
- package/benchmark/auto-resolve/fixtures/retired/F36-cli-session-admission/verifiers/scale.js +100 -0
- package/benchmark/auto-resolve/fixtures/retired/F36-cli-session-admission/verifiers/validation.js +75 -0
- package/benchmark/auto-resolve/fixtures/retired/F37-cli-rule-lookup/NOTES.md +93 -0
- package/benchmark/auto-resolve/fixtures/retired/F37-cli-rule-lookup/RETIRED.md +16 -0
- package/benchmark/auto-resolve/fixtures/retired/F37-cli-rule-lookup/expected.json +65 -0
- package/benchmark/auto-resolve/fixtures/retired/F37-cli-rule-lookup/metadata.json +10 -0
- package/benchmark/auto-resolve/fixtures/retired/F37-cli-rule-lookup/setup.sh +18 -0
- package/benchmark/auto-resolve/fixtures/retired/F37-cli-rule-lookup/spec.md +66 -0
- package/benchmark/auto-resolve/fixtures/retired/F37-cli-rule-lookup/task.txt +9 -0
- package/benchmark/auto-resolve/fixtures/retired/F37-cli-rule-lookup/verifiers/correctness-small.js +84 -0
- package/benchmark/auto-resolve/fixtures/retired/F37-cli-rule-lookup/verifiers/scale.js +184 -0
- package/benchmark/auto-resolve/fixtures/retired/F37-cli-rule-lookup/verifiers/validation.js +74 -0
- package/benchmark/auto-resolve/scripts/pair-rejected-fixtures.sh +12 -0
- package/benchmark/auto-resolve/scripts/run-fixture.sh +39 -1
- package/benchmark/auto-resolve/scripts/test-lint-fixtures.sh +1 -1
- package/bin/devlyn.js +42 -1
- package/config/skills/_shared/adapters/README.md +7 -0
- package/config/skills/_shared/adapters/claude.md +47 -0
- package/config/skills/_shared/adapters/omp.md +17 -0
- package/config/skills/_shared/archive_run.py +8 -2
- package/config/skills/_shared/codex-config.md +22 -6
- package/config/skills/_shared/engine-doctor.sh +107 -0
- package/config/skills/_shared/engine-preflight.md +18 -11
- package/config/skills/_shared/expected.schema.json +26 -0
- package/config/skills/_shared/runtime-principles.md +1 -1
- package/config/skills/_shared/spec-verify-check.py +773 -486
- package/config/skills/_shared/state-phase-write.py +374 -0
- package/config/skills/_shared/verify-merge-findings.py +177 -61
- package/config/skills/devlyn:engines/SKILL.md +47 -0
- package/config/skills/devlyn:ideate/SKILL.md +22 -3
- package/config/skills/devlyn:ideate/references/elicitation.md +2 -2
- package/config/skills/devlyn:ideate/references/from-spec-mode.md +2 -2
- package/config/skills/devlyn:ideate/references/project-mode.md +1 -1
- package/config/skills/devlyn:ideate/references/spec-template.md +15 -4
- package/config/skills/devlyn:queue/SKILL.md +26 -0
- package/config/skills/devlyn:resolve/SKILL.md +54 -24
- package/config/skills/devlyn:resolve/references/free-form-mode.md +1 -1
- package/config/skills/devlyn:resolve/references/phases/build-gate.md +2 -2
- package/config/skills/devlyn:resolve/references/phases/cleanup.md +1 -1
- package/config/skills/devlyn:resolve/references/phases/implement.md +1 -1
- package/config/skills/devlyn:resolve/references/phases/plan.md +3 -2
- package/config/skills/devlyn:resolve/references/phases/probe-derive.md +8 -0
- package/config/skills/devlyn:resolve/references/phases/verify.md +18 -9
- package/config/skills/devlyn:resolve/references/state-schema.md +10 -6
- package/optional-skills/devlyn:pencil-pull/SKILL.md +5 -0
- package/optional-skills/devlyn:pencil-push/SKILL.md +5 -0
- package/package.json +1 -1
- package/scripts/lint-skills.sh +48 -41
|
@@ -1,15 +1,31 @@
|
|
|
1
1
|
# Shared — Codex Invocation
|
|
2
2
|
|
|
3
|
-
Single source of truth for how every skill calls Codex. **MCP is not used.** Skills shell out via the wrapper at `_shared/codex-monitored.sh`, which fronts the local Codex CLI
|
|
3
|
+
Single source of truth for how every skill calls Codex. **MCP is not used.** Skills shell out via the wrapper at `$CODEX_MONITORED_PATH`, resolved from the invoked skill's sibling `_shared/codex-monitored.sh`, which fronts the local Codex CLI.
|
|
4
4
|
|
|
5
5
|
## Canonical invocations
|
|
6
6
|
|
|
7
7
|
All long-running Codex calls go through `codex-monitored.sh` — a thin wrapper that closes stdin (codex 0.124.0 hangs when both stdin is open and a prompt arg is given), streams Codex stdout fully (no `tail -n` truncation), and prints a `[codex-monitored] heartbeat` line every 30s so the outer `claude -p` byte-watchdog stays fed during long reasoning gaps. The wrapper passes its arguments through verbatim to the underlying CLI, so the canonical flag set is unchanged from a raw call — only the launcher differs.
|
|
8
8
|
|
|
9
|
+
Before the first Codex call, resolve the wrapper from the invoked skill directory:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
DEVLYN_SKILL_DIR="${CLAUDE_SKILL_DIR:-__DEVLYN_SKILL_DIR__}"
|
|
13
|
+
if [ "$DEVLYN_SKILL_DIR" = "__DEVLYN_SKILL_DIR__" ] || [ ! -d "$DEVLYN_SKILL_DIR/../_shared" ]; then
|
|
14
|
+
echo "BLOCKED:shared-dir-unresolved: $DEVLYN_SKILL_DIR/../_shared" >&2
|
|
15
|
+
exit 1
|
|
16
|
+
fi
|
|
17
|
+
DEVLYN_SHARED_DIR="$(cd "$DEVLYN_SKILL_DIR/../_shared" && pwd)"
|
|
18
|
+
CODEX_MONITORED_PATH="$DEVLYN_SHARED_DIR/codex-monitored.sh"
|
|
19
|
+
if [ ! -f "$CODEX_MONITORED_PATH" ]; then
|
|
20
|
+
echo "BLOCKED:shared-dir-unresolved: $CODEX_MONITORED_PATH" >&2
|
|
21
|
+
exit 1
|
|
22
|
+
fi
|
|
23
|
+
```
|
|
24
|
+
|
|
9
25
|
**Read-only critique / adversarial review / debate** (`/devlyn:resolve` VERIFY pair-mode, plus any future ideate read-only critique). Security review stays native to Claude Code BUILD_GATE. Codex returns findings on stdout; the orchestrator writes files.
|
|
10
26
|
|
|
11
27
|
```bash
|
|
12
|
-
CODEX_MONITORED_ISOLATED=1 bash
|
|
28
|
+
CODEX_MONITORED_ISOLATED=1 bash "$CODEX_MONITORED_PATH" \
|
|
13
29
|
-C <project-root> \
|
|
14
30
|
-s read-only \
|
|
15
31
|
-c model_reasoning_effort=xhigh \
|
|
@@ -19,16 +35,16 @@ CODEX_MONITORED_ISOLATED=1 bash .claude/skills/_shared/codex-monitored.sh \
|
|
|
19
35
|
**Workspace-write implementation** (`/devlyn:resolve` IMPLEMENT phase when `--engine codex` or `--engine auto` routes to Codex, plus codex-routed `/devlyn:ideate` phases):
|
|
20
36
|
|
|
21
37
|
```bash
|
|
22
|
-
bash
|
|
38
|
+
bash "$CODEX_MONITORED_PATH" \
|
|
23
39
|
-C <project-root> \
|
|
24
|
-
|
|
40
|
+
-s workspace-write \
|
|
25
41
|
-c model_reasoning_effort=xhigh \
|
|
26
42
|
"<inlined-prompt>"
|
|
27
43
|
```
|
|
28
44
|
|
|
29
45
|
Notes:
|
|
30
46
|
- `-C` — project root so Codex's working directory matches.
|
|
31
|
-
- `-s read-only` /
|
|
47
|
+
- `-s read-only` / `-s workspace-write` — sandbox policy. Use workspace-write for implementation/probe phases that write tracked files or `.devlyn` artifacts.
|
|
32
48
|
- `-c model_reasoning_effort=xhigh` — config override for reasoning depth. Required for deep critique; skills may choose `high` or `medium` when thoroughness doesn't warrant xhigh.
|
|
33
49
|
- **Omit `-m <model>`** — Codex CLI uses its configured flagship (currently `gpt-5.5`, automatically whatever ships next). This is the zero-touch mechanism. Only name `-m` when a role explicitly needs a different model (e.g., `gpt-5.3-codex` for SWE-bench-heavy coding tasks, `gpt-5.3-codex-spark` for speed).
|
|
34
50
|
- `CODEX_MONITORED_ISOLATED=1` — required for bounded read-only critique/probe/judge calls. The wrapper adds `--ignore-user-config --ignore-rules --ephemeral --disable codex_hooks --disable hooks` so user config, AGENTS.md, hooks, and project rules cannot add hidden context, tool calls, or transcript side effects. Do not set it for workspace-write implementation phases.
|
|
@@ -52,4 +68,4 @@ The local Codex CLI (fronted by `codex-monitored.sh`) is the primary (and only)
|
|
|
52
68
|
|
|
53
69
|
Skills write the invocation as a Bash command the runtime executes. Example shape from `/devlyn:resolve` PHASE 2 IMPLEMENT when routed to Codex:
|
|
54
70
|
|
|
55
|
-
> Run `bash
|
|
71
|
+
> Run `bash "$CODEX_MONITORED_PATH" -C <state.base_ref.repo_root> -s workspace-write -c model_reasoning_effort=xhigh "<IMPLEMENT prompt>"`. Omit `-m` so the CLI flagship is auto-selected. Capture stdout as the IMPLEMENT reply; non-zero exit → treat as subagent failure. The wrapper emits `[codex-monitored]` heartbeat and lifecycle lines on **stderr** — stdout stays clean for Codex output, so the orchestrator can parse the reply without filtering. Heartbeat-on-stderr keeps the orchestrator's combined-output stream non-silent (defeats the iter-0008 byte-watchdog kill) without polluting the codex-reply view of stdout. Do not pipe the wrapper; direct capture or file redirection preserves streaming and avoids the pipe-refusal exit.
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# engine-doctor.sh — read-only detection for /devlyn:engines' no-arg output.
|
|
3
|
+
#
|
|
4
|
+
# WHY (iter-0050): users need to see what's actually on the machine, not
|
|
5
|
+
# just what's pinned. This script never writes .devlyn/engines.json, never
|
|
6
|
+
# installs anything, never changes pin validation — it only reports.
|
|
7
|
+
#
|
|
8
|
+
# CATALOG NOTE: `pi` (bin/devlyn.js's Pi/earendil-works install target) has
|
|
9
|
+
# no verified CLI binary name anywhere in this repo — its own installer
|
|
10
|
+
# detect() only checks project marker files, never shells out to a binary.
|
|
11
|
+
# Fabricating a `command -v pi` check would be a guess this repo's evidence
|
|
12
|
+
# rule forbids, so its binary column reports "unknown" rather than "no".
|
|
13
|
+
#
|
|
14
|
+
# macOS-safe bash 3.2: no associative arrays, no mapfile/readarray.
|
|
15
|
+
set -uo pipefail
|
|
16
|
+
|
|
17
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]:-$0}")" && pwd)"
|
|
18
|
+
ADAPTERS_DIR="$SCRIPT_DIR/adapters"
|
|
19
|
+
|
|
20
|
+
TARGETS=(claude codex omp pi)
|
|
21
|
+
KINDS=(cli-engine cli-engine cli-engine orchestrator-only)
|
|
22
|
+
BINARIES=(claude codex omp "")
|
|
23
|
+
INSTALL_HINTS=(
|
|
24
|
+
"see https://docs.anthropic.com/en/docs/claude-code"
|
|
25
|
+
"npm install -g @openai/codex"
|
|
26
|
+
"brew install can1357/tap/omp"
|
|
27
|
+
""
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
check_binary() {
|
|
31
|
+
# $1 = binary name, "" means no known binary to probe
|
|
32
|
+
[ -n "$1" ] || { printf 'unknown'; return; }
|
|
33
|
+
if command -v "$1" >/dev/null 2>&1; then printf 'yes'; else printf 'no'; fi
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
check_adapter() {
|
|
37
|
+
# $1 = target name
|
|
38
|
+
if [ -f "$ADAPTERS_DIR/$1.md" ]; then printf 'yes'; else printf 'no'; fi
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
check_role() {
|
|
42
|
+
# $1 = adapter file path. Reads the optional `## Role eligibility` fixed
|
|
43
|
+
# ASCII fields (_shared/adapters/README.md); absent file or section = both
|
|
44
|
+
# roles eligible by default (every adapter shipped before iter-0051).
|
|
45
|
+
[ -f "$1" ] || { printf 'n/a'; return; }
|
|
46
|
+
local exec_ok='yes' judge_ok='yes'
|
|
47
|
+
grep -q '^executor: no' "$1" 2>/dev/null && exec_ok='no'
|
|
48
|
+
grep -q '^pair_judge: no' "$1" 2>/dev/null && judge_ok='no'
|
|
49
|
+
if [ "$exec_ok" = 'yes' ] && [ "$judge_ok" = 'yes' ]; then printf 'executor+judge'
|
|
50
|
+
elif [ "$judge_ok" = 'yes' ]; then printf 'judge-only'
|
|
51
|
+
elif [ "$exec_ok" = 'yes' ]; then printf 'executor-only'
|
|
52
|
+
else printf 'none'
|
|
53
|
+
fi
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
printf '%-8s %-17s %-8s %-8s %-14s %-12s %s\n' \
|
|
57
|
+
'target' 'kind' 'binary' 'adapter' 'role' 'pin_eligible' 'note'
|
|
58
|
+
|
|
59
|
+
pin_eligible_count=0
|
|
60
|
+
missing_hints=()
|
|
61
|
+
|
|
62
|
+
for i in "${!TARGETS[@]}"; do
|
|
63
|
+
target="${TARGETS[$i]}"
|
|
64
|
+
kind="${KINDS[$i]}"
|
|
65
|
+
binary="$(check_binary "${BINARIES[$i]}")"
|
|
66
|
+
adapter="$(check_adapter "$target")"
|
|
67
|
+
role="$(check_role "$ADAPTERS_DIR/$target.md")"
|
|
68
|
+
|
|
69
|
+
pin_eligible='no'
|
|
70
|
+
case "$kind" in
|
|
71
|
+
cli-engine) [ "$binary" = 'yes' ] && [ "$adapter" = 'yes' ] && pin_eligible='yes' ;;
|
|
72
|
+
esac
|
|
73
|
+
|
|
74
|
+
note='-'
|
|
75
|
+
case "$kind" in
|
|
76
|
+
cli-engine)
|
|
77
|
+
if [ "$pin_eligible" = 'yes' ]; then
|
|
78
|
+
pin_eligible_count=$((pin_eligible_count + 1))
|
|
79
|
+
elif [ "$binary" = 'no' ]; then
|
|
80
|
+
note="not installed; ${INSTALL_HINTS[$i]}"
|
|
81
|
+
missing_hints+=("$target: ${INSTALL_HINTS[$i]}")
|
|
82
|
+
else
|
|
83
|
+
note="binary present, no adapter — ship _shared/adapters/$target.md"
|
|
84
|
+
fi
|
|
85
|
+
;;
|
|
86
|
+
orchestrator-only)
|
|
87
|
+
note='informational only; not a routable role engine — no verified CLI binary or adapter'
|
|
88
|
+
;;
|
|
89
|
+
esac
|
|
90
|
+
|
|
91
|
+
printf '%-8s %-17s %-8s %-8s %-14s %-12s %s\n' \
|
|
92
|
+
"$target" "$kind" "$binary" "$adapter" "$role" "$pin_eligible" "$note"
|
|
93
|
+
done
|
|
94
|
+
|
|
95
|
+
printf '\n'
|
|
96
|
+
if [ "$pin_eligible_count" -lt 2 ]; then
|
|
97
|
+
printf 'Recommendation: only %d adapter-valid engine(s) available. VERIFY pair-judge and\n' "$pin_eligible_count"
|
|
98
|
+
printf 'risk-probe escalation need a second, genuinely different model to check against —\n'
|
|
99
|
+
printf 'iter-0045 found different model tiers hit different failure-mode blind spots (not\n'
|
|
100
|
+
printf 'that any arbitrary second model helps); with fewer than 2, those routes can never\n'
|
|
101
|
+
printf 'fire and every run stays solo. Add one of:\n'
|
|
102
|
+
for hint in "${missing_hints[@]}"; do
|
|
103
|
+
printf ' - %s\n' "$hint"
|
|
104
|
+
done
|
|
105
|
+
else
|
|
106
|
+
printf 'Pair-judge diversity: %d adapter-valid engines available.\n' "$pin_eligible_count"
|
|
107
|
+
fi
|
|
@@ -11,21 +11,28 @@ Engine requirements have two classes:
|
|
|
11
11
|
- **Explicit routes** — `--engine`, `--risk-probes`, `--pair-verify`. These are promises. If the required engine is unavailable, fail closed with `BLOCKED:<engine>-unavailable` and never downgrade to solo.
|
|
12
12
|
- **Automatic escalations** — auto high-risk risk-probes and auto VERIFY pair-JUDGE inferred from the spec. These are candidate routes, selected only when their preconditions hold, OTHER-engine availability included. If an auto candidate would fire but the OTHER engine is absent, do not select the cross-engine route: proceed solo and report the skipped escalation and its reason. This is route selection, not a fallback.
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
## Role resolution
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
Two configurable roles; the orchestrator role is whichever CLI the user opened and is not configurable here.
|
|
17
|
+
|
|
18
|
+
- **Executor** (IMPLEMENT / CLEANUP / primary VERIFY judge): explicit `--engine` flag > `cwd/.devlyn/engines.json` `executor` > built-in default `claude`. No parent-directory or global config lookup. Requires an adapter that is executor-eligible (below).
|
|
19
|
+
- **Pair judge** (VERIFY pair-JUDGE, risk-probe derivation): first entry of `engines.json` `pair_judge_priority` that is (a) adapter-valid, (b) pair-judge-eligible (below), (c) not the primary judge engine, (d) available. When the key or file is absent: the binary claude↔codex complement.
|
|
20
|
+
|
|
21
|
+
Validation is fail-closed: malformed JSON, any engine name without a `_shared/adapters/<name>.md` adapter file under `DEVLYN_SHARED_DIR`, or an adapter that declares itself ineligible for the requested role, halts with report-level `BLOCKED:invalid-engine-config` naming the offending entry. This is the plug-in point for new engines — ship an adapter file and the name becomes valid with zero skill-body changes. Availability probe default is `command -v <name>`; an adapter may declare a different probe. A pin is an explicit route (same promise class as `--engine`): pinned-but-unavailable → `BLOCKED:<engine>-unavailable`, never a silent downgrade. `engines.json` is machine-local config — not committed, not archived (`archive_run.py` moves only `PER_RUN_PATTERNS`).
|
|
19
22
|
|
|
20
|
-
|
|
23
|
+
**Role eligibility** — an adapter's optional `## Role eligibility` section (`_shared/adapters/README.md`) declares `executor: yes|no` / `pair_judge: yes|no` as fixed ASCII fields. Absent section = eligible for both roles (every adapter shipped before iter-0051). A completion-only local backend with no tool/file-edit access declares `executor: no`: an `executor <name>` pin against it is invalid config, not an availability gap, and fails the same `BLOCKED:invalid-engine-config` path above rather than `BLOCKED:<name>-unavailable`.
|
|
21
24
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
+
The explicit-vs-automatic split above applies unchanged to resolved engines: explicit routes (`--engine`, `--risk-probes`, `--pair-verify`, config pins) fail closed; automatic escalations select a cross-engine route only when the resolved pair-judge engine is available, else proceed solo and report the skip.
|
|
26
|
+
|
|
27
|
+
When a run or phase requires engine `<name>` (claude, codex, omp, or any adapter-backed engine), before spawning that phase:
|
|
28
|
+
|
|
29
|
+
1. Run the adapter's availability probe — default `command -v <name> >/dev/null 2>&1`; an adapter's `## Invocation` section may declare a stricter contract (e.g. `adapters/claude.md`: the probe is necessary but not sufficient under a network-denying sandbox, so a failed spawn is handled identically to a failed probe).
|
|
30
|
+
2. On failure -> set the current phase/run verdict to `BLOCKED:<name>-unavailable`, preserve the failed check evidence, and show the adapter's setup guidance: install/configure that CLI, run its auth/login flow, verify `<name> --version`, then rerun. If the user intentionally wants solo VERIFY, they may rerun with `--no-pair`.
|
|
31
|
+
3. On success -> proceed with the original engine value.
|
|
25
32
|
|
|
26
33
|
Never prompt the user mid-pipeline. Missing engines for explicit routes are BLOCKED states, not silent fallbacks. Missing OTHER engines for automatic escalations are reported solo-skips, not fallbacks — the auto route was never selected.
|
|
27
34
|
|
|
28
|
-
Per-skill defaults: `/devlyn:resolve` uses Claude for PLAN/IMPLEMENT; VERIFY may invoke the OTHER engine when its pair-JUDGE trigger fires. `/devlyn:ideate` defaults to Claude; `--engine` selects the elicitation/normalization adapter, not an automatic cross-model challenge phase. Any future ideate read-only critique must follow `_shared/codex-config.md` isolation rules. Each SKILL.md flag block is source of truth for that skill's default.
|
|
35
|
+
Per-skill defaults: `/devlyn:resolve` uses Claude for PLAN/IMPLEMENT when the orchestrator has Claude Code's native Agent primitive; Codex CLI and oh-my-pi orchestrators use their own fresh worker as the default route (Codex child process, omp native `task`) so the pipeline still has structural phase isolation. VERIFY may invoke the OTHER engine when its pair-JUDGE trigger fires. `/devlyn:ideate` defaults to Claude; `--engine` selects the elicitation/normalization adapter, not an automatic cross-model challenge phase. Any future ideate read-only critique must follow `_shared/codex-config.md` isolation rules. Each SKILL.md flag block is source of truth for that skill's default.
|
|
29
36
|
|
|
30
37
|
## What a skill must report after a BLOCKED engine check
|
|
31
38
|
|
|
@@ -39,6 +46,6 @@ Setup: install/configure Codex CLI; run the current Codex auth/login flow; verif
|
|
|
39
46
|
|
|
40
47
|
Do not report a downgraded successful run when a required engine is missing.
|
|
41
48
|
|
|
42
|
-
## Canonical
|
|
49
|
+
## Canonical cross-engine invocations
|
|
43
50
|
|
|
44
|
-
|
|
51
|
+
After the availability check passes: a Claude-side orchestrator spawning a Codex judge/worker uses `config/skills/_shared/codex-config.md` (monitored wrapper, canonical flag set); a non-Claude orchestrator spawning a Claude judge uses `_shared/adapters/claude.md` `## Invocation` (headless `claude -p`, locked-down allowlist, hermetic settings).
|
|
@@ -106,6 +106,32 @@
|
|
|
106
106
|
"description": "Hard cap on new entries under dependencies/devDependencies in package.json. Exceeds → DQ.",
|
|
107
107
|
"minimum": 0,
|
|
108
108
|
"default": 0
|
|
109
|
+
},
|
|
110
|
+
"pure_design": {
|
|
111
|
+
"type": "boolean",
|
|
112
|
+
"description": "Declares that every Requirement is pure-design (no observable runtime check). Lets verification_commands stay empty without failing shape validation. Contradictory (and rejected) when true alongside a non-empty verification_commands.",
|
|
113
|
+
"default": false
|
|
114
|
+
},
|
|
115
|
+
"required_risk_probe_requirements": {
|
|
116
|
+
"type": "array",
|
|
117
|
+
"description": "Language-neutral replacement for prose-keyword risk-probe classification: explicit {tag, derived_from} obligations the spec author declares directly. When `--risk-probes` is enabled, risk-probes.jsonl must include a probe whose tags include `tag` and whose derived_from exactly equals `derived_from` for each entry.",
|
|
118
|
+
"items": {
|
|
119
|
+
"type": "object",
|
|
120
|
+
"additionalProperties": false,
|
|
121
|
+
"required": ["tag", "derived_from"],
|
|
122
|
+
"properties": {
|
|
123
|
+
"tag": {
|
|
124
|
+
"type": "string",
|
|
125
|
+
"description": "One of the risk-probe tags defined in _shared/spec-verify-check.py:RISK_PROBE_TAGS (e.g. ordering_inversion, rollback_state, shape_contract)."
|
|
126
|
+
},
|
|
127
|
+
"derived_from": {
|
|
128
|
+
"type": "string",
|
|
129
|
+
"description": "Exact substring of the sibling spec.md's visible verification section that demands this tag.",
|
|
130
|
+
"minLength": 1
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
"default": []
|
|
109
135
|
}
|
|
110
136
|
}
|
|
111
137
|
}
|
|
@@ -51,7 +51,7 @@ This rule exists because LLMs (including you) are trained to be helpful, compreh
|
|
|
51
51
|
**The five drift patterns you must refuse to execute on:**
|
|
52
52
|
|
|
53
53
|
1. **Unrequested work.** "While I'm here, I noticed X is broken/ugly/inefficient" → **stop**. The user did not ask for X. If X is a real defect, surface it as a finding, a follow-up suggestion, or an entry in a TODO list — do NOT fix it inside the current change. Mixing unrequested work with requested work is what makes diffs unreviewable and PRs eternal. **Pre-existing dead code → mention only, do NOT delete; orphans YOUR change created (now-unused imports, variables, functions) → clean them up.**
|
|
54
|
-
2. **Tangential cleanup.** "This file looks messy, let me also tidy..." → **stop**. The current task is the only task. Unrelated cleanup is a separate change requiring its own justification, scope, and pre-flight 0 check. **Match existing style even if you'd write it differently;
|
|
54
|
+
2. **Tangential cleanup.** "This file looks messy, let me also tidy..." → **stop**. The current task is the only task. Unrelated cleanup is a separate change requiring its own justification, scope, and pre-flight 0 check. **Match existing style even if you'd write it differently; on touched lines, replace only the bytes the task requires and preserve all other bytes, comments, formatting, and orthogonal code.**
|
|
55
55
|
3. **Speculative robustness.** "Just adding a check / fallback / handler for the case where..." → **stop**. If the case has not been observed (in production, in tests, in a finding), it does not belong in this change. Defensive code added for unobserved cases is the most common form of accretion debt — it never gets removed because nobody can prove the case never happens.
|
|
56
56
|
4. **Re-scoping mid-flight.** "Actually, the better way to do this is to also restructure / rename / migrate..." → **stop**. If you discover the requested approach is wrong, surface that to the user with evidence and let them adjudicate. Do NOT silently expand scope. The user's explicit redirect is the only authorization to enlarge a task.
|
|
57
57
|
5. **Curiosity detours.** "Let me also explore how Y works to understand this better..." → **stop**, unless Y is provably on the goal's critical path. Curiosity-driven exploration is creative-mode; default is execution-mode.
|