chore: cascade the fleet scaffolding and consolidate the vitest settings - #77
chore: cascade the fleet scaffolding and consolidate the vitest settings#77John-David Dalton (jdalton) wants to merge 1 commit into
Conversation
| line | ||
| .replace(/`[^`]*`/g, '') | ||
| .replace(/<!--[\s\S]*?-->/g, '') |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 3 potential issues.
Done
Or push these changes by commenting:
@cursor push b778e35b58
Preview (b778e35b58)
diff --git a/.claude/hooks/fleet/_shared/ai-attribution.mts b/.claude/hooks/fleet/_shared/ai-attribution.mts
--- a/.claude/hooks/fleet/_shared/ai-attribution.mts
+++ b/.claude/hooks/fleet/_shared/ai-attribution.mts
@@ -377,18 +377,22 @@
}
/**
- * True when a block of text carries attribution boilerplate anywhere in it.
- * This is the whole-text question: a PR body, an MCP tool input, a flattened
- * `git commit` command.
+ * True when a block of text carries attribution — boilerplate anywhere in it,
+ * or a scanner trailer fingerprint on its own line. This is the question a PR
+ * body, an MCP tool input, a flattened `git commit` command, or the pre-push
+ * commit-message backstop asks. Includes the scanner set so a trailer
+ * `stripAiAttribution` would remove can never pass a gate that calls this.
*/
export function containsAiAttribution(text: string): boolean {
- return AI_ATTRIBUTION_RE.test(text)
+ return (
+ AI_ATTRIBUTION_RE.test(text) || matchAiCommitAttribution(text) !== undefined
+ )
}
/**
- * True when any LINE of a commit message is attribution. Line-oriented (unlike
- * `containsAiAttribution`) and folds in the scanner trailer fingerprints, so it
- * agrees exactly with what `stripAiAttribution` would remove.
+ * True when any LINE of a commit message is attribution. Line-oriented, and
+ * folds in the scanner trailer fingerprints, so it agrees exactly with what
+ * `stripAiAttribution` would remove.
*/
export function hasAiAttribution(message: string): boolean {
return splitAttributionLines(message).some(lineCarriesAttribution)
diff --git a/.claude/hooks/fleet/honeypot-echo-guard/outbound-bodies.mts b/.claude/hooks/fleet/honeypot-echo-guard/outbound-bodies.mts
--- a/.claude/hooks/fleet/honeypot-echo-guard/outbound-bodies.mts
+++ b/.claude/hooks/fleet/honeypot-echo-guard/outbound-bodies.mts
@@ -189,6 +189,24 @@
}
continue
}
+ if (
+ isCommentInvocation &&
+ eq > 0 &&
+ BODY_FILE_FLAGS.has(arg.slice(0, eq))
+ ) {
+ const value = arg.slice(eq + 1)
+ if (value === '') {
+ unresolved = true
+ } else {
+ const content = readOutboundBodyFile(cwd, value)
+ if (content === undefined) {
+ unresolved = true
+ } else {
+ bodies.push(content)
+ }
+ }
+ continue
+ }
if (arg === '--input') {
const value = args[i + 1]
if (value === undefined) {
@@ -202,6 +220,20 @@
}
continue
}
+ if (arg.startsWith('--input=')) {
+ const value = arg.slice('--input='.length)
+ if (value === '') {
+ unresolved = true
+ } else {
+ const content = readOutboundBodyFile(cwd, value)
+ if (content === undefined) {
+ unresolved = true
+ } else {
+ bodies.push(content)
+ }
+ }
+ continue
+ }
if (!isCommentInvocation && API_FIELD_FLAGS.has(arg)) {
const value = args[i + 1]
if (value === undefined) {You can send follow-ups to the cloud agent here.
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 0f25314. Configure here.
| // fail closed rather than silently letting an unresolved substitution | ||
| // read as an empty (safe) body. | ||
| return block(unresolvedBodyBlockMessage(surface)) | ||
| } |
There was a problem hiding this comment.
Opaque check blocks non-posting gh
Medium Severity
honeypot-echo-guard fails closed on any Bash line that both mentions gh and has a $VAR/eval binary anywhere, before checking whether the invocation actually posts to a thread. Read-only or unrelated gh commands in a chain with opaque segments are blocked as if they had an unreadable outbound comment body.
Reviewed by Cursor Bugbot for commit 0f25314. Configure here.
| bodies.push(content) | ||
| } | ||
| continue | ||
| } |
There was a problem hiding this comment.
Honeypot misses equals-form body files
High Severity
ghOutboundBodies reads file-backed comment bodies only for space-separated --body-file / -F / --input, not the equals forms (--body-file=path, --input=path). Cobra accepts those forms, and sibling guards already handle --body-file=. A bait file posted that way yields an empty scan with unresolved false, so the guard allows the comment through.
Reviewed by Cursor Bugbot for commit 0f25314. Configure here.
| * `git commit` command. | ||
| */ | ||
| export function containsAiAttribution(text: string): boolean { | ||
| return AI_ATTRIBUTION_RE.test(text) |
There was a problem hiding this comment.
Attribution gates diverge on scanners
High Severity
containsAiAttribution only consults AI_ATTRIBUTION_RE, while hasAiAttribution / stripAiAttribution also match AI_COMMIT_ATTRIBUTION_PATTERNS. Pre-push and the tool-layer commit/PR guards call the narrow API, so trailers such as Co-authored-by: aider or Co-authored-by: GitHub Copilot that commit-msg would strip can still pass the push backstop and Bash/gh blocks.
Additional Locations (2)
Reviewed by Cursor Bugbot for commit 0f25314. Configure here.
…t settings Brings the fleet scaffolding forward, including the CodeQL fixes for the 19 template-owned alerts open on this repo. Three things the cascade does not do for itself, applied here: - Vitest settings moved from a standalone .config/repo/vitest.json into the vitest section of the marker file, but existing content is not migrated. Without the move this repo loses its vscode stub alias and five test files fail to resolve the module. - The README gained the canonical Install / Usage / Development / License sections. The freeform-readme opt-in was retired, so the skeleton now applies here; the existing feature prose is folded into Usage, not dropped. - Two block comments in scripts/repo/update.mts closed on a body line, which the newly cascaded block-comments-are-closed-once check flags. Gates: test 103/103, lint 0, build 0, check --all 0 across 175 checks.
0f25314 to
6e79411
Compare
|
Closing as obsolete. This branch was built from an earlier template SHA and had drifted. Rather than push it, the cascade was rebuilt from scratch against a freshly verified snapshot and landed directly on The rebuilt cascade passes all four gates — tests 116 passed, lint clean, build clean, and the full check suite clean — and it also carries the fix for the high-severity The |



This brings the shared tooling forward. The reason to do it now is that all 19 CodeQL alerts currently open on this repository live in cascaded code, and the fixes for every one of them already exist in our shared template. Nothing in this repository's own source is at fault, and nothing here can close them except taking the update.
Three things the cascade cannot do for itself — each would have broken the build if left out
The vitest settings needed migrating by hand. The template moved vitest configuration out of a standalone
.config/repo/vitest.jsonand into avitestsection of the marker file, but it does not carry existing content across. Without the move this repository loses itsvscodestub alias and five test files fail with "Cannot find package 'vscode'". The alias and pool setting are migrated verbatim and the orphaned file removed, which is whatvitest-config-is-consolidatedasks for.The README needed the canonical sections. The freeform-readme exemption was retired, so the standard skeleton now applies here. The README gains
Install,Usage,Development, andLicensein the required order. The existing feature prose was folded intoUsagerather than discarded, and aDevelopmenttable was added listing the scripts this repository actually has.Two block comments closed on a body line.
scripts/repo/update.mtshad*/sitting at the end of a prose line in two docblocks. Both were valid comments, but the newly cascadedblock-comments-are-closed-oncecheck flags the shape, because a closing token buried in prose is how a comment ends early by accident. The terminators now sit on their own line.Ran — all four gates green, and the earlier attempt was held back until they were
test --alllint --allbuildcheck --allAn earlier build of this same cascade was deliberately not pushed, because it carried template work that was still mid-flight and would have taken this repository from green to red on checks it does not own. This version was rebuilt from a later template commit where those issues were resolved.
Two findings left open on purpose — both are shared-tooling gaps, not this repository's
manifest_stalereports that the template's own file manifest references a path that does not exist in the template. It cannot be fixed from here.thin_wiring_missingwantspackage.json'spreparescript to begin with a bootstrap step. No member repository does this today — the same script appears identically in several siblings — so changing it here alone would make this repository the outlier and would alter what happens on a fresh clone. That is a shared decision, not one to make in a cascade PR.Once this lands, the next CodeQL analysis should close the 19 open alerts, since the code they point at is replaced by this update.
Note
High Risk
Changes security- and session-gating behavior (honeypot blocking, gh token fail-closed, Stop-hook blocking semantics) across the whole fleet hook dispatch path; regressions could block legitimate comments/commits or let bait/tokens slip through.
Overview
Cascades shared fleet scaffolding from the wheelhouse template (vitest config consolidation, README canonical sections, docblock fixes noted in the PR) and ships a large hook-layer update in
.claude/hooks/fleet/.AI attribution is centralized in
_shared/ai-attribution.mts: broader pattern catalogs, line-gated commit fingerprints, branch-prefix detection, andstripAiAttribution. Commit-time guards in the hook tree import this module instead of.git-hooks/_shared.New
honeypot-echo-guardblocks outbound GitHub/MCP thread posts that echo automation bait (standalone twelve-hex tokens, marker literals, bare-token bodies), withgit rev-parseand transcript corroboration so legitimate SHA citations can pass.honesty-framing-guardis removed; categorical honesty bans now live inanti-prose-guard, which also runs on Stop (not only prose-file writes).Several Stop guards no longer whisper when
stop_hook_active(stop-nudge,disowned-dirt-guard,dont-blame-nudge,excuse-detector,anti-prose-guard) so rewritten replies cannot smuggle excuses or banned framing past a sibling block.Shared plumbing adds
git-runner.mts(sanitized git spawns, fail-loud on killed children),gh-invocation.mts,nested-strings.mts,untrusted-instruction.mts, marker-only-line suppressions, and stricter bypass scanning (stripAllCodeSpans, prose-shaped inline spans). Fleet roster dropsfreeform-readme/thinopt-ins;isThinMembertreats every roster repo as a thin consumer except the wheelhouse and non-members.gh-token-hygiene-guardfails closed on unreadable auth probes and retries spawns.excuse-detectorgains futuring-shape deferral patterns.Reviewed by Cursor Bugbot for commit 0f25314. Configure here.