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:
changed=$(git diff --name-only origin/main...HEAD)
- derive touched top-level app dirs
- look each up in an in-repo
app dir -> command registry and run only those
- 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.
Summary
porch.checksoverrides (in.codev/config.json) are a flat, workspace-global map.loadCheckOverrides(porch/config.ts) readsconfig.porch.checksas{ checkName: { command, cwd, skip } }, andgetPhaseChecks(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:pytest && pnpm -C apps/web testbreaks Python builders' worktrees (they lack the JS app'snode_modules).The only built-in knobs are global (
command, a singlecwd,skip).Current workaround (works, but lives outside porch's model)
Point
porch.checks.tests/buildat one maintained dispatcher script in the repo that scopes by what the builder changed:changed=$(git diff --name-only origin/main...HEAD)app dir -> commandregistry and run only thoseO(1) per app, never invokes a suite whose deps the worktree lacks. But it reimplements scoping porch could own.
Proposed
Give
porch.checks(and ideallyporch.consultation) a scoping dimension. Options (not exclusive):porch.checks.<protocol>.<name>overriding the flat default.{ pathGlob: { checks } }mapping resolved against the builder's diff, so a builder that only touchedapps/py-thing/**runs that app's checks.Reported from a mixed Python+JS monorepo adopting the dispatcher workaround.