devlyn-cli 2.4.1 → 2.5.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 CHANGED
@@ -17,7 +17,7 @@ Seven rules govern every change. Cite them by name when a decision touches one.
17
17
  Three discipline rules govern HOW the principles are applied:
18
18
 
19
19
  - **Root cause via flexible why-chain.** Keep asking "why?" until you find the violated invariant. **If the answer surfaces in 2 questions, stop.** If it takes 5 or 7, keep going. Strict counts are wrong; until-found is right.
20
- - **First-principles thinking.** Challenge the requirement before optimizing the answer. Most "we have to do X" assumptions are habit, not necessity. Reduce to irreducible truths and rebuild from there.
20
+ - **First-principles thinking.** Challenge the requirement before optimizing the answer. Surface unstated assumptions, ambiguities, tradeoffs, and simpler alternatives BEFORE implementing — do not silently pick one interpretation when multiple exist, do not hide confusion, push back when a simpler path is genuinely better. Most "we have to do X" assumptions are habit, not necessity. Reduce to irreducible truths and rebuild from there.
21
21
  - **Perfection is achieved not when there is nothing more to add, but when there is nothing left to take away.** — Saint-Exupéry. The operating definition of "done." A change is finished when no further line, branch, flag, or doc paragraph can be removed without breaking a learned failure mode.
22
22
 
23
23
  ## Quick Start
@@ -55,8 +55,8 @@ Default mode is execution toward the user's stated goal. Do not drift.
55
55
 
56
56
  Refuse these patterns:
57
57
 
58
- - Unrequested work ("while here, also fix...").
59
- - Tangential cleanup in files the task does not require.
58
+ - Unrequested work ("while here, also fix..."). Pre-existing dead code → mention only, do NOT delete. Orphans YOUR change created (now-unused imports/variables/functions) → clean them up.
59
+ - Tangential cleanup in files the task does not require. Match existing style even if you'd write it differently; do NOT touch comments, formatting, or code orthogonal to your real change — silent side-effects on neighboring lines are the most common Karpathy-observed regression class.
60
60
  - Speculative robustness for cases not observed in production, tests, findings, or the spec.
61
61
  - Mid-flight re-scoping without user approval.
62
62
  - Curiosity exploration that is not on the critical path.
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. No `any`, no `@ts-ignore`, no silent `catch`, no hardcoded fallback that hides a broken contract. Configuration-level skips that bypass the real issue are also rejects.
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` pair/risk-probe routes — if Codex or Claude is required and unavailable, stop with `BLOCKED:codex-unavailable` or `BLOCKED:claude-unavailable` and setup guidance. `--no-pair` / `--no-risk-probes` are explicit user opt-outs, not fallbacks.
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.
@@ -17,7 +17,7 @@ Seven rules govern every change. Cite them by name when a decision touches one.
17
17
  Three discipline rules govern HOW the principles are applied:
18
18
 
19
19
  - **Root cause via flexible why-chain.** Keep asking "why?" until you find the violated invariant. **If the answer surfaces in 2 questions, stop.** If it takes 5 or 7, keep going. Strict counts are wrong; until-found is right.
20
- - **First-principles thinking.** Challenge the requirement before optimizing the answer. Most "we have to do X" assumptions are habit, not necessity. Reduce the problem to its irreducible truths and rebuild from there.
20
+ - **First-principles thinking.** Challenge the requirement before optimizing the answer. Surface unstated assumptions, ambiguities, tradeoffs, and simpler alternatives BEFORE implementing — do not silently pick one interpretation when multiple exist, do not hide confusion, push back when a simpler path is genuinely better. Most "we have to do X" assumptions are habit, not necessity. Reduce the problem to its irreducible truths and rebuild from there.
21
21
  - **Perfection is achieved not when there is nothing more to add, but when there is nothing left to take away.** — Saint-Exupéry. This is the operating definition of "done." A change is finished when no further line, branch, flag, or doc paragraph can be removed without breaking a learned failure mode. Not before.
22
22
 
23
23
  The runtime sub-agent contract below (Subtractive-first / Goal-locked / No-workaround discipline / Evidence over claim) expands these principles into concrete operational tests. Sub-agents in `/devlyn:resolve` and `/devlyn:ideate` enforce them at every phase.
@@ -44,7 +44,7 @@ Each skill's `SKILL.md` is the source of truth for its flags and workflow — do
44
44
  ### Subtractive-first editing — perfection = nothing left to remove
45
45
  <!-- runtime-principles:section=subtractive-first:begin -->
46
46
 
47
- > "Perfection is achieved not when there is nothing more to add, but when there is nothing left to take away." — Saint-Exupéry. **This is the operating definition of "done" in this repo.** A change is finished when no further line, branch, flag, or doc paragraph can be removed without breaking a learned failure mode. Not before.
47
+ > **Operating definition of "done" in this repo** (Saint-Exupéry discipline rule above): a change is finished when no further line, branch, flag, or doc paragraph can be removed without breaking a learned failure mode. Not before.
48
48
 
49
49
  This rule overrides instinct. LLMs (including you) are trained on corpora that reward elaborate, defensive, "thorough" code — so the default impulse is to add. That impulse is wrong here. Read the rules below as hard tests, not aesthetic preferences. They are not optional, not negotiable, and not satisfiable by writing more careful additions.
50
50
 
@@ -86,8 +86,8 @@ This rule exists because LLMs (including you) are trained to be helpful, compreh
86
86
 
87
87
  **The five drift patterns you must refuse to execute on:**
88
88
 
89
- 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.
90
- 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.
89
+ 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.**
90
+ 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; do NOT touch comments, formatting, or code orthogonal to your real change** — silent side-effects on neighboring lines are the most common Karpathy-observed regression class.
91
91
  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.
92
92
  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.
93
93
  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.
@@ -116,16 +116,6 @@ This rule exists because LLMs (including you) are trained to be helpful, compreh
116
116
  - **Fallbacks are the exception.** Only use them when it's a widely accepted best practice (CSS fallback fonts, CDN failover, image placeholders). Otherwise handle the error explicitly.
117
117
  - **Pattern**: `try { doThing() } catch (error) { showErrorUI(error) }` — NOT `try { doThing() } catch { return fallbackValue }`.
118
118
 
119
- ### No-workaround discipline (runtime salience)
120
- <!-- runtime-principles:section=no-workaround:begin -->
121
-
122
- No `any`, no `@ts-ignore`, no silent `catch`, no hardcoded values, no helper scripts that bypass the root cause. Fix root causes; handle errors with user-visible state per the rule above.
123
-
124
- **Permitted exceptions** (explicitly carved out):
125
- - CSS fallback fonts, CDN failover, image placeholders — widely-accepted best practices.
126
- - No engine-availability fallback is permitted for `/devlyn:resolve` pair/risk-probe routes. If Codex or Claude is required and unavailable, the run stops with `BLOCKED:codex-unavailable` or `BLOCKED:claude-unavailable` plus setup guidance. `--no-pair` / `--no-risk-probes` are explicit user opt-outs, not fallbacks.
127
- <!-- runtime-principles:section=no-workaround:end -->
128
-
129
119
  ### Evidence over claim
130
120
  <!-- runtime-principles:section=evidence:begin -->
131
121
 
@@ -152,9 +142,9 @@ When `/devlyn:resolve` or `/devlyn:ideate` route a phase to Codex (`--engine cod
152
142
 
153
143
  ## Skill Boundary Policy
154
144
 
155
- Post iter-0034 Phase 4 cutover (2026-05-04) the runtime pipeline surface is two skills — `/devlyn:resolve` and `/devlyn:ideate` — plus the required creative UI exploration surface `/devlyn:design-ui`. `/devlyn:resolve` runs PLAN → IMPLEMENT → BUILD_GATE → CLEANUP → VERIFY inline; verification, cleanup, and security review (delegated to the native `security-review` Claude Code skill from BUILD_GATE) all live inside the pipeline. There are no standalone `/devlyn:review`, `/devlyn:evaluate`, `/devlyn:team-resolve`, etc. surfaces to delegate to — those skills were folded into resolve's phases or removed in iter-0034. `/devlyn:design-ui` is the unified creative UI exploration surface — it spawns a 5-specialist design team (Creative Director, Product Designer, Visual Designer, Interaction Designer, Accessibility Designer) by default for any N. The legacy `/devlyn:team-design-ui` was merged into it on 2026-05-14 and its directory deleted; `/devlyn:design-system` was removed outright the same day. The `/devlyn:reap` optional skill lives in `optional-skills/` and is user-invoked only; resolve never delegates to it.
145
+ The runtime pipeline surface is two skills — `/devlyn:resolve` and `/devlyn:ideate` — plus `/devlyn:design-ui` for creative UI exploration. `/devlyn:resolve` runs PLAN → IMPLEMENT → BUILD_GATE → CLEANUP → VERIFY inline; verification, cleanup, and security review (delegated to the native `security-review` Claude Code skill from BUILD_GATE) all live inside the pipeline. There are no standalone `/devlyn:review`, `/devlyn:evaluate`, or `/devlyn:team-resolve` surfaces. `/devlyn:design-ui` spawns a 5-specialist design team (Creative Director, Product Designer, Visual Designer, Interaction Designer, Accessibility Designer). `/devlyn:reap` is an optional user-invoked skill in `optional-skills/`; resolve never delegates to it.
156
146
 
157
- Browser validation routes through `_shared/browser-runner.sh` (Chrome MCP → Playwright → curl tier) directly from BUILD_GATE — there is no separate `/devlyn:browser-validate` skill at HEAD.
147
+ Browser validation runs directly from BUILD_GATE using whichever toolchain is available (Chrome MCP, Playwright, or curl-tier fallback) — there is no separate `/devlyn:browser-validate` skill.
158
148
 
159
149
  ## Communication Style
160
150
 
@@ -4,7 +4,7 @@ You are a code quality evaluator. Your job is to audit work produced by another
4
4
 
5
5
  ## Before You Start
6
6
 
7
- 1. **Check for done criteria**: Read `.devlyn/done-criteria.md` if it exists. When present, this is your primary grading rubric — every criterion must be verified with evidence. When absent, fall back to the checklists below.
7
+ 1. **Check for done criteria**: Read `.devlyn/runs/<run_id>/spec/expected.json` if a structured done-criteria source exists for the current run. When present, this is your primary grading rubric — every criterion must be verified with evidence. When absent, fall back to the checklists below.
8
8
 
9
9
  ## Calibration
10
10
 
@@ -36,14 +36,14 @@ You will be too lenient by default. You will identify real issues, then talk you
36
36
 
37
37
  ## Output
38
38
 
39
- Write findings to `.devlyn/EVAL-FINDINGS.md` for downstream consumption:
39
+ Write findings to `.devlyn/runs/<run_id>/eval-findings.md` for downstream consumption:
40
40
 
41
41
  ```markdown
42
42
  # Evaluation Findings
43
43
 
44
44
  ## Verdict: [PASS / PASS WITH ISSUES / NEEDS WORK / BLOCKED]
45
45
 
46
- ## Done Criteria Results (if done-criteria.md existed)
46
+ ## Done Criteria Results (if a done-criteria source existed)
47
47
  - [x] [criterion] — VERIFIED: [evidence]
48
48
  - [ ] [criterion] — FAILED: [what's wrong, file:line]
49
49
 
@@ -61,4 +61,4 @@ Write findings to `.devlyn/EVAL-FINDINGS.md` for downstream consumption:
61
61
  - [positive observations]
62
62
  ```
63
63
 
64
- Do NOT delete `.devlyn/done-criteria.md` or `.devlyn/EVAL-FINDINGS.md` — the orchestrator or user is responsible for cleanup.
64
+ Do NOT delete the run-directory artifacts (`spec/expected.json`, `eval-findings.md`) — the orchestrator or user is responsible for cleanup.
package/bin/devlyn.js CHANGED
@@ -558,64 +558,66 @@ function installSkillsForCLI(cliKey) {
558
558
  function installAgentsForCLI(cliKey) {
559
559
  const cli = CLI_TARGETS[cliKey];
560
560
  if (!cli) return false;
561
- if (!fs.existsSync(AGENTS_SOURCE)) return false;
562
561
 
563
- const agents = fs.readdirSync(AGENTS_SOURCE).filter((f) => f.endsWith('.md'));
564
- if (agents.length === 0) return false;
562
+ const agents = fs.existsSync(AGENTS_SOURCE)
563
+ ? fs.readdirSync(AGENTS_SOURCE).filter((f) => f.endsWith('.md'))
564
+ : [];
565
565
 
566
- log(`\n🤖 Installing agents for ${cli.name}...`, 'cyan');
566
+ if (agents.length > 0) {
567
+ log(`\n🤖 Installing agents for ${cli.name}...`, 'cyan');
567
568
 
568
- if (cli.configDir) {
569
- // CLI supports an agents directory — copy agent files there
570
- const destDir = path.join(process.cwd(), cli.configDir);
571
- if (!fs.existsSync(destDir)) {
572
- fs.mkdirSync(destDir, { recursive: true });
573
- }
574
- for (const file of agents) {
575
- const src = path.join(AGENTS_SOURCE, file);
576
- const dest = path.join(destDir, file);
577
- fs.copyFileSync(src, dest);
578
- log(` → ${cli.configDir}/${file}`, 'dim');
579
- }
580
- } else {
581
- // CLI uses a single instructions file — append agent content
582
- const destFile = path.join(process.cwd(), cli.instructionsFile);
583
- const separator = '\n\n---\n\n# Devlyn Agent Instructions\n\n';
584
- const agentContent = agents.map((file) => {
585
- return fs.readFileSync(path.join(AGENTS_SOURCE, file), 'utf8');
586
- }).join('\n\n---\n\n');
587
-
588
- let existing = '';
589
- if (fs.existsSync(destFile)) {
590
- existing = fs.readFileSync(destFile, 'utf8');
591
- // Remove previous devlyn agent section if present
592
- const devlynMarker = '# Devlyn Agent Instructions';
593
- const markerIdx = existing.indexOf(devlynMarker);
594
- if (markerIdx > 0) {
595
- // Find the separator before the marker (---\n\n)
596
- const sepIdx = existing.lastIndexOf('---', markerIdx);
597
- existing = existing.slice(0, sepIdx > 0 ? sepIdx : markerIdx).trimEnd();
569
+ if (cli.configDir) {
570
+ // CLI supports an agents directory — copy agent files there
571
+ const destDir = path.join(process.cwd(), cli.configDir);
572
+ if (!fs.existsSync(destDir)) {
573
+ fs.mkdirSync(destDir, { recursive: true });
598
574
  }
599
- } else if (cli.baseInstructionsFile) {
600
- const baseInstructionsSrc = path.join(__dirname, '..', cli.baseInstructionsFile);
601
- if (fs.existsSync(baseInstructionsSrc)) {
602
- existing = fs.readFileSync(baseInstructionsSrc, 'utf8').trimEnd();
575
+ for (const file of agents) {
576
+ const src = path.join(AGENTS_SOURCE, file);
577
+ const dest = path.join(destDir, file);
578
+ fs.copyFileSync(src, dest);
579
+ log(` → ${cli.configDir}/${file}`, 'dim');
580
+ }
581
+ } else {
582
+ // CLI uses a single instructions file — append agent content
583
+ const destFile = path.join(process.cwd(), cli.instructionsFile);
584
+ const separator = '\n\n---\n\n# Devlyn Agent Instructions\n\n';
585
+ const agentContent = agents.map((file) => {
586
+ return fs.readFileSync(path.join(AGENTS_SOURCE, file), 'utf8');
587
+ }).join('\n\n---\n\n');
588
+
589
+ let existing = '';
590
+ if (fs.existsSync(destFile)) {
591
+ existing = fs.readFileSync(destFile, 'utf8');
592
+ // Remove previous devlyn agent section if present
593
+ const devlynMarker = '# Devlyn Agent Instructions';
594
+ const markerIdx = existing.indexOf(devlynMarker);
595
+ if (markerIdx > 0) {
596
+ // Find the separator before the marker (---\n\n)
597
+ const sepIdx = existing.lastIndexOf('---', markerIdx);
598
+ existing = existing.slice(0, sepIdx > 0 ? sepIdx : markerIdx).trimEnd();
599
+ }
600
+ } else if (cli.baseInstructionsFile) {
601
+ const baseInstructionsSrc = path.join(__dirname, '..', cli.baseInstructionsFile);
602
+ if (fs.existsSync(baseInstructionsSrc)) {
603
+ existing = fs.readFileSync(baseInstructionsSrc, 'utf8').trimEnd();
604
+ }
603
605
  }
604
- }
605
606
 
606
- fs.writeFileSync(destFile, existing + separator + agentContent + '\n');
607
- log(` → ${cli.instructionsFile} (agent instructions appended)`, 'dim');
607
+ fs.writeFileSync(destFile, existing + separator + agentContent + '\n');
608
+ log(` → ${cli.instructionsFile} (agent instructions appended)`, 'dim');
609
+ }
608
610
  }
609
611
 
610
- // If this CLI also supports a global skill-loader (currently Codex), install
611
- // devlyn:resolve + devlyn:ideate + devlyn:design-ui + _shared. Codex invokes
612
- // these as skills (for example `$devlyn:resolve`), not Claude slash commands.
612
+ // Always install global skills (Codex-style skill loader) regardless of
613
+ // whether agent files were present. Agent install and skill install are
614
+ // independent capabilities.
613
615
  const skillsCopied = installSkillsForCLI(cliKey);
614
616
  if (skillsCopied > 0) {
615
617
  log(` → ${skillsCopied} skill${skillsCopied > 1 ? 's' : ''} installed (devlyn:resolve / devlyn:ideate / devlyn:design-ui / _shared)`, 'dim');
616
618
  }
617
619
 
618
- return true;
620
+ return agents.length > 0 || skillsCopied > 0;
619
621
  }
620
622
 
621
623
  function installAgentsForAllDetected() {
@@ -31,7 +31,7 @@ Notes:
31
31
  - `-s read-only` / `--full-auto` — sandbox policy. `--full-auto` = `-s workspace-write` with auto-approval of sandboxed commands.
32
32
  - `-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
33
  - **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
- - `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, pyx-memory, hooks, and project rules cannot add hidden context, tool calls, or transcript side effects. Do not set it for workspace-write implementation phases.
34
+ - `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.
35
35
  - Raw `codex exec ...` invocations are **forbidden** in skill prompts. The benchmark variant arm runs a PATH shim (`scripts/codex-shim/codex`) that transparently re-routes any raw `codex exec` to the wrapper as a safety net, but skills should always emit the wrapper form directly so the orchestrator's first-attempt has the right shape. Two prior iterations (iter-0006 universal foreground ban, iter-0008 prompt-level kill-shape contract) failed because the orchestrator picked starvation-prone shapes (`codex exec ... 2>&1 | tail -200`) from its own pattern prior — the wrapper plus the shim is the runtime binding layer those iters lacked. See `autoresearch/iterations/0009-wrapper-and-hook.md`.
36
36
 
37
37
  ## Availability check
@@ -2,13 +2,13 @@
2
2
 
3
3
  The runtime contract every sub-agent inside `/devlyn:resolve` (PLAN / IMPLEMENT / BUILD_GATE / CLEANUP / VERIFY) and `/devlyn:ideate` must satisfy. Source of truth for sub-agent behavior on user tasks. NOT for autoresearch-loop / harness-developer concerns (see `autoresearch/PRINCIPLES.md`).
4
4
 
5
- The four sections below mirror the corresponding CLAUDE.md sections (Subtractive-first editing, Goal-locked execution, No-workaround discipline, Evidence over claim). Each section is wrapped in `<!-- runtime-principles:section=NAME:begin -->` / `:end -->` markers in BOTH this file and CLAUDE.md; lint Check 12 (added in iter-0019.A Step 5) extracts each named block from both files and diffs to detect drift.
5
+ The three sections below mirror the corresponding CLAUDE.md sections (Subtractive-first editing, Goal-locked execution, Evidence over claim). No-workaround discipline lives in CLAUDE.md Core Principle #1 only — it does not have a runtime-mirror block. Each mirrored section is wrapped in `<!-- runtime-principles:section=NAME:begin -->` / `:end -->` markers in BOTH this file and CLAUDE.md; lint Check 12 extracts each named block from both files and diffs to detect drift.
6
6
 
7
7
  <!-- runtime-principles:contract:begin -->
8
8
  ## Subtractive-first editing — perfection = nothing left to remove
9
9
  <!-- runtime-principles:section=subtractive-first:begin -->
10
10
 
11
- > "Perfection is achieved not when there is nothing more to add, but when there is nothing left to take away." — Saint-Exupéry. **This is the operating definition of "done" in this repo.** A change is finished when no further line, branch, flag, or doc paragraph can be removed without breaking a learned failure mode. Not before.
11
+ > **Operating definition of "done" in this repo** (Saint-Exupéry discipline rule above): a change is finished when no further line, branch, flag, or doc paragraph can be removed without breaking a learned failure mode. Not before.
12
12
 
13
13
  This rule overrides instinct. LLMs (including you) are trained on corpora that reward elaborate, defensive, "thorough" code — so the default impulse is to add. That impulse is wrong here. Read the rules below as hard tests, not aesthetic preferences. They are not optional, not negotiable, and not satisfiable by writing more careful additions.
14
14
 
@@ -50,8 +50,8 @@ This rule exists because LLMs (including you) are trained to be helpful, compreh
50
50
 
51
51
  **The five drift patterns you must refuse to execute on:**
52
52
 
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.
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.
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; do NOT touch comments, formatting, or code orthogonal to your real change** — silent side-effects on neighboring lines are the most common Karpathy-observed regression class.
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.
@@ -72,16 +72,6 @@ This rule exists because LLMs (including you) are trained to be helpful, compreh
72
72
  **Stopping rule.** A task is done when the user's stated goal is closed AND no off-path work was added. If you find yourself hesitating because "I should also do Z" — Z is drift. Note it for follow-up, do not execute.
73
73
  <!-- runtime-principles:section=goal-locked:end -->
74
74
 
75
- ## No-workaround discipline
76
- <!-- runtime-principles:section=no-workaround:begin -->
77
-
78
- No `any`, no `@ts-ignore`, no silent `catch`, no hardcoded values, no helper scripts that bypass the root cause. Fix root causes; handle errors with user-visible state per the rule above.
79
-
80
- **Permitted exceptions** (explicitly carved out):
81
- - CSS fallback fonts, CDN failover, image placeholders — widely-accepted best practices.
82
- - No engine-availability fallback is permitted for `/devlyn:resolve` pair/risk-probe routes. If Codex or Claude is required and unavailable, the run stops with `BLOCKED:codex-unavailable` or `BLOCKED:claude-unavailable` plus setup guidance. `--no-pair` / `--no-risk-probes` are explicit user opt-outs, not fallbacks.
83
- <!-- runtime-principles:section=no-workaround:end -->
84
-
85
75
  ## Evidence over claim
86
76
  <!-- runtime-principles:section=evidence:begin -->
87
77
 
@@ -160,7 +160,7 @@ Invocation contract when OTHER engine is Codex:
160
160
  - Invoke Codex only through the monitored wrapper path in `CODEX_MONITORED_PATH`,
161
161
  or `.claude/skills/_shared/codex-monitored.sh` when the env var is absent:
162
162
  `CODEX_MONITORED_ISOLATED=1 bash "$CODEX_MONITORED_PATH" -C "$PWD" --full-auto -c model_reasoning_effort=high "<probe prompt>"`.
163
- Isolation keeps user config, AGENTS.md, pyx-memory, hooks, and project rules
163
+ Isolation keeps user config, AGENTS.md, hooks, and project rules
164
164
  from adding hidden context, tool calls, or transcript side effects.
165
165
  - Do not run `codex`, `codex exec`, `/Users/.../codex`, or a plugin-provided
166
166
  Codex binary directly. A raw Codex child can outlive the phase and makes the
@@ -262,7 +262,7 @@ failed availability check evidence, and print setup guidance:
262
262
  - Claude: install/configure Claude Code, run `claude --version` when available,
263
263
  confirm the host can spawn Claude agents, then rerun.
264
264
 
265
- Findings written to `.devlyn/verify.findings.jsonl`. **VERIFY agents have no code-mutation tools.** Codex pair-JUDGE is read-only: invoke `codex-monitored.sh` with `CODEX_MONITORED_ISOLATED=1` and `-c model_reasoning_effort=medium`, no `tail`/`head`/`grep` pipes, direct stdout/stderr capture, JSONL findings on stdout, and orchestrator-written `.devlyn/verify.pair.findings.jsonl`. Isolation blocks user config, AGENTS.md, pyx-memory, hooks, and project rules from hidden context/tool/transcript side effects. If stdout is captured as `.devlyn/codex-judge.stdout`, run `python3 .claude/skills/_shared/collect-codex-findings.py` before merge; raw stdout is diagnostic only. If stdout contains findings or a non-PASS summary while `.devlyn/verify.pair.findings.jsonl` is empty, `verify-merge-findings.py` blocks VERIFY for `verify.pair.emission-contract`. Do not ask Codex to `apply_patch` or edit `.devlyn`. After primary and pair findings are written, run `python3 .claude/skills/_shared/verify-merge-findings.py --write-state`. Branch only on the merged `state.phases.verify.verdict`; a HIGH/CRITICAL finding from either judge must mechanically become `NEEDS_WORK`. Never write `.devlyn/verify-merged.findings.jsonl` or `.devlyn/verify-merge.summary.json` by hand; `verify-merge-findings.py` is their only writer. State write: `phases.verify.{started_at, verdict, completed_at, duration_ms, sub_verdicts: {mechanical, judge, pair_judge?}, artifacts}`.
265
+ Findings written to `.devlyn/verify.findings.jsonl`. **VERIFY agents have no code-mutation tools.** Codex pair-JUDGE is read-only: invoke `codex-monitored.sh` with `CODEX_MONITORED_ISOLATED=1` and `-c model_reasoning_effort=medium`, no `tail`/`head`/`grep` pipes, direct stdout/stderr capture, JSONL findings on stdout, and orchestrator-written `.devlyn/verify.pair.findings.jsonl`. Isolation blocks user config, AGENTS.md, hooks, and project rules from hidden context/tool/transcript side effects. If stdout is captured as `.devlyn/codex-judge.stdout`, run `python3 .claude/skills/_shared/collect-codex-findings.py` before merge; raw stdout is diagnostic only. If stdout contains findings or a non-PASS summary while `.devlyn/verify.pair.findings.jsonl` is empty, `verify-merge-findings.py` blocks VERIFY for `verify.pair.emission-contract`. Do not ask Codex to `apply_patch` or edit `.devlyn`. After primary and pair findings are written, run `python3 .claude/skills/_shared/verify-merge-findings.py --write-state`. Branch only on the merged `state.phases.verify.verdict`; a HIGH/CRITICAL finding from either judge must mechanically become `NEEDS_WORK`. Never write `.devlyn/verify-merged.findings.jsonl` or `.devlyn/verify-merge.summary.json` by hand; `verify-merge-findings.py` is their only writer. State write: `phases.verify.{started_at, verdict, completed_at, duration_ms, sub_verdicts: {mechanical, judge, pair_judge?}, artifacts}`.
266
266
 
267
267
  Branch:
268
268
  - `PASS` → PHASE 6.
@@ -216,7 +216,7 @@ When eligible and the orchestrator spawns a second VERIFY agent with the OTHER e
216
216
  Codex pair-JUDGE is read-only. Invoke `codex-monitored.sh` directly with
217
217
  `CODEX_MONITORED_ISOLATED=1` and `-c model_reasoning_effort=medium`; this is a
218
218
  bounded two-probe review, not implementation. Isolation blocks user config,
219
- AGENTS.md, pyx-memory, hooks, and project rules from hidden context/tool
219
+ AGENTS.md, hooks, and project rules from hidden context/tool
220
220
  side effects. Do not pipe it to `tail`, `head`, `grep`, `sed`, or `awk`.
221
221
  Capture stdout/stderr directly. The Codex judge must return JSONL findings on
222
222
  stdout; the orchestrator writes `.devlyn/verify.pair.findings.jsonl` and merges
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "devlyn-cli",
3
- "version": "2.4.1",
3
+ "version": "2.5.1",
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": {
@@ -176,18 +176,6 @@ else
176
176
  while IFS= read -r f; do bad "$f"; done <<< "$offenders"
177
177
  fi
178
178
 
179
- # ---------------------------------------------------------------------------
180
- # 2a. Packaged root instruction files must not contain pyx-memory secrets.
181
- # ---------------------------------------------------------------------------
182
- section "Check 2a: No pyx-memory secrets in packaged root instructions"
183
- offenders=$(grep -RInE 'memory\.api\.pyxmate\.com|Authorization: Bearer pyx_[A-Za-z0-9]{12,}|X-API-Key: pyx_[A-Za-z0-9]{12,}|pyx_[A-Za-z0-9]{16,}' \
184
- AGENTS.md CLAUDE.md 2>/dev/null || true)
185
- if [ -z "$offenders" ]; then
186
- ok "AGENTS.md and CLAUDE.md contain no pyx-memory secret material"
187
- else
188
- while IFS= read -r f; do bad "$f"; done <<< "$offenders"
189
- fi
190
-
191
179
  # ---------------------------------------------------------------------------
192
180
  # 3. No stale model strings (gpt-5.0..5.4 hardcoded outside config).
193
181
  # ---------------------------------------------------------------------------
@@ -1458,9 +1446,9 @@ fi
1458
1446
  # ---------------------------------------------------------------------------
1459
1447
  # 10a. Bounded Codex probe/judge calls must run isolated.
1460
1448
  # Pair/risk-probe paths are measured read-only judges, not implementation
1461
- # phases. They must not inherit user config, AGENTS.md, hooks, pyx-memory,
1462
- # or other local rules that can add hidden context or transcript side
1463
- # effects. The wrapper owns the flag expansion; skill docs own requiring
1449
+ # phases. They must not inherit user config, AGENTS.md, hooks, or other
1450
+ # local rules that can add hidden context or transcript side effects.
1451
+ # The wrapper owns the flag expansion; skill docs own requiring
1464
1452
  # CODEX_MONITORED_ISOLATED=1 for probe-derive and pair-JUDGE.
1465
1453
  # ---------------------------------------------------------------------------
1466
1454
  section "Check 10a: Bounded Codex calls use isolated wrapper mode"
@@ -3773,14 +3761,16 @@ fi
3773
3761
  # must mirror the corresponding CLAUDE.md sections. Drift in one source-of-truth without
3774
3762
  # the other produces silent behavioral divergence between session-level and sub-agent
3775
3763
  # enforcement. Per-section markers `<!-- runtime-principles:section=NAME:begin/end -->`
3776
- # wrap each of the 4 sections (subtractive-first, goal-locked, no-workaround, evidence)
3777
- # in BOTH files. Check 12 extracts each named block from both files and diffs.
3764
+ # wrap each of the 3 mirrored sections (subtractive-first, goal-locked, evidence)
3765
+ # in BOTH files. No-workaround discipline lives in CLAUDE.md Core Principle #1
3766
+ # only and is not mirrored to runtime-principles.md.
3767
+ # Check 12 extracts each named block from both files and diffs.
3778
3768
  # ---------------------------------------------------------------------------
3779
3769
  section "Check 12: CLAUDE.md ↔ runtime-principles.md per-section excerpt parity"
3780
3770
  rp_src="config/skills/_shared/runtime-principles.md"
3781
3771
  claude_src="CLAUDE.md"
3782
3772
  rp_drift=0
3783
- expected_sections="subtractive-first goal-locked no-workaround evidence"
3773
+ expected_sections="subtractive-first goal-locked evidence"
3784
3774
 
3785
3775
  if [ ! -f "$rp_src" ]; then
3786
3776
  bad "$rp_src — missing"
@@ -3859,7 +3849,7 @@ else
3859
3849
  fi
3860
3850
 
3861
3851
  if [ $rp_drift -eq 0 ]; then
3862
- ok "all 4 contract sections in parity (subtractive-first / goal-locked / no-workaround / evidence) — markers, topology, content"
3852
+ ok "all 3 mirrored contract sections in parity (subtractive-first / goal-locked / evidence) — markers, topology, content"
3863
3853
  fi
3864
3854
  fi
3865
3855