The cache-first feature injected <standards> blocks into 5 reviewer dispatch prompts, but only performance-reviewer parsed them — code, business-logic, security, and test reviewers ignored the injection and re-fetched standards on every run. The orchestrator-side half shipped without the consumer-side half. Each of the 4 default reviewer agents now has a Standards Loading (Cache-First) section implementing the canonical three-tier resolution: cache hit from state.cached_standards, cache miss via WebFetch with warning, standalone fallback to hardcoded URLs. The per-reviewer fallback URL lists are unique and derived from each reviewer's standards_slice. The 5-way verbatim duplication of the dispatch block in codereview/SKILL.md is collapsed to per-reviewer URL-slice markers that reference shared-patterns/standards-cache-protocol.md as the single source of truth. The shared pattern now carries the canonical <standards> template, orchestrator pseudocode, three-tier protocol, rolling-standards policy, and an anti-rationalization table defending cache-first behavior. Net 117-line reduction in codereview/SKILL.md. X-Lerian-Ref: 0x1
6.6 KiB
| name | description |
|---|---|
| shared-pattern:standards-cache-protocol | Protocol for reading cached standards from cycle state instead of WebFetching directly. Includes the canonical `<standards>` dispatch block format and the cache-first resolution protocol that reviewer agents follow at runtime. |
Standards Cache Protocol
Purpose
Eliminate redundant WebFetch calls during a dev-cycle by pre-caching all required standards at cycle start (dev-cycle Step 1.5) and having sub-skills and reviewer agents read from state instead of fetching inline on every dispatch.
This document is the single source of truth for:
- How orchestrators build the
<standards>block at dispatch time. - How reviewer agents resolve that block (cache hit / cache miss / standalone fallback).
Canonical <standards> Block Format
Orchestrators (dev-cycle, codereview SKILL) MUST use this exact block shape when injecting cached standards into a reviewer's dispatch prompt:
<standards>
<standard url="https://raw.githubusercontent.com/LerianStudio/ring/main/.../file.md">
<content>{{ state.cached_standards["<same url>"].content OR empty }}</content>
</standard>
<!-- ...one <standard> per URL in the reviewer's slice... -->
</standards>
Rules:
urlattribute is ALWAYS populated (the canonical URL onmain).<content>is populated whenstate.cached_standards[url]exists (cache hit).<content>is empty when the orchestrator has no cached entry (cache-miss signal).
Orchestrator Resolution (at dispatch time)
for each url in standards_slice:
if state.cached_standards[url] exists:
emit <standard url="..."><content>{{cached content}}</content></standard>
else:
emit <standard url="..."><content></content></standard> # cache-miss signal
Reviewer/Sub-Skill Resolution (at runtime)
Reviewer agents and sub-skills MUST follow this three-tier protocol, in order:
- Cache hit. If the dispatch prompt contains a
<standards>block and a<standard>'s<content>is populated, use that content as the authoritative rules source. No WebFetch needed. - Cache miss fallback. If a
<standard>'s<content>is empty, WebFetch that<standard>'surlyourself and use the fetched content. Log a "Standard {url} not in cache; fetching inline" warning so operators can detect orchestrator misconfigurations. Do not skip the standard. - Standalone fallback. If the dispatch prompt contains no
<standards>block at all (standalone/legacy invocation, no dev-cycle context), WebFetch the reviewer's hardcoded fallback URL list (defined in the reviewer agent itself) and proceed.
Pseudocode form (equivalent):
STEP 1: Check cache
IF <standards> block is present AND <standard>.<content> is populated:
use content directly (cache hit)
proceed
STEP 2: Cache-miss fallback
IF <standards> block is present AND <standard>.<content> is empty:
log WARNING: "Standard {url} not in cache; fetching inline"
content = WebFetch(standard.url)
proceed
STEP 3: Standalone fallback
IF no <standards> block in dispatch prompt:
FOR EACH url in reviewer's hardcoded fallback list:
content = WebFetch(url)
proceed
Rolling Standards Policy
All URLs point to the main branch. WebFetch always returns current rules;
there is no pinned version. This is intentional — installed plugins pick up
standards updates without a plugin release.
For Orchestrators (dev-cycle, dev-cycle-frontend)
At Step 1.5 of the cycle:
- Detect project stack (Go / TypeScript / Frontend).
- Build the URL list (see dev-cycle Step 1.5 for the current list).
- WebFetch each URL once.
- Write to
state.cached_standards[URL] = {fetched_at, content}. - MANDATORY: Save state to file.
- Blocker if ANY URL fails to fetch.
At dispatch time (Step 3 of codereview, and elsewhere): build the <standards>
block per the canonical format above, one <standard> entry per URL in the
reviewer's slice.
Why
Before: ~15–25 WebFetch calls per cycle (one per sub-skill/reviewer dispatch). Prompt cache TTL of 5 min is regularly exceeded, causing repeated network fetches of identical content.
After: Exactly ONE WebFetch per unique URL per cycle. Same content, ~5x fewer network operations.
Safety
If the cache mechanism fails or is bypassed:
- Sub-skills and reviewers fall back to direct WebFetch (with warning log).
- No correctness regression; only performance regression.
- Operators can monitor "Standard {URL} not in cache" warnings to detect misconfigurations.
Anti-Rationalization Table
| Rationalization | Why It's WRONG | Required Action |
|---|---|---|
| "The cache might be stale — safer to WebFetch directly" | The cache is populated once at dev-cycle Step 1.5 specifically so every sub-skill and reviewer sees identical standards content within a cycle. Re-fetching creates drift between reviewers running in parallel and produces inconsistent verdicts. | MUST read from state.cached_standards[url] when a <standards> block is present in the dispatch prompt. MUST NOT re-WebFetch on cache hit. |
"Empty <content> probably means the orchestrator failed — I'll just skip" |
Empty <content> is the documented cache-miss signal. Skipping standards loading silently omits compliance checks the orchestrator expected to run. |
MUST WebFetch the URL on empty <content> and emit a WARNING to surface the cache miss. MUST NOT skip the standard. |
"No <standards> block in my prompt — I'll abort" |
Absence of the block means standalone invocation (not dispatched from dev-cycle). Standalone invocation is a supported mode; the reviewer MUST still load standards via direct WebFetch using its own fallback URL list. | MUST fall back to WebFetch of hardcoded URLs when no <standards> block is present. MUST NOT fail the review. |
| "The cached content looks old — I'll fetch a fresh copy" | The cache is an intra-cycle consistency guarantee, not a freshness guarantee. Freshness is the orchestrator's concern at Step 1.5. A reviewer that second-guesses cache freshness breaks the guarantee for its peers. | MUST trust cached content within a cycle. Report staleness concerns to the orchestrator via the Standards Compliance section of the review output, not by re-fetching. |
| "Silent fallback is fine — no one reads warnings" | Silent fallbacks hide misconfigured orchestrators and let cache-population bugs fester across cycles. The WARN log is how operators detect cache-population regressions. | MUST emit a clearly-prefixed WARNING log on every cache miss (e.g., [cache-miss] WebFetching <url>). |