Harness Intelligence Wiki
SpecsCLICli Update Enforcement

CLI Update Enforcement Plan

Plan: CLI Update Enforcement

Initial Situation

Requirements grill is closed 100% and the reviewed spec is apps/wiki/content/docs/project/specs/cli/cli-update-enforcement/SPEC.md. No backlog is being created for this delivery. Existing dp update --check detects managed scaffold, pack, and baseline drift, but there is no project-local CLI/baseline pin contract and no dp check command.

Locked Decisions

  • Store cliVersion and baselineVersion in .devpunks/settings.json.
  • Add read-only dp check as the session-start drift command.
  • Keep dp update as the mutating scaffold update command.
  • Warn before work starts when CLI or baseline drift is detected.
  • Summarize relevant changelog content in drift output.
  • If the user accepts remediation, run update/upgrade in a subagent.
  • Edit upstream dp-cli skill in /Users/stefan/Desktop/repos/wearedevpunks-skills first, then sync Harness.

Research Inputs

  • Grill status: apps/wiki/content/docs/project/grilling/cli-update-enforcement-grill-status.md
  • Handoff: /var/folders/y8/fw7tz9gn7yx645tf162zwlnr0000gp/T/harness-cli-update-enforcement-handoff.md
  • CLI update path: apps/cli/src/update/run.ts, apps/cli/src/cli/update-command.ts
  • CLI self-update path: apps/cli/src/core/self-update.ts, apps/cli/src/cli/upgrade-command.ts
  • Settings path: apps/cli/src/core/tools.ts
  • Hook path: apps/cli/src/data/hooks/scaffold-update-check.mjs
  • Shared skill source: /Users/stefan/Desktop/repos/wearedevpunks-skills/skills/agnostic/cli/dp-cli/

Assumptions

  • cliVersion means the running CLI package version recorded whenever the CLI writes or accepts project authority.
  • baselineVersion means baseline.summary.version recorded when scaffold-managed files are written.
  • dp check should return nonzero on detected drift, but not on release metadata unavailability unless existing runUpdate check fails.
  • Changelog summaries can be compact release-note excerpts, not full changelog rendering.

Dependency Graph

T1 and T4 start in parallel. T2 depends on T1. T3 depends on T2. T5 depends on T1-T4. T6 depends on T1-T5. T7 depends on T6. This preserves maximum safe parallelism while keeping dp check available before hooks target it and keeping docs finalization behind implemented behavior.

Parallel Execution Waves

WaveTasksCan Start When
1T1, T4 source editsImmediately
2T2T1 complete
3T3T2 complete
4T4 push/sync, T5T1-T4 source edits and T3 complete
5T6T1-T5 complete
6T7T6 complete

Tasks

T1: Version pins in settings

  • depends_on: []
  • location: apps/cli/src/core/tools.ts; apps/cli/src/scaffold/stage.ts; apps/cli/src/scaffold/run.ts; apps/cli/src/update/run.ts; focused tests beside those modules
  • description: Preserve optional cliVersion and baselineVersion in RepoSettings; write current CLI version and active baseline version through existing scaffold init/setup/update settings write paths. Treat these scaffold-writing flows as the local command-authority acceptance points; read-only commands and tool-check commands do not update pins.
  • validation: Existing scaffold/update tests pass; focused tests assert old settings gain pins after scaffold init/setup/update writes and read-only check paths do not write pins.
  • status: Completed
  • log:
    • 2026-06-30: Added focused RED assertions for settings pins on stage init, scaffold setup, update apply, plus no-mutation check mode; implemented writer-level pin stamping and active-baseline threading; focused suite and CLI typecheck pass.
  • files edited/created: apps/cli/src/core/tools.ts; apps/cli/src/scaffold/stage.ts; apps/cli/src/scaffold/stage.test.ts; apps/cli/src/scaffold/run.ts; apps/cli/src/scaffold/run.test.ts; apps/cli/src/update/run.ts; apps/cli/src/update/run.test.ts
  • backlog_item_id: none
  • backlog_item_url: none
  • relation_mode: none
  • assigned_skills: tdd, codebase-design, simplify, quality-types, turborepo
  • tdd_status: required
  • tdd_target: Public scaffold init/setup/update behavior writes .devpunks/settings.json with cliVersion and baselineVersion; read-only dp check does not mutate them.
  • red_command: bun --cwd apps/cli test src/scaffold/stage.test.ts src/scaffold/run.test.ts src/update/run.test.ts
  • expected_red_failure: Assertions expecting cliVersion/baselineVersion in settings fail before implementation.
  • green_command: bun --cwd apps/cli test src/scaffold/stage.test.ts src/scaffold/run.test.ts src/update/run.test.ts
  • reason_not_testable:
  • red_evidence: bun --cwd apps/cli test src/scaffold/stage.test.ts src/scaffold/run.test.ts src/update/run.test.ts exited 1 before implementation: three assertions failed because .devpunks/settings.json lacked baselineVersion/cliVersion; read-only check-mode no-mutation assertion passed.
  • green_evidence: bun --cwd apps/cli test src/scaffold/stage.test.ts src/scaffold/run.test.ts src/update/run.test.ts passed after implementation: 3 files, 62 tests. bun --cwd apps/cli check-types passed.
  • codebase_design_notes: Keep the settings normalization helper as the single settings schema seam; reuse existing write points instead of inventing a second settings writer.
  • review_mode: cli

T2: Read-only dp check

  • depends_on: [T1]
  • location: apps/cli/src/cli/check-command.ts; apps/cli/src/index.ts; apps/cli/src/core/self-update.ts if tiny formatter helper needed; focused command tests
  • description: Add dp check composes read-only scaffold/baseline drift from runUpdate({ check: true }) read-only CLI drift from autoUpdateCliIfStale, supports JSON, warns changelog summaries, exits nonzero on detected drift.
  • validation: Focused CLI command tests cover command registration, clean exit, CLI drift, baseline drift, JSON output, no-write behavior.
  • status: Complete
  • log:
  • 2026-06-30: Added focused RED assertions for root command registration, clean/CLI/update/baseline drift, JSON wrapper shape, and no-write check-mode composition; implemented dp check as a read-only wrapper over runUpdate({ check: true }) plus autoUpdateCliIfStale; focused suite, CLI typecheck, package check, and runtime help check pass.
  • files edited/created: apps/cli/src/cli/check-command.ts; apps/cli/src/cli/check-command.test.ts; apps/cli/src/index.ts; apps/cli/scripts/assert-dist-commands.mjs
  • backlog_item_id: none
  • backlog_item_url: none
  • relation_mode: none
  • assigned_skills: tdd, codebase-design, simplify, quality-types, turborepo
  • tdd_status: required
  • tdd_target: Public dp check --json reports separate CLI/baseline drift, exits clean when current, exits nonzero when drift exists, performs no writes.
  • red_command: bun --cwd apps/cli test src/cli/check-command.test.ts src/content/content.test.ts
  • expected_red_failure: Assertions fail because command registry lacks check, drift JSON unavailable, or no-write assertion cannot run before implementation.
  • green_command: bun --cwd apps/cli test src/cli/check-command.test.ts src/content/content.test.ts
  • reason_not_testable:
  • red_evidence: bun --cwd apps/cli test src/cli/check-command.test.ts exited 1 before implementation because ./check-command did not exist; importing the registry also exposed the need for an import-safe root command helper.
  • green_evidence: bun --cwd apps/cli test src/cli/check-command.test.ts src/content/content.test.ts passed: 2 files, 25 tests. bun --cwd apps/cli check-types passed. bun --cwd apps/cli check passed. DP_NO_UPDATE_CHECK=1 DP_NO_SKILL_UPDATE_CHECK=1 bun --cwd apps/cli src/index.ts --help | rg "check|update|scaffold" showed root check help.
  • codebase_design_notes: Keep check-command a thin orchestration module over existing runUpdate and self-update seams; JSON wraps the update result under update instead of changing dp update --json.
  • review_mode: cli

T3: Session-start hook retargeting

  • depends_on: [T2]
  • location: apps/cli/src/data/hooks/scaffold-update-check.mjs; apps/cli/src/data/catalog/hooks.ts; generated hook tests/content tests if needed
  • description: Retarget session-start scaffold check hook from dp update --check to dp check, preserving fallback from dp to punks and pre-work warning semantics.
  • validation: node --check apps/cli/src/data/hooks/scaffold-update-check.mjs; hook/content tests pass; generated hook consumer config/mirror inspection confirms session-start invokes the copied hook that runs dp check/punks check.
  • status: Completed
  • log: Added hook assertions for dp check/punks check, no raw update --check, and subagent remediation warning; retargeted session-start scaffold hook to run read-only check through existing CLI fallback.
  • files edited/created: apps/cli/src/data/hooks/scaffold-update-check.mjs; apps/cli/src/data/hooks.test.ts
  • backlog_item_id: none
  • backlog_item_url: none
  • relation_mode: none
  • assigned_skills: tdd, codebase-design, simplify, quality-types, turborepo
  • tdd_status: required
  • tdd_target: Hook source invokes dp check/punks check and warns that accepted remediation belongs in a subagent.
  • red_command: bun --cwd apps/cli test src/content/content.test.ts
  • expected_red_failure: Hook snapshot/string assertion still expects raw update --check.
  • green_command: bun --cwd apps/cli test src/content/content.test.ts src/data/hooks.test.ts src/data/scripts/sync-subagents.test.ts && node --check apps/cli/src/data/hooks/scaffold-update-check.mjs
  • reason_not_testable:
  • red_evidence: bun --cwd apps/cli test src/data/hooks.test.ts exited 1 before hook change: new assertion expected ["dp","check"], received undefined.
  • green_evidence: bun --cwd apps/cli test src/data/hooks.test.ts passed: 1 file, 5 tests. bun --cwd apps/cli test src/content/content.test.ts src/data/hooks.test.ts src/data/scripts/sync-subagents.test.ts passed: 3 files, 29 tests. node --check apps/cli/src/data/hooks/scaffold-update-check.mjs passed.
  • codebase_design_notes: Hook remains a thin shell around CLI drift behavior; command selection is isolated behind a small test seam and still falls back from dp to punks.
  • codebase_design_notes: Preserve the hook as a neutral shell around CLI behavior; avoid duplicating drift logic in hook JavaScript.
  • review_mode: cli

T4: Shared dp-cli skill source-first sync

  • depends_on: []
  • location: /Users/stefan/Desktop/repos/wearedevpunks-skills/skills/agnostic/cli/dp-cli/SKILL.md; /Users/stefan/Desktop/repos/wearedevpunks-skills/skills/agnostic/cli/dp-cli/references/commands.md; /Users/stefan/Desktop/repos/wearedevpunks-skills/skills/agnostic/cli/dp-cli/references/post-command-flow.md; synced Harness skill mirrors
  • description: Document dp check, drift warnings, changelog summaries, .devpunks/settings.json pins, and mandatory subagent remediation in upstream skill source. Push upstream source before syncing Harness because bun run sync:skills fetches from GitHub.
  • validation: git -C /Users/stefan/Desktop/repos/wearedevpunks-skills diff --check; commit/push upstream source; bun run sync:skills; verify apps/cli/.devpunks-cache/skills-sync.json records the pushed commit and Harness mirrors contain the new dp check guidance.
  • status: Complete
  • log:
    • 2026-06-30: Updated upstream dp-cli skill source, committed and pushed wearedevpunks/skills@c0b4378, then ran bun run sync:skills in Harness. Mirror files contain dp check guidance and apps/cli/.devpunks-cache/skills-sync.json records c0b4378576d9f9f5570f0b57d7e14767c2f67f73.
  • files edited/created: /Users/stefan/Desktop/repos/wearedevpunks-skills/skills/agnostic/cli/dp-cli/SKILL.md; /Users/stefan/Desktop/repos/wearedevpunks-skills/skills/agnostic/cli/dp-cli/references/commands.md; /Users/stefan/Desktop/repos/wearedevpunks-skills/skills/agnostic/cli/dp-cli/references/post-command-flow.md; apps/cli/skills/agnostic/cli/dp-cli/SKILL.md; apps/cli/skills/agnostic/cli/dp-cli/references/commands.md; apps/cli/skills/agnostic/cli/dp-cli/references/post-command-flow.md; apps/cli/.devpunks-cache/skills-sync.json
  • backlog_item_id: none
  • backlog_item_url: none
  • relation_mode: none
  • assigned_skills: dp-cli, simplify, writing-shape
  • tdd_status: not_applicable
  • tdd_target: Skill documentation only.
  • red_command:
  • expected_red_failure:
  • green_command: git -C /Users/stefan/Desktop/repos/wearedevpunks-skills diff --check && git -C /Users/stefan/Desktop/repos/wearedevpunks-skills push && bun run sync:skills
  • reason_not_testable: Documentation/source sync change.
  • red_evidence:
  • green_evidence: git -C /Users/stefan/Desktop/repos/wearedevpunks-skills diff --check passed. git -C /Users/stefan/Desktop/repos/wearedevpunks-skills commit -m "docs: document dp check update enforcement" created c0b4378 and git -C /Users/stefan/Desktop/repos/wearedevpunks-skills push origin main succeeded. bun run sync:skills fetched c0b4378 and synced Harness mirrors.
  • codebase_design_notes: Treat shared skill repo as source of truth; Harness mirrors are generated consumers.
  • review_mode: cli

T5: Operator docs and wiki ingest

  • depends_on: [T1, T2, T3, T4]
  • location: docs/README.md; docs/runbooks/dp-cli-scaffolding.md; apps/wiki/content/docs/cli/scaffold-lifecycle/scaffold-update.mdx; apps/wiki/content/docs/cli/scaffold-lifecycle/scaffold-manifest.mdx; apps/wiki/content/docs/harness/validation-and-tools/hooks.mdx; apps/wiki/content/docs/get-started/basic-usage.mdx; spec/implementation notes/log
  • description: Use docs-ingest-phase expectations to align operator docs and routed wiki mirrors with delivered version pins, dp check, session-start warning, changelog summaries, and subagent-owned remediation.
  • validation: bun run --cwd apps/wiki check-types; git diff --check.
  • status: Complete
  • log:
    • 2026-06-30: Updated root docs, scaffolding runbook, and routed wiki pages for dp check, .devpunks/settings.json version pins, session-start hook behavior, changelog summaries, and subagent-owned remediation.
  • files edited/created: docs/README.md; docs/runbooks/dp-cli-scaffolding.md; apps/wiki/content/docs/cli/scaffold-lifecycle/scaffold-update.mdx; apps/wiki/content/docs/cli/scaffold-lifecycle/scaffold-manifest.mdx; apps/wiki/content/docs/harness/validation-and-tools/hooks.mdx; apps/wiki/content/docs/get-started/basic-usage.mdx; apps/wiki/log.md
  • backlog_item_id: none
  • backlog_item_url: none
  • relation_mode: none
  • assigned_skills: docs-ingest-phase, docs-onboarding, writing-shape, simplify, quality-types
  • tdd_status: not_applicable
  • tdd_target: Documentation only.
  • red_command:
  • expected_red_failure:
  • green_command: bun run --cwd apps/wiki check-types && git diff --check
  • reason_not_testable: Docs-only task.
  • red_evidence:
  • green_evidence: pending validation in T6 integration gate.
  • codebase_design_notes: Keep stable CLI mechanics in wiki and operational workflow in root docs/runbook.
  • review_mode: cli

T6: Integration validation and fixups

  • depends_on: [T1, T2, T3, T4, T5]
  • location: full touched surface
  • description: Reconcile worker outputs, resolve conflicts, run focused CLI/wiki validation, perform mandatory no-write dp check smoke, and update task evidence in this plan.
  • validation: Focused CLI tests, CLI typecheck/check if available, wiki check-types, git diff --check, and temp-project dp check --json smoke that snapshots .devpunks plus managed files before/after and asserts no content/hash changes.
  • status: Complete
  • log:
    • 2026-06-30: Reconciled command, hook, settings pins, skill sync, and docs; added top-level command guide coverage for punks check; ran focused CLI/docs validation and temp no-write smoke.
    • 2026-06-30: Fixed review blockers: packaged CLI dist now includes root CHANGELOG.md and BASELINE_CHANGELOG.md; dp check now compares .devpunks/settings.json cliVersion and baselineVersion pins and includes settings in JSON.
  • files edited/created: full touched surface in T1-T5 plus apps/cli/src/ui/brand.ts; apps/cli/src/ui/brand.test.ts
  • backlog_item_id: none
  • backlog_item_url: none
  • relation_mode: none
  • assigned_skills: tdd, quality-types, turborepo, autoreview
  • tdd_status: recovered
  • tdd_target: Integration behavior from T1-T3 remains covered through focused tests.
  • red_command: See T1-T3.
  • expected_red_failure: See T1-T3.
  • green_command: bun --cwd apps/cli test src/cli/check-command.test.ts src/scaffold/stage.test.ts src/scaffold/run.test.ts src/update/run.test.ts src/content/content.test.ts src/data/hooks.test.ts src/data/scripts/sync-subagents.test.ts && bun --cwd apps/cli check-types && bun run --cwd apps/wiki check-types && git diff --check && <temp-project dp check --json no-write smoke>
  • reason_not_testable:
  • red_evidence:
  • green_evidence: bun --cwd apps/cli test src/cli/check-command.test.ts src/scaffold/stage.test.ts src/scaffold/run.test.ts src/update/run.test.ts src/content/content.test.ts src/data/hooks.test.ts src/data/scripts/sync-subagents.test.ts passed 7 files, 97 tests. bun --cwd apps/cli test src/ui/brand.test.ts src/cli/check-command.test.ts src/content/content.test.ts src/data/hooks.test.ts src/data/scripts/sync-subagents.test.ts passed 5 files, 36 tests. bun --cwd apps/cli check-types passed. bun --cwd apps/cli check passed. bun run --cwd apps/wiki check-types passed on rerun after a transient empty generated .source/server.ts. git diff --check passed. Temp-project dp check --json --baseline bundled no-write smoke passed: .devpunks and .agents hashes unchanged; payload had failed, cli, and update; command exited 1 because drift was detected.
  • codebase_design_notes: Parent integration owns cross-task consistency and prevents duplicated drift logic across command, update, and hook surfaces.
  • review_mode: cli

T7: Mandatory review and closeout

  • depends_on: [T6]
  • location: full touched surface
  • description: Run code review, address in-scope findings, complete docs-ingest/implementation notes, update closeout evidence, and final report.
  • validation: Review findings resolved or explicitly parked; implementation notes and wiki log reflect delivered state.
  • status: Planned
  • log:
  • files edited/created:
  • backlog_item_id: none
  • backlog_item_url: none
  • relation_mode: none
  • assigned_skills: review-phase, docs-ingest-phase, autoreview, simplify
  • tdd_status: not_applicable
  • tdd_target: Review/closeout task.
  • red_command:
  • expected_red_failure:
  • green_command: final validation command set from T6 plus review pass
  • reason_not_testable: Review and closeout task.
  • red_evidence:
  • green_evidence:
  • codebase_design_notes: Closeout records behavior and validation, not a new implementation seam.
  • review_mode: cli

Risks and Mitigations

  • Risk: dp check accidentally mutates scaffold files. Mitigation: only call runUpdate in check mode; include tests/JSON checks that no writes happen.
  • Risk: CLI and baseline changelog summaries become overbuilt. Mitigation: render compact latest relevant release sections and keep full changelog as source link/path.
  • Risk: parallel workers overlap. Mitigation: only T1 and upstream T4 source edits run initially; command, hook, docs, sync, and integration are sequenced by dependency.
  • Risk: shared skill sync introduces unrelated drift. Mitigation: inspect upstream and Harness diffs after bun run sync:skills; keep only intended changes.

Validation Gates

  • bun --cwd apps/cli test src/cli/check-command.test.ts src/scaffold/stage.test.ts src/scaffold/run.test.ts src/update/run.test.ts src/content/content.test.ts
  • bun --cwd apps/cli test src/data/hooks.test.ts src/data/scripts/sync-subagents.test.ts
  • bun --cwd apps/cli check-types
  • node --check apps/cli/src/data/hooks/scaffold-update-check.mjs
  • bun run --cwd apps/wiki check-types
  • git -C /Users/stefan/Desktop/repos/wearedevpunks-skills diff --check
  • git -C /Users/stefan/Desktop/repos/wearedevpunks-skills push
  • bun run sync:skills
  • temp-project dp check --json no-write smoke
  • git diff --check

Unresolved Questions

None.

On this page