pigweed / pw_ghish
AGENTS.md561 starsChanged 16 days agoApache-2.0View on GitHub
pw_ghish (./gh) provides GitHub CLI (gh pr, gh run, gh issue, gh auth) commands and multi-agent worktree management (gh wt, gh sense, gh hook) for projects across the Gerrit and LUCI ecosystem (including Pigweed, Fuchsia, Chromium, Android, and downstream repositories). Every change to pw_ghish (and every review via /review, .agents/agents/go_ghish_reviewer.md, and .agents/agents/ghish_security_reviewer.md) MUST enforce these 16 non-negotiable invariants. Regressing into silent failures, swallowed errors, defensive masking, data loss, policy leakage, context bloat, or hacking without tests is STRICTLY PROHIBITED.
- Commits and pushes
Where files are headingNew AGENTS.md files have more rules about keeping secrets out of the code, and fewer about code style.
Of the AGENTS.md files we read, the 31,439 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.
In this repository20 other files it gives its agents.
- AGENTS.mdAGENTS.md
- pw_ide/AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- BluetoothSkill
- Code ReviewSkill
- crankSkill
- docsSkill
- freshenSkill
- ghishSkill
- manual-cli-testSkill
- oncallSkill
- pw_async2Skill
- Pigweed Kernel TestingSkill
- C++ Pigweed RPC ServicesSkill
- respondSkill
- reviewSkill
- run-presubmit-checksSkill
- saleae-analyzerSkill
- Use Pigweed Toolchain ToolsSkill
- Multi-Agent Worktree & Bazel Cache ManagementSkill
The file
Show its rules and text
We split this AGENTS.md into the rules it gives an agent
24 rules. About 0 are common, 2 are distinctive, and 22 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
22
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 7
Decoupled Policy: Avoid baking project-specific assumptions directly into core commands.
- Very specific: line 14
Every change to pw_ghish (and every review via /review, .agents/agents/go_ghish_reviewer.md, and .agents/agents/ghish_security_reviewer.md) …
- Very specific: line 17
MANDATORY: Every Cobra subcommand with an action MUST use RunE: func(cmd *cobra.Command, args []string) error.
- Very specific: line 18
STRICTLY PROHIBITED: NEVER return nil when an underlying operation, RPC, config parse (LoadCommandProjectConfig), or subprocess failed.
- Very specific: line 24
STRICTLY PROHIBITED: When a pointer, dependency, or runner is an internal invariant that should *never* be nil, DO NOT defensively sweep it …
- Distinctive: line 28
MANDATORY: Never duplicate command-config loading, Gerrit error translation, git trailer parsing, or stack validation across subcommands:
- Very specific: line 29
Always call LoadCommandProjectConfig(cmd) instead of re-implementing GetConfig(cmd) + LoadProjectConfig(ctx).
- Very specific: line 30
Always issue Gerrit REST requests through the native *GerritClient (gerrit.go), inspect status codes with IsGerritHTTPStatus (never …
- Very specific: line 31
Keep pre-push commit-stack validation in a single shared pass (ValidateCommitStack in push_pipeline.go) rather than running duplicate git …
- Very specific: line 47
HTTP 401/403: Never return raw HTTP 401/403.
- Very specific: line 55
STRICTLY PROHIBITED: NEVER add ad-hoc git.ConfigGet(ctx, "ghish.<foo>") calls inside individual command files (cmd_issue.go, push.go, etc.).
- Very specific: line 64
3P / External Open-Source Safety: Never assume @google.com identity, sso:// remotes, gob-curl, sso_client, or /google/data/ro/...
- Very specific: line 68
1P Chromebook (Crostini) & 3P Workstations: Treat as standard Linux without corp daemons unless binaries are detected on PATH.
- Very specific: line 75
Bounded Memory (
io.LimitReader): Every io.ReadAll(resp.Body) on Gerrit, Buildbucket, LogDog, Busytown, or Buganizer HTTP responses MUST … - Very specific: line 76
Bounded Concurrency: Every parallel fan-out over changes, worktrees, or builds (errgroup / sync.WaitGroup) MUST bound concurrency with a …
- Very specific: line 77
Batch Gerrit Queries: Never issue N+1 sequential GetChangeDetail RPCs in loops (wt list, pr status).
- Very specific: line 85
Mandatory Code Directive: Every flag registration (Flags().*Var*, PersistentFlags().*Var*) in pw_ghish MUST be preceded by a structured …
- Very specific: line 93
Follow the Pigweed Go Style Guide (docs/sphinx/style/go.rst): use Go 1.27+ standard library generics (slices, maps, cmp), %w error wrapping …
- Very specific: line 96
Programmatic Doc Sync (
doc_sync_test.go): Every non-hidden Cobra subcommand and flag MUST be documented in its pw_ghish/<family>.rst … - Very specific: line 97
Skill Conciseness Budget: Keep .agents/skills/ghish/SKILL.md high-density and under 300 lines—put exhaustive tutorials and prose in …
- Very specific: line 102
Every folded section MUST print a concise 1-line summary with the exact --all or --path command to unfold it.
- Very specific: line 104
Use canonical BMP glyph constants (GlyphPass = "✓", GlyphFail = "✗", GlyphWarn = "⚠", GlyphRunning = "●", GlyphPending = "○", GlyphDot = …
- Very specific: line 105
Never hardcode raw ANSI escape sequences (\x1b[ or \033[) outside pw_ghish/ui.go (enforced by TestInvariants_NoRawANSIEscapesOutsideUIGo).
- Very specific: line 107
Every mutating command (annotated ghish:kind: mutation) MUST emit a structured ✓ <Summary> receipt with contextual Details, URL, and Next: …
≈ “Common” is an estimate: at least 1 in 5 of the 40,246 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
AI Agent Guidelines for pw_ghish
Architectural Scope: Gerrit / LUCI Ecosystem
pw_ghish (./gh) provides GitHub CLI (gh pr, gh run, gh issue, gh auth) commands and multi-agent worktree management (gh wt, gh sense, gh hook) for projects across the Gerrit and LUCI ecosystem (including Pigweed, Fuchsia, Chromium, Android, and downstream repositories).
- Decoupled Policy: Avoid baking project-specific assumptions directly into core commands. High-level commands (
pr view,diff,comment,checks,run view,run rerun,issue,push,create) rely on standard Gerrit REST, git pushrefs/for/*, Buildbucket / LogDog / Busytown, and Buganizer APIs. - Project Profiles &
.ghish.toml: Project-specific policies (such as commit-queue labels, try bucket locations, shortlinks, default Buganizer components, and rerun command syntax) belong strictly in.ghish.toml(ProjectConfiginproject_config.go) orProjectProfileimplementations inprofile.go, rather than hardcoded in the core CLI handlers.
STRICT ENGINEERING & REVIEW INVARIANTS
Every change to pw_ghish (and every review via /review, .agents/agents/go_ghish_reviewer.md, and .agents/agents/ghish_security_reviewer.md) MUST enforce these 16 non-negotiable invariants. Regressing into silent failures, swallowed errors, defensive masking, data loss, policy leakage, context bloat, or hacking without tests is STRICTLY PROHIBITED.
1. NO SILENT FAILURES (RunE & EXPLICIT Try* CONTRACTS)
- MANDATORY: Every Cobra subcommand with an action MUST use
RunE: func(cmd *cobra.Command, args []string) error. NEVER use void-returningRun. - STRICTLY PROHIBITED: NEVER return
nilwhen an underlying operation, RPC, config parse (LoadCommandProjectConfig), or subprocess failed. Returningnilexits with status code 0, silently masking failures from users, scripts, and CI runners. - THE
return nilCONTRACT RULE:if err != nil { return nil }is permitted ONLY inside a helper explicitly namedTry*/BestEffort*(or whose doc comment explicitly declares a best-effort non-fatal contract), AND MUST include both:- An inline
// OK: <why failure is expected and safe to ignore>comment, AND - A debug log (
slog.Debug("...", "err", err)) or structuredWarningattachment so-v/--verbosesurfaces the root cause.
- An inline
2. NEVER MASK INVARIANT VIOLATIONS (if ptr == nil return 0 / return nil)
- STRICTLY PROHIBITED: When a pointer, dependency, or runner is an internal invariant that should never be nil, DO NOT defensively sweep it under the rug with
if ptr == nil return nilorreturn 0. - MANDATORY: Fail immediately with an explicit error (
fmt.Errorf("internal error: runner is uninitialized")) or panic if it represents an unrecoverable programmer defect. Never disguise broken code as a valid empty response.
3. DRY & COPY-PASTA PREVENTION
- MANDATORY: Never duplicate command-config loading, Gerrit error translation, git trailer parsing, or stack validation across subcommands:
- Always call
LoadCommandProjectConfig(cmd)instead of re-implementingGetConfig(cmd)+LoadProjectConfig(ctx). - Always issue Gerrit REST requests through the native
*GerritClient(gerrit.go), inspect status codes withIsGerritHTTPStatus(never external Gerrit client libraries, raw Gerrit HTTP requests, or error-string status scraping), and route Gerrit REST errors throughChangeContext.FormatError/FormatGerritError. - Keep pre-push commit-stack validation in a single shared pass (
ValidateCommitStackinpush_pipeline.go) rather than running duplicategit log/git rev-listpasses increate.goandpush.go.
- Always call
4. NO DATA LOSS (TRAILERS, DRAFTS, REFLOG & WORKTREES)
- Commit Trailers & Amending: Operations that edit commit messages or metadata MUST NEVER wipe out commit bodies or Git trailers (
Change-Id:,Bug:,Fixed:,Reviewed-on:). Always parse, validate, and preserve trailers usingExtractTrailersandMergeTrailers, and guard history rewrites withCheckAmendAllowed(blocking upstream remote branch tips, multi-parent merge commits, and activerebase/cherry-pick/revert/bisectsequencer states, while permitting local non-tip detachedHEADs such asgh pr checkout). - Unpublished Gerrit Drafts (
SetReview):GerritClient.SetReview(ChangeContext.SetReview) MUST defaultDrafts: "KEEP"unless--publishis explicitly passed so voting or commenting never publishes unrelated private draft comments by accident. - Inline Draft Updates: Updating an existing draft in
pr comment --draftMUST preserve the existing draft'sSide, characterRange, andUnresolvedstate unless explicitly overridden by a flag. - Multi-Commit Stack & Branch Memory: Pushing multiple commits without
--stackmust halt immediately.pr pushmust query Gerrit for the change (scoped by(project, branch, Change-Id)or change number) to push to its recorded target branch when unambiguously resolved unless--baseis explicitly set. - Worktree Path Confinement: Any destructive filesystem operation (
os.RemoveAllinworktree/) MUST validate paths throughsafe_fs.go(ValidateSafePath, symlink-escape checks, and non-root depth guards) and refuse to evict or park dirty working trees without--force.
5. ACTIONABLE ERRORS (THE 4 PILLARS)
- MANDATORY: Error messages and failure cases MUST NOT be dead-ends. Every user-facing error must provide:
- What Happened: Clear, unambiguous description of the failure condition (never a bare internal error or cryptic HTTP status).
- Preconditions / Why: Explain the underlying state or invariant (e.g., change is already merged, working tree is dirty, branch is synced with origin).
- Actionable Remediation: Concrete, copy-pasteable commands or step-by-step instructions that directly resolve the issue.
- Discovery Fallback: Inspection commands (e.g.,
gh pr list,gh pr checks,gh pr view --comments) when the next step depends on external state.
- Established Error Patterns:
- HTTP 401/403: Never return raw HTTP 401/403; provide host- and OS-aware authentication remediation (
https://<host>/new-password,luci-auth login,gcert). - HTTP 404 / 409: Distinguish missing change vs. missing patchset; translate 409 conflicts into domain explanations (
change is already merged,change is already closed). - Validation & Enum Guards: Strictly validate
--json <fields>and enum flags (--state,--mode,--reason), listing all valid choices on mismatch.
- HTTP 401/403: Never return raw HTTP 401/403; provide host- and OS-aware authentication remediation (
6. CONFIG SCHEMA POLICY (THE 3-LAYER RULE)
- Layer 1 —
.ghish.toml(Checked-in Repository Policy): Shared project settings ([gerrit],[ci],[issue],[worktree],[oncall]). Strictly validated viamd.Undecoded()inParseProjectConfigTOML—unknown sections or keys fail immediately withfile:line. - Layer 2 —
git config ghish.<section>.<key>(Local User Override): Every.ghish.tomlsetting MUST have a 1:1 local override inapplyGitConfigOverridesinproject_config.go, plus a minimal set of user/machine-only Git config keys (ghish.profile,ghish.authmode,ghish.blockrawpush). - Layer 3 —
ProjectProfile(profile.go): Built-in fallback defaults when no.ghish.tomlis present. - STRICTLY PROHIBITED: NEVER add ad-hoc
git.ConfigGet(ctx, "ghish.<foo>")calls inside individual command files (cmd_issue.go,push.go, etc.). All configuration keys MUST be declared onProjectConfiginproject_config.goand documented inproject_setup.rst(enforced byinvariants_ast_test.goanddoc_sync_test.go).
7. ZERO PIGWEED / FUCHSIA POLICY LEAKAGE & MECHANISM VS. POLICY
- Zero Hardcoded Project Policy Outside
profile.go: Core command handlers (push_pipeline.go,cmd_issue.go,luci.go,sense.go,worktree/) MUST NOT hardcode Pigweed or Fuchsia hostnames, shortlinks (pwbug.dev), directory paths (~/wrk/pigweed), or GCP project IDs (pigweed-gce). Always read fromProjectConfigorProjectProfile. - Mechanism vs. Policy Boundary:
pw_ghishis a fast Go transport and workflow engine (<100ms), NOT a general-purpose linter or build runner:- Belongs in
pw_ghish(Mechanism): Checks that require Gerrit/Git transport state or protectrefs/for/*integrity (Change-Idpresence and per-stack uniqueness,Fixes #123GitHub syntax trap, multi-commit--stackguard,submodule_policy,forbid_topics). - Does NOT belong hardcoded in
pw_ghish(Repo Policy): Project-specific commit message subject-length limits (50/72 chars), module-prefix rules (pw_foo:), or language linters—unless opt-in and driven by declarative[commit]schema in.ghish.toml.
- Belongs in
8. 1P vs. 3P & WORKSTATION PORTABILITY (CLOUDTOP / MAC / CHROMEBOOK)
- 3P / External Open-Source Safety: Never assume
@google.comidentity,sso://remotes,gob-curl,sso_client, or/google/data/ro/...paths exist unlessResolveAuthModeconfirmsgooglermode ANDLookPathFn/os.Statconfirms the binary exists on disk. - Workstation Matrix:
- 1P Linux Cloudtop / gLinux: Full
gob-curl,git-remote-rpc(rpc://7-day LOAS2),sso_client, and/google/data/ro/projects/android/fetch_artifactsupport. - 1P Corp macOS Laptop: Has
gob-curlandgcert, but typically lacksgit-remote-rpcand/google/data/ro/.... Always checkLookPathFn("git-remote-rpc")before attemptingrpc://rewrites, and checkLookPathFn("gcert")/LookPathFn("gob-curl")before prescribing them in remediation messages. - 1P Chromebook (Crostini) & 3P Workstations: Treat as standard Linux without corp daemons unless binaries are detected on
PATH; guide users toluci-auth loginand.gitcookies.
- 1P Linux Cloudtop / gLinux: Full
9. SECURITY & NTK CONFIDENTIALITY
- Credential Safety: NEVER pass OAuth2 bearer tokens or secrets on subprocess command lines (e.g.
git -c http.extraHeader="Authorization: Bearer ..."), because CLI arguments are world-readable inps aux//proc/<pid>/cmdlineand leak into verbose/error logs. UseGIT_CONFIG_COUNT/GIT_CONFIG_KEY_0/GIT_CONFIG_VALUE_0incmd.Envor temporary0600credential files, and redact tokens in all debug/error output. - Need-To-Know (NTK) Boundary: Upstream
pw_ghishsource, tests, docs, and skills are PUBLIC. Never include internal partner codenames, internal builder names, or internalsso://URLs in code, comments, or test fixtures.
10. GERRIT, LUCI & BUGANIZER INFRA GOOD CITIZENSHIP
- Bounded Memory (
io.LimitReader): Everyio.ReadAll(resp.Body)on Gerrit, Buildbucket, LogDog, Busytown, or Buganizer HTTP responses MUST be wrapped inio.LimitReader(resp.Body, maxBytes)to prevent OOMs on multi-hundred-megabyte logs or diffs. - Bounded Concurrency: Every parallel fan-out over changes, worktrees, or builds (
errgroup/sync.WaitGroup) MUST bound concurrency with a semaphore (e.g. max 4–8 in-flight RPCs). - Batch Gerrit Queries: Never issue N+1 sequential
GetChangeDetailRPCs in loops (wt list,pr status); batch changes into a singleQueryChangescall (q=change:1+OR+change:2). - CQ & Rerun Storm Guards: Guard
pr create/push --stack --cqandrun rerun --failedagainst accidentally scheduling hundreds of duplicate tryjobs, and add random jitter topr checks --watchpolling intervals.
11. MOCK TESTS vs. GERRIT REALITY
- Verify Query Options (
o=): Mock Gerrit tests in*_test.gomust assert that production code requested the required Gerrito=parameters (CURRENT_REVISION,CURRENT_COMMIT,DETAILED_LABELS,DETAILED_ACCOUNTS,MESSAGES,SUBMIT_REQUIREMENTS) before returning fields that Gerrit omits by default (labels,revisions,submittable). - Shared Test-Harness Helpers (
test_utils_test.go,kind_fixture_test.go): Prefer the"Declarative Gerrit Fixtures"and"Declarative LUCI / Buildbucket Fixtures"sections oftest_utils_test.go,DecodeRequest,NewKindSmokeFixture, andMockGitRunnerbuilders instead of duplicating hand-builtChangeInfomaps (useOnDefaultChangeand theWith*options), hand-writtenSearchBuildshandlers (useOnSearchBuilds*),json.Unmarshal(LastRequest().Body)(useDecodeRequest), or copy-pasted per-flag test functions (use table-driven subtests). Escape hatches: useserver.Onwhen a test needs per-request behavior (ordering, concurrency, or injected failures) or a realhttptest.NewServerwhen exercising client construction/transport fallback directly. Note thatOnDefaultChangereturnslabelsandrevisionsregardless of whato=was requested, so tests relying on those fields still must assert theo=query options.
12. GH CLI FLAG COMPATIBILITY & //ghish:flag DIRECTIVES
- Mandatory Code Directive: Every flag registration (
Flags().*Var*,PersistentFlags().*Var*) inpw_ghishMUST be preceded by a structured//ghish:flagdirective comment (or registered inflag_policy_test.go), verified byTestFlagPolicy://ghish:flag mode=upstream gh="<cmd> --<flag>"— Same flag name, shorthand, and semantics as upstream GitHub CLI (gh).//ghish:flag mode=extension reason="<why>"— Gerrit/LUCI/Buganizer-specific flag with no upstreamghequivalent. Visible extension flags MUST include(ghish-only)in their usage string and MUST NOT bind a single-letter shorthand that collides with upstreamgh(ghShorthandCollisions).//ghish:flag mode=divergent gh="<cmd> --<flag>" doc="ghDivergenceHelp"— Upstreamghflag whose underlying Gerrit/Buganizer model differs; MUST be documented inghDivergenceHelpinroot.goand in the command's.rstcomparison table.//ghish:flag mode=unsupported-guard gh="<cmd> --<flag>"— Upstreamghflag intercepted to return an actionable error explaining the Gerrit alternative.
- See
flag_compatibility.rstfor the complete compatibility policy.
13. MODERN GO STYLE
- Follow the Pigweed Go Style Guide (
docs/sphinx/style/go.rst): use Go 1.27+ standard library generics (slices,maps,cmp),%werror wrapping witherrors.Is/errors.As, command option structs instead of new package-level flag globals, andt.Context()/t.TempDir()/t.Setenv()/cmp.Diffin tests.
14. DOCUMENTATION & SKILL SYNCHRONIZATION
- Programmatic Doc Sync (
doc_sync_test.go): Every non-hidden Cobra subcommand and flag MUST be documented in itspw_ghish/<family>.rstreference page, every.ghish.toml[section]andkeyMUST be documented inproject_setup.rst, and every./ghexample in.agents/skills/ghish/SKILL.mdMUST use valid subcommands and flags. - Skill Conciseness Budget: Keep
.agents/skills/ghish/SKILL.mdhigh-density and under 300 lines—put exhaustive tutorials and prose inpw_ghish/*.rst, not in the always-loaded skill file.
15. UI DESIGN LANGUAGE, RECEIPTS & CONTEXT BUDGETING
- Answer-First & Progressive Disclosure (
--all):- Never flood stdout with unbounded lists of passing CI checks (
>5passing checks must collapse unless--allis passed, ordering failing/running checks first and clustering identical failure diagnostics viaClusterFailedBuilds), resolved review threads (FormatCommentForestWithOptions), automated bot commit dumps (summarizeBotIssueComment), or multi-thousand-line diffs (defaultDiffMaxLines = 400, folding lockfiles/generated files unless--allor--pathis passed). - Every folded section MUST print a concise 1-line summary with the exact
--allor--pathcommand to unfold it.
- Never flood stdout with unbounded lists of passing CI checks (
- Canonical Glyphs & TTY/Agent Color Discipline (
ui.go):- Use canonical BMP glyph constants (
GlyphPass = "✓",GlyphFail = "✗",GlyphWarn = "⚠",GlyphRunning = "●",GlyphPending = "○",GlyphDot = "·",GlyphArrow = "→"). Do not introduce decorative ASCII===walls or ad-hoc emojis in core commands. - Never hardcode raw ANSI escape sequences (
\x1b[or\033[) outsidepw_ghish/ui.go(enforced byTestInvariants_NoRawANSIEscapesOutsideUIGo). Always useStyle*andPadRightStyled(w, ...)so non-TTY pipes,NO_COLOR,TERM=dumb, and coding-agent environments (IsAgentEnv()) receive pure, column-aligned plaintext.
- Use canonical BMP glyph constants (
- Structured Mutation Receipts (
PrintReceipt/FormatReceipt):- Every mutating command (annotated
ghish:kind: mutation) MUST emit a structured✓ <Summary>receipt with contextualDetails,URL, andNext:step hints.
- Every mutating command (annotated
- Declared Command Kinds & Smoke Harness (
command_kind.go,kind_contract_test.go):- Follow the New command checklist in
developing.rst: declareAnnotations: map[string]string{KindAnnotation: Kind<Mutation|View|List|Stream|Meta>}inline on every runnablecobra.Command(andOutputAnnotation: OutputRawif stdout is a raw machine artifact likepr diff), and add akindSmokeArgsentry inkind_contract_test.gofor every runnablemutation/view/listcommand. Do NOT addkindSmokeSkip,kindSmokeContractGaps, orkindSmokeDuplicateSubprocessesentries to bypass failures on new code.
- Follow the New command checklist in
- JSON Output Contract (
--json):- Under
--json, stdout MUST be a single JSON value (no receipts, progress, warnings, ANSI escapes, orVerdict:/Next:lines), empty slices and maps MUST marshal as[]and{}rather thannull, enum-like fields MUST contain bare ASCII identifiers (never terminal glyphs), and gh-compatible--json <fields>flags MUST reject unknown fields withUnknownJSONFieldsError. Seedeveloping.rst("JSON output contract").
- Under
16. PERFORMANCE BUDGETS (COUNTS, NOT CLOCKS)
- Counts, Never Wall-Clock: Perf regressions fail presubmit via deterministic counts only: commands constructed (≈ subprocesses spawned) and HTTP requests issued. NEVER add a presubmit assertion on elapsed time; wall-clock numbers live only in the informational
live_bench_test.go(//go:build live). - Single Subprocess Choke Point: Construct every external process via
ExecCommand/ExecCommandContextinprocexec.go(pw_ghish.ExecCommandfromworktree/). Directexec.Command/exec.CommandContext,exec.Cmdliterals,os.StartProcess, andsyscall.Exec/syscall.ForkExecare prohibited elsewhere. - Staying Within Budgets: Keep commands within their kind's default subprocess and RPC count budgets (
kind_contract_test.go) and exact hot-command pins (perfbudget_test.go,worktree/perfbudget_test.go). When a budget test fails, prefer removing the extra work (memoize onConfig/GitClient, batch queries, parallelize); if an increase is intentional, update the pin orghish:budget-exemptreason in the same CL and justify it in the CL description.
Testing & Verification Architecture
- Hermetic Unit & Policy Tests (Mandatory on Every Change)
Includes unit tests, AST invariant enforcement (bazelisk test --noshow_progress --noshow_loading_progress //pw_ghish/...invariants_ast_test.go), flag compatibility verification (flag_policy_test.go), and CLI/config/skill documentation sync (doc_sync_test.go). - Live Integration Tests (FTE SWE Invoked)
Validates live RPCs againstgo test -v -tags=live ./pw_ghish -run TestLivepigweed-review.googlesource.com, Buildbucket pRPC, LogDog log streams, and ephemeral draft comment lifecycles (live_test.go). - Agent Behavioral Evaluation
- Evaluation rubric:
agent_eval.rst - Prompt scenarios & triggers:
.agents/skills/ghish/TEST.md
- Evaluation rubric:
Primary Pointers
- User & API Documentation:
docs.rst,subcommands.rst,project_setup.rst,flag_compatibility.rst - Pigweed Go Style Guide:
../docs/sphinx/style/go.rst - Agent Skill & Reviewer Definitions:
.agents/skills/ghish/SKILL.md,.agents/agents/go_ghish_reviewer.md,.agents/agents/ghish_security_reviewer.md - Live Test Suite:
live_test.go
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

