Pular para conteúdo

AUR-444: the Action's entrypoint invokes flags that exist

Documento histórico do board. Pode descrever componentes removidos; para uso atual, consulte o guia do produto.

Problem

The GitHub Action published from this repository (scripts/action-entrypoint.sh, Dockerfile, action.yml) announced that it runs an automated code review, but three things made that announcement false:

  1. scripts/action-entrypoint.sh's review mode invoked "$AURUMCODE_CLI" review --provider= --model= --api-key= --github-token= --post-comments=. None of those five flags exist on cmd/aurumcode's review command; the binary would refuse the parse (usage exit 2) before reviewing a single line.
  2. The comments in scripts/action-entrypoint.sh and Dockerfile claimed there is no cmd/cli (or, in the Dockerfile's phrasing, no other main package) in the source tree, and the Dockerfile did not build or copy cmd/aurumcode into the image. Even with flag names fixed, the binary the entrypoint tried to invoke was never inside the image.
  3. action.yml claimed a gomarkdoc failure is fatal for Go documentation. False since AUR-424, which replaced that subprocess with go/parser + go/doc + go/printer; the same false claim, in paraphrased form, was also present in Dockerfile.

Fix

1. Real flags, mapped deliberately

cmd/aurumcode review's only required flag is --base <ref>: the ref this run diffs against HEAD. Everything else the review command reads (LLM_API_KEY, LLM_BASE_URL, LLM_MODEL, AURUMCODE_LLM_FIXTURE, GITHUB_TOKEN) is read straight from the process environment by cmd/aurumcode itself (main.go's selectProvider, pr.go's newGitHubClient) -- none of it is a flag, so the entrypoint passes nothing extra for it; it inherits those variables from the container's own environment exactly as GitHub Actions (or docker run -e) sets them.

scripts/action-entrypoint.sh now sends exactly:

"$AURUMCODE_CLI" review --base="${AURUMCODE_BASE_REF}"

AURUMCODE_BASE_REF is this entrypoint's own new required input: the ref --base diffs against HEAD (for example, the pull request's base commit SHA -- github.event.pull_request.base.sha, the same value .github/workflows/examples/code-review.yml already wires into --base). It is a usage error (exit 64) when unset, never a silent no-op review.

Inputs mapped, and inputs dropped. The previous revision's LLM_PROVIDER and POST_PR_COMMENTS inputs had no real consumer at all: cmd/aurumcode has no notion of an LLM "provider" name (provider selection is entirely env-var driven) and no --post-comments concept on the --base path (publishing is --pr-only, behind --publicar). Both are removed rather than mapped to something they never meant.

cmd/aurumcode review's other real flags -- --fail-on, --modelo, --seguranca, --limite, and the --pr/--repo/--publicar/--na-linha family -- are not wired into this mode. Wiring the --pr family would mean inventing pull-request-number extraction from GITHUB_EVENT_PATH this entrypoint never had and this card never observed anyone running (Non-goals); .github/workflows/examples/code-review.yml's own canonical review invocation is review --base "${BASE_SHA}" -- the same flag, --base, though that example spells it space-separated where this fix uses --base=<ref>; Go's flag package parses both forms identically. A future card can wire the rest deliberately, against an observed need.

2. The --check discrepancy: measured twice, differently, and why it is still not wired in

This card's own "Achado medido" section names --check among "the real flags, today". First measurement, against this worktree's tip at the time: absent. go build ./cmd/aurumcode && ./aurumcode review --help printed no -check, and git merge-base --is-ancestor cf3273f HEAD (the AUR-439 commit that adds it) reported NOT ANCESTOR -- only a board bookkeeping commit (9e78890, "AUR-439 crosses to done with evidence and delivery record") had moved that card to done on this line of history without ever integrating its code. That was reported as a genuine board-integrity gap this card could not fix itself (.board/cards is a forbidden path for it).

The coordinator has since merged the approved AUR-439 SHA onto this card's base. Second measurement, against the corrected tip:

$ go build -o aurumcode ./cmd/aurumcode && ./aurumcode review --help
  -base string
  -check
        publish a commit status (AUR-439) that fails when a grave
        (error-severity) finding is present, blocking the pull request's
        merge; with --pr, satisfies the --na-linha requirement on its own
        (default: off)
  -fail-on string
  -limite string
  -modelo string
  -na-linha
  -pr int
  -publicar
  -repo string
  -seguranca

--check now exists. Per this card's own instruction -- verify every flag independently, never trust a hand-written list -- this second measurement governs, and tests/unit/AUR-444.go (go/parser over cmd/aurumcode's source) and tests/integration/AUR-444.go (the real built binary's own --help) both confirm it dynamically rather than by a note in this file.

Decision: --check is still not wired into scripts/action-entrypoint.sh. Reading cmd/aurumcode/main.go and pr.go on this tip: check := fs.Bool("check", ...) is registered on the shared review flag set, but it is only ever read inside runPRReview -- it is passed to that function and nowhere else, and runPRReview is reached only when --pr is given (cmd/aurumcode/main.go's prGiven dispatch). AUR-439's own doc comment states its declared command surface directly: review --pr N --repo o/r --publicar --check. So --check is not an independent capability this entrypoint could add on top of the --base path this card already wires; it is a fourth member of the --pr family this spec's Fix section 1 already named as out of scope, for the same three reasons, now confirmed against real code instead of inferred:

  1. Activating --check requires --pr (a pull request number), which this entrypoint has never extracted from GITHUB_EVENT_PATH. Doing so now would be new capability nobody asked for and this card never observed anyone running -- exactly what Non-goals rules out.
  2. --repo is required alongside it -- another input this entrypoint does not currently derive from anything.
  3. The --pr path calls client.HasWritePermission (a live GitHub API call) before anything else, and --check itself needs a commit status API call to publish. This card's own Preconditions state the acceptance sandbox denies network; a capability this card could not test at all inside its own declared acceptance is not one this card should ship as if proven.

If a future card wires the --pr family into this entrypoint (PR-number extraction, --repo derivation, a network-capable acceptance path or a fixture GitHub server as AUR-438's own acceptance already builds), --check is the natural, cheap addition alongside it: it needs no code of its own here, only --check="${AURUMCODE_CHECK:-false}" threaded next to --publicar. This card does not do that, because doing it without observing or testing any of it would be inventing behavior on top of already-fake flags -- the same defect this card exists to remove, one flag later.

3. The binary is in the image

Dockerfile now builds cmd/aurumcode alongside cmd/regenerate-docs and copies both into the final image:

RUN CGO_ENABLED=0 go build -ldflags="-s -w" -o aurumcode ./cmd/aurumcode
...
COPY --from=builder /build/aurumcode /app/aurumcode

scripts/action-entrypoint.sh's AURUMCODE_CLI now defaults to ${AURUMCODE_BIN_DIR}/aurumcode (was: ${AURUMCODE_BIN_DIR}/cli, a path nothing ever built). The image's test -x fail-fast check (Dockerfile) asserts /app/aurumcode exists so the script and the image cannot drift apart silently again.

4. qa mode regression, closed in the same pass

Before this fix, run_qa was unguarded: once a real aurumcode binary exists at AURUMCODE_CLI, require_binary's file-existence check passes, and "$AURUMCODE_CLI" qa ... would hit cmd/aurumcode's default: case ("unknown command") and exit 2 -- a code this file's own EXIT CODES table never documents -- killing the script under set -e instead of reporting one of the three documented outcomes. cmd/aurumcode publishes exactly two subcommands, review and docs; it has never had a qa subcommand. qa mode now fails closed, before the binary is ever invoked, with the documented environment-failure exit 3:

ERROR (environment): mode 'qa' requires a 'qa' subcommand that '.../aurumcode'
does not publish (it implements only review and docs; see
cmd/aurumcode/main.go). Select a mode this image supports (review,
documentation, qa, all).

AURUMCODE_MODE=all still runs review then documentation then qa (unchanged call order). Whenever review and documentation both succeed, all now reaches the qa stage and stops there with the same documented exit 3 -- never the undocumented 2. When review or documentation fails first, all still stops at that earlier stage exactly as before this card, with its own already-documented exit; this card changes nothing about that ordering, only what happens once execution does reach qa. Only the qa-alone path (AURUMCODE_MODE=qa) is exercised directly by this card's e2e proof; all reaching the same run_qa function is a consequence of the two functions being identical, not a separately re-verified path.

5. gomarkdoc prose, fixed where it actually appeared -- twice

action.yml's "Install extractor toolchains" step no longer installs gomarkdoc unconditionally; the comment now says Go needs no external tool since AUR-424 and specifically still names the seven languages that do (python/pydoc-markdown, javascript/typedoc, csharp/dotnet+xmldocmd, cpp/doxygen, rust/cargo, bash/bash, powershell/pwsh) -- the same false claim, in paraphrased form ("the Go extractor shells out to gomarkdoc"), was also in Dockerfile's builder-stage comment and its now-removed tools build stage; both are corrected together, and the tools stage and its COPY --from=tools .../gomarkdoc are removed rather than left installed alongside a comment that says it is unnecessary.

How this is proved: the read_paths closure

An earlier measurement of this card's own read_paths found it listing cmd/aurumcode but none of the internal/... packages that source imports (internal/analyzer, internal/prompt, internal/review, internal/llm, internal/security/redaction, internal/git/githubclient, pkg/types, and the internal/documentation/... + internal/pipeline packages the docs subcommand reuses). Confirmed empirically: staging only the then-declared read_paths and running go build ./cmd/aurumcode failed offline ("finding module for package .../internal/analyzer" et al.), because those packages were not on disk and the sealed acceptance denies network. That was a genuine gap this card could not repair itself (.board/cards is a forbidden path for it).

read_paths has since been corrected to carry the full closure. As a result:

  • tests/unit/AUR-444.go still proves criterion (a) with go/parser alone (no build needed) -- this did not change, and stays the fast, import-free, always-available proof.
  • tests/integration/AUR-444.go now ALSO builds the real cmd/aurumcode binary inside the staged acceptance root and confronts the entrypoint's argv against that binary's own --help output -- criterion (a) proved by running the artifact, not only by reading its source.
  • tests/e2e/AUR-444.sh builds and invokes the real binary as a required step (previously best-effort, gated on the closure happening to be present), asserting it does not reject the entrypoint's flags as unrecognized -- alongside its stand-in-binary scenarios, which remain the right tool for proving the entrypoint's OWN control flow (the AURUMCODE_BASE_REF gate, exact argv construction, determinism, the qa regression fix) independently of cmd/aurumcode's flag registration.

Command

AURUMCODE_MODE=review \
AURUMCODE_BASE_REF=<ref> \
GITHUB_WORKSPACE=<git-repo-path> \
[AURUMCODE_CLI=<path-to-aurumcode>] \
[LLM_API_KEY=... LLM_BASE_URL=... LLM_MODEL=...] \
[AURUMCODE_LLM_FIXTURE=<path>] \
[GITHUB_OUTPUT=<path>] \
bash scripts/action-entrypoint.sh

AURUMCODE_CLI defaults to ${AURUMCODE_BIN_DIR}/aurumcode (AURUMCODE_BIN_DIR defaults to /app, the path the Dockerfile builds).

Exit codes

Unchanged from the file's own pre-existing, self-documented convention (scripts/action-entrypoint.sh's own header comment):

Code Meaning
0 The requested mode ran and produced what it promises.
1 Behavioral failure: the pipeline ran and the result is wrong or absent (includes the review binary reporting failure).
3 Environment failure: a binary, script or workspace this image cannot supply itself is missing -- includes the binary being absent at AURUMCODE_CLI, and now qa mode unconditionally (no qa subcommand exists to run).
64 Usage error: no mode, an unimplemented mode, or a mode invoked without configuration it requires -- includes review without AURUMCODE_BASE_REF.

Executable example (offline, no secret)

cat > /tmp/fake-aurumcode <<'EOF'
#!/bin/sh
echo "reviewed: $*"
exit 0
EOF
chmod +x /tmp/fake-aurumcode

mkdir -p /tmp/workspace

AURUMCODE_MODE=review \
AURUMCODE_BASE_REF=deadbeef \
GITHUB_WORKSPACE=/tmp/workspace \
AURUMCODE_CLI=/tmp/fake-aurumcode \
bash scripts/action-entrypoint.sh

Expected output includes Review: passed and, along the way, reviewed: review --base=deadbeef -- proving the entrypoint invokes the binary with exactly review --base=<ref>, nothing else. Swap the stand-in for a real cmd/aurumcode build and this becomes a genuine review, given a real git workspace and a provider (LLM_API_KEY/LLM_BASE_URL, or AURUMCODE_LLM_FIXTURE for a deterministic offline response).

Diagnosis of failure

  • ERROR (usage): AURUMCODE_MODE is not set... (exit 64) -- set AURUMCODE_MODE to review, documentation, qa or all.
  • ERROR (usage): mode 'review' requires AURUMCODE_BASE_REF... (exit 64) -- set AURUMCODE_BASE_REF to the ref --base should diff against HEAD.
  • ERROR (environment): mode 'review' requires the executable '.../aurumcode'... (exit 3) -- the image (or your override of AURUMCODE_CLI) does not actually carry the binary; build it from cmd/aurumcode.
  • ERROR (environment): mode 'qa' requires a 'qa' subcommand... (exit 3) -- qa is not implemented by cmd/aurumcode and is not this card's scope; select review, documentation or all (which itself still stops at the same qa message).
  • ERROR: review pipeline reported failures. (exit 1) -- the binary ran and returned non-zero; its own stderr (printed above this line) names the reason (missing provider configuration, a diff it could not read, etc.).

Non-goals carried over from the card

  • No behavior is added that nobody can observe by running the declared command above: the other real review flags stay unwired until a future card demonstrates an observed need for them.
  • internal/git/githubclient, internal/review, internal/llm and every other package cmd/aurumcode imports are unmodified; this card only integrates what already exists.

Known gap this card does not close

action.yml at the repository root is a composite action that generates documentation only (go build ./cmd/regenerate-docs, run directly in a step); it does not use Dockerfile or scripts/action-entrypoint.sh at all, so no shipped GitHub Action currently wires a container action's AURUMCODE_MODE=review inputs end to end. This predates this card (its own history shows action.yml has always been the documentation composite action) and is out of this card's declared paths/Outcome, which is specifically the three named false claims. Recorded here so the next card that touches Action wiring does not have to rediscover it.