You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
ORB's backtest system became able to replay logic changes (not just thresholds) only after #8129/#8130 captured bounded raw context in fired-event metadata — the exact inputs the rule evaluated. AMS's eligibility-exclusion capture has the same gap: recordEligibilityExclusionSignals (packages/loopover-miner/lib/discover-cli.ts) records ruleId/targetKey/outcome/occurredAt and no metadata, so a captured exclusion can never be re-evaluated under a candidate ContributionProfile — the inputs (labels, assignees, owner, the exact fields filterCandidatesByProfiles evaluates per FilterCandidate in contribution-profile-filter.ts) are dropped. This issue is the AMS mirror of ORB's bounded raw-context capture, and the hard prerequisite for the eligibility backtest CLI (separate issue).
Requirements
⚠️Capture happens only in discover-cli.ts's existing capture helper. This issue is NOT satisfied by: changing filterCandidatesByProfiles' signature or return shape (contribution-profile-filter.ts is pure and stays untouched), capturing on the dry-run branch, or storing unbounded/whole-candidate objects.
Widen recordEligibilityExclusionSignals' parameter type so each excluded entry's candidate carries optional labels?: string[], assignees?: string[], owner?: string — these fields are already present at runtime on the filter's excluded entries (the generic T passthrough of EligibilityExclusion<T>; see FilterCandidate); the call site passes them through with no new computation.
Each recorded event gains metadata with exactly these bounds:
labels: at most 50 entries; assignees: at most 25 entries; each string truncated to 200 characters.
When a cap truncates (array length or string length), add truncated: true to the metadata; omit the key entirely when nothing was truncated.
Absent source fields are omitted from metadata (no nulls, no empty-array placeholders for missing data).
Dry-run behavior unchanged: still no capture of any kind (the existing deliberate exclusion).
Best-effort discipline unchanged: metadata capture must not introduce any new failure path that could abort discovery.
Metadata recorded with all three fields when present; each field omitted when absent from the candidate.
Both arms of every cap: exactly-at-cap (no truncated key) and one-over-cap (clamped + truncated: true) for labels count, assignees count, and string length.
Dry-run records nothing (existing test extended or new).
100% of changed lines and branches covered.
Deliverables
Bounded metadata on eligibility-exclusion fired events per the exact caps above
Pure filter module untouched; dry-run non-capture preserved
Tests covering presence/omission and both arms of every cap, Codecov-visible
Problem
ORB's backtest system became able to replay logic changes (not just thresholds) only after #8129/#8130 captured bounded raw context in fired-event metadata — the exact inputs the rule evaluated. AMS's eligibility-exclusion capture has the same gap:
recordEligibilityExclusionSignals(packages/loopover-miner/lib/discover-cli.ts) recordsruleId/targetKey/outcome/occurredAtand no metadata, so a captured exclusion can never be re-evaluated under a candidateContributionProfile— the inputs (labels,assignees,owner, the exact fieldsfilterCandidatesByProfilesevaluates perFilterCandidateincontribution-profile-filter.ts) are dropped. This issue is the AMS mirror of ORB's bounded raw-context capture, and the hard prerequisite for the eligibility backtest CLI (separate issue).Requirements
recordEligibilityExclusionSignals' parameter type so each excluded entry'scandidatecarries optionallabels?: string[],assignees?: string[],owner?: string— these fields are already present at runtime on the filter's excluded entries (the genericTpassthrough ofEligibilityExclusion<T>; seeFilterCandidate); the call site passes them through with no new computation.metadatawith exactly these bounds:labels: at most 50 entries;assignees: at most 25 entries; each string truncated to 200 characters.truncated: trueto the metadata; omit the key entirely when nothing was truncated.nulls, no empty-array placeholders for missing data).truncatedkey) and one-over-cap (clamped +truncated: true) for labels count, assignees count, and string length.Deliverables
metadataon eligibility-exclusion fired events per the exact caps aboveLinks & Resources
packages/loopover-miner/lib/discover-cli.ts(recordEligibilityExclusionSignals),packages/loopover-miner/lib/contribution-profile-filter.ts(FilterCandidate,EligibilityExclusion)Boundaries
discover-cli.ts+ tests only. No filter changes, no new events, no dry-run capture, no unbounded storage.