refactor(ambient): remove redundant commands-awareness rule#233
Conversation
The commands rule listed every devflow command and restated the plan auto-execution trigger. Both are already available live via the skills list and preamble hook directive. Ambient mode collapses to a single component: the preamble UserPromptSubmit hook. Changes: - Delete shared/rules/commands.md - Rename removeCommandsRule to removeLegacyCommandsRule; remove installCommandsRule and COMMANDS_RULE_CONTENT; call removeLegacyCommandsRule unconditionally before the early-return in addAmbientHook and removeAmbientHook so stale files are purged on every enable/disable/init -- avoids PF-001, applies ADR-001 - Prune dead tests for removed exports; rename describe block; add ordering-invariant test for the early-return path - Sweep docs: CLAUDE.md, README.md, docs/commands.md, docs/cli-reference.md, plugins/devflow-ambient, src/cli/plugins.ts, src/cli/commands/init.ts, .devflow/features/cli-rules/KNOWLEDGE.md Build: npm run build passes with 12 rules Tests: npm test passes 1521 tests across 56 files Co-Authored-By: Claude <noreply@anthropic.com>
Finding 1: RELIABILITY (HIGH) — src/cli/commands/ambient.ts:67Non-fatal cleanup of deprecated files The current implementation propagates non-ENOENT errors (EACCES, EPERM, etc.) from A best-effort cleanup of a deprecated artifact should never be fatal — it must not block the primary operation. Recommended fix: export async function removeLegacyCommandsRule(): Promise<void> {
try {
await fs.unlink(COMMANDS_RULE_PATH);
} catch (err) {
const code = (err as NodeJS.ErrnoException).code;
if (code === 'ENOENT') return; // already gone — success
// Best-effort cleanup of a deprecated file: never let it abort the
// caller's primary operation (enable/disable/init). Log and continue.
}
}This ensures the legacy file is purged whenever possible, but file system errors (permission denied, read-only FS, etc.) don't regress previously-working functionality. Review feedback from devflow:code-review | 8 reviewers APPROVED |
Finding 2: CONSISTENCY + DOCUMENTATION (HIGH) — README.md:56Docs sweep straggler: rule count should be 12 The PR swept rule-count references everywhere except Fix: Update Review feedback from devflow:code-review | Consistency + Documentation reviewers (96% confidence) |
Finding 3: DOCUMENTATION (MEDIUM) — .devflow/features/cli-rules/KNOWLEDGE.md:241Inaccurate PF citation in cli-rules KNOWLEDGE.md New gotcha line states: "The workflow-bucket predicate is `commands.length > 0` — the language-bucket comment notes this implicit contract is PF-007". Two inaccuracies: (1) the source comment in Fix: Either drop the "is PF-007" claim and reference the Review feedback from devflow:code-review | Documentation reviewer (90% confidence) |
Summary: PR #233 Code ReviewOverall Verdict: 8 reviewers APPROVED with 3 blocking findings above. The refactor is architecturally sound and well-executed — the three findings are concrete, fixable issues (one reliability regression, two documentation stragglers). Review Coverage
Sub-Threshold Findings (60-79% confidence)Cleanup ordering vs. write atomicity (Reliability, 65% confidence)
Version-mark the legacy purge for eventual deletion (Code hygiene, 62% confidence)
Anachronistic parenthetical in init.ts (Documentation, 61% confidence)
DeduplicationThe README "13" count issue was raised independently by both Consistency and Documentation reviewers (96% + 98% confidence) — posted once as Finding 2 above. Key Strengths
Next Steps:
All review reports available in |
removeLegacyCommandsRule now swallows ALL errors (previously re-threw non-ENOENT). It is called unconditionally before the early-return in addAmbientHook/removeAmbientHook, so a propagated EACCES/EPERM/EROFS could abort `devflow init` (silently disabling memory/HUD/flags via the surrounding catch) or crash `ambient --enable/--disable`. Cleanup of a deprecated artifact must never abort the caller's primary operation. Test flipped accordingly (EACCES case now asserts resolve, not reject). Also fixes two docs-sweep stragglers from the same review: - README.md: "13" -> "12" engineering principles (commands.md removed) - cli-rules KNOWLEDGE.md: drop incorrect PF-007 cross-reference Fixes: HIGH-severity reliability issue in code-review resolution. Co-Authored-By: Claude <noreply@anthropic.com>
Testing: Missing mirror test for removeAmbientHook early-return path (90% confidence)File: The new ordering-invariant test (line 94-104) proves The closest test, Drop-in fix: Add a mirror test to the ```typescript (The suite's Inline comment by Claude Code (devflow:git agent) |
Consistency: Stale shared/rules/commands.md in feature knowledge index (90% confidence)File: This PR deletes The companion KNOWLEDGE.md was updated correctly, so the index and KNOWLEDGE.md are now out of sync with each other and with the source tree. Impact: Fix: In
Inline comment by Claude Code (devflow:git agent) |
PR Review Summary — 2026-06-02 Review Cycle 2All 10 reviewers: APPROVED or APPROVED_WITH_CONDITIONS Overall Verdict: APPROVED WITH CONDITIONSThe refactor is architecturally clean, technically correct, and well-tested. The two-component collapse (preamble hook + commands.md rule → preamble hook only) eliminates redundancy and improves separation of concerns. The cleanup-ordering invariant is correctly implemented across all three entry points (enable, disable, init). Conditions for merge:
Key Verification Highlights✅ Cleanup-ordering invariant: Verified that Lower-Confidence Suggestions (60–79%, summary only)These are informational observations that do not block merge:
Pre-Existing Issues (Not Raised)One pre-existing pattern noted in TypeScript review (88% confidence, non-critical):
Summary generated by Claude Code (devflow:git agent) |
…ix brittle restub, drop deleted commands.md from knowledge index - Add mirror ordering-invariant test for removeAmbientHook: asserts fs.unlink is called on the early-return path (no hooks to remove), closing the gap where moving removeLegacyCommandsRule after the early-return would pass all current tests. - Replace vi.restoreAllMocks()+re-stub in the addAmbientHook ordering test with vi.clearAllMocks() -- preserves the stub, avoids coupling to the first call's side-effects. - Remove shared/rules/commands.md from cli-rules referencedFiles and description keywords in .devflow/features/index.json; file was deleted this PR and the dead path was skewing staleness detection. Co-Authored-By: Claude <noreply@anthropic.com>
…knowledge, design/review docs Persist the shared .devflow/ knowledge base to the branch: - decisions.md / pitfalls.md: accumulated ADR/PF entries - features/hooks/KNOWLEDGE.md: updated feature knowledge - docs/design + docs/reviews: design artifact and review/resolution reports for init-flow-simplification (#232) and remove-ambient-commands-rule (#233) Transient per-developer state (memory/, sidecar/, logs, locks, .last-review-head) remains gitignored. Treats .devflow/ as a shared, committed knowledge base. Co-Authored-By: Claude <noreply@anthropic.com>
Summary
commands.mdrule listed every/devflow:<name>command and restated the plan auto-execution trigger, both already available live via the session's available-skills list and thepreamblehook directive at runtime.preambleUserPromptSubmit hook.removeLegacyCommandsRuleruns unconditionally before the early-return in bothaddAmbientHookandremoveAmbientHook, so everydevflow ambient --enable/--disableordevflow initpurges any stalecommands.md. No migration needed (applies ADR-001, avoids PF-001).Changes
shared/rules/commands.mdsrc/cli/commands/ambient.ts: RemovedCOMMANDS_RULE_CONTENT,installCommandsRule; renamedremoveCommandsRule→removeLegacyCommandsRule; updatedaddAmbientHookandremoveAmbientHookto callremoveLegacyCommandsRuleunconditionally before their early-return guards; updated command descriptions and log messagestests/ambient.test.ts: Pruned deadinstallCommandsRuleandCOMMANDS_RULE_CONTENTdescribe blocks; renamedremoveCommandsRulesuite; added ordering-invariant test proving the legacy rule is purged even on the early-return path; updated stubs frommkdir+writeFiletounlink.devflow/features/cli-rules/KNOWLEDGE.mdBreaking Changes
None.
addAmbientHookandremoveAmbientHookretain their existing signatures and return types.Reviewer Focus Areas
removeLegacyCommandsRulemust run before theif (!changed) return settingsJsonearly-return inaddAmbientHook, and beforeif (!removedPrompt && !removedClassification) return settingsJsoninremoveAmbientHook. Verify both call sites respect this.purges legacy rule even when preamble hook already presentguards this invariant.npm run buildshowsFound 12 rules in shared/rules/(was 13).npm testpasses 1521 tests.