devlyn-cli 3.3.1 → 4.0.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.
Files changed (59) hide show
  1. package/AGENTS.md +8 -8
  2. package/CLAUDE.md +17 -17
  3. package/README.md +43 -30
  4. package/bin/devlyn.js +123 -105
  5. package/bin/instruction-templates.json +26 -0
  6. package/config/skills/_shared/adapters/README.md +1 -1
  7. package/config/skills/_shared/adapters/omp.md +2 -2
  8. package/config/skills/_shared/archive_run.py +2 -2
  9. package/config/skills/_shared/codex-config.md +15 -15
  10. package/config/skills/_shared/engine-doctor.sh +1 -1
  11. package/config/skills/_shared/engine-preflight.md +5 -5
  12. package/config/skills/_shared/finish-gate.py +1 -1
  13. package/config/skills/_shared/resolve-bootstrap.py +2 -2
  14. package/config/skills/_shared/runtime-principles.md +6 -6
  15. package/config/skills/_shared/spec-verify-check.py +3 -3
  16. package/config/skills/_shared/task-complete.py +1 -1
  17. package/config/skills/{devlyn:design-ui → devlyn-design-ui}/SKILL.md +1 -1
  18. package/config/skills/{devlyn:engines → devlyn-engines}/SKILL.md +37 -11
  19. package/config/skills/{devlyn:ideate → devlyn-ideate}/SKILL.md +42 -24
  20. package/config/skills/{devlyn:ideate → devlyn-ideate}/references/elicitation.md +2 -2
  21. package/config/skills/{devlyn:ideate → devlyn-ideate}/references/from-spec-mode.md +2 -2
  22. package/config/skills/{devlyn:ideate → devlyn-ideate}/references/project-mode.md +5 -5
  23. package/config/skills/{devlyn:ideate → devlyn-ideate}/references/spec-template.md +1 -1
  24. package/config/skills/{devlyn:queue → devlyn-queue}/SKILL.md +39 -16
  25. package/config/skills/devlyn-queue/scripts/append.py +94 -0
  26. package/config/skills/{devlyn:resolve → devlyn-resolve}/SKILL.md +38 -19
  27. package/config/skills/{devlyn:resolve → devlyn-resolve}/references/free-form-mode.md +3 -3
  28. package/config/skills/{devlyn:resolve → devlyn-resolve}/references/outer-loop.md +1 -1
  29. package/config/skills/{devlyn:resolve → devlyn-resolve}/references/state-schema.md +1 -1
  30. package/config/skills/{devlyn:resolve → devlyn-resolve}/references/task-completion.md +9 -2
  31. package/config/templates/prompt-templates.md +2 -2
  32. package/optional-skills/better-auth-setup/SKILL.md +24 -18
  33. package/optional-skills/{devlyn:pencil-pull → devlyn-pencil-pull}/SKILL.md +1 -1
  34. package/optional-skills/{devlyn:pencil-push → devlyn-pencil-push}/SKILL.md +1 -1
  35. package/optional-skills/{devlyn:reap → devlyn-reap}/SKILL.md +36 -5
  36. package/optional-skills/{devlyn:reap → devlyn-reap}/scripts/reap.sh +1 -1
  37. package/optional-skills/{devlyn:reap → devlyn-reap}/scripts/scan.sh +1 -1
  38. package/optional-skills/dokkit/COMMANDS.md +4 -4
  39. package/optional-skills/dokkit/EXPORT.md +3 -3
  40. package/optional-skills/dokkit/FILLING.md +4 -4
  41. package/optional-skills/dokkit/IMAGE-SOURCING.md +2 -2
  42. package/optional-skills/dokkit/INGESTION.md +3 -3
  43. package/optional-skills/dokkit/PIPELINE.md +5 -4
  44. package/optional-skills/dokkit/SKILL.md +35 -5
  45. package/optional-skills/dokkit/STATE.md +1 -1
  46. package/optional-skills/dokkit/references/image-opportunity-heuristics.md +1 -1
  47. package/optional-skills/generate-skill/REFERENCE.md +10 -13
  48. package/optional-skills/generate-skill/SKILL.md +13 -5
  49. package/package.json +3 -1
  50. /package/config/skills/{devlyn:ideate → devlyn-ideate}/references/templates/decision.md +0 -0
  51. /package/config/skills/{devlyn:ideate → devlyn-ideate}/references/templates/roadmap.md +0 -0
  52. /package/config/skills/{devlyn:ideate → devlyn-ideate}/references/templates/vision.md +0 -0
  53. /package/config/skills/{devlyn:resolve → devlyn-resolve}/references/phases/build-gate.md +0 -0
  54. /package/config/skills/{devlyn:resolve → devlyn-resolve}/references/phases/cleanup.md +0 -0
  55. /package/config/skills/{devlyn:resolve → devlyn-resolve}/references/phases/implement.md +0 -0
  56. /package/config/skills/{devlyn:resolve → devlyn-resolve}/references/phases/plan.md +0 -0
  57. /package/config/skills/{devlyn:resolve → devlyn-resolve}/references/phases/probe-derive.md +0 -0
  58. /package/config/skills/{devlyn:resolve → devlyn-resolve}/references/phases/surface-close.md +0 -0
  59. /package/config/skills/{devlyn:resolve → devlyn-resolve}/references/phases/verify.md +0 -0
@@ -6,23 +6,23 @@ Single source of truth for how every skill calls Codex. **MCP is not used.** Ski
6
6
 
7
7
  All long-running Codex calls go through `codex-monitored.sh`. It streams full stdout and emits a `[codex-monitored] heartbeat` every 30s on stderr. Write multiline prompts as exact UTF-8 bytes to a task-local file; set `DEVLYN_CODEX_PROMPT_FILE` and pass the sole prompt argument `-`. The wrapper snapshots those bytes before dispatch and seals actual argv, prompt digest and completion in `<prompt-file>.transport.json`. Missing/unreadable files, competing prompt arguments and receipt/prompt mismatches fail before launch. Without file transport, stdin remains DEVNULL (avoiding the open-stdin plus argument-prompt hang).
8
8
 
9
- Before the first Codex call, resolve the wrapper from the invoked skill directory:
10
-
9
+ Use the DEVLYN_SHARED_DIR established by the invoking skill; if it was
10
+ lost, re-establish it by that skill's rules. When this document is
11
+ opened directly, bind DEVLYN_SHARED_DIR to its reader-supplied
12
+ containing directory, resolving directory symlinks. Never take it from
13
+ an environment variable, cwd or another installation; without either
14
+ source, stop with BLOCKED:skill-source-unresolved.
15
+
16
+ Bind CODEX_MONITORED_PATH to DEVLYN_SHARED_DIR/codex-monitored.sh and
17
+ verify the file before calling it; failure is
18
+ BLOCKED:shared-dir-unresolved with the failed path.
19
+
20
+ After establishing DEVLYN_SHARED_DIR in a Bash invocation:
11
21
  ```bash
12
- DEVLYN_SKILL_DIR="${CLAUDE_SKILL_DIR:-__DEVLYN_SKILL_DIR__}"
13
- if [ "$DEVLYN_SKILL_DIR" = "__DEVLYN_SKILL_DIR__" ] || [ ! -d "$DEVLYN_SKILL_DIR/../_shared" ]; then
14
- echo "BLOCKED:shared-dir-unresolved: $DEVLYN_SKILL_DIR/../_shared" >&2
15
- exit 1
16
- fi
17
- DEVLYN_SHARED_DIR="$(cd "$DEVLYN_SKILL_DIR/../_shared" && pwd)"
18
22
  CODEX_MONITORED_PATH="$DEVLYN_SHARED_DIR/codex-monitored.sh"
19
- if [ ! -f "$CODEX_MONITORED_PATH" ]; then
20
- echo "BLOCKED:shared-dir-unresolved: $CODEX_MONITORED_PATH" >&2
21
- exit 1
22
- fi
23
23
  ```
24
24
 
25
- **Read-only critique / adversarial review / debate** (`/devlyn:resolve` VERIFY pair-mode, plus any future ideate read-only critique). Codex returns findings on stdout; the orchestrator writes files.
25
+ **Read-only critique / adversarial review / debate** (`/devlyn-resolve` VERIFY pair-mode, plus any future ideate read-only critique). Codex returns findings on stdout; the orchestrator writes files.
26
26
 
27
27
  ```bash
28
28
  DEVLYN_CODEX_PROMPT_FILE="<prompt-file>" CODEX_MONITORED_ISOLATED=1 CODEX_MONITORED_TIMEOUT_SEC=600 bash "$CODEX_MONITORED_PATH" \
@@ -32,7 +32,7 @@ DEVLYN_CODEX_PROMPT_FILE="<prompt-file>" CODEX_MONITORED_ISOLATED=1 CODEX_MONITO
32
32
  -
33
33
  ```
34
34
 
35
- **Workspace-write implementation** (`/devlyn:resolve` IMPLEMENT phase when `--engine codex` or `--engine auto` routes to Codex, plus codex-routed `/devlyn:ideate` phases):
35
+ **Workspace-write implementation** (`/devlyn-resolve` IMPLEMENT phase when `--engine codex` or `--engine auto` routes to Codex, plus codex-routed `/devlyn-ideate` phases):
36
36
 
37
37
  ```bash
38
38
  DEVLYN_CODEX_PROMPT_FILE="<prompt-file>" bash "$CODEX_MONITORED_PATH" \
@@ -76,6 +76,6 @@ The local Codex CLI, fronted by `codex-monitored.sh`, is the integration boundar
76
76
 
77
77
  ## Invocation from inside a skill prompt
78
78
 
79
- Skills write the invocation as a Bash command the runtime executes. Example shape from `/devlyn:resolve` PHASE 2 IMPLEMENT when routed to Codex:
79
+ Skills write the invocation as a Bash command the runtime executes. Example shape from `/devlyn-resolve` PHASE 2 IMPLEMENT when routed to Codex:
80
80
 
81
81
  > Run `DEVLYN_CODEX_PROMPT_FILE="<IMPLEMENT-prompt-file>" bash "$CODEX_MONITORED_PATH" --json -C <state.base_ref.repo_root> -s workspace-write -m <model_requested> -c sandbox_workspace_write.network_access=false -c model_reasoning_effort=xhigh -`. Capture stdout as the IMPLEMENT reply; non-zero exit → treat as subagent failure. The wrapper emits `[codex-monitored]` heartbeat and lifecycle lines on **stderr** — stdout stays clean for Codex output, so the orchestrator can parse the reply without filtering. Heartbeat-on-stderr keeps the orchestrator's combined-output stream non-silent (defeats the iter-0008 byte-watchdog kill) without polluting the codex-reply view of stdout. Do not pipe the wrapper; direct capture or file redirection preserves streaming and avoids the pipe-refusal exit.
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env bash
2
- # engine-doctor.sh — read-only detection for /devlyn:engines' no-arg output.
2
+ # engine-doctor.sh — read-only detection for /devlyn-engines' no-arg output.
3
3
  #
4
4
  # WHY (iter-0050): users need to see what's actually on the machine, not
5
5
  # just what's pinned. This script never writes .devlyn/engines.json, never
@@ -1,10 +1,10 @@
1
1
  # Shared — Engine Pre-flight
2
2
 
3
- Used by `/devlyn:resolve` and `/devlyn:ideate`. One shared availability rule so every skill routes identically.
3
+ Used by `/devlyn-resolve` and `/devlyn-ideate`. One shared availability rule so every skill routes identically.
4
4
 
5
5
  ## Rule
6
6
 
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 the default VERIFY-pair route and conditional risk-probe requirements before the phase that needs the OTHER engine.
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 the default VERIFY-pair route and conditional risk-probe requirements before the phase that needs the OTHER engine.
8
8
 
9
9
  Engine requirements have two classes:
10
10
 
@@ -15,11 +15,11 @@ Engine requirements have two classes:
15
15
 
16
16
  The orchestrator is the CLI the user opened. PLAN remains orchestrator-fixed. Resolve the legacy executor as explicit `--engine` > `cwd/.devlyn/engines.json` `executor` > the invoking skill's supported default. BUILD_GATE runs commands in the orchestrator without a separate model; risk-probe derivation keeps its existing route.
17
17
 
18
- The role profiles and `--role-config` below apply only to `/devlyn:resolve`; `/devlyn:ideate` keeps its existing `--engine` / legacy executor selection and never inherits worker/judge profiles. `role-config.py` is resolve’s deterministic resolver. Optional project `roles.worker`, `roles.primary_judge`, and `roles.pair_judge` each require `engine` and accept exact `model`/`effort`; `/devlyn:resolve --role-config <path>` supplies the same `{"roles": {...}}` object for one run. Each entry replaces the entire lower entry. Worker/primary precedence is run role > `--engine` engine-only > project role > legacy executor. Pair precedence is run role > project role > existing `pair_judge_priority`/binary complement. An absent primary profile follows the legacy executor, not the worker profile. No parent/global devlyn config lookup.
18
+ The role profiles and `--role-config` below apply only to `/devlyn-resolve`; `/devlyn-ideate` keeps its existing `--engine` / legacy executor selection and never inherits worker/judge profiles. `role-config.py` is resolve’s deterministic resolver. Optional project `roles.worker`, `roles.primary_judge`, and `roles.pair_judge` each require `engine` and accept exact `model`/`effort`; `/devlyn-resolve --role-config <path>` supplies the same `{"roles": {...}}` object for one run. Each entry replaces the entire lower entry. Worker/primary precedence is run role > `--engine` engine-only > project role > legacy executor. Pair precedence is run role > project role > existing `pair_judge_priority`/binary complement. An absent primary profile follows the legacy executor, not the worker profile. No parent/global devlyn config lookup.
19
19
 
20
20
  Worker controls IMPLEMENT, its included code/doc cleanup, and their repair rounds only; owner CLEANUP performs artifact/invariant checks without a worker dispatch; primary/pair control VERIFY only. OTHER must differ from the resolved primary engine. Explicit same-engine pair is invalid; a legacy priority list skips the primary. `--no-pair` does not dispatch or check availability of an unused pair. Configured pins remain explicit promises, while an unconfigured unavailable automatic OTHER records its solo reason.
21
21
 
22
- Before the first phase, `/devlyn:resolve` freezes resolution with `state-phase-write.py --freeze-roles`; subsequent status/dispatch reads that state instead of mutable config. `state.engine` stays the legacy executor. The resolver rejects statically unsupported selected channel fields before PLAN, and validates adapter names and the existing ASCII `executor: yes|no` / `pair_judge: yes|no` eligibility markers; absent eligibility section means both. Malformed configuration fails with `BLOCKED:invalid-engine-config`.
22
+ Before the first phase, `/devlyn-resolve` freezes resolution with `state-phase-write.py --freeze-roles`; subsequent status/dispatch reads that state instead of mutable config. `state.engine` stays the legacy executor. The resolver rejects statically unsupported selected channel fields before PLAN, and validates adapter names and the existing ASCII `executor: yes|no` / `pair_judge: yes|no` eligibility markers; absent eligibility section means both. Malformed configuration fails with `BLOCKED:invalid-engine-config`.
23
23
 
24
24
  Before each affected worker/judge, read `role-config.py --state .devlyn/pipeline.state.json --role <role> [--resolved-model <inherited-exact-model>]`. It returns source/channel, requested values and argv additions. Explicit Codex options require current version-matching native model metadata; refresh the native CLI's cache when missing/stale. Explicit Claude judge effort requires the adapter's version/exact-model capability declaration; model-only selection passes the exact ID without that effort declaration and validates the native result. No model/effort fields means unchanged phase defaults. Unknown support fails with `BLOCKED:unsupported-role-option`; no clamp, fallback or invented model identity. Native Agent workers reject unsupported explicit Claude fields without switching to a CLI worker. Show inherited/unknown values honestly; availability is not role fitness.
25
25
 
@@ -33,7 +33,7 @@ When a run or phase requires engine `<name>` (claude, codex, omp, or any adapter
33
33
 
34
34
  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.
35
35
 
36
- Per-skill defaults: `/devlyn:resolve` uses Claude for IMPLEMENT when the orchestrator has Claude Code's native Agent primitive; Codex CLI and oh-my-pi orchestrators use their own fresh worker as the default route (Codex child process, omp native `task`) so implementation and independent verification retain structural isolation. PLAN uses the owner context; BUILD_GATE/CLEANUP use owner commands. VERIFY invokes the OTHER engine by default when available unless `--no-pair` was passed. `/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.
36
+ Per-skill defaults: `/devlyn-resolve` uses Claude for IMPLEMENT when the orchestrator has Claude Code's native Agent primitive; Codex CLI and oh-my-pi orchestrators use their own fresh worker as the default route (Codex child process, omp native `task`) so implementation and independent verification retain structural isolation. PLAN uses the owner context; BUILD_GATE/CLEANUP use owner commands. VERIFY invokes the OTHER engine by default when available unless `--no-pair` was passed. `/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.
37
37
 
38
38
  ## What a skill must report after a BLOCKED engine check
39
39
 
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env python3
2
- """Deterministic PHASE 6 final-diff gate for /devlyn:resolve."""
2
+ """Deterministic PHASE 6 final-diff gate for /devlyn-resolve."""
3
3
  from __future__ import annotations
4
4
 
5
5
  import runpy
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env python3
2
- """Deterministic PHASE-0 bootstrap for /devlyn:resolve."""
2
+ """Deterministic PHASE-0 bootstrap for /devlyn-resolve."""
3
3
  from __future__ import annotations
4
4
 
5
5
  import contextlib
@@ -1027,7 +1027,7 @@ def self_test() -> int:
1027
1027
  "phases": {name: None for name in PHASE_NAMES},
1028
1028
  "verify": {"coverage_failed": False, "pair_trigger": None},
1029
1029
  }
1030
- schema_dirs = [script_shared.parent / name for name in ("devlyn:resolve", "devlyn\uF03Aresolve")
1030
+ schema_dirs = [script_shared.parent / name for name in ("devlyn-resolve",)
1031
1031
  if (script_shared.parent / name).is_dir()]
1032
1032
  assert len(schema_dirs) == 1, schema_dirs
1033
1033
  schema = (schema_dirs[0] / "references" / "state-schema.md").read_text(encoding="utf-8")
@@ -1,6 +1,6 @@
1
1
  # Runtime principles — sub-agent contract
2
2
 
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`).
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
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
 
@@ -58,7 +58,7 @@ This rule exists because LLMs (including you) are trained to be helpful, compreh
58
58
 
59
59
  **The single drift test before any deviation from the stated goal:** *"Did the user ask for this, OR does the user's stated goal strictly require it?"* If the answer to both is no, do not do it. Surface it as a note (commit message, end-of-turn summary, finding) and continue on the original path.
60
60
 
61
- **Creative-mode is the narrow exception, not the default.** Creative-mode applies only when (a) the user explicitly invoked an ideation/exploration surface (`/devlyn:ideate`, `/devlyn:design-ui`, "let's brainstorm", "explore options for"), OR (b) the goal is genuinely under-specified and a clarifying question is impossible (extremely rare — usually you should ask). For everything else — bug fixes, feature work, refactors, doc updates, pipeline runs, code review, debugging — execution-mode is the default and drift is a defect, not a feature.
61
+ **Creative-mode is the narrow exception, not the default.** Creative-mode applies only when (a) the user explicitly invoked an ideation/exploration surface (`/devlyn-ideate`, `/devlyn-design-ui`, "let's brainstorm", "explore options for"), OR (b) the goal is genuinely under-specified and a clarifying question is impossible (extremely rare — usually you should ask). For everything else — bug fixes, feature work, refactors, doc updates, pipeline runs, code review, debugging — execution-mode is the default and drift is a defect, not a feature.
62
62
 
63
63
  **Anti-rationalization clause** — explicitly guarding against LLM hedging:
64
64
 
@@ -67,7 +67,7 @@ This rule exists because LLMs (including you) are trained to be helpful, compreh
67
67
  - "It would be incomplete without this" is **not** a justification. The user defines completeness, not your sense of it.
68
68
  - "I'm being thorough" is **not** a justification. Thoroughness on the requested goal is required; thoroughness extending past the goal is drift.
69
69
 
70
- **When in doubt, ask — outside hands-free pipelines.** In interactive sessions a short clarification ("the requested fix touches the X code path; I notice Y also looks broken — should I fix it in this change or surface it as a follow-up?") is always cheaper than a wrong-scope diff. Asking is not a weakness; silently expanding scope is. **Inside hands-free pipelines** (`/devlyn:resolve`, scheduled remote agents, autonomous skill runs) the contract forbids mid-pipeline prompts — there asking is unsafe because there is no user to answer. The substitute is: stay strictly on the requested goal, do not expand scope, and log the question/assumption explicitly in the final report (or `.devlyn/runs/<run_id>/` artifacts) so the user can adjudicate after the run completes. Choosing scope creep over logging-and-staying-on-path is always wrong.
70
+ **When in doubt, ask — outside hands-free pipelines.** In interactive sessions a short clarification ("the requested fix touches the X code path; I notice Y also looks broken — should I fix it in this change or surface it as a follow-up?") is always cheaper than a wrong-scope diff. Asking is not a weakness; silently expanding scope is. **Inside hands-free pipelines** (`/devlyn-resolve`, scheduled remote agents, autonomous skill runs) the contract forbids mid-pipeline prompts — there asking is unsafe because there is no user to answer. The substitute is: stay strictly on the requested goal, do not expand scope, and log the question/assumption explicitly in the final report (or `.devlyn/runs/<run_id>/` artifacts) so the user can adjudicate after the run completes. Choosing scope creep over logging-and-staying-on-path is always wrong.
71
71
 
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 -->
@@ -82,7 +82,7 @@ Every finding cites concrete evidence. Vague claims are speculation; exclude the
82
82
  - **Doc findings**: quote of the stale text + section/line reference.
83
83
  - **Browser findings**: screenshot reference + URL/route.
84
84
 
85
- **Negative existence claims** ("X lacks Y", "X cannot Z", "X is Y-specific") are the highest-risk shape — they feel like recall but fail to any single counter-example. They require active search at write time, not absence-of-memory. This rule applies to conversational answers and comparison-table cells, not only `/devlyn:resolve` findings — every cell of a trade-off table is a falsifiable claim.
85
+ **Negative existence claims** ("X lacks Y", "X cannot Z", "X is Y-specific") are the highest-risk shape — they feel like recall but fail to any single counter-example. They require active search at write time, not absence-of-memory. This rule applies to conversational answers and comparison-table cells, not only `/devlyn-resolve` findings — every cell of a trade-off table is a falsifiable claim.
86
86
 
87
87
  **A position reversal is itself a claim.** In an oracle-less debate — design, strategy, trade-off, any decision with no spec or verifier to check against — changing your mind after a critique requires a NAMED DELTA: cite the specific prior claim, evidence, or criterion that changed, not a post-hoc rationale invented to justify a flip you were already going to make. Before reversing or choosing between contested positions, state each side's strongest form and the decisive criterion; the chosen outcome may adopt one side wholesale — synthesis means the best decision, not a forced blend. Flipping to whoever spoke last without a cited delta is capitulation, not reasoning; genuinely unresolved disagreement is escalated to the user, never closed by deferring to the last speaker. When you commission an adversarial review, require the critic to return the strongest counter, the strongest form of your own position, AND a synthesis — a refute-only mandate produces debate, not better decisions.
88
88
 
@@ -94,8 +94,8 @@ A finding without one of these forms is excluded. Vague findings produce vague f
94
94
  ## Consumption
95
95
 
96
96
  **Consumers**:
97
- - `devlyn:resolve/SKILL.md` `<harness_principles>` points here as the contract source. Phase prompt bodies inline the operational excerpt needed for each phase.
98
- - `devlyn:ideate/SKILL.md` consumes this file for spec-shaping and conversation discipline through its own `<harness_principles>` block.
97
+ - `devlyn-resolve/SKILL.md` `<harness_principles>` points here as the contract source. Phase prompt bodies inline the operational excerpt needed for each phase.
98
+ - `devlyn-ideate/SKILL.md` consumes this file for spec-shaping and conversation discipline through its own `<harness_principles>` block.
99
99
 
100
100
  **Codex routing**: Codex-routed phases must inline the contract excerpt directly into the prompt body. Bounded read-only Codex critique, probe, or judge calls must also follow `_shared/codex-config.md` isolation rules.
101
101
  <!-- runtime-principles:consumption:end -->
@@ -48,7 +48,7 @@ Check mode (`--check <markdown_path>`):
48
48
  its own inline validation and must not use this sibling-precedence route.
49
49
 
50
50
  Expected-contract check mode (`--check-expected <json_path>`):
51
- - Used by /devlyn:ideate after writing sibling `spec.expected.json`.
51
+ - Used by /devlyn-ideate after writing sibling `spec.expected.json`.
52
52
  - Exits 0 if the file is valid JSON and matches `_shared/expected.schema.json`
53
53
  shape, and if sibling `spec.md` has supported `complexity` frontmatter.
54
54
  Exits 2 on unreadable, malformed, unsupported fields, or unsupported sibling
@@ -605,7 +605,7 @@ def validate_expected_shape(data) -> str | None:
605
605
  """Return None if shape matches the sibling spec.expected.json schema.
606
606
 
607
607
  Keep this dependency-free: it mirrors `_shared/expected.schema.json` enough
608
- to catch malformed ideate output before /devlyn:resolve consumes it.
608
+ to catch malformed ideate output before /devlyn-resolve consumes it.
609
609
  """
610
610
  if not isinstance(data, dict):
611
611
  return "top-level must be a JSON object"
@@ -4667,7 +4667,7 @@ def main() -> int:
4667
4667
  external_diff,
4668
4668
  fix_hint=(
4669
4669
  "Remove `.devlyn/external-diff.patch` for ordinary runs, or use "
4670
- "`/devlyn:resolve --verify-only <diff-or-PR-ref> --spec <path>` only when "
4670
+ "`/devlyn-resolve --verify-only <diff-or-PR-ref> --spec <path>` only when "
4671
4671
  "intentionally verifying an external patch."
4672
4672
  ),
4673
4673
  )
@@ -2,7 +2,7 @@
2
2
  """Outer-owner delivery and recoverable cleanup (task-completion spec, R1–7).
3
3
 
4
4
  No phase/state writer, staging, scheduler, or implicit adoption. See
5
- devlyn:resolve/references/task-completion.md for the owner acceptance contract.
5
+ devlyn-resolve/references/task-completion.md for the owner acceptance contract.
6
6
  """
7
7
  from __future__ import annotations
8
8
 
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: devlyn:design-ui
2
+ name: devlyn-design-ui
3
3
  description: Assemble a world-class design team (Creative Director, Product Designer, Visual Designer, Interaction Designer, Accessibility Designer) to generate N (default 5) radically distinct, portfolio-worthy UI style explorations. Pass a leading integer or `count:N` in the brief to change the count.
4
4
  source: project
5
5
  ---
@@ -1,25 +1,51 @@
1
1
  ---
2
- name: devlyn:engines
2
+ name: devlyn-engines
3
3
  description: Show and pin engine roles for the devlyn pipeline (executor / pair judge). Reads and writes machine-local .devlyn/engines.json with fail-closed validation. Use when the user asks which models are configured, wants to force a specific model for pipeline work ("수동모드", "engine 고정", "use codex to implement"), or wants to clear pins back to auto-detection.
4
4
  ---
5
5
 
6
- Utility front-end for the role-resolution contract in `_shared/engine-preflight.md#role-resolution`. It adds no semantics of its own: everything it writes is exactly what `/devlyn:resolve` PHASE 0 reads.
6
+ Utility front-end for the role-resolution contract in `_shared/engine-preflight.md#role-resolution`. It adds no semantics of its own: everything it writes is exactly what `/devlyn-resolve` PHASE 0 reads.
7
7
 
8
8
  <args>
9
9
  $ARGUMENTS
10
10
  </args>
11
11
 
12
12
  <runtime_paths>
13
- Resolve shared scripts from this skill's installed directory, never from the project cwd, before step 2 below:
14
-
15
- ```bash
16
- DEVLYN_SKILL_DIR="${CLAUDE_SKILL_DIR:-__DEVLYN_SKILL_DIR__}"
17
- if [ "$DEVLYN_SKILL_DIR" = "__DEVLYN_SKILL_DIR__" ] || [ ! -d "$DEVLYN_SKILL_DIR/../_shared" ]; then
18
- echo "BLOCKED:shared-dir-unresolved: $DEVLYN_SKILL_DIR/../_shared" >&2
19
- exit 1
20
- fi
21
- DEVLYN_SHARED_DIR="$(cd "$DEVLYN_SKILL_DIR/../_shared" && pwd)"
13
+ Before the first command, establish the bindings below.
14
+
15
+ Resolve bundled resources from the SKILL.md loaded for this invocation.
16
+
17
+ Reader-rendered directory hint:
18
+ ```text
19
+ ${CLAUDE_SKILL_DIR}
22
20
  ```
21
+
22
+ Treat the hint as literal path data, never shell code. If the reader
23
+ replaced it with an absolute directory, use that directory. Otherwise
24
+ use the filesystem path or base directory reported for this loaded
25
+ SKILL.md. Resolve virtual URIs through the reader's native filesystem
26
+ mapping. If available source locations name different directories,
27
+ stop.
28
+
29
+ Bind DEVLYN_SKILL_DIR to that absolute directory. Do not obtain this
30
+ binding from an environment variable, cwd, or another installation.
31
+ Verify its SKILL.md before proceeding. Missing or conflicting source
32
+ identity is BLOCKED:skill-source-unresolved; include the failed path
33
+ when known.
34
+
35
+ Resolve bundled references against this directory. These bindings are
36
+ workflow values: establish them explicitly using each tool or shell's
37
+ literal-path rules, and include their absolute values in every fresh
38
+ worker's prompt, telling it to set them from those values, never from
39
+ its inherited environment. Do not rely on shell state surviving between
40
+ calls.
41
+
42
+ Resolve directory symlinks on DEVLYN_SKILL_DIR before deriving its
43
+ sibling _shared. Bind that directory as DEVLYN_SHARED_DIR. References
44
+ written as _shared/... use this binding. Verify the directory and each
45
+ required resource before use; failure is BLOCKED:shared-dir-unresolved
46
+ with the failed path. Never search another installation.
47
+
48
+ Verify DEVLYN_SHARED_DIR/role-config.py and DEVLYN_SHARED_DIR/engine-doctor.sh before their respective commands. In omp, use `printf '%s\n' skill://devlyn-engines`.
23
49
  </runtime_paths>
24
50
 
25
51
  ## No args — status + how to choose
@@ -1,16 +1,16 @@
1
1
  ---
2
- name: devlyn:ideate
3
- description: Extract a verifiable spec from a user's idea by driving the conversation with focused questions. Output is a single-feature `spec.md` + `spec.expected.json` that `/devlyn:resolve --spec` consumes directly. Use when the user has an idea but not a spec, or wants AI to elicit the missing engineering context. Modes — default (single spec, AI drives Q&A), `--quick` (assume-and-confirm from one-line goal), `--from-spec <path>` (normalize external spec), `--project` (plan.md index + N specs). Optional in the pipeline — `/devlyn:resolve` works standalone via free-form mode for users who skip ideate.
2
+ name: devlyn-ideate
3
+ description: Extract a verifiable spec from a user's idea by driving the conversation with focused questions. Output is a single-feature `spec.md` + `spec.expected.json` that `/devlyn-resolve --spec` consumes directly. Use when the user has an idea but not a spec, or wants AI to elicit the missing engineering context. Modes — default (single spec, AI drives Q&A), `--quick` (assume-and-confirm from one-line goal), `--from-spec <path>` (normalize external spec), `--project` (plan.md index + N specs). Optional in the pipeline — `/devlyn-resolve` works standalone via free-form mode for users who skip ideate.
4
4
  ---
5
5
 
6
- Spec-elicitation surface for users who have ideas but not engineering specifications. AI drives the conversation with focused questions until a structurally-valid, verifiable spec exists. Output consumed directly by `/devlyn:resolve --spec`.
6
+ Spec-elicitation surface for users who have ideas but not engineering specifications. AI drives the conversation with focused questions until a structurally-valid, verifiable spec exists. Output consumed directly by `/devlyn-resolve --spec`.
7
7
 
8
8
  <elicit_config>
9
9
  $ARGUMENTS
10
10
  </elicit_config>
11
11
 
12
12
  <orchestrator_context>
13
- This skill is OPTIONAL. `/devlyn:resolve` is standalone-capable: free-form mode handles trivial/medium tasks without a spec, `--spec` mode accepts handwritten specs from any source. Use ideate when the user wants AI to do the elicitation work.
13
+ This skill is OPTIONAL. `/devlyn-resolve` is standalone-capable: free-form mode handles trivial/medium tasks without a spec, `--spec` mode accepts handwritten specs from any source. Use ideate when the user wants AI to do the elicitation work.
14
14
  </orchestrator_context>
15
15
 
16
16
  <elicitation_contract>
@@ -24,26 +24,44 @@ The user does not know context engineering. They will under-specify and over-ass
24
24
  </elicitation_contract>
25
25
 
26
26
  <harness_principles>
27
- Read `_shared/runtime-principles.md` (Subtractive-first / Goal-locked / Evidence-over-claim). The principles bind the spec content as well as your conversation. A spec that says "for future flexibility" is a Subtractive-first violation. A spec that asks for `try { ... } catch { return null }` is a No-workaround violation. AI flags these in elicitation, not after `/devlyn:resolve` has built them.
27
+ Read `_shared/runtime-principles.md` (Subtractive-first / Goal-locked / Evidence-over-claim). The principles bind the spec content as well as your conversation. A spec that says "for future flexibility" is a Subtractive-first violation. A spec that asks for `try { ... } catch { return null }` is a No-workaround violation. AI flags these in elicitation, not after `/devlyn-resolve` has built them.
28
28
  </harness_principles>
29
29
 
30
30
  <runtime_paths>
31
- Resolve shared scripts from this skill's installed directory, never from the project cwd:
32
-
33
- ```bash
34
- DEVLYN_SKILL_DIR="${CLAUDE_SKILL_DIR:-__DEVLYN_SKILL_DIR__}"
35
- if [ "$DEVLYN_SKILL_DIR" = "__DEVLYN_SKILL_DIR__" ] || [ ! -d "$DEVLYN_SKILL_DIR/../_shared" ]; then
36
- echo "BLOCKED:shared-dir-unresolved: $DEVLYN_SKILL_DIR/../_shared" >&2
37
- exit 1
38
- fi
39
- DEVLYN_SHARED_DIR="$(cd "$DEVLYN_SKILL_DIR/../_shared" && pwd)"
40
- if [ ! -f "$DEVLYN_SHARED_DIR/spec-verify-check.py" ]; then
41
- echo "BLOCKED:shared-dir-unresolved: $DEVLYN_SHARED_DIR/spec-verify-check.py" >&2
42
- exit 1
43
- fi
31
+ Resolve bundled resources from the SKILL.md loaded for this invocation.
32
+
33
+ Reader-rendered directory hint:
34
+ ```text
35
+ ${CLAUDE_SKILL_DIR}
44
36
  ```
45
37
 
46
- Use `python3 "$DEVLYN_SHARED_DIR/spec-verify-check.py"` for all spec validation commands. Claude Code supplies `CLAUDE_SKILL_DIR` by native render substitution; Codex/oh-my-pi installs receive an absolute copy-time stamp in the default branch. If the resolved skill directory is still the placeholder or `../_shared` is absent, stop with `BLOCKED:shared-dir-unresolved`.
38
+ Treat the hint as literal path data, never shell code. If the reader
39
+ replaced it with an absolute directory, use that directory. Otherwise
40
+ use the filesystem path or base directory reported for this loaded
41
+ SKILL.md. Resolve virtual URIs through the reader's native filesystem
42
+ mapping. If available source locations name different directories,
43
+ stop.
44
+
45
+ Bind DEVLYN_SKILL_DIR to that absolute directory. Do not obtain this
46
+ binding from an environment variable, cwd, or another installation.
47
+ Verify its SKILL.md before proceeding. Missing or conflicting source
48
+ identity is BLOCKED:skill-source-unresolved; include the failed path
49
+ when known.
50
+
51
+ Resolve bundled references against this directory. These bindings are
52
+ workflow values: establish them explicitly using each tool or shell's
53
+ literal-path rules, and include their absolute values in every fresh
54
+ worker's prompt, telling it to set them from those values, never from
55
+ its inherited environment. Do not rely on shell state surviving between
56
+ calls.
57
+
58
+ Resolve directory symlinks on DEVLYN_SKILL_DIR before deriving its
59
+ sibling _shared. Bind that directory as DEVLYN_SHARED_DIR. References
60
+ written as _shared/... use this binding. Verify the directory and each
61
+ required resource before use; failure is BLOCKED:shared-dir-unresolved
62
+ with the failed path. Never search another installation.
63
+
64
+ Verify DEVLYN_SHARED_DIR/spec-verify-check.py before validation. Use `python3 "$DEVLYN_SHARED_DIR/spec-verify-check.py"` for spec validation commands after binding the path in that shell. In omp, use `printf '%s\n' skill://devlyn-ideate`.
47
65
  </runtime_paths>
48
66
 
49
67
  <engine_routing>
@@ -64,8 +82,8 @@ Four modes, selected by flag:
64
82
  <spec_kind_escape_hatch>
65
83
  The spec carries `spec.kind ∈ {feature, spike, prototype}` in its frontmatter. The kind changes downstream behavior:
66
84
 
67
- - **feature** — production-quality implementation expected. `/devlyn:resolve --spec` runs the full pipeline (PLAN → IMPLEMENT → BUILD_GATE → CLEANUP → VERIFY).
68
- - **spike** — exploratory work; deliverable is learning, evidence, or a disposable demo. `/devlyn:resolve --spec` proceeds but VERIFY's quality bar is relaxed for code that the spike says is throwaway.
85
+ - **feature** — production-quality implementation expected. `/devlyn-resolve --spec` runs the full pipeline (PLAN → IMPLEMENT → BUILD_GATE → CLEANUP → VERIFY).
86
+ - **spike** — exploratory work; deliverable is learning, evidence, or a disposable demo. `/devlyn-resolve --spec` proceeds but VERIFY's quality bar is relaxed for code that the spike says is throwaway.
69
87
  - **prototype** — between feature and spike. Production-shape but not production-grade. CLEANUP runs; VERIFY's quality bar is stricter than spike, looser than feature.
70
88
 
71
89
  The user picks the kind during elicitation. Default = feature when not specified. `--quick` infers from the goal text (verbs like "explore", "investigate", "spike" → spike; "implement", "ship", "add" → feature).
@@ -112,7 +130,7 @@ After lint passes:
112
130
  2. Generate `<spec-dir>/<id>-<slug>/spec.expected.json` following `references/spec-template.md` § "Sibling file: `spec.expected.json`" for constraint coverage, diff scope and guard controls.
113
131
  3. Run `python3 "$DEVLYN_SHARED_DIR/spec-verify-check.py" --check <spec-path>` to validate the actual spec's carrier shape and supported `complexity` frontmatter. Sibling `spec.expected.json` takes precedence over the legacy inline `## Verification` JSON carrier. If exit 2, fix the file named in the error and re-run.
114
132
  4. Run `python3 "$DEVLYN_SHARED_DIR/spec-verify-check.py" --check-expected <expected-path>` to validate sibling `spec.expected.json` against `_shared/expected.schema.json` plus sibling spec `complexity` frontmatter. If exit 2, fix the JSON/frontmatter and re-run.
115
- 5. Print: `spec ready — /devlyn:resolve --spec <spec-path>`.
133
+ 5. Print: `spec ready — /devlyn-resolve --spec <spec-path>`.
116
134
 
117
135
  ## PHASE 1Q: QUICK MODE
118
136
 
@@ -145,9 +163,9 @@ Prompt body: `references/project-mode.md`.
145
163
  2. AI decomposes the project into 3-7 feature specs. Each feature is independently shippable; cross-feature dependencies surface explicitly in the spec frontmatter `depends_on:` field.
146
164
  3. AI writes `<spec-dir>/plan.md` — index file with: project name, decomposition rationale, list of feature specs with id + title + dependency, suggested implementation order.
147
165
  4. AI writes one `<spec-dir>/<id>/spec.md` + `<spec-dir>/<id>/spec.expected.json` per feature, each lint-validated.
148
- 5. Announce: `project ready — N specs at <spec-dir>/. Start with /devlyn:resolve --spec <first-spec-path>`.
166
+ 5. Announce: `project ready — N specs at <spec-dir>/. Start with /devlyn-resolve --spec <first-spec-path>`.
149
167
 
150
- `/devlyn:resolve` consumes one spec at a time; the user works through `plan.md`'s suggested order. Multi-feature parallel runs are Mission 2 work.
168
+ `/devlyn-resolve` consumes one spec at a time; the user works through `plan.md`'s suggested order. Multi-feature parallel runs are Mission 2 work.
151
169
 
152
170
  ## State management
153
171
 
@@ -84,7 +84,7 @@ Two files in `<spec-dir>/<id>-<slug>/`:
84
84
  - `spec.md` (per template).
85
85
  - `spec.expected.json` (per `_shared/expected.schema.json`).
86
86
 
87
- Final announcement (one line): `spec ready — /devlyn:resolve --spec <spec-path>`.
87
+ Final announcement (one line): `spec ready — /devlyn-resolve --spec <spec-path>`.
88
88
 
89
89
  Do NOT include the conversation transcript in the output. The spec stands alone.
90
90
  </output>
@@ -105,6 +105,6 @@ Quick mode trades thoroughness for speed. Use it for trivial-medium tasks where
105
105
 
106
106
  - Walls of questions in one turn.
107
107
  - Open-ended "what would you like" questions when the user clearly does not know.
108
- - Adding "for future flexibility" or "just in case" sections to the spec — the user did not ask for those, and the principles binding `/devlyn:resolve` reject them.
108
+ - Adding "for future flexibility" or "just in case" sections to the spec — the user did not ask for those, and the principles binding `/devlyn-resolve` reject them.
109
109
  - Saving the conversation transcript alongside the spec.
110
110
  - Stalling when the user gives a vague answer — re-ask with a more specific shape ("should it be A, B, or other?") rather than re-asking the same question.
@@ -43,7 +43,7 @@ You must NOT:
43
43
  9. If the preserved Requirements combine state mutation with ordering/priority,
44
44
  idempotency, auth/error priority, or exact output shape but the Verification
45
45
  section lacks a compound end-to-end scenario, do not rewrite the author's
46
- content. Add a final warning that `/devlyn:resolve` may need default-mode
46
+ content. Add a final warning that `/devlyn-resolve` may need default-mode
47
47
  ideation or a stronger Verification section before pair-relevant risks are
48
48
  measurable.
49
49
  </flow>
@@ -51,7 +51,7 @@ You must NOT:
51
51
  <output>
52
52
  Same as default mode: `<spec-dir>/<id>-<slug>/spec.md` + `<spec-dir>/<id>-<slug>/spec.expected.json`.
53
53
 
54
- Final announcement: `spec normalized — /devlyn:resolve --spec <spec-path>`. If the spec was lint-passing with no changes needed, announce: `spec already canonical — /devlyn:resolve --spec <spec-path>`. If step 9 applies, append: `warning: Verification may need one compound end-to-end scenario before pair-relevant risks are measurable`.
54
+ Final announcement: `spec normalized — /devlyn-resolve --spec <spec-path>`. If the spec was lint-passing with no changes needed, announce: `spec already canonical — /devlyn-resolve --spec <spec-path>`. If step 9 applies, append: `warning: Verification may need one compound end-to-end scenario before pair-relevant risks are measurable`.
55
55
 
56
56
  If lint failed unfixably: print the specific failure, exit non-zero. Do not write a partial output.
57
57
  </output>
@@ -21,7 +21,7 @@ The user wants to build a project, not a single feature. Your job is to elicit t
21
21
  - Features should be vertically sliced (full stack of one user-facing capability), not horizontally sliced (a layer that other features will need to consume).
22
22
  - A feature whose ONLY value is enabling other features (pure infrastructure) belongs in the first feature that needs it OR as an explicit "enabling spec" with the dependent feature waiting on it.
23
23
  - Feature dependencies are explicit in `frontmatter.depends_on`. The plan's suggested implementation order respects topological dependency.
24
- - Aim for features that take 1-3 hours of `/devlyn:resolve --spec` work each. Larger → split. Trivial → merge with neighbor.
24
+ - Aim for features that take 1-3 hours of `/devlyn-resolve --spec` work each. Larger → split. Trivial → merge with neighbor.
25
25
  </decomposition_rules>
26
26
 
27
27
  <plan_md_shape>
@@ -48,8 +48,8 @@ Output `<spec-dir>/plan.md`:
48
48
 
49
49
  ## Suggested implementation order
50
50
 
51
- 1. `/devlyn:resolve --spec <spec-dir>/<id-1>/spec.md`
52
- 2. `/devlyn:resolve --spec <spec-dir>/<id-2>/spec.md`
51
+ 1. `/devlyn-resolve --spec <spec-dir>/<id-1>/spec.md`
52
+ 2. `/devlyn-resolve --spec <spec-dir>/<id-2>/spec.md`
53
53
  3. ...
54
54
 
55
55
  The order respects `depends_on`. Topologically equivalent specs can be parallelized later (Mission 2 work); single-task L1 ships them sequentially.
@@ -59,7 +59,7 @@ The order respects `depends_on`. Topologically equivalent specs can be paralleli
59
59
  Anything binding all features (e.g. "no new top-level dependencies", "all CLI output must support `NO_COLOR`"). Each feature spec inherits these in its Constraints section.
60
60
  ```
61
61
 
62
- `plan.md` is the **index**, not a hidden dependency. `/devlyn:resolve` reads only the spec it is invoked with; it does not parse `plan.md`.
62
+ `plan.md` is the **index**, not a hidden dependency. `/devlyn-resolve` reads only the spec it is invoked with; it does not parse `plan.md`.
63
63
  </plan_md_shape>
64
64
 
65
65
  <output>
@@ -69,7 +69,7 @@ Anything binding all features (e.g. "no new top-level dependencies", "all CLI ou
69
69
 
70
70
  Each per-feature spec is structurally lint-validated using `python3 "$DEVLYN_SHARED_DIR/spec-verify-check.py" --check <spec-path>`, including supported `complexity` frontmatter, and each sibling expected contract plus sibling spec `complexity` frontmatter is validated using `python3 "$DEVLYN_SHARED_DIR/spec-verify-check.py" --check-expected <expected-path>`.
71
71
 
72
- Final announcement: `project ready — N specs at <spec-dir>/. Start with /devlyn:resolve --spec <first-spec-path>`.
72
+ Final announcement: `project ready — N specs at <spec-dir>/. Start with /devlyn-resolve --spec <first-spec-path>`.
73
73
  </output>
74
74
 
75
75
  <anti_patterns>
@@ -1,6 +1,6 @@
1
1
  # Canonical spec template
2
2
 
3
- The shape `/devlyn:ideate` writes and `/devlyn:resolve --spec` consumes. Single source of truth for spec structure.
3
+ The shape `/devlyn-ideate` writes and `/devlyn-resolve --spec` consumes. Single source of truth for spec structure.
4
4
 
5
5
  ## Frontmatter
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
- name: devlyn:queue
3
- description: Manage and drain the intent queue (docs/specs/queue.md) — the backlog the loop-engineering contract runs on. Use when the user wants to stack work for later ("큐에 넣어줘", "queue this"), see what is queued, or start an unattended serial drain ("큐 드레인 시작", "밤새 돌려줘", "drain the queue") that takes each item through spec → /devlyn:resolve → verified done.
2
+ name: devlyn-queue
3
+ description: Manage and drain the intent queue (docs/specs/queue.md) — the backlog the loop-engineering contract runs on. Use when the user wants to stack work for later ("큐에 넣어줘", "queue this"), see what is queued, or start an unattended serial drain ("큐 드레인 시작", "밤새 돌려줘", "drain the queue") that takes each item through spec → /devlyn-resolve → verified done.
4
4
  ---
5
5
 
6
6
  Utility front-end for the intent-queue contract in the project instructions ("Intent queue" in CLAUDE.md / AGENTS.md — whichever this CLI loads). It adds no semantics of its own: the queue file is the API, and the drain loop follows the documented contract exactly — a runner (this skill, a long session, or a future devlyn-os daemon) is a replaceable driver over the same file.
@@ -9,19 +9,42 @@ Utility front-end for the intent-queue contract in the project instructions ("In
9
9
  $ARGUMENTS
10
10
  </args>
11
11
 
12
- For `drain`, resolve the installed shared scripts before the first item:
12
+ Before `add` or `drain`, establish the bindings below.
13
13
 
14
- ```bash
15
- DEVLYN_SKILL_DIR="${CLAUDE_SKILL_DIR:-__DEVLYN_SKILL_DIR__}"
16
- if [ "$DEVLYN_SKILL_DIR" = "__DEVLYN_SKILL_DIR__" ] || [ ! -d "$DEVLYN_SKILL_DIR/../_shared" ]; then
17
- echo "BLOCKED:shared-dir-unresolved: $DEVLYN_SKILL_DIR/../_shared" >&2
18
- exit 1
19
- fi
20
- DEVLYN_SHARED_DIR="$(cd "$DEVLYN_SKILL_DIR/../_shared" && pwd)"
14
+ Resolve bundled resources from the SKILL.md loaded for this invocation.
15
+
16
+ Reader-rendered directory hint:
17
+ ```text
18
+ ${CLAUDE_SKILL_DIR}
21
19
  ```
22
20
 
23
- Before processing the first item, read and obey
24
- `../devlyn:resolve/references/outer-loop.md`. Its scoped-commit order is binding.
21
+ Treat the hint as literal path data, never shell code. If the reader
22
+ replaced it with an absolute directory, use that directory. Otherwise
23
+ use the filesystem path or base directory reported for this loaded
24
+ SKILL.md. Resolve virtual URIs through the reader's native filesystem
25
+ mapping. If available source locations name different directories,
26
+ stop.
27
+
28
+ Bind DEVLYN_SKILL_DIR to that absolute directory. Do not obtain this
29
+ binding from an environment variable, cwd, or another installation.
30
+ Verify its SKILL.md before proceeding. Missing or conflicting source
31
+ identity is BLOCKED:skill-source-unresolved; include the failed path
32
+ when known.
33
+
34
+ Resolve bundled references against this directory. These bindings are
35
+ workflow values: establish them explicitly using each tool or shell's
36
+ literal-path rules, and include their absolute values in every fresh
37
+ worker's prompt, telling it to set them from those values, never from
38
+ its inherited environment. Do not rely on shell state surviving between
39
+ calls.
40
+
41
+ Resolve directory symlinks on DEVLYN_SKILL_DIR before deriving its
42
+ sibling _shared. Bind that directory as DEVLYN_SHARED_DIR. References
43
+ written as _shared/... use this binding. Verify the directory and each
44
+ required resource before use; failure is BLOCKED:shared-dir-unresolved
45
+ with the failed path. Never search another installation.
46
+
47
+ For `add`, verify DEVLYN_SKILL_DIR/scripts/append.py before invoking it. For `drain`, before processing the first item, read and obey ../devlyn-resolve/references/outer-loop.md (its scoped-commit order is binding) and read ../devlyn-resolve/references/task-completion.md, both relative to this bound skill directory. Load the sibling devlyn-resolve/SKILL.md by its absolute path and preserve this bundle's DEVLYN_SHARED_DIR when handing off; do not rediscover resolve by its bare command name. In omp, use `printf '%s\n' skill://devlyn-queue`.
25
48
 
26
49
  Queue state is base's `docs/specs/queue.md` plus owned receipts: for each `$(git rev-parse --git-common-dir)/devlyn-completion/*/receipt.json`, read `git show <ref>:docs/specs/queue.md` from its `recovery_ref` if that ref exists (it is never deleted), else its `branch` if it still exists; an item unmarked on base but `[x]`/`[F]` there counts as that mark. Two different terminal marks for one item stop for inspection. Status and drain selection both use this view.
27
50
 
@@ -31,13 +54,13 @@ Read the queue state above (absent `docs/specs/queue.md` → report "queue empty
31
54
 
32
55
  ## Subcommands
33
56
 
34
- - `add <intent text>` — append `- [ ] <intent>` to `docs/specs/queue.md` (create the file with its header if missing). If the intent came out of a conversation that already produced a spec, link it: `- [ ] (spec: docs/specs/<id>/spec.md) <intent>`.
57
+ - `add <intent text>` — use the Write tool to place the exact full intent in a new file `.devlyn/queue-intent-<unique>.txt` (a name no other add uses, made of letters, digits, `.`, `_` and `-`, e.g. `queue-intent-20261001-1230-k3x9.txt`); do not create it with shell syntax. If the conversation already produced a spec, the file must start with `(spec: docs/specs/<id>/spec.md)`. Then, from the project root, run exactly once `python3 "$DEVLYN_SKILL_DIR/scripts/append.py" .devlyn/queue-intent-<unique>.txt`. The helper consumes that file, appends one `- [ ] <intent>` line at the physical end of `docs/specs/queue.md` under a lock (creating it with its header if missing), and is the sole queue writer. Never edit `docs/specs/queue.md` directly for `add` and never use a direct-edit fallback; a nonzero helper exit is shown to the user and stops the `add`.
35
58
  - `drain` — serial drain per the project-instructions contract. For each pending item, in order:
36
- 1. Allocate the owner's absent task branch with `--worktree <absent path>` per `../devlyn:resolve/references/task-completion.md`, and work in that worktree; then spec it if unspecced (the queue entry is the user's go-ahead). Unattended assumptions may only take scope-narrowing, reversible, non-user-visible defaults; material ambiguity (user-visible behavior, data/state semantics, new files/scripts/flags, implementation surface) → mark `[F] needs-review: <question>`, commit that queue transition, and continue.
37
- 2. Bring only the current queue-item delta and linked spec bundle from the queue view into the task worktree, which starts from the fetched remote base with no other local commits, commit that scoped owner baseline, then run `/devlyn:resolve --spec <path>` hands-free.
59
+ 1. Allocate the owner's absent task branch with `--worktree <absent path>` per `../devlyn-resolve/references/task-completion.md`, and work in that worktree; then spec it if unspecced (the queue entry is the user's go-ahead). Unattended assumptions may only take scope-narrowing, reversible, non-user-visible defaults; material ambiguity (user-visible behavior, data/state semantics, new files/scripts/flags, implementation surface) → mark `[F] needs-review: <question>`, commit that queue transition, and continue.
60
+ 2. Bring only the current queue-item delta and linked spec bundle from the queue view into the task worktree, which starts from the fetched remote base with no other local commits, commit that scoped owner baseline, then run the sibling devlyn-resolve loaded above with `--spec <path>` hands-free.
38
61
  After every resolve invocation, run `python3 "$DEVLYN_SHARED_DIR/terminal-claim-check.py" .`; exit 79 marks `[F] FAILED-INCOMPLETE` from the predicate, never from the session self-report.
39
62
  3. Outer loop on the terminal verdict: PASS → mark `[x]`. Findings-backed verdicts (NEEDS_WORK, BLOCKED:repair-budget-exhausted) → amend the spec, commit that scoped amendment, then re-run — at most 3 outer iterations. Infrastructure / invalid-input / engine-availability / implement-empty BLOCKED verdicts are not spec-amendable → mark `[F] <verdict>` immediately.
40
63
  4. Commit each terminal `[x]` / `[F]` queue transition before advancing. For successfully archived normal runs, invoke owner completion once after that declared queue-file-only commit; bind it separately from the verified source. Honor local-only/no-push. Failed products never publish. Retain PR/pending workspaces and use a separate owned branch from base for the next item; unavailable safe placement stops the drain with remaining items pending. A product-blocked item otherwise never halts the queue.
41
64
  5. When the queue is drained (or the session must stop), emit the drain report: per-item product verdict and separate delivery status/URL/resume, every logged assumption, and the commit range produced.
42
65
 
43
- Strictly SERIAL — one `/devlyn:resolve` run at a time, never parallel. Never invent queue items, never reorder them, and never delete an item — only mark `[x]` / `[F]`.
66
+ Strictly SERIAL — one `/devlyn-resolve` run at a time, never parallel. Never invent queue items, never reorder them, and never delete an item — only mark `[x]` / `[F]`.