Skip to content

controller: Read the board scheduler's pass from its job's notices - #84

Merged
cgwalters-bot merged 1 commit into
cgwalters-forge:mainfrom
cgwalters-bot:dispatch/implement/agent-run-38849050524
Oct 16, 2026
Merged

cgwalters-bot merged 1 commit into
cgwalters-forge:mainfrom
cgwalters-bot:dispatch/implement/agent-run-38849050524

Conversation

@cgwalters-bot

Copy link
Copy Markdown
Collaborator

The Controller panel's board row can now show the scheduler's mode (preview or acting) and how many items it would start or started without anyone pasting the log. It reads the board job's check-run annotations, which are the one copy of the pass on api.github.com: summaries have no API, and logs redirect outside the page's connect-src. It takes the notices titled "Board scheduler" and parses them with the existing controller.json formats. A finished job costs at most one request, since the response cache keeps the answer and a 403/404 is remembered per job. When there's no such notice, which is the case until tracker's schedule.cjs emits one ::notice title=Board scheduler:: per pass line (a separate tracker change), or the annotations can't be read, the row stays "unknown · see the job's log" with the paste box. The README documents the contract.

Verified with npm run check (exit 0, 1578 tests). New tests cover preview, acting, absent, 403/404 and 500.

Review: 1 adversarial pass, no blockers. Open follow-ups:

  • Actions keeps at most 10 notices a step, so a long pass is cut short. That shows as an exact, too-low count; it could be flagged by comparing the item lines with the header's candidate count.
  • Annotation order is taken as the API returns it, which GitHub doesn't document. If the header came after the items, the count would be wrong.
  • An empty annotation list is cached as final for that job, so notices that appear a little late are missed.
  • The in-memory set of refused jobs is not cleared when the token changes without a page reload.

Generated by dispatch · ◷

The Controller panel's board row now shows the scheduler's mode and how many items it would start or started, read from the board job's check-run annotations: the notices titled "Board scheduler", one per pass line, parsed with the controller.json formats. That is the one copy of the pass on api.github.com (summaries have no API; logs redirect outside connect-src). The check run comes from the job's check_run_url, since its id isn't the job's; a pass with fewer item notices than the header's candidates is shown as a lower bound with the paste box kept, and a 403/404 is remembered per response cache, so a new sign-in asks again. Until tracker's schedule.cjs emits the notices, the row stays "unknown" with the paste box; the README documents the contract.

Verified with `npm run check` (exit 0, 1584 tests).

Generated-by: AI
@github-actions

Copy link
Copy Markdown

VERDICT: CHANGES — the annotation lookup uses the wrong identifier.

Reviewed head: 7b7505c319d5c908feff3408bfef4821aefa22d2.

  • blocker — src/github/controller.ts:234–236 (caller at line 299): An Actions job ID is not its check-run ID. The workflow-jobs API supplies a separate check_run_url for that association, but this code constructs /check-runs/{job.id}/annotations. For jobs whose identifiers differ, this reads an unrelated check run or gets a 404, which is then remembered permanently for that job. Consequently the main feature cannot retrieve the board job's published pass. Preserve the job's check_run_url, validate its API origin/repository/path before using it, and request that check run's annotations. Add a fixture with distinct job and check-run IDs; the current fixtures bake in the incorrect equality.

  • important — src/github/controller.ts:237–239 and src/github/opsview.ts:710–711: Truncated notices are presented as a complete, exact start count, and the manual correction box is removed. With the documented ten-notices-per-step limit, a header plus nine item notices from a larger pass can display started 0 even when later, omitted items dispatched work. Detect incomplete passes using the header's candidate count (and any required producer completeness marker); show an unknown/partial count and retain the paste fallback rather than treating the prefix as a complete pass. Cover truncation with a header declaring more candidates than the returned item notices.

  • important — src/github/controller.ts:102 and 230–243: The refusal cache is module-global and keyed only by repository/job, unlike the response cache that sign-out clears. If one token receives 403/404, signing out and using a token that can read the annotations still skips the request and displays unknown for that same job. Scope negative entries to the authenticated cache/session, or clear them with authentication changes, and cover an unreadable-token → readable-token transition.

No test suites, formatters, linters, or CI results were run/read. The identifier concern was checked against GitHub's workflow-jobs REST schema, which exposes id and check_run_url separately.

Generated by review for #84 · ◷

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

VERDICT: CHANGES — the annotation lookup uses the wrong identifier.

Reviewed head: 7b7505c319d5c908feff3408bfef4821aefa22d2.

  • blocker — src/github/controller.ts:234–236 (caller at line 299): An Actions job ID is not its check-run ID. The workflow-jobs API supplies a separate check_run_url for that association, but this code constructs /check-runs/{job.id}/annotations. For jobs whose identifiers differ, this reads an unrelated check run or gets a 404, which is then remembered permanently for that job. Consequently the main feature cannot retrieve the board job's published pass. Preserve the job's check_run_url, validate its API origin/repository/path before using it, and request that check run's annotations. Add a fixture with distinct job and check-run IDs; the current fixtures bake in the incorrect equality.

  • important — src/github/controller.ts:237–239 and src/github/opsview.ts:710–711: Truncated notices are presented as a complete, exact start count, and the manual correction box is removed. With the documented ten-notices-per-step limit, a header plus nine item notices from a larger pass can display started 0 even when later, omitted items dispatched work. Detect incomplete passes using the header's candidate count (and any required producer completeness marker); show an unknown/partial count and retain the paste fallback rather than treating the prefix as a complete pass. Cover truncation with a header declaring more candidates than the returned item notices.

  • important — src/github/controller.ts:102 and 230–243: The refusal cache is module-global and keyed only by repository/job, unlike the response cache that sign-out clears. If one token receives 403/404, signing out and using a token that can read the annotations still skips the request and displays unknown for that same job. Scope negative entries to the authenticated cache/session, or clear them with authentication changes, and cover an unreadable-token → readable-token transition.

No test suites, formatters, linters, or CI results were run/read. The identifier concern was checked against GitHub's workflow-jobs REST schema, which exposes id and check_run_url separately.

Generated by review for #84 · ◷

@cgwalters-bot

Copy link
Copy Markdown
Collaborator Author

Fix round 1 of 2 for 7b7505c319d5: claimed.

Generated-by: https://github.com/cgwalters/#llms

@cgwalters-bot

cgwalters-bot commented Oct 16, 2026 •

Copy link
Copy Markdown
Collaborator Author

Fix round 1 of 2 for 7b7505c319d5: run.

Generated-by: https://github.com/cgwalters/#llms

@cgwalters-bot

cgwalters-bot commented Oct 16, 2026 •

Copy link
Copy Markdown
Collaborator Author

✅ dispatch ended well. Result: #84

@cgwalters-bot
cgwalters-bot force-pushed the dispatch/implement/agent-run-38849050524 branch from 7b7505c to 35d3915 Compare October 16, 2026 04:37
@github-actions

Copy link
Copy Markdown

VERDICT: APPROVE

Reviewed admitted head: 35d3915.

Follow-ups

  • [important] src/github/opsview.ts:717 (interaction with src/github/homeview.ts:388-394): A newly retrieved partial pass can remain invisible. fillOps unconditionally replaces each new .ctl-output with the previous node for the same job, even when the user has not pasted anything. If a cached render initially shows unknown and a subsequent network read supplies a partial pass, both renders use this wrapper and the old unknown detail wins on every refresh. Likewise, a transient annotation failure followed by a successful partial response never updates the row. Preserve the paste value/open state rather than the whole detail node, or only preserve actual pasted evidence. Add a cache-only/unknown → partial render regression test.

  • [important] src/github/controller.ts:245: Every annotation response, including an empty list, is treated as permanently final. The completed job status and its annotation list are separate API reads; an empty or not-yet-complete annotation response on the first read is therefore retained without revalidation, so notices becoming visible later cannot repair the row (and a truncated first response cannot gain its missing items). Use a bounded retry/revalidation policy for absent or incomplete passes rather than accepting every response as final, and cover a first-empty/then-populated response.

No existing test suites, formatters, or linters were run. Static review included the diff, surrounding loader/cache/render code, and git diff --check origin/main...HEAD (exit 0).

Generated by review for #84 · ◷

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

VERDICT: APPROVE

Reviewed admitted head: 35d3915.

Follow-ups

  • [important] src/github/opsview.ts:717 (interaction with src/github/homeview.ts:388-394): A newly retrieved partial pass can remain invisible. fillOps unconditionally replaces each new .ctl-output with the previous node for the same job, even when the user has not pasted anything. If a cached render initially shows unknown and a subsequent network read supplies a partial pass, both renders use this wrapper and the old unknown detail wins on every refresh. Likewise, a transient annotation failure followed by a successful partial response never updates the row. Preserve the paste value/open state rather than the whole detail node, or only preserve actual pasted evidence. Add a cache-only/unknown → partial render regression test.

  • [important] src/github/controller.ts:245: Every annotation response, including an empty list, is treated as permanently final. The completed job status and its annotation list are separate API reads; an empty or not-yet-complete annotation response on the first read is therefore retained without revalidation, so notices becoming visible later cannot repair the row (and a truncated first response cannot gain its missing items). Use a bounded retry/revalidation policy for absent or incomplete passes rather than accepting every response as final, and cover a first-empty/then-populated response.

No existing test suites, formatters, or linters were run. Static review included the diff, surrounding loader/cache/render code, and git diff --check origin/main...HEAD (exit 0).

Generated by review for #84 · ◷

@cgwalters-bot
cgwalters-bot merged commit 1f8671f into cgwalters-forge:main Oct 16, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant