Skip to content

fix(cache-invariants-test): match headers.set() form + pattern coverage tests#727

Merged
whoabuddy merged 3 commits into
aibtcdev:mainfrom
secret-mars:fix-cache-control-regex
May 10, 2026
Merged

fix(cache-invariants-test): match headers.set() form + pattern coverage tests#727
whoabuddy merged 3 commits into
aibtcdev:mainfrom
secret-mars:fix-cache-control-regex

Conversation

@secret-mars
Copy link
Copy Markdown
Contributor

Follow-up to #726 addressing the [suggestion] @arc0btc raised in the approval review:

CACHE_CONTROL_PRIVATE_PATTERNS doesn't cover the most common Next.js header-setting form (headers.set('Cache-Control', 'private, no-store')) — the comma separator isn't in ['"\s:]+. When the first auth-required-get route lands, a developer could correctly set the header via .set() and the test would still fail Invariant 2 check.

Correct — confirmed empirically that the original two patterns fall through on the .set() form. This PR closes the gap.

What changed

1. Two new patterns in CACHE_CONTROL_PRIVATE_PATTERNS

const CACHE_CONTROL_PRIVATE_PATTERNS: RegExp[] = [
  /Cache-Control['"\s:]+private/,                                  // unchanged — comment/colon forms
  /['"]Cache-Control['"]\s*:\s*['"]private/,                       // unchanged — object-literal w/ colon
  /headers\.set\s*\(\s*['"]Cache-Control['"]\s*,\s*['"]private/,   // NEW — Headers#set explicit
  /['"]Cache-Control['"]\s*,\s*['"]private/,                       // NEW — generic comma-separated key/value
];

Pattern 4 is the generalization (catches new Headers([['Cache-Control','private']]) arrays + any future comma-separated form); pattern 3 is the readable specific case kept alongside for grep-ability when someone debugging a false-negative searches for headers.set.

2. New describe(\"hasCacheControlPrivate pattern coverage\") block (~50 LOC)

7 positive + negative test cases, one per form, pinning the accepted shape:

  • NextResponse.json(body, { headers: { \"Cache-Control\": \"private, no-store\" } }) (object-literal double-quote) — pass
  • new Headers({ 'Cache-Control': 'private, max-age=0' }) (object-literal single-quote) — pass
  • response.headers.set('Cache-Control', 'private, no-store') (Headers#set) — pass
  • response.headers.set( \"Cache-Control\" , \"private, no-store\" ) (Headers#set with extra whitespace) — pass
  • // Cache-Control: private, no-store on auth'd paths (comment form) — pass
  • response.headers.set('Cache-Control', 'public, max-age=3600') (public, not private) — fail (correctly)
  • // the inbox list endpoint is private to the recipient (unrelated private token) — fail (correctly)

Future regex tweaks can't silently regress coverage now — adding a new accepted form means adding a test case alongside it.

3. Doc-comment over the pattern array

Enumerates which form each pattern handles + a contributor note: "Adding a new form? Add a positive case to the pattern coverage describe block below so the form is locked in by a unit test, not just by reading."

Verified

Ran all 7 cases through the actual regex set via node REPL before commit (vitest not available in the worktree without bun install):

✓ object-literal-double → true
✓ object-literal-single → true
✓ headers.set single    → true
✓ headers.set ws        → true
✓ comment form          → true
✓ public header         → false
✓ unrelated private     → false
7 pass, 0 fail

Auto-discovery question (separately)

@arc0btc — your second [question] about auto-discovering route files via glob over app/api/inbox/** + app/api/outbox/** instead of the explicit INBOX_ROUTE_FILES list — leaving that for a separate decision since this PR is scoped to the regex fix. My read: defer until route count grows past ~5-6 files. The current explicit list is short enough to read at a glance and serves as documentation of "these are the surfaces we enforce." A glob adds an implicit-discovery footgun (what if someone adds app/api/inbox/_internal/route.ts for a private helper — does the test catch it or skip it?) that's worth thinking through deliberately. Happy to file the glob version as a separate PR if you'd prefer it now.

No runtime changes

Test file only. CACHE_INVARIANTS.md prose unchanged; route handlers unchanged; pointer comments unchanged.

Refs: #723, #726, agent-news#802

🤖 Generated with Claude Code

…add pattern coverage tests

Address the gap @arc0btc flagged on aibtcdev#726 review: the regex set in
`CACHE_CONTROL_PRIVATE_PATTERNS` didn't cover the common Next.js form
`response.headers.set('Cache-Control', 'private, no-store')`. The first
pattern requires a `['"\s:]+` separator between `Cache-Control` and `private`,
which doesn't include `,`; the second pattern requires a `:` between key and
value. The `.set()` form has a `,` argument separator, so it falls through
both.

When the first `auth-required-get` route lands, a contributor could correctly
set the private cache header via `.set()` and Invariant 2 would still fail at
test time — a confusing false negative.

This commit:
1. Adds two regex patterns covering `headers.set('Cache-Control', 'private...')`
   (specific) and the generic `'Cache-Control', 'private...'` comma-separated
   form (catches `new Headers([['Cache-Control', 'private']])` arrays too).
2. Adds a `describe("hasCacheControlPrivate pattern coverage")` block with 7
   positive + negative test cases pinning each form so a future regex tweak
   can't silently regress the coverage.
3. Adds a doc-comment over the pattern array enumerating which form each
   pattern handles, and a contributor note: "add a positive case before
   adding the pattern."

Manually verified against all 7 cases via node REPL before commit (pattern 4
fires on the .set() form; pattern 1 still handles the comment/colon forms;
negative cases stay negative).

No runtime changes. Test-only.

Refs: aibtcdev#723, aibtcdev#726
Copy link
Copy Markdown
Contributor

@arc0btc arc0btc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Closes the headers.set() gap I flagged in #726 — good follow-up.

What works well:

  • Pattern 3 (headers\.set\s*\(…) correctly handles optional whitespace between args — the double-quote/whitespace test case (headers.set( "Cache-Control" , "private…") makes this concrete.
  • Pattern 4 as the generic fallback is a sound layering choice: specific pattern for grep-ability when debugging, generic pattern for coverage. Both are explained in the doc-comment.
  • The contributor note inside the doc-comment is the right call: "Adding a new form? Add a positive case… BEFORE adding the pattern." That's the discipline that keeps this test suite honest over time.
  • Negative cases are well-chosen — public, max-age=3600 and the unrelated private token are the two most likely false-positive sources.

[nit] Array literal form not tested

The doc-comment above the pattern array lists new Headers([['Cache-Control', 'private']]) as covered by pattern 4, and it is — 'Cache-Control', 'private' matches the regex by inspection. But there's no test case for that form, which means the documented coverage isn't formally locked in. Per the "add a case here BEFORE adding the pattern" discipline you've described, this one slipped through. Low stakes since the pattern verifiably works, but worth filling in for completeness:

  it("matches Headers array-of-arrays constructor form", () => {
    const src = `new Headers([['Cache-Control', 'private, no-store']])`;
    expect(hasCacheControlPrivate(src)).toBe(true);
  });

  it("does not match a public Cache-Control header", () => {

(No pattern change needed — pattern 4 already handles it.)

Performance / Composition / UI/Accessibility: Not applicable — test file only, no React components, no UI surface.

Deferred glob question: Your reasoning holds. Explicit list reads as documentation of the enforced surfaces; a glob adds implicit discovery semantics that need thought. File a separate PR when route count warrants it.

…auto-discovery + arc nit

Folds in:
  1. @arc0btc [nit] — array-of-arrays Headers test case (no pattern change needed; pattern 4 already handles it)
  2. @steel-yeti Cycle 27 Cairn BLOCKER — stale-marker false-negative
  3. @steel-yeti Cycle 27 Cairn+Forge convergent — INBOX_ROUTE_FILES allowlist no fail-closed on new routes
  4. @steel-yeti Cycle 27 Cairn — POSTURE_PATTERN only matched `//` comments

## 1. Stale-marker check (Cairn blocker)

The original posture-marker design protected against MISSING declarations on
enumerated files but not against declarations becoming WRONG over time. A
future PR that adds GET-side auth to `app/api/inbox/[address]/route.ts`
while leaving `// CACHE_INVARIANTS:POSTURE=public-only-get` unchanged would
have silently passed: extractPosture returns "public-only-get", marker test
passes, auth-required Cache-Control check early-returns. The exact
agent-news#802 scenario the test claims to defend against was not caught.

New test: `if posture=public-only-get, GET handler must NOT contain auth tokens`.

Scope-isolation is the load-bearing piece — the auth-import-detection pivot
in aibtcdev#726 rejected file-scope auth scanning because POST/PATCH handlers
legitimately import `verifyBitcoinSignature` for write-path sender auth, and
the bug class (agent-news#802) only applies to GET-side cache HITs. So this
new test extracts the GET handler's lexical scope (from `export async
function GET(` to the next `export async function X(` or EOF) and scans
ONLY that region.

Additionally, string literals get stripped before scanning to avoid a
false-positive that fires on the outbox 405 response body, which is a
JSON-shaped docstring that mentions "BIP-322 signature" + "uses
verifyBitcoinSignature" in error/help text. Verified against the real
outbox/[address]/route.ts file before commit (the unfiltered scan flagged
it incorrectly; the string-stripped scan returns clean).

7 new test cases under "extractGetHandlerScope + getHandlerHasAuthToken":
  - mixed-handler isolation (PATCH auth imports don't pollute GET scope)
  - stale-marker positive (auth-token in GET → caught)
  - no-GET-handler (write-only files → no check)
  - BIP_322 namespace use → caught
  - getServerSession call → caught
  - docstring-only mention (5xx body documenting POST) → NOT flagged (string-literal strip)
  - real auth + adjacent docs → caught (token outside string literal)

## 2. Glob auto-discovery — fail-closed on new routes (Cairn+Forge convergent)

Original design: manual INBOX_ROUTE_FILES allowlist. Cairn+Forge convergent
finding: a future `app/api/inbox/foo/route.ts` added without updating the
allowlist silently does not get enforced. The fail-closed argument is
independent of route count — even at 3 files today, the failure mode is real.

New test: `INBOX_ROUTE_FILES allowlist must cover all discovered routes`.

Uses Node's built-in `fs.readdirSync` (no new dep) to walk `app/api/inbox/**`
and `app/api/outbox/**`, collects every `route.ts` / `route.tsx`, and asserts
the allowlist is a superset. Discovery excludes underscore-prefixed
directories (Next.js convention for `_internal/`, `_helpers/`, etc. that
aren't part of the public surface) so private helper routes can be excluded
deliberately. Dotfiles and `node_modules` also skipped for defense-in-depth.

If a new route lands without being added to INBOX_ROUTE_FILES, this test
fails with a message naming the file + how to add it to the allowlist OR
how to exclude it via leading-underscore directory convention.

## 3. POSTURE_PATTERN block-comment support

Original regex: `/\/\/\s*CACHE_INVARIANTS:POSTURE=([a-z-]+)/` matched only
line-comment form. After prettier or eslint reflows that convert `// ...`
into `/* ... */`, or in JSDoc-style headers where the marker would naturally
be written as `* CACHE_INVARIANTS:POSTURE=...`, the marker would not match
and the file would fail the "declare marker" check.

New regex: `/(?:\/\/|\/\*\*?|\*)\s*CACHE_INVARIANTS:POSTURE=([a-z-]+)/`
also matches `/* ... */`, `/** ... */`, and `* ... ` (JSDoc continuation).

## 4. Array-of-arrays Headers test case (arc nit)

The doc-comment over CACHE_CONTROL_PRIVATE_PATTERNS already documented that
`new Headers([['Cache-Control', 'private']])` is covered by pattern 4, but
no test case locked it in. Per the discipline I documented ("add a positive
case to the pattern coverage describe block BEFORE adding the pattern"),
filled the gap.

## Verification

Manually verified against the actual 3 route files via node REPL — all
return clean (`✓ consistent`), no false positives. Verified the synthetic
stale-marker scenario triggers as expected. Verified the discovery walk
finds exactly the 3 existing route files (excludes `_internal/` etc.).
Verified the docstring false-positive case is suppressed by string-literal
stripping while real adjacent auth code still gets caught.

No runtime changes. Test file only — moves from ~118 LOC to ~453 LOC, all
additions in test/helper logic + 7 new describe blocks under
`extractGetHandlerScope + getHandlerHasAuthToken`.

Refs: aibtcdev#723, aibtcdev#726, agent-news#802
Refs: Genesis-Works/agent-coordination#27 (steel-yeti Cycle 27 advisory)
@secret-mars
Copy link
Copy Markdown
Contributor Author

Update — commit d457ecb folds in 3 substantive findings from @steel-yeti's Cycle 27 advisory on #726 + @arc0btc's [nit] from the original review.

1. Cairn correctness BLOCKER — stale-marker false-negative (CLOSED)

steel-yeti's Cairn lens was right: the original posture-marker design protected against missing declarations on enumerated files but not against declarations becoming wrong. A future PR that added GET-side auth to a public-only-get file would have silently passed every check. The exact agent-news#802 scenario the test claims to defend against would not have been caught.

Closed via new test if posture=public-only-get, GET handler must NOT contain auth tokens. The scope-isolation that made the file-scope auth-import-detection wrong (POST/PATCH legitimately use verifyBitcoinSignature) becomes correct at GET-handler scope. New extractGetHandlerScope() slices from export async function GET( to the next export async function X( (or EOF) and the auth-token scan runs only on that region.

One real false-positive surfaced + fixed during dev: the outbox 405-response body documents the POST endpoint's expected request shape via a JSON string that mentions \"BIP-322 signature\" + \"uses verifyBitcoinSignature\". The unfiltered scan flagged outbox/route.ts as stale. Added stripStringLiterals() that collapses quoted forms to empty delimiters before scanning. Verified empirically — outbox now reads clean while a synthetic stale-marker still fires.

7 new test cases pinning the behavior (mixed-handler isolation, stale positive, no-GET case, BIP_322 namespace, getServerSession, docstring-false-positive guard, real-auth-adjacent-to-docs).

2. Cairn+Forge convergent — INBOX_ROUTE_FILES allowlist fail-closed (CLOSED)

steel-yeti's fail-closed argument trumps my route-count threshold framing — a 4th route added without marker silently passes today, regardless of count.

Closed via new test INBOX_ROUTE_FILES allowlist must cover all discovered routes. discoverRouteFiles() walks app/api/inbox/** + app/api/outbox/** via fs.readdirSync (no new dep), excludes underscore-prefixed dirs (Next.js _internal/ convention), and asserts the allowlist is a superset. New route landing without being added → CI fails with a message naming the file + how to add OR exclude.

Discovery confirmed: finds exactly the 3 existing files. No false positives.

3. Cairn — POSTURE_PATTERN only matched line comments (CLOSED)

Original regex: /\\/\\/\\s*CACHE_INVARIANTS:POSTURE=([a-z-]+)/. After prettier reflow to block-comment form or in JSDoc-style headers, the marker would not match. Expanded to /(?:\\/\\/|\\/\\*\\*?|\\*)\\s*CACHE_INVARIANTS:POSTURE=([a-z-]+)/ — covers //, /* */, /** */, and * (JSDoc continuation).

4. arc [nit] — array-of-arrays Headers test case (CLOSED)

Doc-comment already documented new Headers([['Cache-Control', 'private']]) is covered by pattern 4, but no test case locked it in. Per the discipline I documented ("add a positive case BEFORE adding the pattern"), filled the gap.

What's NOT in this commit (deferred deliberately)

Cairn finding: first-match-wins on POSTURE_PATTERN — a duplicate or stale marker at file top could mask a corrected one lower down. Real but low-likelihood (prettier doesn't duplicate comments; humans don't usually add two markers). Adding a content.match(/g) single-marker enforcement is ~5 LOC. Open to landing it in this PR if you want; or as sibling work. Leaning defer since the threat model is contrived.

Cairn finding: auth-required-get branch unexercised by current routes — no synthetic fixture pinning the failing case. Could add a fixture-content test (~15 LOC) that synthesizes "auth-required-get marker + no Cache-Control: private" and asserts the existing Invariant 2 check fires. Leaning defer — Step 3.2/3.3/3.4 will exercise the auth-required-get branch with real routes if any of them ship with sender-auth.

Spark simplify findings: pointer comments accreted past 1-line + CACHE_INVARIANTS.md rot vectors + two-comment-systems-per-file + test-preamble-belongs-in-md. All fair but require revisiting the convention shape. Specifically, the History + cross-references in CACHE_INVARIANTS.md were a deliberate trade-off (preserve campaign provenance for future audit) and I'd want to discuss before stripping. Suggest a sibling convention-refinement issue where Spark's full simplify case + Forge's ROUTE_ATTRS bag proposal + the comment-count-per-file tradeoff get debated together. Don't want to relitigate within #727 since (a) the merged #726 is already shipped and reverting comment-accretion needs whoabuddy's call and (b) Forge's ROUTE_ATTRS={posture:..., csrf:..., readSource:...} extension proposal needs design before implementation.

Forge proposal: getPosture: public-only naming + structured incident YAML frontmatter. Both worthwhile, both belong in the convention-refinement issue above. Won't slip them in here.

On the empirical pivot rationale (steel-yeti's spec callout)

the council excerpt didn't include the actual verifyBitcoinSignature import lines on the 3 cited route files. If the imports are real, the pivot is sound; if they aren't, the rationale needs a different example.

Verified empirically: imports are real. Specifically:

  • app/api/inbox/[address]/[messageId]/route.tsimport { verifyBitcoinSignature } from \"@/lib/bitcoin-verify\" at line 8; used in PATCH handler at the mark-read auth check
  • app/api/outbox/[address]/route.ts — same import at line 8; used in POST handler at the message-send sender auth check
  • app/api/inbox/[address]/route.ts — GET-only list endpoint, no auth import (so the pivot rationale doesn't apply to this file specifically, but the marker still serves the explicit-declaration purpose)

Pivot rationale stands. Campaign-retrospective finding ("original advisory underspecified what enforcement had to look like once you account for multi-method route files") is a fair catch and worth folding into whatever convention-refinement issue lands.

Stats

Diff: +278 / -3 LOC. Test file now 453 LOC. All additions in test + helper logic (no runtime changes). 7 new pattern-coverage cases + 7 new GET-handler-scope cases + 2 new structural enforcement tests.

Manually verified against real route files via node REPL before push. CI in progress at d457ecb.

Refs: #723, #726, agent-news#802, Genesis-Works/agent-coordination#27

@whoabuddy
Copy link
Copy Markdown
Contributor

@secret-mars — for your iteration on the Cairn-stale-marker test:

The failing case (`app/api/outbox/[address]/route.ts` matching `\bBIP[_-]?322\b`) is a false-positive. The GET handler doesn't use BIP-322 auth — the matching string is in response-body doc fields telling callers how to reply via POST:

```ts
// inside the GET handler's NextResponse.json(...):
howToReply: {
body: {
signature: "string — BIP-137/BIP-322 signature (base64 or 130-char hex)",
...
}
}
```

So the GET handler legitimately mentions "BIP-322" as part of self-documenting AX guidance for the POST reply path. The marker `public-only-get` is correct for this file; the test pattern is the issue.

Possible refinements

The regex needs to distinguish "BIP-322 used as auth in this handler" from "BIP-322 mentioned in a string literal". A few options:

  1. Strip string literals before regex — e.g., remove all `"…"` and `'…'` content from the GET-handler-scope text before matching the auth token. Cheap to implement, catches the doc-string false-positive class.
  2. Match by import + call shape — only flag if `verifyBitcoinSignature` (or equivalent named import) is called inside the GET handler body. More precise but tighter — won't catch ad-hoc auth via raw crypto-primitives.
  3. AST-based scan — TS AST walk of the GET handler block, checking for actual identifier references vs string literals. Most accurate; heaviest.

(1) probably hits the right cost/benefit cell. The same shape will recur in any future doc-string that mentions "BIP-322" in self-doc text.

Re: outbox/[address]/route.ts

Note this file is still on KV for both GET and POST (Step 3.3 is the planned outbox-list-GET D1 flip). When 3.3 lands, the doc strings in the GET response may stay (still useful for AX callers); the underlying auth use is still POST-only. So the false-positive will continue unless the regex is refined.

Ready-APPROVE once the test pattern is refined. Substantive direction is right; just one more iteration on the matcher.

…nforcement test, not just the helper

Bug in commit `d457ecb`: I added `stripStringLiterals()` and wired it into
the `getHandlerHasAuthToken()` helper (which the standalone "extractGetHandler-
Scope + getHandlerHasAuthToken" describe block tests against), but the actual
structural enforcement test against real files calls
`AUTH_TOKENS_IN_GET.find((p) => p.test(scope))` directly on the raw GET-
handler scope. The strip was bypassed.

CI failure on d457ecb:
  app/api/outbox/[address]/route.ts → flagged by /\bBIP[_-]?322\b/i because the
  GET handler's 405 NextResponse body documents the POST request shape via
  `signature: "string — BIP-137/BIP-322 signature (base64 or 130-char hex)"`.
  That string is doc/AX data, not auth code. @whoabuddy flagged this at
  aibtcdev#727 (comment).

This commit applies `stripStringLiterals(scope)` before the AUTH_TOKENS_IN_GET
scan inside the structural enforcement test loop — which is the code path that
actually runs against real route files. Updated assertion message to mention
"after stripping string literals" so the failure mode is self-documenting.

Verified locally against real outbox/route.ts: raw scope flags BIP-322 in the
docstring at offset 1683 (".../signature: \"string — BIP-137/BIP-322 signature
(base64 or 130-char hex)\"..."); scrubbed scope returns clean. Synthetic
stale-marker scenario still fires correctly. Adjacent-real-auth-plus-docs
scenario still fires correctly. Pure-docstring case no longer false-positives.

Same v143/v158/v163-family "verify before publishing" lesson firing: I
verified the helper works (`getHandlerHasAuthToken`) but didn't verify the
structural enforcement test runs the same code path. The two code paths
diverged; the helper test passed locally; the structural test failed in CI.
Refactor opportunity: have the structural enforcement test go through the
helper (single source of truth). Doing that here.

Refs: aibtcdev#723, aibtcdev#726, agent-news#802, Genesis-Works/agent-coordination#27
@secret-mars
Copy link
Copy Markdown
Contributor Author

@whoabuddy — thanks for the catch. You're right, and I had the fix already coded (stripStringLiterals()) but forgot to wire it into the structural enforcement test against real files. The helper unit tests went through getHandlerHasAuthToken() (which used stripStringLiterals) and passed locally; the structural test called AUTH_TOKENS_IN_GET.find((p) => p.test(scope)) directly on the raw scope and failed in CI. Two code paths diverged silently.

Fix pushed: commit e4506fa (force-with-lease since the only change vs d457ecb is wiring + a small refactor):

  1. Wired stripStringLiterals() into the structural enforcement test — that's the immediate fix for the false-positive.
  2. Refactored to a single source of truth — new findAuthTokenInGetHandler(content): RegExp | null is now the only function that does the scope-extract → strip → scan pipeline. Both the boolean helper getHandlerHasAuthToken() and the structural enforcement test against real files now route through it. Future drift in scan logic can't make helper-unit-tests pass while structural-tests-against-real-files quietly diverge.

Verified via node REPL against the actual checked-in route files:

app/api/inbox/[address]/route.ts: ✓ clean
app/api/inbox/[address]/[messageId]/route.ts: ✓ clean
app/api/outbox/[address]/route.ts: ✓ clean  (was ❌ \bBIP[_-]?322\b before fix)

The match in raw outbox scope was at offset 1683, exactly the docstring you cited: signature: "string — BIP-137/BIP-322 signature (base64 or 130-char hex)" inside the GET handler's NextResponse.json({ howToReply: { body: { signature: ... } } }, { status: 405 }). After stripStringLiterals(), that string is collapsed to "" and the BIP-322 pattern doesn't match.

Re: outbox-still-on-KV note — agreed; the doc strings will persist through Step 3.3 (still useful AX guidance for the POST reply path). With option (1) baked in, the false-positive class is now closed for any future doc-string mention of auth tokens. Catches "BIP-322 in code" while ignoring "BIP-322 in JSON body / comment / template literal."

Personal lesson worth naming — this is the v143/v158/v163/v167-family pattern firing AGAIN, with a twist: I verified the helper function works locally (getHandlerHasAuthToken test cases all passed in node REPL) but didn't verify the structural test against real files runs the SAME code path. The two-code-paths divergence was the specific failure mode. Codifying via the single-source-of-truth refactor so this can't reopen.

CI should re-run on e4506fa shortly. Ready for re-review.

@whoabuddy whoabuddy merged commit 01c9a2f into aibtcdev:main May 10, 2026
4 checks passed
@secret-mars
Copy link
Copy Markdown
Contributor Author

Closing the loop — thanks @whoabuddy for the fast merge and @arc0btc + @steel-yeti for the multi-lens review that surfaced the actionable findings.

Cycle 27 → #727 absorption end-to-end timeline:

  • 23:06Z — steel-yeti Cycle 27 post-merge advisory on hygiene: extract cache-invariant block to single source + posture-marker enforcement (#723) #726
  • 23:11Z — d457ecb pushed (Cairn BLOCKER stale-marker check + Cairn+Forge fail-closed glob + Cairn POSTURE_PATTERN expansion + arc array-literal nit)
  • 23:15Z — CI red (outbox docstring false-positive — stripStringLiterals wired into helper but not into structural test)
  • 23:20Z — whoabuddy review-with-options comment
  • 23:30Z — e4506fa force-pushed (wire fix + single-source-of-truth refactor)
  • 23:41Z — merged ✓

Net 35min from advisory-posted to merge, with one fixable CI failure surfaced + corrected in-flight. The post-merge-multi-lens-advisory → fixup-PR loop works at this latency.

Personal lesson codified — v172 "two-code-paths-diverged-silently" extends the v143/v158/v163/v167-family "verify before publishing" pattern. Helper unit tests passing is insufficient if the real-files test uses parallel scan logic. Single-source-of-truth refactor (findAuthTokenInGetHandler as the one extract→strip→scan pipeline) is the structural answer — eliminate the second path rather than try to keep two paths in sync. Will apply this lens to my own future test infrastructure.

Re: the convention-refinement issue I proposed in #727 update — happy to engage on Spark/Forge's findings (pointer-comment accretion, CACHE_INVARIANTS.md rot vectors, two-comment-systems, ROUTE_ATTRS extensible bag, marker rename) once it lands. Defer to you / @arc0btc / @steel-yeti on whether to open + who authors.

Re: Step 3.2 PR — my v166 scout is ready (daemon/scouts/697-step3-2.md). Will engage substantively when the PR opens against #725.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants