Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Design — hk policy simplification

Metadata

  • Beads feature root: dstack-mol-5v0
  • Feature slug: hk-policy-simplification
  • Design path: docs/src/features/hk-policy-simplification/design.md
  • Implemented record: docs/src/features/hk-policy-simplification/index.md
  • Base branch: main
  • Status: reviewed

Feature Summary

Replace the generated and repository hk policies’ unnecessary command overrides and broad dependency chain with hk built-ins, native config discovery, and file-level locking while restoring observable Harper commit-message linting.

User Intent

The user expects dstack to add a small quality baseline without fighting hk’s native behavior. Existing checks must not silently disappear, depends must be exceptional rather than the default, built-ins should own standard tools, and commit-message grammar checks must have executable proof.

Goals

  • Use Builtins.harper_commit_message without the current rule-disabling command override.
  • Prefer hk built-ins and each tool’s standard config discovery where behavior matches the contract.
  • Remove dependency edges used only to serialize overlapping files; rely on hk read/write locks.
  • Retain custom steps only for project-specific behavior and document why each remains custom.
  • Preserve every supported validation capability across root and generated policies.
  • Prove check, fix, pre-commit, and commit-msg behavior through representative generated projects.

Non-Goals

  • Replace hk, change its pinned binary/Pkl version, or redesign mise provisioning.
  • Remove project-specific semantic documentation checks or manifest-gated language tests merely to reduce line count.
  • Introduce a general step registry, Pkl generator, or second hook runner.
  • Change language-profile selection, task names, application manifests, or GitHub workflow behavior.

User-Facing Behavior

Generated projects retain the same six mise tasks and hooks. Checks and deterministic fixes run with greater native parallelism. Harper rejects representative spelling, repetition, and agreement defects while accepting valid Conventional Commit subjects and optional canonical Beads footers. Documentation lists the actual checks without claiming artificial ordering.

Requirements

Functional Requirements

Native commit-message linting

Both root and generated hk.pkl derive harper_commit_message from Builtins.harper_commit_message. Direct use is not compatible with the existing commit contract: Harper 2.6 rejects a valid canonical Beads: dstack-mol-v8c.1 footer as spelling and split-word errors. The sole command override filters Git comments, scissors/diff content, a canonical machine-authored release: vX.Y.Z subject only when it is the first line and exact stable release form, and a canonical Beads: footer before piping the remaining human-authored text to harper-cli lint --quiet --no-color. It does not ignore any Harper rule class. Tests invoke the Harper step in isolation and the complete real commit-msg hook with:

  • a valid scoped Conventional Commit subject;
  • a valid subject plus final Beads: footer;
  • a canonical release: vX.Y.Z subject;
  • the same release-shaped text in a human-authored body, which must still be linted;
  • repeated words;
  • a representative spelling error;
  • pronoun/verb disagreement.

The three valid messages pass and each invalid fixture fails in the isolated Harper step. Separate fixtures prove Cocogitto, subject/body length, required scope, and Beads footer checks independently reject their own invalid inputs.

Built-in and config-discovery policy

For every current custom step, implementation records one disposition:

  1. use the hk built-in unchanged;
  2. use the built-in with the smallest necessary project-specific field override; or
  3. retain a custom step because no built-in represents required behavior.

Rumdl uses normal .config/rumdl.toml discovery rather than an explicit default config argument. Equivalent redundant flags are removed. The semantic documentation validator, commit footer rules, manifest prerequisite guards, and the minimal Harper machine-line filter remain custom because they represent dstack-specific behavior not covered by the upstream built-ins.

Dependency policy

Remove the global dependency chain that serializes unrelated steps. hk’s file-level read/write locking owns ordinary overlap between checks and fixers. A remaining depends edge is allowed only when one step consumes another step’s output or the final content is order-sensitive; its rationale must appear in design/reference documentation and a test. No dependency may exist solely to force a stable display order or avoid a race hk already prevents.

Capability preservation

Capture the intended root and generated step inventories before refactoring. The final policies must retain all supported universal, profile, manifest, commit-message, and repository-specific checks. Renaming a step requires an explicit mapping in tests; deleting a capability requires separate user approval.

Quality Requirements

  • Root and rendered Pkl evaluate successfully.
  • hk check, hk fix, pre-commit, and commit-msg fixtures are deterministic.
  • Fix followed by check converges without unstaged-work loss.
  • Representative single-profile, polyglot, and other projects retain selected-only behavior.
  • Tests assert behavior and capability sets rather than the removed dependency implementation.

Compatibility and Migration Requirements

Existing Copier-managed projects receive the simpler policy through normal three-way update. Project-owned hk customizations remain subject to Copier conflict handling and the additive protections owned by Migration safety and clarity. Task names, tool answers, and lock platforms do not change.

Existing Context

Universal project tooling introduced one generated hk.pkl; Language quality profiles extended it with conditional steps. A later race fix serialized nearly every step with depends, despite hk 1.49 coordinating overlapping fixers through file-level read/write locks. Rumdl and Harper were replaced with custom commands, including a Harper ignore list that disables major rule classes. Current tests assert the dependency chain and command strings rather than the desired native behavior.

Proposed Design

Keep one direct Pkl mapping shared by check, fix, and pre-commit. Replace standard custom steps with built-ins, remove non-semantic dependencies, and let hk lock matching files. Keep small custom definitions only for dstack-specific semantic checks, manifest gates, or tools without a suitable built-in. Test the public hook behavior directly.

Architecture Consistency

Existing Patterns Reused

The feature keeps the single mise/hk interface, version-coupled hk pin, profile-gated template sections, root-manifest gates, and generated tooling documentation.

Invariants Preserved

check remains read-only; fix and pre-commit remain deterministic; pre-commit retains stash = "git"; tests do not run during pre-commit/fix except the existing explicit Go tidy behavior; generated projects keep six task names.

New Decisions Introduced

hk native locking is authoritative for ordinary fixer coordination. Custom step definitions and dependency edges now require a concrete behavioral justification.

Architecture Documentation Changes

docs/src/architecture/index.md will describe native locking and the narrow custom-step boundary.

Operational Considerations

The simplified graph may expose latent non-convergent tool combinations previously hidden by a fixed chain. The final matrix therefore runs fix then check and reports any genuine order-sensitive exception. Harper failures must name the lint so contributors can correct the message rather than bypass the hook.

Documentation Impact

Documentation concernExact pageCreate or updatePlanned changeOwning Beads task
Architecturedocs/src/architecture/index.mdUpdateNative lock and customization boundarydstack-mol-v8c.2
Usage / OperationsNot applicableContributor behavior is development/reference material
Developmentdocs/src/development/index.mdUpdate incrementallyHarper behavior (.1), native policy (.2), validation matrix (.3)tasks .1.3
Referencedocs/src/reference/index.mdUpdate incrementallyHarper contract (.1), exact custom steps/dependency exceptions (.2)tasks .1.2
Generated Developmentskills/setup-project/template/docs/src/development/tooling.md.jinjaUpdate incrementallyHarper behavior (.1) and native check/fix behavior (.2)tasks .1.2
Generated Referenceskills/setup-project/template/docs/src/reference/tooling.md.jinjaUpdate incrementallyHarper contract (.1) and actual steps/justified ordering (.2)tasks .1.2
Published Developmentdocs/src/development/tooling.mdUpdate incrementallyKeep dog-food contributor contract aligned with template changestasks .1.2
Published Referencedocs/src/reference/tooling.mdUpdate incrementallyKeep dog-food exact contract aligned with template changestasks .1.2
Planned navigationdocs/src/SUMMARY.mdAlready updatedDesign is registered under planned featuresplanning
Delivered navigationdocs/src/SUMMARY.md; docs/src/features/index.mdUpdate during close-outRegister the implemented feature in both delivered indexeslifecycle close-out
Implemented Feature Recorddocs/src/features/hk-policy-simplification/index.mdCreate during close-outPreserve delivery and audit historylifecycle close-out

Validation Strategy

  • Evaluate root and representative rendered Pkl.
  • Invoke the isolated Harper step and complete commit-msg hook with valid and invalid fixtures, attributing each failure to the intended validator.
  • Compare pre/post capability inventories.
  • Exercise check/fix/pre-commit convergence with overlapping Markdown and language files, verifying byte-for-byte restoration of unrelated unstaged content.
  • Give every retained dependency a focused output/order-sensitivity fixture.
  • Render both Copier entrypoints for other, representative single profiles, and one polyglot profile.
  • Run focused tests while iterating, then the full repository suite, mise run check, documentation checker, and mdBook build after review fixes stabilize.

Implementation Decomposition

  1. dstack-mol-v8c.1: restore native Harper behavior, direct hook fixtures, and Harper-specific root/generated docs.
  2. dstack-mol-v8c.2: replace redundant custom steps, remove non-semantic dependencies, test each retained edge, and update native-policy root/generated docs.
  3. dstack-mol-v8c.3: validate representative generated policies, fix→check convergence, unstaged restoration, and final matrix evidence without re-owning the product-contract pages.

Dependencies and Parallelism

This feature builds on delivered Language quality profiles. Tasks are serialized because the first two intentionally modify the same root/template hk files and the final task validates their combined result. Every task depends directly on specification reconciliation. Migration safety and clarity and Monorepo tooling layout depend on this feature.

Rollout and Migration

Ship through the normal Copier update path. Existing projects reconcile local hk changes through three-way merge; the migration feature separately prevents additive-adoption loss. No answer or lock schema migration is required.

Risks and Tradeoffs

Removing artificial order can reveal a genuinely order-sensitive pair. Such a pair receives the smallest tested exception rather than rebuilding the global chain. Native built-ins may change when hk is upgraded, but the synchronized hk/Pkl pin bounds that behavior.

Rejected Alternatives

  • Keep the chain because it currently passes: rejected because it defeats hk’s locking and obscures real dependencies.
  • Remove all custom steps categorically: rejected because semantic docs checks and manifest guards are project-specific.
  • Preserve the Harper ignore list: rejected because it disables expected lint categories and has no acceptance proof.
  • Introduce generated Pkl fragments: rejected as unnecessary for the current direct conditional template.

Open Questions

None.

Deferred Decisions

A future hk version upgrade is separate maintenance and must rerun these behavioral fixtures.

Planning Record

Questions Asked and Answers

The user explicitly required native Harper linting, removal of unnecessary depends, use of standard config discovery, and preservation rather than deletion of useful checks.

Assumptions

hk 1.49’s documented file-level locking remains the behavior of the currently pinned binary and Pkl package.

Design Changes During Planning

The work was separated from migration safety so the template policy can stabilize before migration preservation tests consume it. Specification review added published dog-food pages and delivered-index ownership, made task documentation ownership explicitly incremental, strengthened convergence/dependency acceptance, and replaced direct Harper use with a minimal machine-line filter after Harper 2.6 rejected valid canonical release and Beads metadata.

Source Material

Current root/generated hk policies and tests; hk 1.49 configuration, hook, built-in Rumdl, and Harper sources; the user’s migration and hook observations.