Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .devflow/features/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
- **ambient-orchestrator** — scripts/hooks, src/cli/commands/ambient.ts, plugins/devflow-ambient — Use when modifying the ambient mode hooks (preamble, session-start-orchestrator), the orchestrator charter file (including the feature-knowledge operating rule), the git-marker helper, the ambient CLI toggle, or the plan-handoff fast-path. Keywords: ambient, preamble, orchestrator, charter, plan-handoff, session-start-orchestrator, git-marker, DEVFLOW_BG_UPDATER, devflow ambient, UserPromptSubmit, SessionStart, feature-knowledge.
- **dynamic-workflow-engine** — commands/dynamic-build.mds, commands/dynamic-plan.mds, commands/dynamic-tickets.mds, commands/dynamic-wave.mds, commands/dynamic-profile.mds, commands/_partials/_engine.mds, commands/_partials/_wave.mds, plugins/devflow-dynamic/commands, tests/build-mds.test.ts — Use when authoring or modifying the dynamic-* commands (dynamic-build, dynamic-plan, dynamic-tickets, dynamic-wave, dynamic-profile), the shared engine/wave/preamble/factory MDS partials, or the build-mds test suite that pins doctrine literals. Keywords: dynamic-build, dynamic-plan, dynamic-tickets, dynamic-wave, dynamic-profile, Workflow tool, agentType, Gate 1, Gate 2, review loop, wave, tickets→plan→build, MDS, _engine.mds, _wave.mds.
- **resolve-pipeline** — commands/resolve.mds, shared/agents/triager.md, shared/agents/coder.md, plugins/devflow-resolve, commands/code-review.mds — Use when modifying /resolve or /code-review convergence logic, adding or changing Triager disposition rules, adjusting Coder operating modes (issue-fix/validation-fix), touching the resolution-summary.md parser contract, changing the Verification Gate retry loop, or understanding how DIFF_FILES flows from git validate-branch into blast-radius triage. Keywords: resolve, triager, disposition matrix, blast-radius, FIX_NOW, FIX_SEPARATE, TECH_DEBT, FALSE_POSITIVE, BY_DESIGN, ESCALATED, resolution-summary, convergence parser, DIFF_FILES, issue-fix, validation-fix, Verification Gate, manage-debt.
- **installer-shadowing** — src/cli/utils/installer.ts, src/cli/commands/init.ts, src/cli/commands/uninstall.ts, src/cli/commands/rules.ts, src/cli/commands/skills.ts, src/cli/plugins.ts, src/cli/utils/marketplace-cleanup.ts — Use when modifying the install pipeline (installViaFileCopy, installAllRules, InstallReport), adding or changing skill/rule shadow override logic, touching uninstall scope or leftover-warning behavior, or extending the CLI skills/rules management commands. Keywords: installViaFileCopy, installAllRules, InstallReport, RuleInstallOutcome, SkillShadowState, RuleShadowState, shadow, unshadow, validateSkillShadow, validateRuleShadow, seedRuleShadow, prefixSkillName, unprefixSkillName, devflow:, skills, rules, uninstall, EISDIR, computeShadowLeftoverWarnings, ShadowWarning, marketplace-cleanup.
- **installer-shadowing** — src/cli/utils/installer.ts, src/cli/commands/init.ts, src/cli/commands/uninstall.ts, src/cli/commands/rules.ts, src/cli/commands/skills.ts, src/cli/plugins.ts — Use when modifying the install pipeline (installViaFileCopy, installAllRules, InstallReport), adding or changing skill/rule shadow override logic, touching uninstall scope or leftover-warning behavior, or extending the CLI skills/rules management commands. Keywords: installViaFileCopy, installAllRules, InstallReport, RuleInstallOutcome, SkillShadowState, RuleShadowState, shadow, unshadow, validateSkillShadow, validateRuleShadow, seedRuleShadow, prefixSkillName, unprefixSkillName, devflow:, skills, rules, uninstall, EISDIR, computeShadowLeftoverWarnings, ShadowWarning.
- **learning-capture-system** — scripts/hooks, shared/agents/learning.md, src/cli/commands/learning.ts, src/cli/utils/feature-config.ts, src/cli/utils/learning-tuning-config.ts, src/cli/hud/components/learning-counts.ts, commands/_partials — Use when modifying capture hooks (capture-prompt/capture-turn/capture-question), the learning or memory pending-turns queues, the Learning agent (shared/agents/learning.md), the session-start-context learning directive, the feature-config toggles, the learning tuning config, the decisions content files (decisions.md/pitfalls.md/index.md) or their ledger ops, or the devflow learning CLI. Keywords: capture-prompt, capture-turn, capture-question, queue-append, pending-turns, memory-worker, Learning agent, learning directive, LEARNING MAINTENANCE, DEVFLOW_BG_UPDATER, learning-lock, queue_read_gates, decisions_load, DECISIONS_CONTEXT, feature-config, config.json, learning.json, decisions-ledger, assign-anchor, retire-anchor, render-decisions.
11 changes: 3 additions & 8 deletions .devflow/features/installer-shadowing/KNOWLEDGE.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
---
feature: installer-shadowing
name: Installer & Skill/Rule Shadowing
description: "Use when modifying the install pipeline (installViaFileCopy, installAllRules, InstallReport), adding or changing skill/rule shadow override logic, touching uninstall scope or leftover-warning behavior, or extending the CLI skills/rules management commands. Keywords: installViaFileCopy, installAllRules, InstallReport, RuleInstallOutcome, SkillShadowState, RuleShadowState, shadow, unshadow, validateSkillShadow, validateRuleShadow, seedRuleShadow, prefixSkillName, unprefixSkillName, devflow:, skills, rules, uninstall, EISDIR, computeShadowLeftoverWarnings, ShadowWarning, marketplace-cleanup."
description: "Use when modifying the install pipeline (installViaFileCopy, installAllRules, InstallReport), adding or changing skill/rule shadow override logic, touching uninstall scope or leftover-warning behavior, or extending the CLI skills/rules management commands. Keywords: installViaFileCopy, installAllRules, InstallReport, RuleInstallOutcome, SkillShadowState, RuleShadowState, shadow, unshadow, validateSkillShadow, validateRuleShadow, seedRuleShadow, prefixSkillName, unprefixSkillName, devflow:, skills, rules, uninstall, EISDIR, computeShadowLeftoverWarnings, ShadowWarning."
category: architecture
directories: [src/cli/utils/installer.ts, src/cli/commands/init.ts, src/cli/commands/uninstall.ts, src/cli/commands/rules.ts, src/cli/commands/skills.ts, src/cli/plugins.ts, src/cli/utils/marketplace-cleanup.ts]
directories: [src/cli/utils/installer.ts, src/cli/commands/init.ts, src/cli/commands/uninstall.ts, src/cli/commands/rules.ts, src/cli/commands/skills.ts, src/cli/plugins.ts]
created: 2026-07-13
updated: 2026-07-13
---
Expand Down Expand Up @@ -191,10 +191,6 @@ Positional actions dispatch **before** flags. When `action` is present, flag opt

Exports: `hasRuleShadow(ruleName, devflowDir?)`, `listShadowedRules(devflowDir?)`, `seedRuleShadow(...)` — used by uninstall and tests.

### Marketplace cleanup migration

`marketplace-cleanup.ts` exports `stripDevflowMarketplaceFromJson` (pure string→string) and `stripDevflowMarketplace` (async file I/O wrapper). The global migration `purge-stale-extra-known-marketplaces-v1` calls `stripDevflowMarketplace` to remove the `devflow` key from `extraKnownMarketplaces` in `settings.json`. Per ADR-003, if `extraKnownMarketplaces` becomes empty after removal, the entire key is deleted (clean end-state). Malformed JSON and missing keys are returned unchanged so a corrupt file never causes the migration to record a false success.

## Anti-Patterns

- **Installing all of `~/.devflow/` on uninstall** — only `~/.devflow/scripts/` is Devflow-owned; `~/.devflow/skills/`, `~/.devflow/rules/`, and config files are user-owned and must survive uninstall.
Expand All @@ -221,10 +217,9 @@ Exports: `hasRuleShadow(ruleName, devflowDir?)`, `listShadowedRules(devflowDir?)
- `src/cli/commands/rules.ts` — `rulesCommand` positional dispatch, `seedRuleShadow`, `handleRuleShadow`, `handleRuleUnshadow`, `buildRuleShadowTag`, `printRulesList`, `hasRuleShadow`, `listShadowedRules`
- `src/cli/commands/skills.ts` — `skillsCommand` positional dispatch, `buildSkillShadowTag`, `hasShadow`, `listShadowed`
- `src/cli/plugins.ts` — `prefixSkillName`, `unprefixSkillName`, `SKILL_NAMESPACE`, `DEVFLOW_PLUGINS`, `buildFullSkillsMap`, `buildRulesMap`, `LEGACY_SKILL_NAMES`, `LEGACY_AGENT_NAMES`
- `src/cli/utils/marketplace-cleanup.ts` — `stripDevflowMarketplaceFromJson` (pure), `stripDevflowMarketplace` (async file wrapper); consumed by `purge-stale-extra-known-marketplaces-v1` migration

## Related

- ADR-010: Productionalize skill/rule shadowing — governs the decision to make `installViaFileCopy` the sole install path and to surface invalid shadows as warn-and-install-source (not hard-fail) (applies ADR-010)
- ADR-003: Leave the end-state, not the transition — governs removals and legacy cleanup (no tombstone comments, no `*_old` names; `LEGACY_SKILL_NAMES` tracks accumulated deprecated names; `extraKnownMarketplaces` key removal in `marketplace-cleanup.ts`) (applies ADR-003)
- ADR-003: Leave the end-state, not the transition — governs removals and legacy cleanup (no tombstone comments, no `*_old` names; `LEGACY_SKILL_NAMES` tracks accumulated deprecated names) (applies ADR-003)
- Feature knowledge: `feature-knowledge-system` — the Knowledge agent writes to `.devflow/features/` which is tracked in git; related to the `.gitignore` carve-out maintained by the installer (`ensureDevflowGitignore` in `post-install.ts`)
15 changes: 1 addition & 14 deletions .devflow/features/learning-capture-system/KNOWLEDGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ directories:
- src/cli/utils/learning-tuning-config.ts
- src/cli/utils/learning-queue-cleanup.ts
- src/cli/utils/project-paths.ts
- src/cli/utils/migrations.ts
- src/cli/hud/components/learning-counts.ts
- commands/_partials
created: 2026-07-15
Expand Down Expand Up @@ -214,14 +213,6 @@ HUD coupling to markdown format (D309). Label: `Learning: N decisions, M pitfall
| `--clear` | Truncates `decisions-log.jsonl` |
| `--reset` | Removes `.devflow/learning/` state; prints pinned message: `Reset complete — removed .devflow/learning/ state.` |

### Migrations

Two migrations consolidate older installs:
- `consolidate-dream-decisions-to-learning-v1` (per-project): moves `.devflow/dream/` + `.devflow/decisions/`
→ `.devflow/learning/`; writes `.devflow/config.json`; maps `decisions` key → `learning`
- `rename-global-decisions-config-v1` (global): renames `~/.devflow/decisions.json` →
`~/.devflow/learning.json`

## Naming Boundary (Critical Convention)

The Learning agent processes the queue and produces **decisions content**. Content identifiers
Expand Down Expand Up @@ -275,7 +266,7 @@ agents must not "fix" the naming mismatch.

- **`decisions` legacy key wins over `learning` in `coerceConfig`**: older configs that have
`"decisions": false` will override a `"learning": true` in the same file. This is intentional
(migration compatibility) but can cause confusion when reading a config with both keys.
(backward compatibility) but can cause confusion when reading a config with both keys.

- **HUD reads `decisions-ledger.jsonl`, not the `.md` files**: a row is active only when
`anchor_id` is set (non-empty string) AND `decisions_status` is absent or not in the
Expand All @@ -289,10 +280,6 @@ agents must not "fix" the naming mismatch.
feature config where there is no project-vs-global concept (`.devflow/config.json` is
project-only).

- **D37 edge case on fresh clones**: if a project is cloned after global migration markers are
set, `readConfig` falls through to `DEFAULT_CONFIG` (all features enabled). Recovery is
`rm ~/.devflow/migrations.json` to force a re-sweep, or re-running `devflow init`.

- **json_extract_cwd_field SOH delimiter**: `capture-turn` splits the combined `cwd+field`
output using `$'\001'` (bash SOH literal). The jq side emits `""`. If you add a
new hook that uses this helper, verify both branches (jq and node fallback) emit the same
Expand Down
5 changes: 2 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- **`/resolve` pipeline split** (BREAKING): the monolithic Resolver agent (which both validated and fixed issues) is replaced by a Triager + Coder pair. The Triager (opus) runs a blast-radius disposition pass; the Coder (sonnet, `OPERATION: issue-fix`) applies fixes. Plugins that declared the `resolver` agent must update their agent list to `[git, triager, coder, simplifier, validator]`.

### Removed
- **1.x migration registry and helper modules** (BREAKING): all 20 run-once 1.x upgrade migrations removed from `MIGRATIONS`; helper modules `legacy-decisions-purge.ts`, `decisions-ledger-migration.ts`, `marketplace-cleanup.ts`, and `mkdir-lock.ts` deleted. The migration framework stays for future 2.x entries. No 1.x → 2.0 upgrade path.
- **Native `claude plugin install` path** (BREAKING): the `claude plugin install` code path is removed; `installViaFileCopy` (file copy) is the sole install mechanism for all Devflow assets.
- **`extraKnownMarketplaces` registration from settings template**: the Devflow marketplace entry is no longer written to `~/.claude/settings.json` on install.
- **SHADOW_RENAMES migration machinery**: the `SHADOW_RENAMES` constant and associated migration logic for renaming skill shadow directories are removed; no active renames remain.
Expand All @@ -41,14 +42,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- **Learning**: Skill artifacts now include `user-invocable: false`, Iron Law section, and `self-learning:` name prefix

### Fixed
- **Learning**: reject observations with empty id/type/pattern fields (validation + auto-purge on migration)
- **Learning**: reject observations with empty id/type/pattern fields
- **Learning**: Handle string-typed `.message.content` in transcript extraction (was only handling arrays)
- **Learning**: Eliminate empty-array loop noise when Sonnet returns no observations
- **Learning**: Race condition in batch file handoff (atomic `mv` replaces `cp`+`rm`)
- **Learning**: `--enable` now auto-upgrades legacy Stop hook to SessionEnd
- **Learning**: `--status` detects legacy hook and shows upgrade instructions
- **Self-learning reconciler self-heal**: `reconcile-manifest` now recovers from `render-ready` crash-window states. When a knowledge file contains an ADR/PF anchor absent from the manifest, and exactly one `status: 'ready'` log observation matches by normalized pattern, the observation is upgraded to `status: 'created'` and the manifest entry is reconstructed. Zero matches are treated as user-curated (left alone); multiple matches are silently skipped as ambiguous. Adds `healed` counter to all reconcile-manifest output shapes. Heal is gated by the `- **Source**: self-learning:` marker on the knowledge-file section, preventing false-positive heals against pre-v2 seeded entries.
- **Legacy knowledge purge v3 migration** (`purge-legacy-knowledge-v3`): sweeps all remaining pre-v2 seeded knowledge entries using the `- **Source**: self-learning:` format discriminator. Any ADR/PF section lacking this marker is removed. Replaces the v2 hardcoded allow-list approach with a format-based approach that catches entries the v2 migration missed. Self-learning-generated entries and user-opted-in entries (entries containing the source marker) survive.

---

Expand Down
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ Knowledge write-back is in-command (not a background pipeline): gated by `devflo

**Two-Mode Init**: `devflow init` offers Recommended (sensible defaults, quick setup) or Advanced (full interactive flow) after plugin selection. `--recommended` / `--advanced` CLI flags for non-interactive use. Recommended applies: ambient ON, memory ON, learning ON, rules ON, HUD ON, default-ON flags, .claudeignore ON, auto-install safe-delete if trash CLI detected, user-mode security deny list, viewMode preserved from existing settings.json. Advanced path adds a view mode selector (default/verbose/focus) after Claude Code flags. Use `--learning/--no-learning` to toggle the learning agent independently. Use `--rules/--no-rules` to toggle rules independently.

**Migrations**: Run-once migrations execute automatically on `devflow init`, tracked at `~/.devflow/migrations.json` (scope-independent; single file regardless of user-scope vs local-scope installs). Registry: append an entry to `MIGRATIONS` in `src/cli/utils/migrations.ts`. Scopes: `global` (runs once per machine, no project context) vs `per-project` (sweeps all discovered Claude-enabled projects in parallel). Failures are non-fatal — migrations retry on next init. Currently registered per-project migrations include `purge-legacy-knowledge-v2` (removes 4 hardcoded pre-v2 ADR/PF IDs and orphan `PROJECT-PATTERNS.md`), `purge-legacy-knowledge-v3` (v3: sweeps all remaining pre-v2 seeded entries using the `- **Source**: self-learning:` format discriminator — any ADR/PF section lacking this marker is removed; entries the user edited to include the marker survive), `purge-orphaned-sidecar-judgment-state` (per-project; removes orphaned `.decisions-manifest.json`, `.decisions-notifications.json` — judgment-state files written by the now-removed deterministic render/reconcile layer), `purge-stale-memory-markers-v1` (per-project; removes stale `dream/memory.*` markers left by the old Dream-subagent memory pipeline now that `background-memory-update` handles memory refresh — ENOENT-idempotent, rethrows non-ENOENT errors), `purge-dead-working-memory-sentinel-v1` (per-project; removes the stale `.devflow/memory/.working-memory-disabled` sentinel now that the memory gate is config-only per ADR-001 — ENOENT-tolerant, rethrows non-ENOENT errors), `purge-dream-worker-state-v1` (per-project; removes the `.devflow/decisions/.disabled` sentinel, `dream/.last-dream-ok`, `dream/last-run-summary`, and the `dream/.worker.lock/` directory left by the retired detached dream worker), `purge-dream-marker-pipeline-v1` (per-project; removes stale `decisions.*`/`curation.*` markers and legacy fixed-name stamps — `.decisions-runs-today`, `.curation-last`, `.processor-spawned-at` — left by the retired dream marker pipeline), `consolidate-dream-decisions-to-learning-v1` (per-project; consolidates `.devflow/dream/` + `.devflow/decisions/` into flat `.devflow/learning/`, writes `.devflow/config.json` feature toggles, and re-renders `index.md` with updated footer paths). Global migrations: `rename-global-decisions-config-v1` renames `~/.devflow/decisions.json` → `~/.devflow/learning.json` (global tuning config); `purge-orphaned-dream-commit-hook-v1` removes the orphaned `~/.devflow/scripts/hooks/dream-commit` (the `dream-commit` helper was deleted when `.devflow/` became gitignored-by-default per ADR-021, but the installer copies `scripts/` additively — `copyDirectory` never deletes — so the stale file would otherwise linger; ENOENT-idempotent). **D37 edge case**: a project cloned *after* migrations have run won't be swept (the marker is global, not per-project). Recovery: `rm ~/.devflow/migrations.json` forces a re-sweep on next `devflow init` — but note that per-project discovery reads `~/.claude/history.jsonl` (`post-install.ts`), so a linked worktree that never hosted a Claude session is NOT swept even after removing the marker; recovery for such worktrees requires opening a Claude session there first (to register it in history), then re-running `devflow init`.
**Migrations**: Run-once migrations execute automatically on `devflow init`, tracked at `~/.devflow/migrations.json` (scope-independent; single file regardless of user-scope vs local-scope installs). To add a 2.x migration, append an entry to `MIGRATIONS` in `src/cli/utils/migrations.ts`. Scopes: `global` (runs once per machine, no project context) vs `per-project` (sweeps all discovered Claude-enabled projects in parallel). Failures are non-fatal — migrations retry on next init. The registry is empty as of 2.0 — no 1.x upgrade path.

## Project Structure

Expand Down
Loading
Loading