Skip to content

fix(recruit): native clipboard copy + deferred-confirm target cap#163

Merged
Sootopolis merged 2 commits into
mainfrom
wip
Jul 14, 2026
Merged

fix(recruit): native clipboard copy + deferred-confirm target cap#163
Sootopolis merged 2 commits into
mainfrom
wip

Conversation

@Sootopolis

Copy link
Copy Markdown
Owner

What

Two operator-facing recruit fixes surfaced from a live ccas recruit session.

1. Clipboard copy actually works (cli). The confirm-flow and --report copy wrote only an OSC 52 terminal escape, which GNOME Terminal / VTE silently ignore — clipboard stayed empty while "Copied N usernames." printed unconditionally (OSC 52 has no ack). Now shells out to a native tool by environment (wl-copy Wayland / xclip X11 / pbcopy macOS), whose daemon keeps owning the selection after the CLI exits; OSC 52 is kept only as an SSH fallback, and the success line prints only on a real exit 0.

2. Deferred-confirm no longer over-invites (recruitment). A chunk overshoot (the last explore batch runs fully) persists more Deferred candidates than the run's target; the interactive confirm flipped all of them, so --report showed e.g. 31 for a target of 30. The confirm now matches the auto-confirm path: it invites only the target set and leaves the excess Deferred to carry to the next run. The run stores its effective target; /found and the confirm flip both cap at target − already-invited-this-run (lowest player_ids first) — idempotent re-POST, overshoot carried forward, not deleted.

3. Report/clipboard == file output. Drop player_ids that don't resolve to a handle (paste-ready lists carry only invitable usernames), matching the server's usernamesFor; showReport logs the resolved count.

Fixes

  • Empty clipboard after confirm / --report on GNOME/Wayland.
  • --report invited count one over target (over-invite via uncapped confirm).

Testing

  • Full sbt test: 1032 passed, 0 failed (pre-push hook, green).
  • New/updated recruitment tests: excess stays Deferred & carries forward (auto-confirm); deferred-confirm caps at target + is idempotent on re-POST (secondFlip == 0, invited stays at target).

⚠️ Deployment note

recruitment_run gains a nullable target column (CREATE TABLE is canonical; legacy NULL rows = no cap). Apply to any existing DB before deploying:

ALTER TABLE recruitment_run ADD COLUMN IF NOT EXISTS target INT;

Already applied to local ccas / ccas_test; prod (Neon) still needs it.

🤖 Generated with Claude Code

Sootopolis and others added 2 commits July 14, 2026 13:54
The confirm-flow and `--report` copy wrote only an OSC 52 terminal
escape, which GNOME Terminal / VTE silently ignore, so the clipboard
stayed empty while "Copied N usernames." printed unconditionally (OSC 52
has no acknowledgement to check).

Prefer a native clipboard tool selected by environment (wl-copy on
Wayland, xclip on X11, pbcopy on macOS) whose forked daemon keeps owning
the selection after this short-lived CLI exits; a JVM/AWT clipboard would
lose the contents the moment we exit. OSC 52 is kept only as a remote/SSH
fallback, and the "Copied" line now prints only when the tool exits 0;
otherwise the usernames (already listed above) plus a hint are shown.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A chunk overshoot (the last explore batch runs fully, no mid-chunk stop)
persists more passing candidates as Deferred than the run's target. The
interactive confirm (confirmDeferredByRun) flipped ALL of them to Invited,
uncapped, so `ccas recruit --report` showed e.g. 31 invited for a target
of 30 — one more than intended.

Match the auto-confirm path, which already invites only the target set
and leaves the excess Deferred to carry to the next run (selectDeferredBy
Club). The run now stores its effective target, and both the /found prompt
and the confirm flip cap at `target - already-invited-this-run` (lowest
player_ids first). That keeps the confirm idempotent — a re-POST flips 0,
per the endpoint contract — and carries the overshoot forward rather than
deleting it.

Also align the report/clipboard username list with the file output: drop
player_ids that don't resolve to a handle (paste-ready invite lists carry
only invitable usernames), matching the server's usernamesFor, and log the
resolved count in showReport.

Schema: recruitment_run gains a nullable `target` column (CREATE TABLE is
canonical; legacy NULL rows fall through to no cap). Apply
`ALTER TABLE recruitment_run ADD COLUMN IF NOT EXISTS target INT` to any
existing database (incl. prod) before deploying this.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Sootopolis
Sootopolis merged commit 8caa10d into main Jul 14, 2026
1 check 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