Skip to content

porch.checks is workspace-global only — add per-protocol / per-changed-path scoping for mixed-language monorepos #1103

Description

@waleedkadous

Summary

porch.checks overrides (in .codev/config.json) are a flat, workspace-global map. loadCheckOverrides (porch/config.ts) reads config.porch.checks as { checkName: { command, cwd, skip } }, and getPhaseChecks (porch/protocol.ts) applies the same override to every builder, regardless of protocol, project, or which paths the builder changed. There is no per-protocol, per-project, or per-changed-path scoping.

This is the same global-precedence shape already called out as a footgun for porch.consultation.models (a project-wide SPIR-tuned model list silently inflates lighter protocols like PIR — see the PIR notes in CLAUDE.md).

Why it's a gap

Mixed-language / multi-app monorepos can't express "run the current project's tests." Example: a repo with Python apps (pytest) and a JS app (vitest/pnpm). A single global porch.checks.tests:

  • can't run the right suite per builder, and
  • a naive pytest && pnpm -C apps/web test breaks Python builders' worktrees (they lack the JS app's node_modules).

The only built-in knobs are global (command, a single cwd, skip).

Current workaround (works, but lives outside porch's model)

Point porch.checks.tests/build at one maintained dispatcher script in the repo that scopes by what the builder changed:

  1. changed=$(git diff --name-only origin/main...HEAD)
  2. derive touched top-level app dirs
  3. look each up in an in-repo app dir -> command registry and run only those
  4. nothing touched → pass; any suite fails → non-zero

O(1) per app, never invokes a suite whose deps the worktree lacks. But it reimplements scoping porch could own.

Proposed

Give porch.checks (and ideally porch.consultation) a scoping dimension. Options (not exclusive):

  • Per-protocol sections: porch.checks.<protocol>.<name> overriding the flat default.
  • Per-changed-path: a { pathGlob: { checks } } mapping resolved against the builder's diff, so a builder that only touched apps/py-thing/** runs that app's checks.
  • At minimum, expose the builder's changed-path set / project mapping to the check layer so scoping is first-class rather than a userland dispatcher.

Reported from a mixed Python+JS monorepo adopting the dispatcher workaround.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/porchArea: Porch state machine / protocol orchestration

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions