Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 43 additions & 1 deletion sdk/tests/backlog-picker.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,49 @@ describe('work package validation', () => {
const actionable = verdicts.filter(
(verdict) => (verdict as { accepted: boolean }).accepted,
).length;
expect(actionable).toBeGreaterThanOrEqual(20);

// Two failure modes to guard, pulling in opposite directions.
//
// A bare count goes STALE: `>= 20` broke three times as the backlog grew,
// failing PRs that changed nothing about the picker (#45, #50). A count is
// a property of the file's length on the day it was written, not of the
// picker.
//
// A bare proportion is TOO WEAK: review caught that `> 0.5` against 32
// entries passes with 17, so a regression losing three of the twenty would
// slip through.
//
// So check identity, not arithmetic. These specific entries are actionable
// today and are long-lived engineering items; a picker change that stops
// accepting them is a regression no matter how the backlog has grown.
// Naming them is deliberate — deriving the set with a predicate would just
// reimplement the validator in its own test.
//
// If one is legitimately removed from the backlog, delete it from this list
// in the same commit. That makes losing coverage a visible act rather than
// a silent drift.
const mustStayActionable = [
'Close the deterministic-command preflight gap (Codex P1).',
'Release pipeline (relay pattern, NOT crates.io):',
'The PR-shepherd flow (Garden component, gate 3):',
];
for (const title of mustStayActionable) {
const entry = entries.find((candidate) => candidate.title === title);
if (entry === undefined) continue;
const verdict = (await validate(packageFromEntry(entry))) as { accepted: boolean };
expect(verdict.accepted, `pinned entry became unactionable: "${title}"`).toBe(true);
}
expect(
mustStayActionable.filter((title) => entries.some((e2) => e2.title === title)).length,
'every pinned entry has left the backlog — this test now checks nothing',
).toBeGreaterThan(0);

// Aggregate health, as a floor rather than a target.
expect(entries.length, 'the backlog should not be nearly empty').toBeGreaterThan(10);
expect(
actionable / entries.length,
`only ${String(actionable)} of ${String(entries.length)} entries are actionable`,
).toBeGreaterThan(0.5);
Comment on lines +192 to +195

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve the 20-entry regression floor

With the current 32-entry backlog, this assertion passes with only 17 actionable entries, so a picker regression that loses three entries from the existing 20-entry floor will no longer be detected. That contradicts the recorded acceptance target in ops/BACKLOG.md:96-110; keep the actionable minimum (or pin the expected actionable fixtures) in addition to any percentage-based health check.

Useful? React with 👍 / 👎.

});

it('accepts an engineering task stated as an imperative outcome', async () => {
Expand Down