You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
chore(agents): add actions/cache exclude and target-shell testing rules
Two lessons from the hippolytus release-artifact work:
- Every `!` exclude on an actions/cache path was a no-op for years, silently
shipping stale bundles in every release. resolvePaths globs with
implicitDescendants:false and tars the result with --files-from and no
--no-recursion, so tar recurses into the ancestor dirs and re-adds every
"excluded" file. Verified against the shipped dist.
- Testing a `shell: bash` step under the zsh Bash tool reported a false
failure: zsh aborts on an unexpanded glob where bash passes it through.
Copy file name to clipboardExpand all lines: home/dot_agents/AGENTS.md
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -16,6 +16,7 @@ These constraints are unconditional. Apply them without being asked.
16
16
-**Diagnose from logs, not theory.** When investigating a failure (CI, runtime, hang, regression), the last lines of output before the failure are ground truth, not a guess based on which script's name matches your current hypothesis or which prior bug looked similar. If the visible log doesn't pin the cause, add a diagnostic and re-run rather than speculate further. When reporting findings, mark claims as observed ("log line N says X") versus suspected ("I think Y because…") and never let suspicion harden into assertion without evidence.
17
17
-**Contradictory observations mean a bad instrument, not a new theory.** When two measurements of the same thing disagree (a value healthy at line N but "null" at line N+1, a passing run and a failing run of identical code), stop hypothesising and instrument the exact divergent reads side by side in one run; the discrepancy is the bug's address. Treat tool-reported metadata as suspect until verified: logcat's tid column is the logger thread, not the caller (log gettid() yourself), and addr2line on optimised binaries misattributes merged inlined frames, so confirm the throw/crash site with a direct probe before acting on it.
18
18
-**When diagnosing CI, read the repo at the SHA the runner checked out.** Your working tree is not what CI ran: it can be stale by many commits, and the failing run is often triggered by a commit you have never fetched (a bot's release or merge commit is the common case). Reading a config, manifest, or lockfile at local HEAD then yields a value that contradicts the log and sends you hunting a phantom, or worse, concluding the log is wrong. The checkout step prints the exact SHA it landed on (`git log -1 --format=%H`); fetch that commit and read files with `git show <sha>:<path>`. When a file's contents disagree with what the log implies, suspect you are reading the wrong ref before you suspect the log.
19
+
-**An `actions/cache``!` exclude does nothing if an ancestor directory is also matched.**`resolvePaths` globs the `path:` input with `implicitDescendants: false` and hands the resulting list to `tar --files-from` with no `--no-recursion`, so tar recurses into every directory in that list. The `!` line does drop the file from the glob output, but its parent is still there, and tar puts the file straight back: `target/**` plus `!target/release/bundle/deb/*.deb` caches the .deb regardless. Never express "cache everything except X" this way, since `dir/**` guarantees an ancestor is matched; instead delete X after restore, or cache only the specific subdirectories you want. The failure is silent and can persist for years: verify by resolving the real patterns through `@actions/glob` and taring the result. Suspect this whenever cached build output reappears in artifacts that a clean build could not have produced.
19
20
-**A quoted error string in a log is not proof the error fired.** CI runners echo the script before executing it (GitHub Actions prints the whole `##[group]Run` body, `echo "::error ..."` conditionals included, often ANSI-highlighted), so a line containing an error template may just be the source of an un-taken branch. Identify where the annotation was actually emitted (the bare `##[error] ...` line, or the failing command's own stderr) before naming a cause, not where the text merely appears. Mis-reading an echoed conditional as a fired error sends you fixing the wrong thing.
20
21
-**When a project's prose and its enforcement disagree, the enforcement wins.** A skill, README, or comment can drift from the CI gate, linter, or schema that actually rejects your change (e.g. a documented file layout that a CI guard now forbids adding). Before following a documented process that touches generated or tool-owned files, confirm it against the mechanism that will gate the PR; if they conflict, satisfy the gate and fix the stale doc in the same effort.
21
22
-**Make the failure reproduce without a human before iterating on fixes.** When verification needs a human round-trip (someone wearing a headset, clicking a UI, plugging in hardware), build an autonomous repro first: a self-test that runs the failing path at startup, auto-dismissal of interactive gates, retry loops around known-flaky launches, and a streamed log capture started before launch so rotation can't eat the evidence. Each fix-then-ask-the-human cycle costs minutes and goodwill; the harness pays for itself by the second iteration.
@@ -86,6 +87,7 @@ Always edit the source, not the deployed file. When updating any memory file: re
86
87
- Prefer the smallest atomic command that completes the immediate next step. Do not chain concerns across policy boundaries.
87
88
- Destructive or policy-sensitive actions should be isolated so intent is easy to inspect.
88
89
- Do not check whether a directory exists before using it. Attempt the operation; create the directory if it fails.
90
+
-**Test a command in the shell that will actually run it.** The Bash tool here is zsh, while CI `run:` steps are typically `bash -e`, and the two disagree in ways that fake a failure. zsh aborts on an unexpanded glob (`no matches found`, nonzero exit) where bash passes the pattern through literally, so a perfectly safe `rm -rf foo/*/bar` reports a false failure locally and tempts you to "fix" a command that was never broken. Run the real thing (`bash -c '...'` or `bash script.sh`) before concluding anything about a snippet destined for bash. Generally: when validating a snippet for another runtime, reproduce that runtime's semantics rather than trusting your interactive shell's.
89
91
- On Windows, when admin rights are required, launch elevated commands with `Start-Process -Verb RunAs` instead of failing back to manual instructions.
90
92
- On Windows, use the Bash tool (not PowerShell) for POSIX-style commands like `grep`, `find`, `head`, `tail`, and path operations that use forward slashes. Use PowerShell only when you need Windows-native cmdlets, `$env:` variables, or paths with backslashes that POSIX tools cannot handle.
91
93
- On Windows, POSIX-style paths like `/tmp/...` resolve only inside the Bash tool. Native filesystem tools (read/edit/write/grep/glob in any agent harness) use Windows file APIs and need Windows-style paths (`C:\...` or `C:/...`). When a Bash command reports a canonical path (e.g. `Cloning into 'C:/Users/.../Temp/repo'`), use that path for subsequent tool calls; do not reuse the `/tmp/` shortcut.
0 commit comments