⚠️ Definition of Done: this issue must be completed in full, in a single PR. Do not split this
work across multiple PRs, and do not defer any Deliverable below to a follow-up issue. A PR that
satisfies only some of the Deliverables, stubs a required test, or leaves a checkbox
partially-done does NOT resolve this issue and will be closed.
Context
normalizeRepoList in packages/loopover-engine/src/fleet-run-manifest.ts (~lines 90-102) parses
each entry of a fleet-run manifest's repos list, computing a per-repo maxConcurrentWorktrees.
For a bare-string repo entry ("owner/repo"), the default is initialized as:
let maxConcurrentWorktrees = DEFAULT_FLEET_RUN_MANIFEST.totalConcurrentWorktrees;
— reusing the fleet-wide total worktree default constant for a per-repo value.
For an object-form repo entry ({ repoFullName, maxConcurrentWorktrees }), the same
conceptual default is instead computed via:
maxConcurrentWorktrees = normalizePositiveInteger(record.maxConcurrentWorktrees, "maxConcurrentWorktrees", 1, warnings);
— a hardcoded literal 1, not the same constant reused above.
These two code paths for "what's the default per-repo worktree budget when unspecified" currently
agree only because DEFAULT_FLEET_RUN_MANIFEST.totalConcurrentWorktrees also happens to be 1
today (confirmed at its definition, ~line 45). If the fleet-wide total default is ever changed to
something other than 1, bare-string repo entries would silently and incorrectly inherit the new
fleet-wide total as their per-repo cap, while object-form entries would keep defaulting to 1 —
a divergence with no test pinning either path independently.
test/unit/fleet-run-manifest-parser.test.ts has no test asserting the bare-string-entry default
value independently of DEFAULT_FLEET_RUN_MANIFEST.totalConcurrentWorktrees.
Requirements
- Introduce a dedicated per-repo default constant (e.g.
DEFAULT_FLEET_RUN_MANIFEST_REPO_MAX_CONCURRENT_WORKTREES = 1, named clearly to distinguish it
from the fleet-wide totalConcurrentWorktrees default) and use it as the default for BOTH the
bare-string branch and the object-form branch's normalizePositiveInteger(...) fallback
argument, so both paths derive their default from the same single source of truth instead of two
independently-hardcoded values that only coincidentally agree.
- Do not change
DEFAULT_FLEET_RUN_MANIFEST.totalConcurrentWorktrees itself or any other field of
DEFAULT_FLEET_RUN_MANIFEST — this issue only fixes the per-repo default's source.
- Do not change the parsing/validation behavior for explicitly-specified
maxConcurrentWorktrees
values — only the fallback used when a repo entry doesn't specify one.
Deliverables
All four deliverables are required in this single PR.
Test Coverage Requirements
This repo enforces 99%+ Codecov patch coverage, branch-counted, on every changed line/branch in
src/**/workers/** (this applies to packages/loopover-engine/src/** as well — confirm via the
repo's Codecov config). The new constant and both updated branches must be covered by the new test
above plus existing passing tests.
Expected Outcome
A bare-string repo entry's default maxConcurrentWorktrees no longer silently tracks
DEFAULT_FLEET_RUN_MANIFEST.totalConcurrentWorktrees — both the bare-string and object-form entry
paths derive their per-repo default from one dedicated, independently-testable constant, so a
future change to the fleet-wide total default can no longer silently and incorrectly change
per-repo defaults for bare-string entries.
Links & Resources
packages/loopover-engine/src/fleet-run-manifest.ts (normalizeRepoList, ~lines 90-102;
DEFAULT_FLEET_RUN_MANIFEST, ~line 45)
test/unit/fleet-run-manifest-parser.test.ts (existing test file to extend)
Context
normalizeRepoListinpackages/loopover-engine/src/fleet-run-manifest.ts(~lines 90-102) parseseach entry of a fleet-run manifest's
reposlist, computing a per-repomaxConcurrentWorktrees.For a bare-string repo entry (
"owner/repo"), the default is initialized as:— reusing the fleet-wide total worktree default constant for a per-repo value.
For an object-form repo entry (
{ repoFullName, maxConcurrentWorktrees }), the sameconceptual default is instead computed via:
— a hardcoded literal
1, not the same constant reused above.These two code paths for "what's the default per-repo worktree budget when unspecified" currently
agree only because
DEFAULT_FLEET_RUN_MANIFEST.totalConcurrentWorktreesalso happens to be1today (confirmed at its definition, ~line 45). If the fleet-wide total default is ever changed to
something other than
1, bare-string repo entries would silently and incorrectly inherit the newfleet-wide total as their per-repo cap, while object-form entries would keep defaulting to
1—a divergence with no test pinning either path independently.
test/unit/fleet-run-manifest-parser.test.tshas no test asserting the bare-string-entry defaultvalue independently of
DEFAULT_FLEET_RUN_MANIFEST.totalConcurrentWorktrees.Requirements
DEFAULT_FLEET_RUN_MANIFEST_REPO_MAX_CONCURRENT_WORKTREES = 1, named clearly to distinguish itfrom the fleet-wide
totalConcurrentWorktreesdefault) and use it as the default for BOTH thebare-string branch and the object-form branch's
normalizePositiveInteger(...)fallbackargument, so both paths derive their default from the same single source of truth instead of two
independently-hardcoded values that only coincidentally agree.
DEFAULT_FLEET_RUN_MANIFEST.totalConcurrentWorktreesitself or any other field ofDEFAULT_FLEET_RUN_MANIFEST— this issue only fixes the per-repo default's source.maxConcurrentWorktreesvalues — only the fallback used when a repo entry doesn't specify one.
Deliverables
packages/loopover-engine/src/fleet-run-manifest.ts, set to the same value (1) the twoexisting defaults currently coincidentally share.
normalizeRepoListuses the new constant instead ofDEFAULT_FLEET_RUN_MANIFEST.totalConcurrentWorktrees.normalizePositiveInteger(...)call uses the new constant insteadof the hardcoded literal
1.test/unit/fleet-run-manifest-parser.test.tsthat changesDEFAULT_FLEET_RUN_MANIFEST.totalConcurrentWorktrees(via whatever the test's existingfixture/override mechanism is — inspect the file for how other tests already override
manifest defaults) to a value other than
1, then asserts a bare-string repo entry's parsedmaxConcurrentWorktreesis still the new dedicated per-repo constant's value, not thechanged fleet-wide total — proving the two defaults are now genuinely decoupled.
All four deliverables are required in this single PR.
Test Coverage Requirements
This repo enforces 99%+ Codecov patch coverage, branch-counted, on every changed line/branch in
src/**/workers/**(this applies topackages/loopover-engine/src/**as well — confirm via therepo's Codecov config). The new constant and both updated branches must be covered by the new test
above plus existing passing tests.
Expected Outcome
A bare-string repo entry's default
maxConcurrentWorktreesno longer silently tracksDEFAULT_FLEET_RUN_MANIFEST.totalConcurrentWorktrees— both the bare-string and object-form entrypaths derive their per-repo default from one dedicated, independently-testable constant, so a
future change to the fleet-wide total default can no longer silently and incorrectly change
per-repo defaults for bare-string entries.
Links & Resources
packages/loopover-engine/src/fleet-run-manifest.ts(normalizeRepoList, ~lines 90-102;DEFAULT_FLEET_RUN_MANIFEST, ~line 45)test/unit/fleet-run-manifest-parser.test.ts(existing test file to extend)