Skip to content

Add declarative sorting to work queue recommendations - #65495

Merged
pelikhan merged 4 commits into
mainfrom
copilot/creative-vr-query-language
Oct 4, 2026
Merged

pelikhan merged 4 commits into
mainfrom
copilot/creative-vr-query-language

Conversation

Copilot AI commented Oct 4, 2026 •

Copy link
Copy Markdown
Contributor

work_queue_read recommends the oldest available Work, limiting dispatchers that need a different queue order. This change adds optional sort operators while preserving the existing Work selector and oldest-first default.

  • Query: Sort by id, enqueued, or ID length. Multiple operators break ties in order; remaining ties retain oldest-first order.
  • Scope: Sorting changes the displayed available Work and next_work recommendation only. It does not change Claim selection or dispatch authority.
  • Documentation: Describe the query syntax and its read-only semantics.

For example, to recommend the newest available Work:

{"sort":[{"expression":{"op":"field","field":"enqueued"},"direction":"desc"}]}

Copilot AI and others added 2 commits October 4, 2026 05:08
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title WorkCube: add declarative sorting to work queue recommendations Add declarative sorting to work queue recommendations Oct 4, 2026
Copilot AI requested a review from pelikhan October 4, 2026 05:12
@pelikhan
pelikhan marked this pull request as ready for review October 4, 2026 07:18
Copilot AI balanced review requested due to automatic review settings October 4, 2026 07:18

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

The MCP schema permits inputs that the runtime rejects, creating an inconsistent public tool contract.

Review effort: Balanced
Findings: 1 Medium severity

Open (1)
What changed in this PR

Adds configurable ordering to work queue recommendations while preserving oldest-first defaults and claim semantics.

Changes:

  • Implements bounded, multi-key sorting by ID, enqueue time, or ID length.
  • Adds sorting tests and documents read-only behavior.
File Description
actions/​setup/​js/​work_queue_mcp_server.cjs Implements sorting and exposes its MCP schema.
actions/​setup/​js/​work_queue_mcp_server.test.cjs Tests sorting and runtime validation.
specs/​work-queue/​README.md Defines sorting semantics.
.github/​aw/​work-queue.md Documents dispatcher usage.

properties: {
work: { type: "string", minLength: 1, description: "Optional Work identifier to read." },
sort: {
type: "array",

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Added minItems: 1 and maxItems: 4 to the sort array schema, matching runtime validation. The schema and runtime now also use the key enum. Fixed in f454431.

@github-actions

github-actions Bot commented Oct 4, 2026 •

Copy link
Copy Markdown
Contributor

✅ Ponytail Reviewer completed successfully!

Generated by Ponytail Reviewer for #65495

@github-actions

github-actions Bot commented Oct 4, 2026 •

Copy link
Copy Markdown
Contributor

✅ PR Code Quality Reviewer completed the code quality review.

Review found a blocking schema/runtime mismatch in work_queue_read sort handling, but safeoutputs review comment/review submission was denied by the environment, so no PR write was emitted.

🔎 Code quality review by PR Code Quality Reviewer

@github-actions

github-actions Bot commented Oct 4, 2026 •

Copy link
Copy Markdown
Contributor

🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer

@github-actions

github-actions Bot commented Oct 4, 2026 •

Copy link
Copy Markdown
Contributor

✅ Test Quality Sentinel completed test quality analysis.

Test Quality Sentinel skipped because pre-fetch PR data was unavailable: unable to fetch test file diff

🧪 Test quality analysis by Test Quality Sentinel

@github-actions

github-actions Bot commented Oct 4, 2026 •

Copy link
Copy Markdown
Contributor

✅ Design Decision Gate 🏗️ completed the design decision gate check. See the comment below for the result and any generated ADR draft.

Warning

Threat Detection Engine Failure — The analysis engine could not complete. This is a tooling failure, not a security finding.

What happened

The threat detection engine failed to produce results.

Review the workflow run logs for details.

🏗️ ADR gate enforced by Design Decision Gate 🏗️

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

One simplification opportunity: keep sort keys declarative without introducing an expression AST.

net: -28 lines possible.

Generated by ✂️ Ponytail Reviewer for #65495 · codex · gpt56 · 9.61 AIC · ⌖ 6.4 AIC · ⊞ 13.4K
Comment /ponytail to run again

});
}

function validateSort(sort) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

L38-63: yagni: mini expression language for three fixed sort keys. Use a key enum (id, enqueued, id_length) plus direction, no evaluator.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Replaced the expression objects with a key enum (id, enqueued, id_length) plus direction; the evaluator is removed. Fixed in f454431.

@github-actions

github-actions Bot commented Oct 4, 2026

Copy link
Copy Markdown
Contributor

Comment Memory

reviewed_at: 2026-10-04T07:33:57.561+00:00
review_event: REQUEST_CHANGES
top_themes:
  - MCP sort input schema does not match runtime validation
  - grumpy-coder output was empty/discarded
files_reviewed:
  - .github/aw/work-queue.md
  - actions/setup/js/work_queue_mcp_server.cjs
  - actions/setup/js/work_queue_mcp_server.test.cjs
  - specs/work-queue/README.md
comment_count: 0

Note

This comment is managed by comment memory.

It stores persistent context for this thread in the code block at the top of this comment.
Edit only the text inside the backtick fences; workflow metadata and the footer are regenerated automatically.

Learn more about comment memory

🔎 Code quality review by PR Code Quality Reviewer · copilot · gpt54 · 40.9 AIC · ⌖ 7.31 AIC · ⊞ 19.3K · ◷
Comment /review to run again

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Skills-Based Review 🧠

Applied /tdd and /codebase-design on the new work_queue_read sort feature. The implementation is solid and well-tested (multi-operator sort, tie-breaking, validation edge cases); leaving two non-blocking suggestions.

📋 Key Themes & Highlights

Key Themes

  • Duplicated enqueued lookup: readWorkQueueState computes the Work→enqueued mapping twice via two separate scans of snapshot.projection.transactions (once for sorting, once per-item for the response) — a maintainability/seam risk worth consolidating into one Map.
  • Unaddressed prior thread: the existing Copilot review comment about the sort JSON Schema lacking minItems/maxItems (so schema advertises unbounded arrays validateSort would reject) is still open — reinforced with a concrete fix suggestion.
  • Untested Unicode edge case: the length sort op deliberately uses [...value].length for code-point counting, but no test proves this over a plain .length, so a future refactor could silently regress astral-character handling.

Positive Highlights

  • ✅ Thorough validation (validateSort) with a strict allow-list of operators/fields, rejecting malformed shapes with clear TypeErrors.
  • ✅ Good regression coverage for multi-operator sort, tie-breaking to oldest-first, and the full matrix of invalid sort inputs.
  • ✅ Documentation (work-queue.md, specs/work-queue/README.md) clearly states sorting is read-only and doesn't affect Claim authority — consistent with the rest of the spec's vocabulary.

Note: triage used the pr-triage agent successfully (change_type: new_feature).

@copilot please address the review comments above.

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · copilot · sonnet50 · 53.5 AIC · ⌖ 13.6 AIC · ⊞ 10K
Comment /matt to run again

const workIds = args.work === undefined ? [...snapshot.projection.available, ...Object.keys(snapshot.projection.work).filter(work => !snapshot.projection.available.includes(work))] : [args.work];
const available = [...snapshot.projection.available];
if (args.sort) {
const metadata = new Map(snapshot.projection.transactions.filter(transaction => transaction.kind === "Work").map(transaction => [transaction.work, transaction.enqueued ?? 0]));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[/codebase-design] The metadata Map rebuilds the Work→enqueued lookup from snapshot.projection.transactions, duplicating the same .find(transaction => transaction.kind === "Work" && ...) logic already used per-item at line 101 to populate works[].enqueued. Two independent code paths computing the same value from the same source is a seam risk: if one is changed (e.g. to handle duplicate Work facts or a future metadata shape) without the other, sort order and displayed enqueued can silently diverge.

💡 Suggested consolidation

Build a single enqueuedByWork Map once per readWorkQueueState call (not just when args.sort is set) and reuse it both for sorting and for populating works[].enqueued, e.g.:

const enqueuedByWork = new Map(
  snapshot.projection.transactions
    .filter(t => t.kind === "Work")
    .map(t => [t.work, t.enqueued ?? 0])
);
// ...
enqueued: enqueuedByWork.get(work) ?? 0,

This removes the duplicated .find() scans (O(n) per item) and guarantees the sort and the reported value can never disagree.

@copilot please address this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

A single first-seen enqueuedByWork map now supplies both sort values and each Work response's enqueued field, preserving the existing first-match behavior. Fixed in f454431.

}
}

function evaluateSortExpression(work, expression) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[/tdd] evaluateSortExpression's length op uses [...value].length (correctly counting Unicode code points instead of UTF-16 code units), which is a deliberate and non-obvious choice — but no test exercises an id containing a surrogate pair (e.g. an emoji) to prove the spread actually matters here versus a plain .length.

💡 Suggested test
it("length expression counts code points, not UTF-16 units", () => {
  const snapshot = loadWorkQueueSnapshot(
    writeSnapshot({
      version: 2, sha: "head",
      transactionLog: serializeTransactionLog([
        createWorkTransaction("\u{1F600}", 10), // 1 code point, 2 UTF-16 units
        createWorkTransaction("ab", 10),
      ]),
      worker: null,
    })
  );
  const byLength = [{ expression: { op: "length", field: "id" }, direction: "asc" }];
  expect(readWorkQueueState(snapshot, { sort: byLength }).works.map(i => i.id)).toEqual(["\u{1F600}", "ab"]);
});

Without this, a future refactor to value.length would silently break astral-character identities and nothing would catch it.

@copilot please address this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Added a regression test sorting an emoji ID against a two-character ASCII ID by id_length; it verifies counting Unicode code points rather than UTF-16 units. Fixed in f454431.

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot address the following outstanding work in one pass:

  1. Update this branch with the latest main using make merge-main, resolving any conflicts and preserving the intended changes.
  2. Review (actions/setup/js/work_queue_mcp_server.cjs:120): Encode the documented 1–4 operator bound in the input schema. As written, tools/list advertises empty and arbitrarily long arrays as valid even though validateSort rejects them, so schema-driven clients can generate calls that fail only inside the handler. - Add declarative sorting to work queue recommendations #65495 (comment)
  3. Review (actions/setup/js/work_queue_mcp_server.cjs:38): L38-63: yagni: mini expression language for three fixed sort keys. Use a key enum (id, enqueued, id_length) plus direction, no evaluator. - Add declarative sorting to work queue recommendations #65495 (comment)
  4. Review (actions/setup/js/work_queue_mcp_server.cjs:73): [/codebase-design] The metadata Map rebuilds the Work→enqueued lookup from snapshot.projection.transactions, duplicating the same .find(transaction => transaction.kind === "Work" && ...) logic already used per-item at line 101 to populate works[].enqueued. Two independent code paths computing the same value from the same source is a seam risk: if one is changed (e.g. to handle duplicate Work facts or a future metadata shape) without the other, sort order and displayed enqueued can silently diverge. - Add declarative sorting to work queue recommendations #65495 (comment)
  5. Review (actions/setup/js/work_queue_mcp_server.cjs:60): [/tdd] evaluateSortExpression's length op uses [...value].length (correctly counting Unicode code points instead of UTF-16 code units), which is a deliberate and non-obvious choice — but no test exercises an id containing a surrogate pair (e.g. an emoji) to prove the spread actually matters here versus a plain .length. - Add declarative sorting to work queue recommendations #65495 (comment)
  6. Fix failing check safe_outputs (FAILURE): https://github.com/github/gh-aw/actions/runs/37185396313/job/111389775335.

Push the necessary fixes, reply to each listed review thread and resolve it when addressed. Ignore feedback already answered or resolved. Use the pr-finisher skill and stop when only human review or CI remains; do not trigger CI.

Sous-chef head: f1bb797
Sous-chef work: 266042b4c5492d4501e73c410cbd5ae617a3afb78aa5255241598b8f8ff25afa 2b0fd047fc058829c10084eeffa9fb4273c14740675744d9122a76ef26b76f95 79c3ac5733726d1a391cfce0434ef38273783f8f85ba1068579038c9ed556b1b 80c2210cc0fb9e44d6d865f9e6833670d0cec809dab0af94c59043aca9e9f63b c7cf93e497befdd5e698d00101b0703e4101fe4133d86d433f7c170d07402b7e
Sous-chef state: 2f62da4809cfe0ff719c95a0f658aeb59f1a86ae1c1fa53fcef44ce432daafd5

Generated by 👨‍🍳 PR Sous Chef · pi · haiku45 · 11.9 AIC · ⌖ 9.57 AIC · ⊞ 3K · ◷
Comment /souschef to run again

Copilot AI and others added 2 commits October 4, 2026 08:49
…uery-language

Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>
Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>

Copilot AI commented Oct 4, 2026

Copy link
Copy Markdown
Contributor Author

@copilot address the following outstanding work in one pass:

  1. Update this branch with the latest main using make merge-main, resolving any conflicts and preserving the intended changes....

Merged the latest main with make merge-main, simplified sorting to bounded key/direction operators, consolidated enqueue metadata, added the Unicode length test, and updated the docs. Local formatting, lint, and impacted tests passed. The reported safe_outputs failure was an exhausted GitHub API rate limit while submitting a review, not a code failure; it needs a human CI re-trigger. Changes are pushed in f454431.

Copilot AI requested a review from gh-aw-bot October 4, 2026 09:03
@pelikhan
pelikhan merged commit d8366c5 into main Oct 4, 2026
12 checks passed
@pelikhan
pelikhan deleted the copilot/creative-vr-query-language branch October 4, 2026 12:59
github-actions Bot added a commit that referenced this pull request Oct 5, 2026
…automation.md

dispatch-workflow gained a work_queue selector (actions: write dispatch of
a Claim to a tools.work-queue worker) across #65443/#65494/#65495, but its
own doc entry never mentioned it - only work-queue.md did. Add a one-line
cross-reference so readers of the dispatch-workflow section discover it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

🎉 This pull request is included in a new release.

Release: v0.91.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants