devlyn-cli 2.5.3 → 2.5.5
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 +1 -1
- package/CLAUDE.md +1 -1
- package/benchmark/auto-resolve/scripts/judge-opus-pass.sh +3 -3
- package/benchmark/auto-resolve/scripts/run-fixture.sh +6 -2
- package/config/skills/_shared/adapters/README.md +2 -2
- package/config/skills/_shared/adapters/{opus-4-7.md → claude.md} +5 -5
- package/config/skills/_shared/adapters/{gpt-5-5.md → codex.md} +3 -3
- package/config/skills/_shared/engine-preflight.md +6 -1
- package/config/skills/_shared/verify-merge-findings.py +25 -2
- package/config/skills/devlyn:ideate/SKILL.md +1 -1
- package/config/skills/devlyn:resolve/SKILL.md +16 -9
- package/config/skills/devlyn:resolve/references/phases/plan.md +1 -1
- package/config/skills/devlyn:resolve/references/phases/verify.md +16 -10
- package/optional-skills/prompt-engineering/SKILL.md +5 -5
- package/package.json +1 -1
- package/scripts/lint-skills.sh +11 -11
package/AGENTS.md
CHANGED
|
@@ -73,7 +73,7 @@ No silent fallbacks.
|
|
|
73
73
|
- Fallbacks allowed only when widely accepted and harmless (CSS fallback fonts, CDN failover, image placeholders).
|
|
74
74
|
- Silent `catch` blocks are bugs.
|
|
75
75
|
- Logging is not user-visible error handling.
|
|
76
|
-
- No engine-availability fallback
|
|
76
|
+
- No engine-availability fallback for EXPLICITLY-requested routes (`--engine`, `--risk-probes`, `--pair-verify`): if the required engine is unavailable, emit `BLOCKED:codex-unavailable` or `BLOCKED:claude-unavailable` with setup guidance; never downgrade an explicit route to solo. Automatic high-risk escalations (auto risk-probes / auto VERIFY pair) are capability-gated: they activate only when the OTHER engine is available, else the run proceeds solo and reports the skip (route selection, not a fallback — keeps single-LLM users first-class). `--no-pair` and `--no-risk-probes` remain explicit opt-outs.
|
|
77
77
|
|
|
78
78
|
## Evidence Over Claim
|
|
79
79
|
|
package/CLAUDE.md
CHANGED
|
@@ -6,7 +6,7 @@ devlyn-cli installs `/devlyn:ideate` (optional) and `/devlyn:resolve` (required)
|
|
|
6
6
|
|
|
7
7
|
Seven rules govern every change. Cite them by name when a decision touches one.
|
|
8
8
|
|
|
9
|
-
1. **No workaround** — fix the root cause, never the symptom. Blocked patterns: `any`, `@ts-ignore`, silent `catch`, hardcoded fallback hiding a broken contract, config-level skip bypassing the real issue, helper script that routes around it. **Permitted exceptions** (widely-accepted defaults only): CSS fallback fonts, CDN failover, image placeholders. **No engine-availability fallback** for `/devlyn:resolve`
|
|
9
|
+
1. **No workaround** — fix the root cause, never the symptom. Blocked patterns: `any`, `@ts-ignore`, silent `catch`, hardcoded fallback hiding a broken contract, config-level skip bypassing the real issue, helper script that routes around it. **Permitted exceptions** (widely-accepted defaults only): CSS fallback fonts, CDN failover, image placeholders. **No engine-availability fallback** for EXPLICITLY-requested `/devlyn:resolve` routes (`--engine`, `--risk-probes`, `--pair-verify`) — if the required engine is unavailable, stop with `BLOCKED:codex-unavailable` or `BLOCKED:claude-unavailable` and setup guidance; never downgrade an explicit route to solo. AUTOMATIC high-risk escalations (auto risk-probes / auto VERIFY pair) are capability-gated: they activate only when the OTHER engine is available; otherwise the run proceeds solo and reports the skip — route selection, not a fallback, and the reason single-LLM users stay first-class. `--no-pair` / `--no-risk-probes` remain explicit opt-outs.
|
|
10
10
|
2. **No overengineering** — smallest change that closes the goal. New abstractions require an observed failure mode they prevent. Subtractive-first: ask "what can I delete instead?" before writing anything new.
|
|
11
11
|
3. **No guesswork** — verify with the actual files, logs, diffs, and run output before forming conclusions. State the falsifiable prediction BEFORE the experiment; record raw results AFTER. Retroactive prediction edits are dishonest.
|
|
12
12
|
4. **Worldclass** — code that survives review at a non-trivial codebase. Zero CRITICAL, zero HIGH security/design findings on the shippable path.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# judge-opus-pass.sh — POST-RUN Opus
|
|
2
|
+
# judge-opus-pass.sh — POST-RUN Opus dual-judge sidecar.
|
|
3
3
|
#
|
|
4
|
-
# Runs Opus
|
|
4
|
+
# Runs Opus (the Claude CLI's default model) over the SAME sanitized blind prompts that judge.sh wrote
|
|
5
5
|
# (judge-prompt.txt), producing a parallel judge-opus.json alongside the
|
|
6
6
|
# canonical judge.json. Does NOT modify judge.sh and does NOT change the
|
|
7
7
|
# measurement contract for the in-flight run — this is a sidecar that adds
|
|
@@ -107,7 +107,7 @@ PY
|
|
|
107
107
|
command -v claude >/dev/null 2>&1 || { echo "claude CLI not on PATH"; exit 1; }
|
|
108
108
|
|
|
109
109
|
CLAUDE_CLI_VER=$(claude --version 2>/dev/null || echo "claude-cli unknown")
|
|
110
|
-
JUDGE_MODEL_ALIAS="opus-
|
|
110
|
+
JUDGE_MODEL_ALIAS="opus-default"
|
|
111
111
|
|
|
112
112
|
echo "[opus-judge] run-id=$RUN_ID cli=$CLAUDE_CLI_VER model=$JUDGE_MODEL_ALIAS"
|
|
113
113
|
|
|
@@ -336,8 +336,12 @@ if [ "$ARM" = "variant" ] || [ "$ARM" = "solo_claude" ] \
|
|
|
336
336
|
|| [ "$ARM" = "l2_gated" ] || [ "$ARM" = "l2_risk_probes" ] || [ "$ARM" = "l2_forced" ]; then
|
|
337
337
|
case "$ARM" in
|
|
338
338
|
solo_claude)
|
|
339
|
-
|
|
340
|
-
|
|
339
|
+
# L1 = pure solo by construction. --no-risk-probes --no-pair so a high-risk
|
|
340
|
+
# spec measures Claude-only solo deterministically instead of auto-escalating
|
|
341
|
+
# toward the (blocked) OTHER engine. Without these, a security/high-risk
|
|
342
|
+
# fixture auto-triggers the cross-engine path and the arm mis-measures L1.
|
|
343
|
+
ENGINE_CLAUSE="--engine claude --no-risk-probes --no-pair"
|
|
344
|
+
ENGINE_PROMPT_HINT="Run with \`--engine claude --no-risk-probes --no-pair\` for every phase — pure solo L1. Codex must not be invoked — the harness has blocked it at the binary layer for this run."
|
|
341
345
|
;;
|
|
342
346
|
variant)
|
|
343
347
|
ENGINE_CLAUSE="--engine claude --risk-probes"
|
|
@@ -14,10 +14,10 @@ This is also the load-bearing piece for **multi-LLM evolution**. When Qwen / Gem
|
|
|
14
14
|
|
|
15
15
|
## Format
|
|
16
16
|
|
|
17
|
-
Each adapter is a single markdown file named `<
|
|
17
|
+
Each adapter is a single markdown file named `<engine>.md`, matching the `--engine` selector value (e.g. `claude.md`, `codex.md`). Structure:
|
|
18
18
|
|
|
19
19
|
```markdown
|
|
20
|
-
# <
|
|
20
|
+
# <Engine> adapter
|
|
21
21
|
|
|
22
22
|
> Source: <official-prompt-engineering-guide URL>
|
|
23
23
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
# Claude Opus
|
|
1
|
+
# Claude Opus adapter
|
|
2
2
|
|
|
3
3
|
> Source: <https://platform.claude.com/docs/en/build-with-claude/prompt-engineering/claude-prompting-best-practices>
|
|
4
4
|
|
|
5
5
|
## Identity
|
|
6
6
|
|
|
7
|
-
You are Claude Opus
|
|
7
|
+
You are Claude Opus by Anthropic. Anthropic's prompt-engineering guide for this model governs your behavior on top of the canonical phase prompt below. When the canonical body and this header conflict on tactics, the canonical body wins on what to deliver; this header wins on how to deliver it.
|
|
8
8
|
|
|
9
9
|
## Output discipline
|
|
10
10
|
|
|
@@ -16,7 +16,7 @@ When prompt maintenance adds examples for Claude, prefer concise positive exampl
|
|
|
16
16
|
|
|
17
17
|
## Tool-use posture
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
When the canonical body lists tools, use them when their result would change your answer. Make independent tool calls in parallel; chain only when one depends on another's output. Do not narrate "I'll now call X" preambles unless the canonical body requests progress updates.
|
|
20
20
|
|
|
21
21
|
## Effort and autonomy
|
|
22
22
|
|
|
@@ -28,10 +28,10 @@ When the canonical body asks you to verify your output before declaring done ("s
|
|
|
28
28
|
|
|
29
29
|
## Anti-patterns
|
|
30
30
|
|
|
31
|
-
You interpret instructions
|
|
31
|
+
You interpret instructions literally and explicitly. The official guide is explicit about three failure modes:
|
|
32
32
|
|
|
33
33
|
1. **Review-prompt self-filtering**: when the canonical body asks for findings, report every issue you find — including low-severity and low-confidence ones; do not filter for importance or confidence. The harness has a separate filter step.
|
|
34
|
-
2. **Subagent
|
|
34
|
+
2. **Subagent spawning**: do NOT spawn a subagent for work you can complete in a single response. Spawn only when the canonical body explicitly requests it OR when fanning out across independent items.
|
|
35
35
|
3. **Overengineering**: do NOT add files, abstractions, error handling, validation, or "future flexibility" beyond what the spec asks. A bug fix doesn't need surrounding cleanup. The right complexity is the minimum needed for the current task.
|
|
36
36
|
|
|
37
37
|
You do NOT need stronger imperatives ("CRITICAL!", "YOU MUST!") to follow rules. Normal phrasing is sufficient.
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
# OpenAI
|
|
1
|
+
# Codex (OpenAI) adapter
|
|
2
2
|
|
|
3
3
|
> Source: <https://developers.openai.com/api/docs/guides/prompt-guidance?model=gpt-5.5>
|
|
4
4
|
|
|
5
5
|
## Identity
|
|
6
6
|
|
|
7
|
-
You are
|
|
7
|
+
You are OpenAI's Codex model. OpenAI's prompt-guidance for this model governs your behavior on top of the canonical phase prompt below. When the canonical body and this header conflict on tactics, the canonical body wins on what to deliver; this header wins on how to deliver it.
|
|
8
8
|
|
|
9
9
|
## Output discipline
|
|
10
10
|
|
|
@@ -28,6 +28,6 @@ The official guide warns explicitly about carrying over instructions from older
|
|
|
28
28
|
|
|
29
29
|
## Prompt-maintenance cue
|
|
30
30
|
|
|
31
|
-
When asked to improve a failed prompt, act as
|
|
31
|
+
When asked to improve a failed prompt, act as a metaprompter for itself: name the observed failure, then propose the smallest instruction to add, remove, or relocate. Prefer subtractive changes before adding new rules; keep the canonical body model-neutral and put only GPT-specific tactics in this adapter.
|
|
32
32
|
|
|
33
33
|
Do not narrate internal deliberation. State results and decisions directly.
|
|
@@ -6,6 +6,11 @@ Used by `/devlyn:resolve` and `/devlyn:ideate`. One shared availability rule so
|
|
|
6
6
|
|
|
7
7
|
Each skill resolves the effective engine from its own SKILL.md default plus any explicit `--engine` flag passed by the user. `/devlyn:resolve` also computes conditional pair/risk-probe requirements before the phase that needs the OTHER engine.
|
|
8
8
|
|
|
9
|
+
Engine requirements have two classes:
|
|
10
|
+
|
|
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
|
+
- **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
|
+
|
|
9
14
|
When a run or phase requires Codex, before spawning that phase:
|
|
10
15
|
|
|
11
16
|
1. Check if the Codex CLI is installed: `command -v codex >/dev/null 2>&1` (or equivalent bash test).
|
|
@@ -18,7 +23,7 @@ When a run or phase requires Claude, before spawning that phase:
|
|
|
18
23
|
2. On failure -> set the current phase/run verdict to `BLOCKED:claude-unavailable` and show setup guidance: install/configure Claude Code, verify `claude --version` where available, then rerun.
|
|
19
24
|
3. On success -> proceed.
|
|
20
25
|
|
|
21
|
-
Never prompt the user mid-pipeline. Missing
|
|
26
|
+
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.
|
|
22
27
|
|
|
23
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.
|
|
24
29
|
|
|
@@ -33,7 +33,12 @@ VERDICT_RANK = {
|
|
|
33
33
|
"BLOCKED": 3,
|
|
34
34
|
}
|
|
35
35
|
RANK_VERDICT = {0: "PASS", 1: "PASS_WITH_ISSUES", 2: "NEEDS_WORK", 3: "BLOCKED"}
|
|
36
|
-
ALLOWED_PAIR_SKIP_REASONS = {
|
|
36
|
+
ALLOWED_PAIR_SKIP_REASONS = {
|
|
37
|
+
"user_no_pair",
|
|
38
|
+
"mechanical_blocker",
|
|
39
|
+
"primary_judge_blocker",
|
|
40
|
+
"auto_pair_other_engine_unavailable",
|
|
41
|
+
}
|
|
37
42
|
KNOWN_PAIR_TRIGGER_REASONS = {
|
|
38
43
|
"mode.verify-only",
|
|
39
44
|
"mode.pair-verify",
|
|
@@ -504,10 +509,28 @@ def pair_trigger_skip_contract_violation(
|
|
|
504
509
|
"id": "verify-pair-trigger-skipped-reason-unsupported",
|
|
505
510
|
"message": (
|
|
506
511
|
"pair_trigger.skipped_reason must be user_no_pair, "
|
|
507
|
-
"mechanical_blocker, primary_judge_blocker,
|
|
512
|
+
"mechanical_blocker, primary_judge_blocker, "
|
|
513
|
+
"auto_pair_other_engine_unavailable, or null."
|
|
508
514
|
),
|
|
509
515
|
"file": "pipeline.state.json",
|
|
510
516
|
}
|
|
517
|
+
if skipped_reason == "auto_pair_other_engine_unavailable":
|
|
518
|
+
# alpha+ capability-gating: an AUTOMATIC pair trigger may skip to solo
|
|
519
|
+
# VERIFY when the OTHER engine is unavailable (single-LLM users stay
|
|
520
|
+
# first-class). An EXPLICIT --pair-verify route is a promise and must
|
|
521
|
+
# BLOCK on an unavailable engine, never skip — enforce that here so the
|
|
522
|
+
# auto-skip cannot launder an explicit request.
|
|
523
|
+
pair_verify = state.get("pair_verify") if isinstance(state, dict) else None
|
|
524
|
+
if pair_verify is True:
|
|
525
|
+
return {
|
|
526
|
+
"id": "verify-pair-trigger-auto-skip-explicit-conflict",
|
|
527
|
+
"message": (
|
|
528
|
+
"pair_trigger skipped_reason auto_pair_other_engine_unavailable is "
|
|
529
|
+
"only valid for an automatic trigger; an explicit --pair-verify run "
|
|
530
|
+
"must BLOCK on an unavailable OTHER engine, not skip."
|
|
531
|
+
),
|
|
532
|
+
"file": "pipeline.state.json",
|
|
533
|
+
}
|
|
511
534
|
if skipped_reason == "user_no_pair":
|
|
512
535
|
risk_profile = state.get("risk_profile") if isinstance(state, dict) else {}
|
|
513
536
|
if not isinstance(risk_profile, dict) or risk_profile.get("pair_default_enabled") is not False:
|
|
@@ -28,7 +28,7 @@ Read `_shared/runtime-principles.md` (Subtractive-first / Goal-locked / No-worka
|
|
|
28
28
|
</harness_principles>
|
|
29
29
|
|
|
30
30
|
<engine_routing>
|
|
31
|
-
Default engine: Claude. The per-engine adapter from `_shared/adapters/<
|
|
31
|
+
Default engine: Claude. The per-engine adapter from `_shared/adapters/<engine>.md` is prepended to the elicitation prompt so the model honors its own official prompt-engineering guidance during the Q&A.
|
|
32
32
|
</engine_routing>
|
|
33
33
|
|
|
34
34
|
<modes>
|
|
@@ -17,7 +17,7 @@ Long-horizon agentic work; context auto-compacts. State lives in `.devlyn/pipeli
|
|
|
17
17
|
Hands-free. Measured by how far we get without human intervention.
|
|
18
18
|
|
|
19
19
|
1. Do not prompt the user mid-pipeline. When tempted to ask, pick the safe default, proceed, and log it in the final report.
|
|
20
|
-
2. Engine availability: follow `_shared/engine-preflight.md`.
|
|
20
|
+
2. Engine availability: follow `_shared/engine-preflight.md`. Two classes. **Explicit cross-engine routes** (`--engine`, `--risk-probes`, `--pair-verify`) are promises: if the required engine is unavailable, fail closed with `BLOCKED:<engine>-unavailable` and setup guidance — never downgrade an explicitly requested route to solo. **Automatic cross-engine escalations** (auto high-risk risk-probes, auto VERIFY pair-JUDGE) are candidate routes selected only when their preconditions hold, including OTHER-engine availability. 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. Skipping an unselected optional route is route selection, not a fallback; an explicitly requested route is never skipped this way.
|
|
21
21
|
3. Phases run in declared order. No extra phases.
|
|
22
22
|
4. Orchestrator does not write code. It parses input, spawns phases, reads state, branches on verdicts, emits the report.
|
|
23
23
|
5. Continue by default. Halt only on (a) unrecoverable subagent failure, (b) IMPLEMENT producing zero code changes, (c) BUILD_GATE or VERIFY fix-loop exhausting `max_rounds`.
|
|
@@ -28,7 +28,7 @@ Every phase reads `_shared/runtime-principles.md` (Subtractive-first / Goal-lock
|
|
|
28
28
|
</harness_principles>
|
|
29
29
|
|
|
30
30
|
<engine_routing>
|
|
31
|
-
Each phase routes to an engine and prepends the per-engine adapter header from `_shared/adapters/<
|
|
31
|
+
Each phase routes to an engine and prepends the per-engine adapter header from `_shared/adapters/<engine>.md` (e.g. `claude.md`, `codex.md`) to the canonical phase body. Adapter is the per-model delta (Anthropic's Opus prompt-engineering guide for Claude, OpenAI's GPT-5.5 guide for Codex). Canonical body is engine-agnostic.
|
|
32
32
|
|
|
33
33
|
- Claude phases: spawn `Agent` (`mode: "bypassPermissions"`); prompt = adapter-header + canonical-body + task-context.
|
|
34
34
|
- Codex phases: shell out via `bash _shared/codex-monitored.sh` with the same compounded prompt. The wrapper closes stdin and emits a heartbeat. No MCP.
|
|
@@ -76,7 +76,7 @@ Once `state.implement_passed_sha` is non-null (PHASE 2 returned and produced a d
|
|
|
76
76
|
- **Spec**: validate spec exists. If sibling `spec.expected.json` exists, run `--check-expected <expected-path>` to validate both the expected contract, sibling spec `complexity` frontmatter, and any present actionable solo-headroom hypothesis; if the spec has a solo-headroom hypothesis, its observable command must match `spec.expected.json.verification_commands[].cmd`. Then stage `.devlyn/spec-verify.json` from `verification_commands`. Otherwise run `--check <spec-path>` to validate the legacy inline carrier plus supported `complexity` frontmatter and any present actionable solo-headroom hypothesis; if the spec uses an inline `## Verification` JSON carrier, any solo-headroom hypothesis command must match that carrier's `verification_commands[].cmd`. Then stage from the legacy inline carrier. Compute `state.source.spec_sha256`.
|
|
77
77
|
- **Verify-only**: skip to PHASE 5 with `state.source.spec_path` set, the supplied diff captured at `.devlyn/external-diff.patch`.
|
|
78
78
|
|
|
79
|
-
5. Compute `state.risk_profile` from the user goal plus spec/criteria text. Mark `high_risk: true` when the work touches any of: auth/authz, permissions, security, token/session, payment/money/billing/invoice/pricing/tax/ledger, persistence/data mutation/deletion/migration, idempotency/replay/duplicate, API/webhook/raw-body/signature, allocation/scheduling/inventory/rollback/transaction, or explicit error-priority/output-shape contracts. If high-risk and `--no-risk-probes` is absent, set `risk_probes_enabled: true
|
|
79
|
+
5. Compute `state.risk_profile` from the user goal plus spec/criteria text. Mark `high_risk: true` when the work touches any of: auth/authz, permissions, security, token/session, payment/money/billing/invoice/pricing/tax/ledger, persistence/data mutation/deletion/migration, idempotency/replay/duplicate, API/webhook/raw-body/signature, allocation/scheduling/inventory/rollback/transaction, or explicit error-priority/output-shape contracts. Explicit `--risk-probes` sets `risk_probes_enabled: true` unconditionally (the OTHER engine is then a promise; unavailability blocks at PHASE 1.5). If high-risk is detected and `--no-risk-probes` is absent, this is an AUTO escalation: set `risk_probes_enabled: true` only when the OTHER engine is available (for a Claude run, `command -v codex`); if it is unavailable, leave `risk_probes_enabled: false`, keep `high_risk: true`, and append a reason such as `auto-risk-probes skipped: codex-unavailable` so the report shows it. `--no-risk-probes` disables only the auto escalation; a single-engine run does not need it to proceed. If `--no-pair` is present, set `pair_default_enabled: false`. Add concise string reasons for the classification, but do not use reasons as substitutes for the boolean fields.
|
|
80
80
|
|
|
81
81
|
6. Announce one line: `resolve starting — run <run_id> — engine <engine> — mode <mode> — complexity <complexity-or-na> — pair <conditional|disabled> — risk_probes <on|off>`.
|
|
82
82
|
|
|
@@ -98,9 +98,12 @@ After return:
|
|
|
98
98
|
|
|
99
99
|
Skip unless `--risk-probes` is set OR `state.risk_profile.risk_probes_enabled`
|
|
100
100
|
is true. This phase is findings-as-executable-checks, not a second plan and not
|
|
101
|
-
debate.
|
|
101
|
+
debate. When it runs, the OTHER engine is required: if unavailable, halt with
|
|
102
102
|
`BLOCKED:codex-unavailable` or `BLOCKED:claude-unavailable` plus setup guidance;
|
|
103
|
-
do not silently continue without probes.
|
|
103
|
+
do not silently continue without probes. Reaching this halt means the route was
|
|
104
|
+
explicitly requested (`--risk-probes`) — an auto high-risk escalation toward an
|
|
105
|
+
unavailable OTHER engine was already gated off in PHASE 0 by leaving
|
|
106
|
+
`risk_probes_enabled: false`, so a single-engine high-risk run proceeds solo here.
|
|
104
107
|
|
|
105
108
|
Engine: OTHER engine from PHASE 2's selected IMPLEMENT engine. Prompt body:
|
|
106
109
|
`references/phases/probe-derive.md`.
|
|
@@ -245,10 +248,14 @@ After MECHANICAL and the primary JUDGE finish, compute `pair_trigger = { eligibl
|
|
|
245
248
|
|
|
246
249
|
The `--engine` flag never suppresses this rule. Explicit `--engine claude`
|
|
247
250
|
means "Claude is the primary judge"; it does not mean "do not run Codex as the
|
|
248
|
-
second pair judge." The
|
|
249
|
-
trigger are deterministic MECHANICAL HIGH/CRITICAL blockers
|
|
250
|
-
`--no-pair
|
|
251
|
-
|
|
251
|
+
second pair judge." The valid skip reasons after a non-empty eligible
|
|
252
|
+
trigger are deterministic MECHANICAL HIGH/CRITICAL blockers, an explicit
|
|
253
|
+
`--no-pair`, or — when none of the applicable reasons is `mode.pair-verify` (i.e.
|
|
254
|
+
every reason is automatic) — the OTHER engine being unavailable. In that
|
|
255
|
+
auto-only-unavailable case, set `eligible: false`, leave `reasons` empty, set
|
|
256
|
+
`skipped_reason: "auto_pair_other_engine_unavailable"`, and run solo VERIFY.
|
|
257
|
+
Explicit `--pair-verify` (`mode.pair-verify`) with the OTHER engine absent is a
|
|
258
|
+
promise: it stays `BLOCKED:<engine>-unavailable` and is never skipped.
|
|
252
259
|
|
|
253
260
|
Pair-mode JUDGE: spawn a second Agent with the OTHER engine's adapter; the second judge is a bounded adversarial complement, not a duplicate broad audit. The primary judge owns broad coverage; pair-JUDGE targets the two highest-risk explicit `## Verification` bullets that cross state mutation, all-or-nothing rollback, ordering, idempotency, auth, or error-priority clauses. If the spec includes a solo-headroom hypothesis, one of those targeted probes must exercise that hypothesis with the visible command/input shape and full externally visible result, using the hypothesis's backticked observable command as its command anchor before adding bounded input variations. It must not read `.claude/skills`, `.codex/skills`, `CLAUDE.md`, `AGENTS.md`, or other harness docs unless the orchestrator pasted a specific excerpt into the prompt. It may use only the spec, diff, implementation files, tests, and the repo's existing CLI/API/test runner. It may execute at most two targeted probes before first output, and each probe must compare the full externally visible result (exit/stdout/stderr plus full parsed output object, including accepted/scheduled rows, rejected rows, and remaining state when present), not just a single property. When the spec names exact keys, row shapes, JSON object shape, or an exact error body, pair-JUDGE must compare parsed key sets/deep equality so aliased keys, missing keys, and extra keys are verdict-binding failures, and it must construct inputs with the spec's visible key names. For priority/stateful specs, at least one probe must include an earlier input entity that would succeed under input-order processing, a later higher-priority entity that consumes or blocks the critical resource, and a failure/blocked/rollback edge that determines a later entity's state. For cart/pricing specs where visible verification combines duplicate items, line promotions, tax, coupon, and shipping, the success-path probe must include interleaved duplicates plus taxable and non-taxable items and assert full output rows. Scope qualifiers are binding: pair-JUDGE must not reinterpret `inside a warehouse`, `per resource`, or line-scoped rules as global rules. When both priority ordering and rollback/blocked-interval behavior appear in the spec, this dominance-loss probe is mandatory and comes before any other probe: an earlier lower-priority entity that would succeed alone or under input-order processing must lose because a later higher-priority entity is processed first; a failed/blocked middle entity must not corrupt later state; and the assertion must cover complete accepted/scheduled and rejected output ordering. It must stop and emit JSONL immediately on the first verdict-binding finding, and must emit PASS immediately if both probes plus static scope/dependency checks pass. Both judgments merge with the rule "any HIGH/CRITICAL finding either model surfaces is verdict-binding; high-confidence MEDIUM findings are also verdict-binding when they identify a concrete behavioral regression against the spec, public contract, or existing test contract." Cross-model disagreement on advisory lower-severity findings is logged but does not change the verdict. If MECHANICAL or the primary JUDGE has a verdict-binding finding, skip the second judge and record `pair_judge: null`; the fix loop needs the blocker, not duplicate review.
|
|
254
261
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# PHASE 1 — PLAN (canonical body)
|
|
2
2
|
|
|
3
|
-
The per-engine adapter header from `_shared/adapters/<
|
|
3
|
+
The per-engine adapter header from `_shared/adapters/<engine>.md` is prepended at runtime. This file is engine-agnostic.
|
|
4
4
|
|
|
5
5
|
<role>
|
|
6
6
|
You translate a spec or generated criteria into a concrete plan: the file list to touch, the risks the implementation must navigate, and a verbatim restatement of what acceptance requires. The plan is the contract IMPLEMENT executes against.
|
|
@@ -148,18 +148,24 @@ reasons and at least one reason: `mode.verify-only`, `complexity.high`, `complex
|
|
|
148
148
|
The `--engine` flag never disables this rule. Explicit `--engine claude` means
|
|
149
149
|
Claude is the primary judge; if pair-mode triggers, Codex is still the mandatory
|
|
150
150
|
OTHER-engine judge. Do not record "explicit --engine claude" as a skip reason.
|
|
151
|
-
The
|
|
152
|
-
MECHANICAL HIGH/CRITICAL blockers
|
|
153
|
-
|
|
151
|
+
The valid skip reasons after a non-empty eligible trigger are deterministic
|
|
152
|
+
MECHANICAL HIGH/CRITICAL blockers, an explicit `--no-pair`, or — when none of the
|
|
153
|
+
applicable reasons is `mode.pair-verify` (every reason is automatic) — the OTHER
|
|
154
|
+
engine being unavailable. Explicit `--pair-verify` with the OTHER engine absent
|
|
155
|
+
is a promise and stays `BLOCKED:<engine>-unavailable`, never a skip.
|
|
154
156
|
|
|
155
157
|
Before invoking the OTHER-engine judge, run the shared availability pre-flight
|
|
156
|
-
for that engine. If
|
|
157
|
-
`BLOCKED:codex-unavailable` and tell the user to
|
|
158
|
-
run the current Codex auth/login flow, verify
|
|
159
|
-
Claude is required and the host cannot spawn a
|
|
160
|
-
`BLOCKED:claude-unavailable` and tell the user to
|
|
161
|
-
verify `claude --version
|
|
162
|
-
solo pass
|
|
158
|
+
for that engine. If the route is explicit (`--pair-verify`) and Codex is required
|
|
159
|
+
and unavailable, set VERIFY to `BLOCKED:codex-unavailable` and tell the user to
|
|
160
|
+
install/configure the Codex CLI, run the current Codex auth/login flow, verify
|
|
161
|
+
`codex --version`, and rerun. If Claude is required and the host cannot spawn a
|
|
162
|
+
Claude agent, set VERIFY to `BLOCKED:claude-unavailable` and tell the user to
|
|
163
|
+
install/configure Claude Code, verify `claude --version`, and rerun. For an
|
|
164
|
+
explicit route, do not convert this to a solo pass and do not synthesize pair
|
|
165
|
+
findings. When the trigger was AUTO-only and the OTHER engine is unavailable, set
|
|
166
|
+
`eligible: false`, `reasons: []`, `skipped_reason:
|
|
167
|
+
"auto_pair_other_engine_unavailable"`, run solo VERIFY, and report the skipped
|
|
168
|
+
auto escalation — route selection, not a fallback.
|
|
163
169
|
|
|
164
170
|
When eligible and the orchestrator spawns a second VERIFY agent with the OTHER engine's adapter, both judgments are merged:
|
|
165
171
|
- Any HIGH/CRITICAL finding either model surfaces is verdict-binding.
|
|
@@ -5,7 +5,7 @@ allowed-tools: Read, Grep, Glob, Edit, Write
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
<!--
|
|
8
|
-
Version: 2026-
|
|
8
|
+
Version: 2026-05 | Claude 4.x (Opus 4.8, Sonnet 4.6, Haiku 4.5)
|
|
9
9
|
Source: https://platform.claude.com/docs/build-with-claude/prompt-engineering/claude-4-best-practices
|
|
10
10
|
-->
|
|
11
11
|
|
|
@@ -103,13 +103,13 @@ explicitly requested. Incorporate information naturally into sentences.
|
|
|
103
103
|
START: Which Claude model?
|
|
104
104
|
│
|
|
105
105
|
├─► Complex reasoning, multi-step analysis, or highest quality?
|
|
106
|
-
│ → Opus 4.
|
|
106
|
+
│ → Opus 4.8 (claude-opus-4-8)
|
|
107
107
|
│
|
|
108
108
|
├─► Balance of quality, speed, and cost?
|
|
109
|
-
│ → Sonnet 4.
|
|
109
|
+
│ → Sonnet 4.6 (claude-sonnet-4-6)
|
|
110
110
|
│
|
|
111
111
|
└─► Fast responses, simple tasks, cost-sensitive?
|
|
112
|
-
→ Haiku 4.5 (claude-haiku-4-5-
|
|
112
|
+
→ Haiku 4.5 (claude-haiku-4-5-20251001)
|
|
113
113
|
```
|
|
114
114
|
|
|
115
115
|
---
|
|
@@ -152,7 +152,7 @@ results, execute sequentially. Never use placeholders for missing parameters.
|
|
|
152
152
|
|--------------|--------------|-----|
|
|
153
153
|
| "Can you suggest changes?" | Claude will only suggest, not implement | "Change this function to..." |
|
|
154
154
|
| "Think about this carefully" | Triggers thinking sensitivity | "Consider this carefully" |
|
|
155
|
-
| "CRITICAL: You MUST..." |
|
|
155
|
+
| "CRITICAL: You MUST..." | Claude may over-trigger | "Use this when..." |
|
|
156
156
|
| Vague instructions | Literal interpretation | Add explicit detail |
|
|
157
157
|
| No context for rules | Claude can't generalize | Explain WHY behind rules |
|
|
158
158
|
| Examples with unwanted patterns | Claude mimics examples precisely | Remove unwanted behaviors from examples |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "devlyn-cli",
|
|
3
|
-
"version": "2.5.
|
|
3
|
+
"version": "2.5.5",
|
|
4
4
|
"description": "AI development toolkit for Claude Code — ideate, resolve, and ship with context engineering and agent orchestration",
|
|
5
5
|
"homepage": "https://github.com/fysoul17/devlyn-cli#readme",
|
|
6
6
|
"bin": {
|
package/scripts/lint-skills.sh
CHANGED
|
@@ -75,8 +75,8 @@ devlyn:resolve/references/phases/cleanup.md
|
|
|
75
75
|
devlyn:resolve/references/phases/verify.md
|
|
76
76
|
_shared/expected.schema.json
|
|
77
77
|
_shared/adapters/README.md
|
|
78
|
-
_shared/adapters/
|
|
79
|
-
_shared/adapters/
|
|
78
|
+
_shared/adapters/claude.md
|
|
79
|
+
_shared/adapters/codex.md
|
|
80
80
|
_shared/codex-config.md
|
|
81
81
|
_shared/codex-monitored.sh
|
|
82
82
|
_shared/engine-preflight.md
|
|
@@ -1586,29 +1586,29 @@ fi
|
|
|
1586
1586
|
section "Check 10d: Prompt adapters cite official model guidance"
|
|
1587
1587
|
adapter_missing=0
|
|
1588
1588
|
if ! grep -Fq 'https://developers.openai.com/api/docs/guides/prompt-guidance?model=gpt-5.5' \
|
|
1589
|
-
config/skills/_shared/adapters/
|
|
1590
|
-
bad "
|
|
1589
|
+
config/skills/_shared/adapters/codex.md; then
|
|
1590
|
+
bad "codex adapter missing official OpenAI prompt guidance URL"
|
|
1591
1591
|
adapter_missing=1
|
|
1592
1592
|
fi
|
|
1593
1593
|
if ! grep -Fq 'https://platform.claude.com/docs/en/build-with-claude/prompt-engineering/claude-prompting-best-practices' \
|
|
1594
|
-
config/skills/_shared/adapters/
|
|
1595
|
-
bad "
|
|
1594
|
+
config/skills/_shared/adapters/claude.md; then
|
|
1595
|
+
bad "claude adapter missing official Claude prompting best-practices URL"
|
|
1596
1596
|
adapter_missing=1
|
|
1597
1597
|
fi
|
|
1598
1598
|
for pattern in 'Use Markdown only where it carries structure' 'metaprompter for itself'; do
|
|
1599
|
-
if ! grep -Fq "$pattern" config/skills/_shared/adapters/
|
|
1600
|
-
bad "
|
|
1599
|
+
if ! grep -Fq "$pattern" config/skills/_shared/adapters/codex.md; then
|
|
1600
|
+
bad "codex adapter missing official-guidance tactic: $pattern"
|
|
1601
1601
|
adapter_missing=1
|
|
1602
1602
|
fi
|
|
1603
1603
|
done
|
|
1604
1604
|
for pattern in 'high` or `xhigh` effort' 'report every issue you find' 'do not filter for importance or confidence' 'prefer concise positive examples' '<example>'; do
|
|
1605
|
-
if ! grep -Fq "$pattern" config/skills/_shared/adapters/
|
|
1606
|
-
bad "
|
|
1605
|
+
if ! grep -Fq "$pattern" config/skills/_shared/adapters/claude.md; then
|
|
1606
|
+
bad "claude adapter missing official-guidance tactic: $pattern"
|
|
1607
1607
|
adapter_missing=1
|
|
1608
1608
|
fi
|
|
1609
1609
|
done
|
|
1610
1610
|
for file in config/skills/devlyn:resolve/SKILL.md config/skills/devlyn:ideate/SKILL.md; do
|
|
1611
|
-
if ! grep -Fq '_shared/adapters/<
|
|
1611
|
+
if ! grep -Fq '_shared/adapters/<engine>.md' "$file"; then
|
|
1612
1612
|
bad "$file — missing per-engine adapter injection contract"
|
|
1613
1613
|
adapter_missing=1
|
|
1614
1614
|
fi
|