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 +3 -3
- package/CLAUDE.md +7 -17
- package/agents-config/evaluator.md +4 -4
- package/bin/devlyn.js +47 -45
- package/config/skills/_shared/codex-config.md +1 -1
- package/config/skills/_shared/runtime-principles.md +4 -14
- package/config/skills/devlyn:resolve/SKILL.md +2 -2
- package/config/skills/devlyn:resolve/references/phases/verify.md +1 -1
- package/package.json +1 -1
- package/scripts/lint-skills.sh +9 -19
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.
|
|
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
|
-
>
|
|
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
|
-
|
|
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
|
|
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/
|
|
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/
|
|
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
|
|
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
|
|
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.
|
|
564
|
-
|
|
562
|
+
const agents = fs.existsSync(AGENTS_SOURCE)
|
|
563
|
+
? fs.readdirSync(AGENTS_SOURCE).filter((f) => f.endsWith('.md'))
|
|
564
|
+
: [];
|
|
565
565
|
|
|
566
|
-
|
|
566
|
+
if (agents.length > 0) {
|
|
567
|
+
log(`\n🤖 Installing agents for ${cli.name}...`, 'cyan');
|
|
567
568
|
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
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
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
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
|
-
|
|
607
|
-
|
|
607
|
+
fs.writeFileSync(destFile, existing + separator + agentContent + '\n');
|
|
608
|
+
log(` → ${cli.instructionsFile} (agent instructions appended)`, 'dim');
|
|
609
|
+
}
|
|
608
610
|
}
|
|
609
611
|
|
|
610
|
-
//
|
|
611
|
-
//
|
|
612
|
-
//
|
|
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
|
|
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,
|
|
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
|
|
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
|
-
>
|
|
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,
|
|
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,
|
|
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,
|
|
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.
|
|
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": {
|
package/scripts/lint-skills.sh
CHANGED
|
@@ -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,
|
|
1462
|
-
#
|
|
1463
|
-
#
|
|
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
|
|
3777
|
-
# in BOTH files.
|
|
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
|
|
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
|
|
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
|
|