Skip to content
Merged
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
4 changes: 2 additions & 2 deletions .claude/routines/desk.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,9 @@ Done when: the PR body starts with this run's "Desk last ran" line, or the new `

### 8. Clean the queue

In QUEUE, remove every queue item whose worklist item ended `actioned` or `dismissed`, or `deferred` as a needs-maintainer result or verdict or a legacy suspect: those wait on the maintainer, whose answer on the PR comes back through step 5. Use `python utils/desk_queue.py` (see its `--help`) or edit the JSON as `QUEUE/README.md` describes, and delete each file left with no items. Leads, items whose subagent failed and items not reached stay queued. Write `ledger/pending.md` from step 7, or delete it once its text is in the PR. Commit these changes as one commit and push them following "Pushing" with `git -C QUEUE push origin HEAD:desk-queue`.
In QUEUE, remove every queue item whose worklist item ended `actioned` or `dismissed`, or `deferred` as a needs-maintainer result or verdict or a legacy suspect: those wait on the maintainer, whose answer on the PR comes back through step 5. Remove them with `python utils/desk_queue.py remove QUEUE <id> ...`, which also records each id as handled, so the writers do not queue the same finding again. Leads, items whose subagent failed and items not reached stay queued. Write `ledger/pending.md` from step 7, or delete it once its text is in the PR. Commit these changes as one commit and push them following "Pushing" with `git -C QUEUE push origin HEAD:desk-queue`.

Done when: after `git -C QUEUE fetch origin desk-queue`, `origin/desk-queue` holds none of the removed item ids and its `ledger/pending.md` matches step 7.
Done when: after `git -C QUEUE fetch origin desk-queue`, no `items` list on `origin/desk-queue` holds a removed id, each removed id is in its file's `handled` list, and `ledger/pending.md` matches step 7.

### 9. Report

Expand Down
89 changes: 89 additions & 0 deletions .github/actions/desk-queue-write/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
name: Write to the desk queue
description: >-
Add JSON-line records to the desk-queue branch with utils/desk_queue.py,
creating the branch when it does not exist. Run it after actions/checkout,
from the repository root, with contents: write.

inputs:
records:
description: File of queue records, one JSON object per line. A missing or empty file writes nothing.
required: true
message:
description: Commit message for the queue commit.
required: true

outputs:
added:
description: Number of items the push added to the queue.
value: ${{ steps.write.outputs.added }}

runs:
using: composite
steps:
- id: write
shell: bash
env:
RECORDS: ${{ inputs.records }}
MESSAGE: ${{ inputs.message }}
BRANCH: desk-queue
INIT_BRANCH: desk-queue-init
run: |
set -euo pipefail
cd "$GITHUB_WORKSPACE"

if [ ! -s "$RECORDS" ]; then
echo "No records to queue"
echo "added=0" >> "$GITHUB_OUTPUT"
exit 0
fi

SCRIPT="$GITHUB_WORKSPACE/utils/desk_queue.py"
QUEUE="$RUNNER_TEMP/desk-queue"
RESULTS="$RUNNER_TEMP/desk-queue-results.txt"

# The queue only grows by appends keyed on stable ids, so a rejected
# push is retried from a fresh copy of the branch; never forced.
for attempt in 1 2 3 4 5 6 7 8; do
git worktree remove --force "$QUEUE" 2>/dev/null || rm -rf "$QUEUE"
git worktree prune
git branch -D "$INIT_BRANCH" 2>/dev/null || true

if git ls-remote --exit-code origin "refs/heads/$BRANCH" > /dev/null; then
git fetch --quiet --depth=1 origin "$BRANCH"
git worktree add --quiet --detach "$QUEUE" FETCH_HEAD
else
echo "::notice title=Desk queue::Creating the $BRANCH branch"
git worktree add --quiet --detach "$QUEUE"
git -C "$QUEUE" checkout --quiet --orphan "$INIT_BRANCH"
git -C "$QUEUE" rm -rfq .
fi

# Rejected records and broken queue files are reported as warnings;
# the valid records are still written.
python3 "$SCRIPT" add "$QUEUE" --jsonl "$RECORDS" \
2> >(sed 's/^desk_queue: /::warning title=Desk queue::/' >&2) | tee "$RESULTS"
git -C "$QUEUE" add -A
if git -C "$QUEUE" diff --cached --quiet; then
echo "Nothing new to queue"
echo "added=0" >> "$GITHUB_OUTPUT"
exit 0
fi

git -C "$QUEUE" \
-c user.name="github-actions[bot]" \
-c user.email="github-actions[bot]@users.noreply.github.com" \
commit --quiet -m "$MESSAGE"
if git -C "$QUEUE" push --quiet origin "HEAD:refs/heads/$BRANCH"; then
ADDED=$(grep -c '^added ' "$RESULTS" || true)
echo "added=$ADDED" >> "$GITHUB_OUTPUT"
echo "::notice title=Desk queue::Queued $ADDED item(s)"
exit 0
fi

WAIT=$(( attempt * 2 + RANDOM % 5 ))
echo "Push rejected (attempt $attempt), retrying in ${WAIT}s"
sleep "$WAIT"
done

echo "::error title=Desk queue::Could not push to $BRANCH after 8 attempts"
exit 1
16 changes: 15 additions & 1 deletion .github/workflows/canonical-source-update.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ concurrency:
cancel-in-progress: false

permissions:
# actions: write lets the job start the TBA enrichment run
actions: write
contents: write
pull-requests: write

Expand Down Expand Up @@ -125,6 +127,9 @@ jobs:
id: merge
env:
SOURCE: ${{ steps.source.outputs.source }}
# Questions the merge would ask a person are answered with their
# default here and written to this file for the desk to check.
DESK_QUEUE_OUT: ${{ runner.temp }}/desk-records.jsonl
run: |
echo "::group::Running merge for source: $SOURCE"

Expand All @@ -150,6 +155,15 @@ jobs:
# Capture which source was processed for commit message
echo "source_label=$SOURCE" >> $GITHUB_OUTPUT

# A queue problem must not hold back the data merge.
- name: Queue the merge's open questions for the desk
if: inputs.dry_run != true
continue-on-error: true
uses: ./.github/actions/desk-queue-write
with:
records: ${{ runner.temp }}/desk-records.jsonl
message: "Queue merge questions from canonical source ${{ steps.source.outputs.source }}"

- name: Verify no conference data loss
run: |
# An automated merge must never delete or rename existing conferences.
Expand Down Expand Up @@ -302,7 +316,7 @@ jobs:
GH_TOKEN: ${{ github.token }}
run: |
echo "::notice title=Triggering TBA Enrichment::Starting TBA conference enrichment workflow"
gh workflow run enrich-tba-conferences.yml -f enrichment_level=full || {
gh workflow run enrich-tba-conferences.yml || {
echo "::warning title=Trigger Failed::Could not trigger TBA enrichment workflow"
}

Expand Down
Loading
Loading