Harness Intelligence Wiki
SpecsCLIManaged Format Hook

Manifest-Backed Scaffold Format-Hook Exclusion

Spec: Manifest-Backed Scaffold Format-Hook Exclusion

Context

Harness distributes an automatic format hook that formats eligible files after agent edits. The hook currently excludes only a hard-coded subset of scaffold-owned paths. Other paths recorded in .devpunks/scaffold-manifest.json, including lint selection and workspace Oxlint configuration, can be formatted after Harness writes their authoritative bytes. A later hi check then reports those formatter-only byte changes as managed-file drift.

Repository operators and agents need the automatic hook to preserve every scaffold-managed path without weakening strict scaffold ownership or adding repository formatter execution to CLI commands.

Non-Goals

  • Run a repository formatter from hi check, hi update, scaffold desired-state compilation, or another CLI lifecycle.
  • Infer ownership from path, extension, generated comments, Git tracking, or formatter behavior.
  • Add project-producer declarations, repository mirrors, formatter-specific ignore configuration, or a force-overwrite path.
  • Govern manually invoked repository-wide format commands.
  • Reconcile or mutate Collective Intelligence, including its existing formatter-changed files or stale opensrc/ guides.
  • Publish another npm CLI version unless implementation proves that executable CLI code or a schema must change.
  • Write or synchronize provider backlog items.

User Stories

US-001: Preserve scaffold-managed output

As a repository operator, I want automatic formatting to skip every path recorded in the scaffold manifest so that Harness-managed bytes remain authoritative.

US-002: Preserve normal project formatting

As a repository contributor, I want eligible unmanaged files to retain the hook's existing format and lint behavior.

US-003: Fail safely without ownership evidence

As a repository operator, I want the hook to make no formatting mutation when it cannot read a valid scaffold manifest so that unavailable ownership evidence cannot create false drift.

US-004: Distribute the corrected hook

As a Harness operator, I want the corrected hook delivered through the stable baseline so compatible CLI consumers receive it without an unnecessary npm release.

Acceptance Criteria

  • AC-001: Given a valid .devpunks/scaffold-manifest.json, an eligible file whose normalized repository-relative path appears in managedFiles is not formatted, linted, or otherwise mutated by the automatic format hook.
    • Covers: US-001
  • AC-002: The managed-path rule applies to every manifest entry and does not use a special list for lint, Oxlint, source-guide, skill, hook, or agent paths.
    • Covers: US-001
  • AC-003: Given a valid manifest, an eligible unmanaged file follows the existing formatter and linter selection, command resolution, result reporting, and failure behavior.
    • Covers: US-002
  • AC-004: When the scaffold manifest is missing, unreadable, malformed, or has an invalid managed-file collection, the hook invokes no formatter or linter and mutates no candidate file for that invocation.
    • Covers: US-003
  • AC-005: A missing or invalid manifest does not fall back to the existing partial hard-coded scaffold-owned path rule.
    • Covers: US-003
  • AC-006: Focused tests prove managed and unmanaged behavior through the hook's supported invocation surfaces and prove that no subprocess mutation occurs on the fail-closed path.
    • Covers: US-001, US-002, US-003
  • AC-007: The built baseline archive contains the tested corrected hook bytes, uses the existing compatible baseline contract, and has release notes describing the behavior boundary.
    • Covers: US-004
  • AC-008: The change does not alter scaffold desired bytes, managed-file ownership classification, source-guide replacement policy, or consumer repository state.
    • Covers: US-001, US-004

Constraints

  • Raw scaffold bytes remain authoritative.
  • .devpunks/scaffold-manifest.json managedFiles is the complete managed-path source for the automatic format-hook boundary. The manifest file itself is the sole bootstrap exclusion because it cannot recursively list and hash itself.
  • Managed-path comparison uses normalized repository-relative paths and cannot escape the repository root.
  • The read-only and update CLI lifecycles do not invoke repository format commands.
  • Existing strict behavior remains for scaffold-managed opensrc/ guides. Their consumer reconciliation is separate.
  • A manual repository-wide format command can still create legitimate managed-file drift.
  • Baseline publication uses the repository-supported clean-worktree release command and existing compatibility policy.

Dependency Readiness

No Stack Required.

The managed-file receipt and strict ownership behavior are already present on base commit 441d87f5, including the project-generated ownership implementation landed by c89c73cf.

Branch/Base Intent

  • Base: main at 441d87f5 (v3.1.4).
  • Delivery branch: team/stefan/investigate-generated-file-triggers.
  • Constraint: keep Collective Intelligence reconciliation and unrelated scaffold divergence out of this branch's implementation scope.

Accepted Technical Decisions

  • Extend the distributed automatic format hook's ownership boundary from a partial hard-coded rule to the complete managed-file receipt.
  • Treat manifest loading and validation as a fail-closed prerequisite for all formatting and linting in one hook invocation.
  • Preserve only .devpunks/scaffold-manifest.json outside receipt membership as bootstrap evidence; remove the broader hard-coded path fallback.
  • Preserve the existing unmanaged-file formatter and linter behavior.
  • Carry the hook change through the baseline asset surface. Add executable or schema work only if implementation evidence makes it necessary.

Accepted Testing Decisions

  • Reproduce the defect with a formattable path present in managedFiles and prove its bytes and subprocess boundary remain unchanged.
  • Prove an equivalent unmanaged path still formats and retains existing lint behavior.
  • Cover missing, unreadable, malformed, and structurally invalid manifests.
  • Exercise the hook's supported invocation modes that produce edited-file candidates.
  • Build the baseline and compare the archived hook bytes with the tested source.
  • Run focused hook tests before broader CLI checks, documentation checks, and git diff --check.

Verification Seams

  • Public behavior seam: the distributed format-edited-file.mjs hook invoked through its supported agent/file modes.
  • Ownership seam: normalized candidate path membership in .devpunks/scaffold-manifest.json managedFiles.
  • Mutation seam: candidate file bytes and formatter/linter subprocess observation before and after invocation.
  • Distribution seam: hook bytes inside the built scaffold baseline manifest/archive.

Parked Decisions

  • Collective Intelligence check and reconciliation. Owner: Stefan. Resume trigger: the new baseline is released and Stefan runs hi check in that repository.
  • Existing formatter-changed managed files and stale opensrc/ guides in consumer repositories. Owner: each repository operator. Resume trigger: explicit consumer reconciliation authorization.
  • Provider backlog projection. Owner: Stefan. Resume trigger: an explicit request to write or synchronize backlog items.

Decision Log

DecisionEvidenceRationale
Keep all affected files scaffold-managedClosed grill Q1 and Q10No independent repository producer exists; raw scaffold bytes stay authoritative.
Skip every manifest-managed pathClosed grill Q10The receipt is the existing complete ownership source and avoids path-specific exceptions.
Make no mutation without a valid manifestClosed grill Q11A missed format is reversible; formatting an unknown managed file can recreate drift.
Leave manual format commands outside HarnessClosed grill Q13Formatter-specific repository control would expand scope and complexity.
Release through a stable baselineClosed grill Q14 and Q16The hook is a baseline asset and CLI 3.1.4 already supports the compatible distribution contract.
Park consumer reconciliationClosed grill Q15 and Q16Consumer mutation is separate from the preventive Harness hook fix.

On this page