From 66b242f9ab3c9745e25878da040847d91fde5a3c Mon Sep 17 00:00:00 2001 From: "d3mlabs-ai-flow[bot]" <305891656+d3mlabs-ai-flow[bot]@users.noreply.github.com> Date: Sun, 2 Aug 2026 09:42:24 -0400 Subject: [PATCH 1/3] ai-flow /build: capture learnings from the build pass Co-authored-by: JPDuchesne <2636122+JPDuchesne@users.noreply.github.com> --- .cursor/rules/learnings-index.mdc | 5 +++ .../skills/architecture/module-map/SKILL.md | 10 +++--- .../learnings/command-runner-exec/SKILL.md | 36 +++++++++++++++++++ 3 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 .cursor/skills/learnings/command-runner-exec/SKILL.md diff --git a/.cursor/rules/learnings-index.mdc b/.cursor/rules/learnings-index.mdc index 054feed..ca98b62 100644 --- a/.cursor/rules/learnings-index.mdc +++ b/.cursor/rules/learnings-index.mdc @@ -44,6 +44,11 @@ propose a retirement, a consolidation, or a glob-scoped sub-index split. as the idempotent hygiene hooks (skill links, learnings sync): never raise, network only as a bounded pull before distribution. → .cursor/skills/architecture/hook-points/ +- [architecture/command-runner-exec] CommandRunner exec-replaces the dev + process for project `run:` commands, so nothing after `cmd.execute` in + Runner#run happens for them (e.g. `dev up` with a project `up:` never + reaches `stamp_installed`). + → .cursor/skills/learnings/command-runner-exec/ ## toolchain diff --git a/.cursor/skills/architecture/module-map/SKILL.md b/.cursor/skills/architecture/module-map/SKILL.md index 3e03864..4bdea73 100644 --- a/.cursor/skills/architecture/module-map/SKILL.md +++ b/.cursor/skills/architecture/module-map/SKILL.md @@ -19,10 +19,12 @@ description: >- `.cursor/rules/separation-of-concerns.mdc`: Repository resolves, Integration installs, Lockfile serializes, the orchestrator coordinates — one class, one layer. -- **`lib/dev/learnings/`** — the learnings read path: Cache (bounded git - clone/pull of the knowledge repo), Synchronizer (orchestration), - InvariantsRenderer (one machine-side org-invariants.mdc render plus the - per-project symlink and the `dev learnings invariants` prompt seam). +- **`lib/dev/learnings/`** — the learnings read path plus its scaffold: + Cache (bounded clone/pull of the knowledge repo), Synchronizer + (orchestration), InvariantsRenderer (machine-side render + per-project + symlink + the `dev learnings invariants` prompt seam), Layout (canonical + owner of both tiers' paths and index templates; ai-flow mirrors them), + Scaffolder (`dev learnings init`'s write-once materialization). - **`lib/dev/skill_installer.rb`** — the one symlink mechanism behind all three skill channels (shipped, org, gem); the gem channel's lockfile scan is `lib/dev/deps/gem_skill_linker.rb`. diff --git a/.cursor/skills/learnings/command-runner-exec/SKILL.md b/.cursor/skills/learnings/command-runner-exec/SKILL.md new file mode 100644 index 0000000..9216762 --- /dev/null +++ b/.cursor/skills/learnings/command-runner-exec/SKILL.md @@ -0,0 +1,36 @@ +--- +name: command-runner-exec +description: >- + MUST be used when sequencing work after cmd.execute in Dev::Runner#run, + or when diagnosing a post-command step (like the installed stamp) that + silently never happens. +--- + +# CommandRunner exec ends the dev process + +`Dev::CommandRunner` runs project `run:` commands with `Kernel.exec` — the +dev process is replaced, so nothing after `cmd.execute` in +`Dev::Runner#run` executes for a yaml-declared command, nor for an +`OverriddenCommand` whose body is one. Post-execute steps only ever run +for fully in-process builtins; work that must always happen belongs +before the exec point. + +Wrong — a follow-up step after execute, expecting it for every command: + + cmd.execute(args:, context:) + stamp_installed(cmd_name, context.project_root) # skipped on exec + +Right — do must-happen work before execute (which may never return), or +keep the command fully in-process: + + stamp_installed(cmd_name, context.project_root) + cmd.execute(args:, context:) + +Observed symptom: in a repo whose dev.yml defines `up:`, `dev up` exec's +into the project's up command and never reaches `stamp_installed`, so the +staleness gate keeps reporting "never installed" — fatal in a CI=true +shell. `dev install-deps` stays in-process and stamps. Check this before +suspecting the staleness digests themselves. + +learned-from: dev#73 build pass (dev up never stamped; install-deps did) +date: 2026-08-02 From f464ec69c40c26107bcd1ec131bb3f17783d5912 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Date: Mon, 3 Aug 2026 08:50:04 -0400 Subject: [PATCH 2/3] Reword command-runner-exec: don't teach stamp-before-execute The stamp records a successful provisioning run; hoisting it before execute would mark a failed dev up as installed. The skill now states the invariant (success-contingent work can't sit after a maybe-exec point) and points at dev#85, the spawn-and-wait fix. Co-authored-by: Cursor --- .../learnings/command-runner-exec/SKILL.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/.cursor/skills/learnings/command-runner-exec/SKILL.md b/.cursor/skills/learnings/command-runner-exec/SKILL.md index 9216762..d8c1048 100644 --- a/.cursor/skills/learnings/command-runner-exec/SKILL.md +++ b/.cursor/skills/learnings/command-runner-exec/SKILL.md @@ -12,19 +12,19 @@ description: >- dev process is replaced, so nothing after `cmd.execute` in `Dev::Runner#run` executes for a yaml-declared command, nor for an `OverriddenCommand` whose body is one. Post-execute steps only ever run -for fully in-process builtins; work that must always happen belongs -before the exec point. +for fully in-process builtins. Wrong — a follow-up step after execute, expecting it for every command: cmd.execute(args:, context:) stamp_installed(cmd_name, context.project_root) # skipped on exec -Right — do must-happen work before execute (which may never return), or -keep the command fully in-process: - - stamp_installed(cmd_name, context.project_root) - cmd.execute(args:, context:) +Also wrong: hoisting the step before execute, when it records an outcome +(the stamp means "provisioning *succeeded*" — stamping first marks a +failed `dev up` as installed). Success-contingent work needs the command +to run in-process: spawn-and-wait with the exit status propagated, not +exec-replace — that fix is dev#85. Only outcome-independent work may +move before the exec point. Observed symptom: in a repo whose dev.yml defines `up:`, `dev up` exec's into the project's up command and never reaches `stamp_installed`, so the @@ -32,5 +32,6 @@ staleness gate keeps reporting "never installed" — fatal in a CI=true shell. `dev install-deps` stays in-process and stamps. Check this before suspecting the staleness digests themselves. -learned-from: dev#73 build pass (dev up never stamped; install-deps did) +learned-from: dev#73 build pass (dev up never stamped; install-deps did); +the sequencing bug itself is dev#85 date: 2026-08-02 From ff2a33209b841ca417d33b40007506853119208a Mon Sep 17 00:00:00 2001 From: Jean-Philippe Date: Mon, 3 Aug 2026 08:57:59 -0400 Subject: [PATCH 3/3] Cue command-runner-exec on command placement, not post-hoc sequencing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Origin-firing failed twice with the same verdict: the origin thread (dev#73) is about adding a command, not about sequencing after cmd.execute, so a mechanism-led cue never triggers there. The exec seam is an input to where a command lives — a builtin can carry post-steps, a run: command cannot — so the cue now leads with that decision. Co-authored-by: Cursor --- .cursor/rules/learnings-index.mdc | 9 +++++---- .cursor/skills/learnings/command-runner-exec/SKILL.md | 9 +++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/.cursor/rules/learnings-index.mdc b/.cursor/rules/learnings-index.mdc index ca98b62..bef5c53 100644 --- a/.cursor/rules/learnings-index.mdc +++ b/.cursor/rules/learnings-index.mdc @@ -44,10 +44,11 @@ propose a retirement, a consolidation, or a glob-scoped sub-index split. as the idempotent hygiene hooks (skill links, learnings sync): never raise, network only as a bounded pull before distribution. → .cursor/skills/architecture/hook-points/ -- [architecture/command-runner-exec] CommandRunner exec-replaces the dev - process for project `run:` commands, so nothing after `cmd.execute` in - Runner#run happens for them (e.g. `dev up` with a project `up:` never - reaches `stamp_installed`). +- [architecture/command-runner-exec] When adding a dev command or any + step that must run after one (installed stamp, hygiene hooks): project + `run:` commands exec-replace the dev process, so nothing after + `cmd.execute` in Runner#run runs for them — post-command work needs a + builtin or spawn-and-wait (dev#85). → .cursor/skills/learnings/command-runner-exec/ ## toolchain diff --git a/.cursor/skills/learnings/command-runner-exec/SKILL.md b/.cursor/skills/learnings/command-runner-exec/SKILL.md index d8c1048..68bc724 100644 --- a/.cursor/skills/learnings/command-runner-exec/SKILL.md +++ b/.cursor/skills/learnings/command-runner-exec/SKILL.md @@ -1,9 +1,9 @@ --- name: command-runner-exec description: >- - MUST be used when sequencing work after cmd.execute in Dev::Runner#run, - or when diagnosing a post-command step (like the installed stamp) that - silently never happens. + MUST be used when adding a dev command, sequencing work after + cmd.execute in Dev::Runner#run, or diagnosing a post-command step (like + the installed stamp) that silently never happens. --- # CommandRunner exec ends the dev process @@ -12,7 +12,8 @@ description: >- dev process is replaced, so nothing after `cmd.execute` in `Dev::Runner#run` executes for a yaml-declared command, nor for an `OverriddenCommand` whose body is one. Post-execute steps only ever run -for fully in-process builtins. +for fully in-process builtins — which makes this an input to command +placement: a builtin can carry post-steps, a `run:` command cannot. Wrong — a follow-up step after execute, expecting it for every command: