Harness Intelligence Wiki
Research

Lefthook Commit Gate Delivery Planning Research

Lefthook Commit Gate Delivery Planning Research

Scope

Read-only planning discovery for Linear Story IP-425 and Task IP-426. The accepted spec, grill status, and glossary remain requirements authority.

Research lanes

LaneCoveragePrimary evidence
Policy and contextProject Settings, repository analysis, catalogue compilation, Quality Command Contract gapapps/cli/src/features/project-settings/{model,service}.ts; apps/cli/src/features/repository-analysis/model.ts; apps/cli/src/features/context-planning/compiler.ts; packages/scaffold/src/{catalog,context-plan}.ts
Scaffold and receiptsDesired state, structured merge, managed receipt, handoff and live-proof gapapps/cli/src/features/scaffold-state/{reconcile,receipt}.ts; apps/cli/src/scaffold/output.ts; apps/cli/src/update/run.ts; apps/cli/src/content/scaffold-copy.ts
Hook runtimeStaged owner selection and Lefthook install/config/run/uninstall behaviorapps/cli/scripts/staged-verification-selector.mjs; .githooks/pre-commit; exact Lefthook 2.1.10 source
Check and docsRead-only check, JSON/facts/rendering, health vocabulary, docs/release gatesapps/cli/src/features/repository-check/*; apps/cli/src/platform/repository-check-capabilities.ts; apps/cli/src/presentation/operation-result/repository-check-facts.ts; docs/runbooks/hi-cli-scaffolding.md

Trusted facts

Durable policy and compilation

  • ProjectSettingsDocument has no commitGate. Writes start from the raw decoded object, so known-field changes preserve unrelated keys. Initialization and reconfiguration need typed policy support (apps/cli/src/features/project-settings/model.ts:12-31; service.ts:292-400).
  • hi ensure is settings-only today, matching the accepted policy-only command boundary (apps/cli/src/cli/ensure-command.ts:17-75).
  • ContributionKind has no Commit Gate family, and catalogue hooks are AI-agent lifecycle hooks only (packages/scaffold/src/context-plan.ts:8-15; apps/cli/src/data/catalog/hooks.ts:1-26). Reusing lifecycle-hook would violate the accepted boundary.
  • Repository manifest evidence lacks package-manager, lockfile, and quality-command fields (apps/cli/src/features/repository-analysis/model.ts:20-31). Context compilation cannot yet prove applicability or compile a complete Quality Command Contract.
  • Lint catalogue entries contain configuration/dependency metadata, not executable lint and read-only format-check commands (apps/cli/src/data/catalog/lint.ts:25-43). Runtime package-script discovery would create a second authority.

Desired state, coexistence, and proof

  • packages/scaffold owns behavior-free shared contracts. CLI materialization belongs to apps/cli/src/scaffold/output.ts; reconciliation belongs to apps/cli/src/update/run.ts.
  • Reconciliation already preserves consumer-owned structured entries and removes only receipt-proven HI entries. This is the correct pattern for the one owned Lefthook lint command (apps/cli/src/update/run.ts:1910-1963; apps/cli/src/features/scaffold-state/reconcile.ts:185-256).
  • Managed scaffold and AI projection receipts do not prove an installed Git hook or completed agent follow-through (apps/cli/src/features/scaffold-state/receipt.ts:55-104; apps/cli/src/scaffold/output.ts:2367-2385). The Commit Gate Lifecycle Receipt must remain separate.
  • .devpunks/AGENT-HANDOFF.md already carries post-scaffold work but has no Commit Gate verification section (apps/cli/src/content/scaffold-copy.ts:243-381).

Staged execution and Lefthook 2.1.10

  • staged-verification-selector.mjs is NUL-safe, accounts for both rename paths, maps apps/* and packages/* owners, falls back for global paths, and spawns nothing for empty staged scope (apps/cli/scripts/staged-verification-selector.mjs:19-113). It is Harness-specific, sequential, and fail-fast, so it is not the consumer runner required by the spec.
  • Lefthook npm 2.1.10 runs node postinstall.js, which runs lefthook install -f from INIT_CWD or the current directory. Dependency installation can reactivate hooks unless policy and migration preflight prevent materialization.
  • Lefthook rejects custom local/global core.hooksPath by default. Force/reset can replace consumer behavior, so automatic force/reset is forbidden.
  • Plain lefthook uninstall removes Lefthook-owned hooks and keeps config. It is safe only when evidence proves HI is sole owner.
  • Hook-level parallel: true completes and collects all jobs; empty staged lists skip jobs. piped: true is fail-fast and unsuitable.

Read-only health and evidence

  • hi check uses check: true, write: false, yes: false (apps/cli/src/cli/check-command.ts:24-99; apps/cli/src/platform/feature-application-operations.ts:193-205). Commit Gate health must preserve this.
  • RepositoryCheckResult has no Commit Gate health. Facts, JSON, terminal rendering, and remediation guidance must change together (apps/cli/src/features/repository-check/application.ts:34-52; apps/cli/src/presentation/operation-result/repository-check-facts.ts; apps/cli/src/ui/renderer.ts).
  • Accepted states are disabled, healthy, unresolved handoff, dependency drift, missing/changed lint, missing/wrong hook, and conflicting manager. Current health must not claim historical bypass detection.
  • CLI workflow/setup changes require docs/README.md and docs/runbooks/hi-cli-scaffolding.md. Changelog changes select the release path and require classifier readback.

Design alternatives

  1. Extend broad existing modules directly. This minimizes new files but spreads policy, desired state, observed health, proof, and recovery across callers; it also risks overloading managed receipts.
  2. Add one deep features/commit-gate boundary. Keep shared schemas in packages/scaffold, policy in project-settings, compilation in repository analysis/context planning, and raw filesystem/Git/package-manager/process mechanics in adapters. Existing scaffold/update/check callers consume one typed feature result.

Select option 2. It keeps one semantic owner, supports deterministic failure-path tests, and preserves desired-state versus live-proof boundaries.

Uncertainty and conclusion

  • The connected Linear tool exposes only Collective Intelligence, not Devpunks IP-*. The same-day handoff retains the exact IP-425/IP-426 hierarchy and V4.1 membership, but live provider readback remains required before mutation/closeout.
  • No implementation, PR, CI run, lifecycle receipt, or real consumer Git evidence exists.
  • The change is architecture-bearing. IP-426 is one provider Task, so one worker must deliver vertical RED/GREEN cycles inside one behavior-complete architecture wave, with no temporary seam.

On this page