Commit Graph

1 Commits

Author SHA1 Message Date
b924d1e9cb feat: propose-work — push, open the PR, and move the issue, in one command
GITEA-SETUP.md has listed this under "Still to build" since 2026-09-04:

  `propose-work`, superseding `push-work` -- push the branch AND open the PR
  with `Closes #N` AND set the label, in one step. Today `push-work` does the
  first third; the other two thirds being manual is how they get skipped.

PROTOCOL.md 145-149 requires all three:

  * branch `auto/<agent>/<issue#>-<topic>`, one item per branch
  * open the PR with `Closes #<issue>` in the body
  * label the issue `state/needs-human` and say, in one line, what to look at

Until now those were three things to remember, and PR #20 had to add a warning
to `port-loop.md` about the two that get forgotten. A rule enforced by memory
decays; this makes the sequence structural.

WHAT IT DOES NOT DO is reimplement push-work's refusals -- it CALLS push-work,
so `main`, shared branches and force-push stay refused in exactly one place.
Duplicating them would let the copies drift, and the copy that drifts is the
one that matters.

Three design choices worth stating:

  * THE ISSUE NUMBER IS DERIVED FROM THE BRANCH NAME, which PROTOCOL already
    specifies as `auto/<agent>/<issue#>-<topic>`. So a PR cannot cite a
    different issue than the branch was cut for -- a mismatch no reviewer would
    catch. `-i` overrides.
  * `-m` IS MANDATORY. PROTOCOL says an issue in `state/needs-human` must say
    what to look at and what pass and fail look like, "so a person can judge it
    in under a minute". Refusing without that line is cheaper than letting the
    label carry an empty promise and costing a human a round trip.
  * IT MOVES THE LABEL RATHER THAN ADDING IT -- other `state/*` labels are
    removed. Leaving `state/in-progress` attached makes the board lie about
    what is waiting on a person.

The token is read from a file and handed to curl through a `--config` document
on stdin: never an argument, never exported. Arguments are world-readable in
/proc and this token can push. Verified that the mechanism actually delivers
the header rather than silently dropping it -- with a bogus token the API
answers "invalid username, password or token", while the same URL with no
header returns the list anonymously, so the header is demonstrably being read.

Also verified: issue derived from the branch (#42 from
`auto/decoder/42-widget-census`), refusal without `-m`, refusal when the branch
carries no number, `--dry-run` sends nothing, and repo/API derivation from the
remote. `--dry-run` deliberately does NOT require a credential -- it exists so
an agent can check the command it is about to run, and demanding a token it
never sends would make the check unavailable exactly where it is cheapest.

Identical in both agents' bin/ on purpose: the agent name comes from the
branch, so there is nothing per-agent to diverge.

UNVERIFIED, and stated as such: no end-to-end run. That needs a real token and
a real issue, which this desktop does not have -- it is the second machine, and
the agent credentials live on the agent box. Everything above the network call
is exercised; the POSTs are not.

Refs #11

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-10 19:17:41 +02:00