Context
packages/loopover-engine/src/goal-model.ts has zero doc comments — no module header, no TSDoc on its one exported type (GoalModelInput) or its one exported function (computeLaneFit). This is unusual for the package: nearly every other module has at minimum a module-level header explaining scope and intent (compare miner-goal-lane-fit.ts in the same directory, which imports from this file and has three /** ... */ blocks for a smaller surface).
computeLaneFit is not obscure — it's referenced by name in packages/loopover-engine/README.md's "Metadata opportunity signals" section ("computeMetadataLaneFit — label-only lane fit by default; honors optional candidatePaths via computeLaneFit") without ever explaining what it does. A reader who follows that reference to the actual source finds no explanation there either.
The function's behavior is genuinely non-obvious and worth documenting precisely:
blockedPaths/blockedLabels are a hard veto — any match against either returns 0 immediately, before wantedPaths/preferredLabels are even considered.
- If neither
wantedPaths nor preferredLabels is configured, the result is a fixed neutral 0.5, not 0 or 1.
- If either is configured but neither actually matches, the result is
0.
- Otherwise the result is
matchedDimensions / activeDimensions — i.e. partial credit when only one of two configured dimensions (paths vs. labels) matches.
compileGlobMatcher implements its own glob semantics (*, **, **/, ?) rather than using an existing glob library — worth a one-line note on exactly what's supported, since a caller writing a wantedPaths/blockedPaths pattern in .loopover-miner.yml's MinerGoalSpec needs to know this.
Requirements
- Add a module-level header comment to
goal-model.ts explaining its role: the pure lane-fit scorer that MinerGoalSpec's path/label preferences compile down to, consumed by miner-goal-lane-fit.ts and opportunity-metadata.ts's computeMetadataLaneFit.
- Add a TSDoc block on
GoalModelInput explaining each field.
- Add a TSDoc block on
computeLaneFit spelling out the exact precedence/scoring rules above (blocked = hard veto → no criteria = 0.5 → partial credit by matched/active dimension count), since callers need this to reason about scores, not just the return type.
- Add a short comment on
compileGlobMatcher (or promote it alongside computeLaneFit's doc) noting which glob tokens are supported (*, **, **/, ?) and which aren't (e.g. character classes, brace expansion).
Deliverables
Test Coverage Requirements
Doc-comment-only change — no new executable lines or branches, so it does not add to the src/**/packages/loopover-engine/src/** patch-coverage surface Codecov measures. The existing packages/loopover-engine/test/goal-model.test.ts suite must stay green (run npm test --workspace @loopover/engine and npm run test:coverage locally — this file is inside coverage.include, so if a doc-comment edit accidentally reformats/removes an existing line it would still need re-verifying).
Expected Outcome
computeLaneFit's exact scoring behavior (hard-veto, neutral-default, partial-credit rules) is documented at its own definition site, not left implicit in the implementation or referenced-but-unexplained from the README.
Links & Resources
packages/loopover-engine/src/goal-model.ts (the file to change)
packages/loopover-engine/src/miner-goal-lane-fit.ts — a caller, and an example of this package's TSDoc style
packages/loopover-engine/src/opportunity-metadata.ts — computeMetadataLaneFit, the other caller
packages/loopover-engine/README.md's "Metadata opportunity signals" section — where computeLaneFit is referenced by name today
packages/loopover-engine/test/goal-model.test.ts — existing test coverage to cross-check the documented rules against
Context
packages/loopover-engine/src/goal-model.tshas zero doc comments — no module header, no TSDoc on its one exported type (GoalModelInput) or its one exported function (computeLaneFit). This is unusual for the package: nearly every other module has at minimum a module-level header explaining scope and intent (compareminer-goal-lane-fit.tsin the same directory, which imports from this file and has three/** ... */blocks for a smaller surface).computeLaneFitis not obscure — it's referenced by name inpackages/loopover-engine/README.md's "Metadata opportunity signals" section ("computeMetadataLaneFit— label-only lane fit by default; honors optionalcandidatePathsviacomputeLaneFit") without ever explaining what it does. A reader who follows that reference to the actual source finds no explanation there either.The function's behavior is genuinely non-obvious and worth documenting precisely:
blockedPaths/blockedLabelsare a hard veto — any match against either returns0immediately, beforewantedPaths/preferredLabelsare even considered.wantedPathsnorpreferredLabelsis configured, the result is a fixed neutral0.5, not0or1.0.matchedDimensions / activeDimensions— i.e. partial credit when only one of two configured dimensions (paths vs. labels) matches.compileGlobMatcherimplements its own glob semantics (*,**,**/,?) rather than using an existing glob library — worth a one-line note on exactly what's supported, since a caller writing awantedPaths/blockedPathspattern in.loopover-miner.yml'sMinerGoalSpecneeds to know this.Requirements
goal-model.tsexplaining its role: the pure lane-fit scorer thatMinerGoalSpec's path/label preferences compile down to, consumed byminer-goal-lane-fit.tsandopportunity-metadata.ts'scomputeMetadataLaneFit.GoalModelInputexplaining each field.computeLaneFitspelling out the exact precedence/scoring rules above (blocked = hard veto → no criteria = 0.5 → partial credit by matched/active dimension count), since callers need this to reason about scores, not just the return type.compileGlobMatcher(or promote it alongsidecomputeLaneFit's doc) noting which glob tokens are supported (*,**,**/,?) and which aren't (e.g. character classes, brace expansion).Deliverables
GoalModelInputandcomputeLaneFitinpackages/loopover-engine/src/goal-model.tscompileGlobMatcher's supported glob syntaxTest Coverage Requirements
Doc-comment-only change — no new executable lines or branches, so it does not add to the
src/**/packages/loopover-engine/src/**patch-coverage surface Codecov measures. The existingpackages/loopover-engine/test/goal-model.test.tssuite must stay green (runnpm test --workspace @loopover/engineandnpm run test:coveragelocally — this file is insidecoverage.include, so if a doc-comment edit accidentally reformats/removes an existing line it would still need re-verifying).Expected Outcome
computeLaneFit's exact scoring behavior (hard-veto, neutral-default, partial-credit rules) is documented at its own definition site, not left implicit in the implementation or referenced-but-unexplained from the README.Links & Resources
packages/loopover-engine/src/goal-model.ts(the file to change)packages/loopover-engine/src/miner-goal-lane-fit.ts— a caller, and an example of this package's TSDoc stylepackages/loopover-engine/src/opportunity-metadata.ts—computeMetadataLaneFit, the other callerpackages/loopover-engine/README.md's "Metadata opportunity signals" section — wherecomputeLaneFitis referenced by name todaypackages/loopover-engine/test/goal-model.test.ts— existing test coverage to cross-check the documented rules against