Skip to content
Closed
Show file tree
Hide file tree
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
13 changes: 7 additions & 6 deletions sdk/src/backlog-picker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@

/** First bold top-level bullet: `- **Title** rest`. */
const ENTRY = /^- \*\*(.+?)\*\*\s*(.*(?:\n .*)*)/m;
const ACTION_TITLE =
/** Work describes a change or a required outcome; reference notes do not. */
const WORK_INTENT =
/\b(?:add|build|change|close|create|document|fix|implement|must|persist|refuse|release|remove|rename|replace|sharpen|touch(?:es|ing)?|update|validate|verified by|wire)\b/i;

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 Avoid restricting work intent to a closed verb list

For a valid task whose title is not one of these exact imperatives and whose body uses an unlisted verb, WORK_INTENT discards otherwise valid explicit checks. In this commit's backlog, “The executable bit does not survive the snapshot upload” has an ops/cargo.sh scope and an explicit command but says “Invoke it”; the parent accepted it, while this commit rejects it with missing_definition_of_done, reducing the aggregate actionable count from 4 to 3. Work phrased with verbs outside this list therefore becomes unselectable.

Useful? React with 👍 / 👎.

const IMPERATIVE_TITLE =
/^(?:add|build|change|close|create|document|fix|implement|persist|refuse|release|remove|rename|replace|sharpen|update|validate|wire)\b/i;
const NOTES_TITLE = /^(?:notes?|release notes|upstream issues)\s*(?:\(|:|$)/i;

export interface BacklogEntry {
title: string;
Expand Down Expand Up @@ -122,11 +124,10 @@ export function packageFromEntry(entry: BacklogEntry): Record<string, unknown> {
const explicitChecks = (entry.body.match(/`[^`]+`/g) || [])
.map((candidate) => candidate.slice(1, -1))
.filter((candidate) => /\s/.test(candidate));
const definitionOfDone = NOTES_TITLE.test(entry.title)
? []
: explicitChecks.length > 0
const definitionOfDone =
explicitChecks.length > 0 && WORK_INTENT.test(`${entry.title} ${entry.body}`)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Derive scope for prose-only engineering tasks

When an engineering entry names no backticked path, this condition can now supply a definition of done, but files remains empty and validateWorkPackage still returns missing_scope. Running the requested aggregate against this commit's ops/BACKLOG.md yields TOTAL=31 ACTIONABLE=3, not the required minimum of 20; for example, “Close the deterministic-command preflight gap” remains rejected. The actionability change must also derive usable scope from prose or revise the package requirement rather than changing only definitionOfDone.

Useful? React with 👍 / 👎.

? explicitChecks
: ACTION_TITLE.test(entry.title)
: IMPERATIVE_TITLE.test(entry.title)
? [entry.title.replace(/[.:]\s*$/, '')]
: [];
return {
Expand Down
4 changes: 2 additions & 2 deletions sdk/tests/backlog-picker.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,9 @@ describe('work package validation', () => {
});
});

it('refuses a dated notes blob even when identifiers look actionable', async () => {
it('refuses an observations blob even when identifiers look actionable', async () => {
const work = packageFromEntry({
title: 'Upstream issues (2026-08-27):',
title: 'Incident observations',
body: 'relay#1620 (`--daemon` crash + `worker status` blind). Acceptance: `regressions/`.',
});

Expand Down