Documentation
¶
Overview ¶
Cost control for `aurumcode review` (AUR-433).
--limite gives the user a hard USD ceiling on what a single review run may spend calling the configured model, and the command REFUSES to call the model at all when the estimate exceeds it. The enforcement itself is not new logic: internal/llm/cost.Tracker.Reserve already computes a per-request estimate and fails closed against a configured ceiling, atomically, BEFORE internal/llm.Orchestrator.Complete ever invokes provider.Complete (see internal/llm/orchestrator.go). This file's only job is to wire that already-existing, already-tested budget package into cmd/aurumcode's provider selection and to report what it decided.
There is exactly one gate: the tracker built by buildCostTracker, passed into llm.NewOrchestrator. Nothing here re-implements or duplicates that decision -- a second, independent check would make the two disagree at the margin and would let a defect in either one hide behind the other.
Command aurumcode's docs subcommand (AUR-426, extended by AUR-447):
aurumcode docs [--source <dir>] [--output <dir>] [--languages <list>]
generates project documentation from source code the same way cmd/regenerate-docs does, but driven by discoverable command-line flags instead of requiring the operator to discover AURUMCODE_-prefixed environment variables first. `aurumcode docs --help` documents every flag and its default.
This subcommand reuses the exact reusable engine cmd/regenerate-docs already wires -- internal/pipeline.ExtractorPipeline driving the internal/documentation/extractors/* language extractors -- instead of reimplementing extraction. cmd/regenerate-docs itself is untouched by this card and keeps working exactly as published; this file only adds a second, flag-driven caller of the same packages.
Rust and C# (AUR-427/AUR-447): registerDocsExtractors below registers the same native, tool-free extractors (internal/documentation/extractors/rust and .../csharp's NewNativeExtractor) cmd/regenerate-docs registers BY DEFAULT. Neither starts a subprocess or reads a repository-controlled build script, so there is nothing to gate behind an opt-in here. Before this card, this file kept its own separate registration list that predated AUR-427 and never grew the two native extractors cmd/regenerate-docs gained -- a real defect a reviewer reproduced: running this command against a Rust-only source tree returned exit 1, "no extractor registered", zero pages, while cmd/regenerate-docs documented the same tree correctly. What stays unwired on purpose is cmd/regenerate-docs's SECOND, opt-in path for these two languages: the cargo/dotnet-backed RustExtractor/CSharpExtractor behind AURUMCODE_ALLOW_REPO_CODE_EXECUTION (cmd/regenerate-docs/repo_code_execution.go), which executes code that lives in the documented repository. That logic is defined inside cmd/regenerate-docs's own `main` package -- unimportable (Go does not allow importing a `main` package) and outside this card's paths -- so it necessarily stays a cmd/regenerate-docs-only capability; this file's registered set is exactly cmd/regenerate-docs's DEFAULT set (the opt-in toolchain off), never a superset of what cmd/regenerate-docs can do.
A genuinely single, shared registration function both binaries call would need to live in an importable package (internal/pipeline or internal/documentation) AND cmd/regenerate-docs/main.go would need to be rewritten to call it instead of keeping its own inline list -- both outside this card's paths, and the latter is exactly the "reescrever pacote existente que ja cumpre a funcao" this card's Non-goals forbids. Absent that, this file's own registerDocsExtractors is kept in exact, visible correspondence with cmd/regenerate-docs's registerLanguageExtractors default branch instead: the residual risk is that a future language added to one list is not mirrored in the other, same as this card's own root cause. See docs/specs/AUR-447.md's "Achado e desenho" section.
Welcome-page LLM generation and Jekyll-build validation are likewise out of scope: nothing `aurumcode docs --help` documents depends on a model call, so the sealed, network-denied acceptance profile always exercises the real code path end to end, deterministically.
See docs/specs/AUR-426.md and docs/specs/AUR-447.md for the full flag reference, exit codes and offline, secret-free examples.
Command aurumcode is the entrypoint for this reconstruction's local code review engine (AUR-430). It currently supports one subcommand:
aurumcode review --base <ref> [--fail-on <level>] [--modelo <nome>] [--seguranca]
which diffs <ref> against HEAD in the git repository rooted at the current working directory, sends that diff to an LLM through internal/llm.Orchestrator, and prints the findings the model reports.
With --fail-on (AUR-431), the command additionally acts as a CI gate: it exits with the distinct code 3 when any finding sits at the chosen severity or above, and 0 otherwise. Without --fail-on, behavior is exactly AUR-430's: findings never change the exit code.
With --modelo (AUR-436), the user chooses which model reviews -- including a local one, by pointing LLM_BASE_URL at a local OpenAI-compatible endpoint -- and when nothing is configured to serve the chosen model the command fails with a clear, actionable error on stderr and exit 1, never an empty review with exit 0. Without --modelo, provider selection is exactly AUR-430's.
With --seguranca (AUR-435), the command additionally runs the project's deterministic security pass over the diff: the ADDED lines are matched against the patterns carried by the security-category rules of the embedded catalog (internal/review/rules/security.yml, scoped by standards/security-review), and the findings print in their own section AFTER the unchanged quality output, each citing its sustaining rule and the standard rule that scopes it. Without --seguranca, stdout is byte-identical to the published contract.
With --pr (AUR-438), the command reviews a GitHub pull request instead of a local ref:
aurumcode review --pr <numero> --repo <dono>/<projeto> --publicar --na-linha
It reads the pull request's diff through the restored GitHub client (AUR-437, internal/git/githubclient), reviews it through the same engine and provider selection as the --base path, and publishes every finding as a pull request comment: at the file's exact changed line when the diff added that line, or as a general pull request comment when the finding sits outside the changed lines, so it is never silently dropped. Publishing refuses, before anything is posted, when the token lacks write permission on the repository. --repo and --publicar are always required with --pr; --na-linha is required too, UNLESS --check (below) is given -- every other flag (--base, --fail-on, --modelo, --seguranca) and its published behavior is unchanged when --pr is absent.
With --check (AUR-439), the command additionally publishes a commit status (internal/git/githubclient.SetStatus, restored by AUR-437) on the pull request's head commit: "failure" when at least one finding is grave (error severity, the same rank --fail-on high|error already names), "success" otherwise -- so a branch protection rule that requires this check blocks the merge until the grave finding is fixed. --check needs a commit SHA exactly like an inline comment already does (GITHUB_SHA), and folds into the very same fail-closed gate instead of a second one.
aurumcode review --pr 42 --repo dono/projeto --publicar --check
With --limite (AUR-433), the command caps what one run may spend calling the model: it estimates the cost before the model is ever invoked and refuses to call it -- spending nothing -- when the estimate exceeds the USD ceiling given, reporting both the estimated and, on success, the real cost on stderr. Without --limite, behavior and output are exactly as already published: no budget is enforced. Like the other --base-path flags, --limite is inert when --pr is given.
With the --base path (AUR-441), the command does not pay twice for the same file: before calling the review engine, it checks internal/review/cache for each changed file's content, under the exact model and prompt version this run would use. A file whose cached entry matches is never resent; a run where every file matches skips the model call entirely. Reused files, when any, are reported on stderr -- stdout is byte-identical whether or not caching engaged. The cache lives at AURUMCODE_CACHE_DIR when the caller sets it, so two invocations that name the same directory reuse each other's entries; without it, each invocation gets its own process-scoped cache and behaves exactly as if caching were off, so nothing shares state across separate `aurumcode` runs unless asked to (see internal/review/cache.ResolveDir). --pr's review path is unaffected.
With AUR-443, a user who has never read the source can discover what this binary does and run a first review without reading code: top-level `aurumcode --help` / `-h` (also `help`) lists every subcommand with a one-line summary and a runnable example, on stdout, exit 0; `aurumcode --version` (also `version`) prints a build-stamped version, on stdout, exit 0 -- see the version var below for how to inject a real value at build time. `review --help` now follows the exact convention `docs --help` already established (AUR-426): an explicitly requested --help is a fulfilled request (stdout, exit 0), and a genuine usage error is a refusal (stderr, exit 2) -- the same channel and exit code for both subcommands, where before this card `review --help` printed usage to stderr with exit 2 and `docs --help` printed to stdout with exit 0. Provider-missing errors (selectProvider, reportModelUnavailable) now point at a concrete, versioned fixture example (tests/fixtures/review/known-problem-response.json) instead of only naming the environment variable to set. computeDiff's git-repository and ref-resolution errors no longer wrap internal/analyzer's own message verbatim: OpenRepo's single error case used to produce a literally duplicated "not a git repository: not a git repository (...)" phrase, and a ref that does not resolve used to leak a raw filesystem path (the pure-Go path, e.g. "open <repo>/.git/refs/heads/<ref>: no such file or directory") or git's own "fatal: ..." wording (the git-binary path); both are now one clean, actionable sentence, and the two backends report the identical text for the same user mistake. See docs/specs/AUR-443.md for the --limite exit code and the model response's unused `summary` field, both of which this card investigated and deliberately left unchanged: docs/specs/AUR-443.md records why.
With AUR-449, `--seguranca` alone no longer needs a provider: the security pass it runs (restored by AUR-442) is a deterministic regex matcher over the diff's added lines and calls no model, so requiring a provider for it was an artificial lock -- the product's only free, offline, deterministic path sat behind the one thing that needs a credential. When --seguranca is given, --modelo is NOT (an explicit model choice is a specific request that must still fail loudly when it cannot be served -- reportModelUnavailable, unchanged), and no provider is configured at all (selectProvider's errNoProviderConfigured, not some other provider failure such as an unreadable fixture path), the command now skips the quality review and runs the security pass alone, reporting its findings -- and says so plainly on stderr before anything prints, never silently. With a provider configured, or with --modelo, or without --seguranca, behavior and output are byte-identical to what was already published: this card does not touch that path. See docs/specs/AUR-449.md.
See docs/specs/AUR-430.md for the base command reference, docs/specs/AUR-431.md for the --fail-on gate, docs/specs/AUR-436.md for --modelo, docs/specs/AUR-435.md for --seguranca, docs/specs/AUR-438.md for --pr, docs/specs/AUR-433.md for --limite, docs/specs/AUR-439.md for --check, docs/specs/AUR-441.md for the review cache, docs/specs/AUR-443.md for the top-level help, version and error-message cleanups, docs/specs/AUR-448.md for the complete no-provider fixture shape (rule_id included) and the stderr warning a discarded finding now gets, and docs/specs/AUR-449.md for running --seguranca without a provider, each with an offline, secret-free example.
AUR-438: the PR review path for `aurumcode review`.
aurumcode review --pr <numero> --repo <dono>/<projeto> --publicar --na-linha
reads a pull request's changes through the restored GitHub client (AUR-437, internal/git/githubclient), runs them through the exact same review engine and provider selection the --base path already uses (internal/review.Reviewer, selectProvider), and publishes every finding as a pull request comment: at the file's exact changed line when the diff actually added that line, or as a general pull request comment when the finding sits outside the changed lines -- so a real finding is never silently dropped just because it cannot be anchored to a line the diff touched (see MUT-001), and one finding's failure to post never costs another finding its own comment (the publish loop aggregates failures instead of aborting on the first one). Publishing delegates authorization to the GitHub write endpoints: a workflow token may have pull-requests:write or statuses:write while the repository role reports push=false, so GET /repos/{owner}/{repo} is not a valid preflight here. The client still fails closed on an actual API denial and refuses when an inline comment would need a commit SHA that is not available (GITHUB_SHA unset): never a POST is built with an empty commit_id.
This file owns only the wiring: flag handling, the diff-shape conversion from the client's package-local types to pkg/types (the client deliberately cannot import pkg/types itself -- see internal/git/githubclient/diff.go), the changed/unchanged-line classification, and the publish loop. It reuses the client and the engine exactly as they already exist; see docs/specs/AUR-438.md.
AUR-439 adds --check: after the comment publish loop above, when --check was given, it publishes one commit status via the same restored client's SetStatus (internal/git/githubclient; the API response is authoritative in the reusable workflow) -- "failure" when at least one finding is grave (error severity), "success" otherwise -- so a branch protection rule that requires this check blocks the pull request's merge until the grave finding is fixed. See publishCheckStatus below and docs/specs/AUR-439.md.
AUR-451 closes the gap its own measurement named: before this card, --seguranca/--fail-on/--limite/--modelo were parsed but never reached this path at all, so the security pass, the severity gate, the cost ceiling and the model choice only ever worked on --base -- the product's main use case, reviewing a pull request, ran none of them. This card wires all four into prReviewOptions below by calling the EXACT functions the --base path already uses (review.SecurityScanWithCoverage, severityRank/countAtOrAbove/exitFindings, printSecurityCoverage, costPrice/buildCostTracker/fixedModelProvider/printCostEstimate/ printRealCost/reportBudgetExceeded, selectProviderForModel/ reportModelUnavailable -- all in cmd/aurumcode/main.go and cmd/aurumcode/cost.go), never a second implementation. A security finding becomes its own published comment exactly like a quality finding does -- inline when the diff added that line, general otherwise -- because its Message already carries its rule citation (review.enforceRuleCitations), so no separate PR-comment section is needed the way the --base path's stdout report has one. Without any of the four flags, prReviewOptions is its zero value and this path's behavior is exactly AUR-438's/AUR-439's, unchanged.
AUR-441: do not pay twice for the same file.
internal/review.Reviewer.GenerateReview sends the whole reviewed diff to the model in a single prompt, one Complete call per invocation (internal/review/reviewer.go:109,117,120; internal/prompt/builder.go folds every file into that one prompt) -- there is no per-file send for a cache to intercept. So the wiring lives here, in cmd/aurumcode, one layer above GenerateReview: filter diff.Files down to the files internal/review/cache does not already hold an entry for BEFORE calling GenerateReview (zero misses skips the call to the model entirely), merge the cache hits' previously-found issues into the printed result, and report how many files were reused.