Lefthook Pre-Commit Catalogue Grill Log
Lefthook Pre-Commit Catalogue Grill Log
Source Intent
The user supplied these starting requirements on 2026-08-27:
- integrate Lefthook as tooling for HI Catalogue consumers;
- enable it by default and expose an opt-out in
hi initorhi ensure; - make the first rule require lint and format success before commit.
The research report is evidence, not an accepted product decision: Lefthook Pre-Commit Catalogue Integration Research.
Branch: Product Identity
Q1
Prerequisites:
- none
Evidence anchor:
https://www.npmjs.com/package/lefthook/v/2.1.10
Observed constraint:
left-hookis not a published npm package.lefthookis the researched Evil Martians package.
Question:
Does “left-hook” mean the published Evil Martians lefthook package?
Recommendation:
- Yes. Use Lefthook for the product and
lefthookfor the package and executable.
Accepted answer:
- Yes. “left-hook” means the published Evil Martians Lefthook product and
lefthookpackage and executable.
Code consequence:
- This selects the dependency identity, executable, upstream configuration contract, and version source.
State: answered.
Branch: Durable Opt-Out Enforcement
Q16
Prerequisites:
- Q6, Q8, Q11, Q12
Evidence anchor:
- Lefthook npm package
package.json:postinstall - Lefthook npm package
postinstall.js - Lefthook 2.1.10
docs/configuration/no_auto_install.md - Lefthook 2.1.10
docs/configuration/skip.md
Observed constraint:
- The npm package runs
lefthook install -fduring package installation unless CI suppresses it.no_auto_installonly disables synchronization duringlefthook run; it does not disable npm postinstall. - Keeping the dependency with an active HI pre-commit command can therefore recreate executable hook state after the user opted out.
Question:
Should $hi-cli make manual opt-out durable by removing the project-local
Lefthook dependency and uninstalling it when HI is the sole owner, while a
shared consumer-owned Lefthook setup keeps the dependency and removes or marks
only the HI pre-commit command skip: true?
Recommendation:
- Yes. Persist policy first, then let the agent apply the ownership-safe path. Future scaffold/update must not re-add the dependency, command, or install action while opted out.
Accepted answer:
- Yes. Persist Commit Gate Opt-Out before any manual disable work.
- When HI is the sole Lefthook owner, the
$hi-cliagent removes the project-local Lefthook dependency and runs plainlefthook uninstall. - When the consumer shares ownership of Lefthook, the agent keeps the
dependency and removes only the HI pre-commit command or sets that command to
skip: true. - While the project remains opted out, scaffold/update must not restore an HI-owned dependency, command, configuration, or installation action.
Code consequence:
- This prevents npm postinstall from reviving a sole-owned gate and preserves consumer-owned Lefthook usage when ownership is shared.
State: answered.
Glossary Q16
Question:
How does persisted Commit Gate Opt-Out relate to manual disable work?
Accepted answer:
- Axiom: persisting Commit Gate Opt-Out does not itself mutate current hook
state; the
$hi-cliagent performs separate ownership-aware disable work. - Axiom: future scaffold/update must not restore the HI-owned Commit Gate while Commit Gate Opt-Out remains selected.
Branch: Migration Before Dependency Installation
Q17
Prerequisites:
- Q9, Q13
Evidence anchor:
- Lefthook npm package
postinstall.js - Lefthook 2.1.10
cmd/install.go:force - Lefthook 2.1.10
internal/command/install.go:ensureHooksPathUnset
Observed constraint:
- npm postinstall invokes
lefthook install -f. The force flag can proceed in an existing customcore.hooksPath, before an agent has reviewed or migrated the current manager.
Question:
When another hook manager is detected, should scaffold defer the Lefthook dependency, configuration, and installation, return migration evidence for the agent, and materialize only after the agent completes an authorized migration and reruns scaffold?
Recommendation:
- Yes. Do not allow package lifecycle scripts to perform the migration before
$hi-cliguidance and agent review.
Accepted answer:
- Yes. Scaffold must detect another hook manager before it adds the Lefthook dependency, configuration, or installation action.
- Scaffold defers materialization and returns migration evidence to the
$hi-cliagent. - After the agent completes an authorized migration, the agent reruns scaffold to materialize the Commit Gate from the updated repository state.
Code consequence:
- Existing-manager detection becomes a pre-dependency materialization gate; migration remains agent-owned and scaffold resumes from updated repository evidence.
State: answered.
Glossary Q17
Question:
When can Commit Gate materialization start after another hook manager is detected?
Accepted answer:
- Relationship: a Hook Migration Proposal and authorized agent migration precede Lefthook dependency, configuration, and installation materialization.
- Axiom: package lifecycle scripts must not perform an unreviewed hook-manager migration.
Branch: Persisted Policy Shape
Q18
Prerequisites:
- Q3, Q7, Q12, Q16
Evidence anchor:
apps/cli/src/features/project-settings/model.ts:ProjectSettingsDocumentapps/cli/src/features/project-settings/service.ts:writeProjectSettings
Observed constraint:
- Project Settings use typed persisted values and currently have no Commit Gate
field. The integration is default-on, but an explicit opt-out must survive
later scaffold runs.
hi ensuredoes not materialize scaffold state.
Question:
Should Project Settings store commitGate: "enabled" | "disabled", treat an
absent field as the default enabled policy, and wait until the next
scaffold-capable command to materialize a re-enable?
Recommendation:
- Yes. Keep one two-state policy.
hi initandhi ensurepersist it; scaffold and update consume it; check reports it read-only.
Accepted answer:
- Yes. Project Settings store
commitGate: "enabled" | "disabled". - An absent field means the default enabled policy for existing consumers.
hi initandhi ensurepersist the policy without materializing it.- The next scaffold-capable command materializes a re-enable;
hi checkonly reports the current policy and health.
Code consequence:
- This determines the settings schema, backward-compatible default, command ownership, and re-enable lifecycle.
State: answered.
Branch: Existing Lefthook Configuration
Q19
Prerequisites:
- Q4, Q9, Q13, Q16, Q17
Evidence anchor:
- Lefthook configuration supports multiple named commands under
pre-commit - scaffold structured-entry and receipt ownership model
Observed constraint:
- A consumer can already use Lefthook for its own hooks and commands. Replacing the full configuration would destroy consumer-owned behavior; silently choosing a colliding command name would hide a real ownership conflict.
Question:
When Lefthook already exists, should the $hi-cli agent propose a structured
merge of one named HI pre-commit command, preserve every consumer-owned entry,
and return any command-name or semantic conflict for user decision?
Recommendation:
- Yes. Give HI one owned command boundary. Do not replace the consumer's full hook or config.
Accepted answer:
- Yes. Preserve every consumer-owned Lefthook command and configuration entry.
- HI adds one owned pre-commit command named exactly
lint; do not usehi-quality. - If
lintalready exists or the merge is otherwise unsafe, the agent returns the conflict for user decision and does not overwrite consumer state.
Code consequence:
- This fixes the merge seam, receipt granularity, drift boundary, and conflict behavior for shared Lefthook ownership.
State: answered.
Glossary Q19
Question:
What command does HI own inside an existing Lefthook pre-commit configuration?
Accepted answer:
- Axiom: HI's owned Lefthook pre-commit command is named exactly
lint. - Relationship: the Commit Gate preserves consumer-owned Lefthook entries
and adds the HI-owned
lintcommand; unsafe conflicts require user decision.
Branch: Install And Clone Recovery
Q20
Prerequisites:
- Q8, Q12, Q14, Q17
Evidence anchor:
- Lefthook npm package
package.json:postinstall - Lefthook npm package
postinstall.js - Lefthook 2.1.10
docs/usage/commands/install.md - scaffold dependency and check boundaries
Observed constraint:
- Package lifecycle scripts can install the hook after dependency installation, but CI, ignored scripts, pnpm build-script policy, or a failed postinstall can suppress that action. Configuration and dependency presence do not prove that the Git hook is installed.
Question:
After conflict preflight, should scaffold materialize configuration and the
dependency, satisfy the detected package manager's lifecycle requirements, and
explicitly verify hook installation, while hi check performs only a read-only
installation-health check?
Recommendation:
- Yes. Treat installation as explicit scaffold health. Do not infer it from the
package or config alone, and do not let
hi checkrepair it.
Accepted answer:
- Scaffold can emit the remaining package-manager lifecycle work and hook
installation verification to the
$hi-cliagent as a post-command handoff. - The agent consumes that handoff, completes the required follow-through, and verifies that the Git hook is installed.
hi checkremains read-only and does not repair installation state.
Code consequence:
- This moves imperative install follow-through and proof to the agent after the scaffold command, while preserving the CLI's evidence output and the read-only check boundary. Receipt completion semantics remain for a later frontier.
State: answered.
Glossary Q20
Question:
What carries required installation follow-through from scaffold to the agent?
Accepted answer:
- Canonical term: Post-Command Handoff — structured scaffold output that
tells the
$hi-cliagent which lifecycle work and verification remain after the CLI command returns. - Relationship: scaffold emits a Post-Command Handoff; the agent completes the work and verifies hook installation.
Branch: Quality Command Execution
Q21
Prerequisites:
- Q2, Q10, Q15
Evidence anchor:
apps/cli/scripts/staged-verification-selector.mjs- Lefthook parallel command execution and failure output
Observed constraint:
- Lint and format-check are independent read-only commands over the same selected scope. Sequential fail-fast execution can hide the second failure and makes the user repeat the commit only to discover it.
Question:
Should the Commit Gate run lint and format-check in parallel and report both failures from the same attempt?
Recommendation:
- Yes. Both commands are required and read-only, so one attempt should return all available repair evidence.
Accepted answer:
- Yes. Commit Gate runs lint and format-check in parallel and reports both failures from the same commit attempt.
Code consequence:
- This determines execution topology, failure aggregation, and local feedback behavior.
State: answered.
Branch: Empty Applicable Scope
Q22
Prerequisites:
- Q10, Q15
Evidence anchor:
apps/cli/scripts/staged-verification-selector.mjs- Quality Command Contract applicability boundary
Observed constraint:
- A commit can contain only paths that do not map to an applicable Quality Command Contract. Starting repository tools in that case provides no quality signal and can create false failures.
Question:
Should an empty or non-applicable staged scope make the Commit Gate succeed without starting lint or format-check?
Recommendation:
- Yes. No applicable contract means there is no local gate work for that commit; CI retains repository-wide authority.
Accepted answer:
- Yes. An empty or non-applicable staged scope succeeds without starting lint or format-check. CI retains repository-wide authority.
Code consequence:
- This fixes the no-op invariant and avoids unnecessary tool execution for non-applicable commits.
State: answered.
Branch: Multi-Owner Command Dispatch
Q23
Prerequisites:
- Q10, Q15, Q21, Q22
Evidence anchor:
apps/cli/scripts/staged-verification-selector.mjs:workspaceForPathapps/cli/scripts/staged-verification-selector.mjs:runStagedVerification- Quality Command Contract
Observed constraint:
- One commit can contain staged paths from several workspace owners. The current selector groups those owners but has no Quality Command Contract routing and stops at the first failed command.
- Equal command text does not prove equal execution scope; two workspaces can require separate runs even when their commands look the same.
Question:
When staged paths have several owners, should the HI-owned lint command run
each applicable owner's complete Quality Command Contract exactly once and
avoid deduplicating contracts only because their command text matches?
Recommendation:
- Yes. Preserve workspace ownership. Run every applicable owner's lint and format-check, aggregate all failures, and deduplicate only when the compiled contract explicitly identifies one shared execution scope.
Accepted answer:
- Yes. The HI-owned
lintcommand runs every applicable owner's complete Quality Command Contract exactly once. - Matching command text does not deduplicate contracts across owners.
- Deduplication is allowed only when compiled contract evidence identifies one shared execution scope.
- All attempted failures are aggregated for the same commit attempt.
Code consequence:
- This defines polyglot and multi-workspace fan-out, command identity, and cross-owner failure aggregation.
State: answered.
Branch: Deliberate Bypass Reporting
Q24
Prerequisites:
- Q5
Evidence anchor:
- Git
--no-verifybehavior - Lefthook
LEFTHOOK=0behavior apps/cli/src/features/repository-check/application.ts
Observed constraint:
git commit --no-verifyprevents the pre-commit hook from running, andLEFTHOOK=0is temporary process state. A standard Git commit does not record whether either bypass occurred.hi checkcan inspect current Commit Gate health, but it cannot reconstruct historical bypasses without a new attestation or telemetry system.
Question:
Should HI avoid adding bypass telemetry or attestations, report only current Commit Gate health, and make no claim that it can detect historical deliberate bypasses?
Recommendation:
- Yes. Keep the accepted local-gate boundary honest. CI remains merge authority; historical bypass detection is outside the Commit Gate promise.
Accepted answer:
- Yes. HI adds no historical bypass telemetry or attestation system.
- HI reports only current Commit Gate health and does not claim that it can
detect past
--no-verifyorLEFTHOOK=0use. - CI remains merge authority.
Code consequence:
- This sets the observability boundary and avoids introducing a separate commit attestation system.
State: answered.
Branch: Post-Command Handoff Completion
Q25
Prerequisites:
- Q8, Q14, Q19, Q20
Evidence anchor:
apps/cli/src/features/scaffold-state/receipt.ts:advanceManagedScaffoldReceiptapps/cli/src/features/repository-check/port.ts:RepositoryCheckResult$hi-cliscaffold post-command flow
Observed constraint:
- Current managed scaffold receipts record files, dependencies, structured entries, and known degradations. They do not prove that an agent consumed a Post-Command Handoff or installed a Git hook.
Question:
Should a Post-Command Handoff become complete only after the agent verifies the
exact pinned Lefthook dependency, the active lint command in configuration,
and the installed Git hook that resolves to Lefthook?
Recommendation:
- Yes. Require observed runtime facts. The handoff file alone proves that work was requested, not that the Commit Gate is operational.
Accepted answer:
- Yes. A Post-Command Handoff becomes complete only after the agent verifies
the exact pinned Lefthook dependency, the active
lintcommand in the Lefthook configuration, and the installed Git hook that resolves to Lefthook. - The handoff artifact alone does not prove operational Commit Gate health.
Code consequence:
- This defines installation completion evidence and the boundary between materialized desired state and operational health.
State: answered.
Branch: Unresolved Handoff State
Q26
Prerequisites:
- Q20
Evidence anchor:
apps/cli/src/features/scaffold-state/receipt.ts:advanceManagedScaffoldReceiptapps/cli/src/features/scaffold-state/apply.ts:applyScaffoldReconciliation$hi-cliscaffold completion criterion
Observed constraint:
- The scaffold command returns before agent follow-through. It cannot later change its process exit status if the agent does not consume the handoff or installation fails.
- Treating the managed files as complete would hide an inoperable Commit Gate.
Question:
Should missing or failed agent follow-through remain a distinct unresolved
Post-Command Handoff state, so the $hi-cli scaffold branch is incomplete even
when the CLI write command itself succeeded?
Recommendation:
- Yes. Preserve both facts: the CLI write succeeded, but the Commit Gate is not operational. Do not collapse this into a successful receipt or a generic warning.
Accepted answer:
- Yes. Missing or failed agent follow-through remains a distinct unresolved Post-Command Handoff state.
- The CLI write can be successful while the
$hi-cliscaffold branch remains incomplete because the Commit Gate is not operational. - An unresolved handoff is neither a successful receipt nor a generic warning.
Code consequence:
- This defines failure ownership, recovery continuity, and branch completion semantics across the CLI-to-agent boundary.
State: answered.
Branch: Read-Only Commit Gate Health
Q27
Prerequisites:
- Q12, Q16, Q17, Q19, Q20
Evidence anchor:
apps/cli/src/features/repository-check/port.ts:RepositoryCheckResultapps/cli/src/features/repository-check/application.ts$hi-clicheck post-command flow
Observed constraint:
- Current
hi checkreports one general repository drift issue and has no Commit Gate health model. It cannot distinguish policy-disabled, handoff pending, dependency drift, config drift, missing hook, or manager conflict.
Question:
Should hi check report these Commit Gate states separately and read-only:
policy disabled, healthy, unresolved handoff, dependency/version drift,
missing or changed lint command, hook missing or pointing elsewhere, and
conflicting hook manager?
Recommendation:
- Yes. Report the exact observed state and return the matching scaffold or
$hi-cliagent follow-through guidance; never repair it fromhi check.
Accepted answer:
- Yes.
hi checkreports Commit Gate policy disabled, healthy, unresolved handoff, dependency or version drift, missing or changedlintcommand, hook missing or pointing elsewhere, and conflicting hook manager as separate read-only states. - Each unhealthy state returns the matching scaffold or
$hi-cliagent follow-through guidance. hi checknever repairs Commit Gate state.
Code consequence:
- This defines the health vocabulary, diagnostic contract, and non-mutating remediation boundary.
State: answered.
Glossary Q23-Q27
Question:
Which execution and operational-health invariants are now fixed?
Accepted answer:
- Axiom: each applicable workspace owner runs its complete Quality Command Contract exactly once unless compiled evidence identifies one shared execution scope.
- Axiom: HI reports current Commit Gate health but does not claim historical deliberate-bypass detection.
- Relationship: a Post-Command Handoff becomes complete only after the agent verifies dependency, configuration, and installed-hook facts.
- Axiom: failed or missing agent follow-through remains an unresolved
Post-Command Handoff and keeps the
$hi-cliscaffold branch incomplete. - Axiom:
hi checkreports exact Commit Gate health states without repair.
Branch: Operational Evidence Authority
Q28
Prerequisites:
- Q25, Q26, Q27
Evidence anchor:
apps/cli/src/features/scaffold-state/reconcile.ts:ManagedScaffoldReceiptapps/cli/src/features/scaffold-state/receipt.ts:advanceManagedScaffoldReceiptapps/cli/src/update/run.ts:persistReceipt
Observed constraint:
- The managed scaffold receipt proves ownership of dependencies, files, and structured entries. It has no lifecycle or runtime-health evidence channel.
- Operational proof can become stale when the Commit Gate policy, pinned
dependency,
lintentry, configuration, installed hook, or applicable owner scope changes.
Question:
Should Post-Command Handoff completion use a separate durable Commit Gate lifecycle receipt, bound to the exact desired-state fingerprint and live Q25 proof, while the managed scaffold receipt remains limited to managed entries and degradations?
Recommendation:
- Yes. Keep ownership evidence separate from operational evidence. Any relevant desired or observed change makes the lifecycle proof stale and requires agent re-verification.
Accepted answer:
- Yes. Post-Command Handoff completion is persisted in a separate durable Commit Gate Lifecycle Receipt.
- The receipt is bound to the exact desired-state fingerprint and the live Q25 dependency, configuration, and installed-hook proof.
- A relevant desired or observed change makes the proof stale and requires agent re-verification.
- The managed scaffold receipt remains limited to managed entries and degradations.
Code consequence:
- This fixes persistence authority, proof invalidation, and the boundary between scaffold ownership and operational Commit Gate health.
State: answered.
Branch: Non-Package-Manager Consumers
Q29
Prerequisites:
- Q2, Q8, Q14
Evidence anchor:
apps/cli/src/integrations/repository-detector.tsapps/cli/src/scaffold/output.ts:lintTargetManifestsapps/cli/src/update/run.ts:dependencyLockfileCommand
Observed constraint:
- HI detects Python-only repositories that have no
package.json. - Current project dependency planning and lockfile reconciliation support Bun,
pnpm, npm, and Yarn. A Python-only repository has no target for the accepted
project-local
lefthookdev dependency. - Therefore “all HI Catalogue consumers” is broader than the Q8 installation contract.
Question:
Should Commit Gate applicability exclude Python-only and other consumers that lack a supported JavaScript package-manager and lockfile path, or must HI add a second project-local Lefthook installation authority for them?
Recommendation:
- Exclude them from this integration and report Commit Gate as non-applicable. This preserves Q8 and avoids adding a global or unpinned installation model. Choose the second authority only if “all consumers” must remain literal.
Accepted answer:
- For now, exclude Python-only and other consumers that lack a supported JavaScript package-manager and lockfile path.
- Commit Gate is non-applicable for those consumers.
- HI does not add a second installation or version-authority model in this integration.
Code consequence:
- This sets the final consumer boundary or expands dependency ownership into a second installation and version-authority model.
State: answered.
Glossary Q28-Q29
Question:
What terms close operational evidence authority and consumer applicability?
Accepted answer:
- Canonical term: Commit Gate Lifecycle Receipt — durable operational proof bound to the exact desired Commit Gate state and the agent-verified dependency, configuration, and installed-hook facts.
- Canonical term: Commit Gate Consumer — an HI Catalogue consumer with a supported JavaScript package-manager and lockfile path plus a complete Quality Command Contract.
- Relationship: the managed scaffold receipt proves HI-owned desired state; the Commit Gate Lifecycle Receipt proves operational Commit Gate health.
- Axiom: Python-only and other consumers without a supported JavaScript package-manager and lockfile path are not Commit Gate Consumers for this integration.
Final Domain Consistency Pass
- The original “all HI Catalogue consumers” source wording is narrowed by Q29 to all Commit Gate Consumers.
- “Format passes” means the accepted read-only format-check command; Commit Gate never formats or restages files.
- Lint assets, the agent-time
format-edited-filelifecycle hook, and the Quality Command Contract remain separate concepts. - The managed scaffold receipt and Commit Gate Lifecycle Receipt have separate authorities. No accepted axiom assigns operational health to the managed scaffold receipt.
- No unanswered requirement or contradictory accepted axiom remains.
Shared Understanding Confirmation
- Confirmed by the user on 2026-09-01.
- The requirements frontier is closed with no parked branch.
- The canonical glossary and accepted decisions are ready for
create-spec.
Branch: Manual Disable Guidance
Q11
Prerequisites:
- Q6, Q9
Evidence anchor:
- Lefthook 2.1.10
docs/usage/commands/uninstall.md - Lefthook 2.1.10
internal/command/uninstall.go:Uninstall
Observed constraint:
- Plain
lefthook uninstallremoves all Lefthook-managed Git hooks, restores saved.oldhooks, removes its checksum/remotes state, and uninstalls Lefthook-managed AI hooks. It keeps configuration unless--remove-configsis supplied.--forcecan remove non-Lefthook hooks. - A consumer may use Lefthook for work beyond the HI Commit Gate, so blanket uninstall can exceed opt-out scope.
Question:
Should $hi-cli give ownership-aware disable guidance: use plain
lefthook uninstall only when receipts prove HI is the sole Lefthook owner, and
otherwise guide removal or disabling of only the HI-managed pre-commit entry?
Recommendation:
- Yes. Never recommend
--forceor--remove-configs. Preserve consumer-owned Lefthook hooks, configuration, and dependency.
Accepted answer:
- Yes.
$hi-cligives ownership-aware disable guidance. Plainlefthook uninstallis suggested only when receipts prove HI is the sole Lefthook owner. Guidance never suggests--forceor--remove-configs.
Code consequence:
- Guidance must inspect receipt and coexistence evidence before selecting the disable path; one unconditional command is not safe.
State: answered.
Branch: Policy Consumption
Q12
Prerequisites:
- Q6, Q7
Evidence anchor:
$hi-cliScaffold, Check, Ensure, and Update branchesapps/cli/src/scaffold/stage.tsapps/cli/src/update/run.ts
Observed constraint:
hi ensurenow only records intent.hi scaffoldmaterializes hooks;hi update --writerefreshes managed hook inputs;hi checkis read-only.
Question:
Should hi scaffold and hi update --write consume Commit Gate Opt-Out by
skipping every install/reactivation action, while hi check reports the policy
and never treats the intentionally disabled installed hook as repairable drift?
Recommendation:
- Yes. Keep ensure settings-only and check read-only. Materializing commands must honor the policy without undoing the user's manual disable action.
Accepted answer:
- Yes.
hi scaffoldandhi update --writeskip Commit Gate installation and reactivation when opted out.hi checkreports the policy and does not treat the intentionally disabled installed hook as repairable drift.
Code consequence:
- This defines policy flow across commands and prevents update/check loops from reactivating an opted-out hook.
State: answered.
Branch: Migration Consent
Q13
Prerequisites:
- Q9
Evidence anchor:
- upstream Lefthook
core.hooksPathconflict handling scripts/install-git-hooks.mjs
Observed constraint:
- Lefthook normally stops on a custom local or global
core.hooksPathunless a force/reset option is used. Resetting or replacing a manager can alter consumer-owned Git behavior.
Question:
Should a Hook Migration Proposal identify the existing manager, show the exact planned migration, and require explicit human acceptance before any hook path, configuration, dependency, or installed hook is changed?
Recommendation:
- Yes. A declined proposal preserves the existing manager and records Commit Gate Opt-Out so later scaffolds do not repeat or bypass the decision.
Accepted answer:
- Hook migration is agent-owned follow-through governed by
$hi-cliguidance, not a new interactive migration engine inside the CLI. - The agent inspects the detected manager, presents the Hook Migration Proposal, and performs only authorized migration work. The CLI supplies current command evidence and persists policy; the proposal itself remains non-authorizing.
Code consequence:
- This creates an interactive migration checkpoint and a durable decline path; force/reset flags cannot run implicitly.
State: answered.
Branch: Version Authority
Q14
Prerequisites:
- Q8
Evidence anchor:
- scaffold planned dependency model
- baseline catalogue revision and dependency receipts
Observed constraint:
- A project-local dependency still needs one version authority. Unbounded
latestresolution makes identical catalogue revisions produce different lockfile state over time.
Question:
Should the selected HI baseline pin the Lefthook dependency version that scaffold declares?
Recommendation:
- Yes. The baseline supplies an exact reviewed version; normal package-manager installation records it in the consumer lockfile. Baseline update owns later version movement.
Accepted answer:
- Yes. The selected HI baseline pins the exact reviewed Lefthook version. Baseline updates own later version changes.
Code consequence:
- This makes desired state reproducible and assigns upgrades to baseline release policy rather than install time.
State: answered.
Branch: Staged Workspace Routing
Q15
Prerequisites:
- Q10
Evidence anchor:
apps/cli/scripts/staged-verification-selector.mjs
Observed constraint:
- HI already has a worktree-aware selector that reads the staged index,
includes both sides of renames, maps
apps/*andpackages/*owners, and expands root or unknown paths to repository scope.
Question:
Should Commit Gate use the same staged ownership semantics: selected workspace commands for known owners, and all applicable Quality Command Contracts for root or unknown paths?
Recommendation:
- Yes. Reuse the accepted semantic contract rather than create a second path ownership model. The implementation may share or extract code later.
Accepted answer:
- Yes. Commit Gate uses the current worktree-aware staged ownership semantics: known owners run selected workspace commands; renames include both paths; root or unknown paths run every applicable Quality Command Contract.
Code consequence:
- This fixes rename, worktree, workspace-owner, and root/unknown behavior while leaving code reuse to planning.
State: answered.
Glossary Q13
Question:
Who owns a Hook Migration Proposal and its execution?
Accepted answer:
- Relationship:
$hi-clidefines safe migration guidance; the agent produces the Hook Migration Proposal and performs authorized migration work; the CLI supplies evidence and persists policy. - Axiom: Hook migration is agent follow-through, not a CLI migration workflow.
Branch: Consumer Eligibility
Q2
Prerequisites:
- none
Evidence anchor:
apps/cli/src/integrations/repository-detector.ts:PackageJsonRecordapps/cli/src/features/repository-analysis/model.ts:ManifestInfoapps/cli/src/data/catalog/lint.tsapps/cli/src/data/hooks/format-edited-file.mjs
Observed constraint:
- Current repository detection does not read consumer
package.jsonscripts.ManifestInfocarries package identity and dependencies, but no lint or format command. - Current lint catalogue entries carry configuration, dependency, and optional preparation metadata, but no lint or format command fields.
- The existing edit hook derives Ruff, Oxlint, and Oxfmt commands internally; those commands are not received from the consumer or catalogue.
Current pack and scaffold inspection:
- There is no dedicated lint pack or format pack. A pack can select
lintAssetsand theformat-edited-filelifecycle hook. - The TypeScript language pack selects
typescript-anti-slopandformat-edited-file. Other detected packs add framework lint assets. The Python language pack selectsformat-edited-fileand no lint asset. - Selected lint assets scaffold nearest
oxlint.config.tsfiles, required Oxlint/Ultracite/plugin dev dependencies, optional vendored rule sources, optionalscripts.preparecommand segments, and.devpunks/specs/lint/*evidence. They do not scaffoldscripts.lint,scripts.format, or a genericscripts.check. format-edited-fileis an AI-agent lifecycle hook. It is materialized only for detected Python or an existing Oxfmt dependency. It derives per-fileruff format,ruff check --fix, Oxfmt, and Oxlint commands internally. The Python pack does not install Ruff, and generic lint setup does not install Oxfmt.- Fresh generated wiki applications are a separate scaffold template. They do
receive Oxfmt/Oxlint dependencies and a
checkscript containingoxlint . && oxfmt --check .; this is not a general catalogue-pack contract.
Question:
Should selected catalogue contributions resolve one explicit lint command and one explicit format-check command for every Commit Gate consumer, instead of reusing the current setup-only lint assets or AI edit-hook commands as an implicit executable contract?
Recommendation:
- Yes. Extend the catalogue-derived quality contribution with explicit executable commands. Let lint assets continue to own configuration and dependencies, let the edit hook continue to own agent-time mutation, and let Commit Gate consume the resolved lint and format-check commands. Reject an applicable compiled context that lacks either command.
Accepted answer:
- Yes. Selected catalogue contributions must resolve one explicit lint command and one explicit read-only format-check command for each Commit Gate consumer. Compiled context is invalid when either command is missing.
User correction and verification:
- The user states that HI receives the commands. Current code does not yet carry them. Q2 now asks whether that statement is the intended new catalogue contract.
Code consequence:
- This adds a command-bearing catalogue or compiled-context contract and makes completeness validation part of context compilation. It preserves current lint-asset and lifecycle-hook boundaries while removing runtime command discovery from Commit Gate reconciliation.
State: answered.
Glossary Q2
Question:
What canonical name identifies the two executable commands resolved for a Commit Gate consumer?
Accepted answer:
- Canonical term: Quality Command Contract — compiled catalogue output that contains one lint command and one read-only format-check command for a Commit Gate consumer.
- Relationship: selected catalogue contributions resolve a Quality Command Contract; a Commit Gate consumes it.
- Axiom: context compilation rejects an applicable Commit Gate consumer whose Quality Command Contract lacks either command.
Branch: Opt-Out Semantics
Q6
Prerequisites:
- Q3, Q4
Evidence anchor:
apps/cli/src/features/project-settings/model.ts:ProjectSettingsDocumentapps/cli/src/features/scaffold-state/desired-output.ts
Observed constraint:
- Desired scaffold state can include or exclude HI-owned files, dependencies, structured entries, and reconciliation actions. An execution-only disable would leave installed HI state without a clear owner.
Question:
When a user opts out, should desired state remove execution and every HI-owned Commit Gate artifact while preserving all consumer-owned hook state?
Recommendation:
- Yes. Opt-out means absent desired state: no HI-owned Lefthook dependency, config, installed hook, or receipt entry. Remove only artifacts whose existing receipt proves HI ownership.
Accepted answer:
- No automatic cleanup. Opt-out is persisted project state that prevents future scaffold runs from installing or reactivating the Commit Gate.
- Existing installed hook state remains unchanged when the policy is selected.
- The canonical
$hi-cliskill must guide the operator through disabling the current pre-commit hook. That shared-skill change remains source-first work for delivery, not an edit to a generated mirror during this grill.
Code consequence:
- This defines disable, removal, re-enable, and ownership-safe cleanup invariants.
State: answered.
Branch: Ensure Lifecycle
Q7
Prerequisites:
- Q3, Q4
Evidence anchor:
apps/cli/src/cli/ensure-command.ts:runEnsureapps/cli/src/scaffold/stage.tsapps/cli/src/update/run.ts
Observed constraint:
- Current
hi ensurewrites settings only. A Commit Gate policy change would have no immediate effect unless ensure also reconciles desired scaffold state or asks the user to run another command.
Question:
Should hi ensure apply the selected Commit Gate policy and reconcile its
owned state in one operation?
Recommendation:
- Yes. Persist policy and reconcile it as one recoverable transaction. Do not report success with settings and installed behavior out of sync.
Accepted answer:
- No reconciliation.
hi ensureonly persists the Commit Gate policy. - A later scaffold-capable command reads the policy and must not reactivate a persisted opt-out.
Code consequence:
- This expands ensure from settings-only reconfiguration into a scoped write-capable reconciliation boundary with rollback or recovery evidence.
State: answered.
Branch: Dependency Ownership
Q8
Prerequisites:
- Q1, Q4
Evidence anchor:
apps/cli/src/integrations/tool-management.tsapps/cli/src/scaffold/output.ts:plannedDependencies
Observed constraint:
- Global HI tools use operator PATH management. Scaffold dependencies use the consumer package manager and lockfile. Lefthook executes inside the consumer repository.
Question:
Should Lefthook be an HI-managed project-local dev dependency rather than a global required tool?
Recommendation:
- Yes. Declare it through desired scaffold dependencies and let the detected consumer package manager own installation and lockfile resolution.
Accepted answer:
- Yes. Lefthook is an HI-managed project-local dev dependency installed through the consumer package manager and recorded in the repository lockfile.
Code consequence:
- This assigns version and installation state to the repository and keeps the operator PATH outside the execution contract.
State: answered.
Branch: Existing Hook Managers
Q9
Prerequisites:
- Q4
Evidence anchor:
scripts/install-git-hooks.mjs- upstream Lefthook installation and configuration contract
Observed constraint:
- A repository may already use Husky, lint-staged,
.githooks, a customcore.hooksPath, or direct.git/hooksscripts. Automatic takeover can disable consumer-owned checks.
Question:
Should HI stop Commit Gate reconciliation when it detects a different existing hook manager, preserving that manager and requiring an explicit human choice?
Recommendation:
- Yes. Do not replace, merge, or chain a different manager automatically. Show the conflict and allow the user to keep the existing manager by opting out.
Accepted answer:
- No. An existing hook manager does not terminate the flow. HI proposes a migration from the detected manager to Lefthook.
- Migration execution and consent rules remain open; no automatic replacement was accepted by this answer.
Code consequence:
- This creates a fail-closed coexistence boundary and avoids implicit multi-manager composition.
State: answered.
Branch: Command Scope
Q10
Prerequisites:
- Q2, Q5
Evidence anchor:
apps/cli/scripts/staged-verification-selector.mjs- upstream Lefthook staged-file placeholders
Observed constraint:
- Repository-wide checks can make every commit depend on unrelated existing debt. Staged-path checks are fast but require the Quality Command Contract to accept an affected path or workspace selection.
Question:
Should the Commit Gate run its Quality Command Contract only for staged paths and their owning workspaces, while CI keeps repository-wide merge authority?
Recommendation:
- Yes. Compile staged or affected-scope commands. Reject the commit when either scoped command fails; leave full-repository verification to CI.
Accepted answer:
- Yes. Commit Gate runs the Quality Command Contract only against staged paths and their owning workspaces. CI retains repository-wide merge authority.
Code consequence:
- This determines command parameterization, monorepo routing, rename handling, performance, and the boundary between local and hosted verification.
State: answered.
Glossary Q6
Question:
What does the persisted disabled state mean?
Accepted answer:
- Canonical term: Commit Gate Opt-Out — durable project policy that prevents future scaffold runs from installing or reactivating the Commit Gate.
- Axiom: Commit Gate Opt-Out does not uninstall or mutate current hook state.
- Relationship:
hi ensurepersists Commit Gate Opt-Out; scaffold-capable commands consume it.
Glossary Q9
Question:
What does HI produce when another hook manager exists?
Accepted answer:
- Canonical term: Hook Migration Proposal — an HI recommendation to replace a detected existing hook manager with Lefthook.
- Axiom: a Hook Migration Proposal is not migration approval.
Branch: Policy Authority
Q3
Prerequisites:
- none
Evidence anchor:
apps/cli/src/features/project-settings/model.ts:ProjectSettingsDocumentapps/cli/src/features/project-settings/service.ts:writeProjectSettings
Observed constraint:
- Project settings have no gate policy today. A command-only choice would not
explain later
hi update,hi check, opt-out, or re-enable behavior.
Question:
Should the default-on or opted-out choice be durable typed project policy in
.devpunks/settings.json?
Recommendation:
- Yes. Persist one explicit policy value.
hi init,hi ensure,hi update, andhi checkmust derive the same desired state from it.
Accepted answer:
- Yes. The default-on or opted-out choice is durable typed project policy in
.devpunks/settings.json.
Code consequence:
- This assigns policy persistence to Project Settings and makes scaffold and check behavior deterministic across commands and sessions.
State: answered.
Branch: Harness Ownership Boundary
Q4
Prerequisites:
- none
Evidence anchor:
packages/scaffold/src/context-plan.ts:ContributionKindapps/cli/src/data/catalog/hooks.ts:hookCatalogapps/cli/src/data/scripts/harness-projection/adapters
Observed constraint:
- Existing
lifecycle-hookcontributions target AI-agent events. None of the provider adapters owns a Git commit event.
Question:
Should the Git commit gate be a first-class catalog contribution that is separate from AI-agent lifecycle hooks?
Recommendation:
- Yes. Model a distinct Commit Gate contribution and let scaffold desired state reconcile its policy, dependency, config, and installed Git hook.
Accepted answer:
- Yes. Commit Gate is a first-class catalogue contribution separate from AI-agent lifecycle hooks.
Code consequence:
- This keeps provider adapters unchanged and creates an explicit ownership seam for Git-hook planning, materialization, receipts, and drift.
State: answered.
Branch: Product Promise
Q5
Prerequisites:
- none
Evidence anchor:
- Lefthook documents
LEFTHOOK=0 git commit; Git also supportsgit commit --no-verify.
Observed constraint:
- A local pre-commit hook cannot be a non-bypassable compliance boundary.
Question:
Does “before any commit” mean the normal local commit path, while CI remains the non-bypassable merge authority?
Recommendation:
- Yes. Promise a default local quality gate with deliberate developer bypass. Keep merge protection and CI authority separate.
Accepted answer:
- Yes. “Before any commit” means the normal local commit path. Deliberate local bypass remains possible, and CI remains the merge authority.
Code consequence:
- This defines the enforcement invariant, documentation language, bypass behavior, and the boundary between local hooks and hosted verification.
State: answered.