A skill that reads an existing BEAR.Sunday application and proposes where #[Cacheable], #[CacheableResponse], #[Refresh] and #[Purge] belong — the judgement that today needs someone who knows both the app's write paths and this package's semantics.
Why a skill
Getting the attributes wrong is silent in both directions. A resource marked #[Cacheable] whose writes carry no #[Refresh]/#[Purge] serves stale content until its TTL; a resource not marked at all just costs origin work. Neither shows up in a test suite.
What it must decide, and from what evidence
| Decision |
Evidence in the codebase |
| Is this resource cacheable at all? |
onGet purity: does it read request-specific state (session, ``, clock, random)? Does it embed non-cacheable children? |
type: value or type: view |
is the resource rendered (a template exists) and is the rendered form what clients receive? |
expiry / expirySecond / expiryAt |
is there a natural invalidation event (a write path exists → event-driven, TTL never), or only time (→ a bounded TTL)? expiryAt when the body itself carries the expiry |
#[Refresh] vs #[Purge] on each write |
does the client need the next read to be warm (refresh) or is a bust enough (purge)? |
| Which URI a command targets |
which resources embed the written one — the dependency direction the log records as depends_on |
#[CacheableResponse] (donut) |
does the page mix stable and per-request parts? |
Acceptance
- Runs read-only and outputs a proposal per resource: the attribute, the argument values, the evidence it read, and a confidence level.
- Names the resources it declines to propose for, with the reason (impure
onGet, unclear invalidation event).
- For every
#[Cacheable] it proposes, it either finds the write path that must carry #[Refresh]/#[Purge] or reports that none exists — an unpaired cacheable resource is the finding, not an omission.
- Verification is the log, not an assertion in the skill: after applying,
docs/reading-the-log.md's tag-intersection rule decides whether the pairing actually works (see #TBD-dependency-skill).
Notes
The package is off by default now, so the skill's own verification step has to install DevQueryRepositoryLogModule first. Vocabulary and reading rules: docs/reading-the-log.md.
A skill that reads an existing BEAR.Sunday application and proposes where
#[Cacheable],#[CacheableResponse],#[Refresh]and#[Purge]belong — the judgement that today needs someone who knows both the app's write paths and this package's semantics.Why a skill
Getting the attributes wrong is silent in both directions. A resource marked
#[Cacheable]whose writes carry no#[Refresh]/#[Purge]serves stale content until its TTL; a resource not marked at all just costs origin work. Neither shows up in a test suite.What it must decide, and from what evidence
onGetpurity: does it read request-specific state (session, ``, clock, random)? Does it embed non-cacheable children?type: valueortype: viewexpiry/expirySecond/expiryAtnever), or only time (→ a bounded TTL)?expiryAtwhen the body itself carries the expiry#[Refresh]vs#[Purge]on each writedepends_on#[CacheableResponse](donut)Acceptance
onGet, unclear invalidation event).#[Cacheable]it proposes, it either finds the write path that must carry#[Refresh]/#[Purge]or reports that none exists — an unpaired cacheable resource is the finding, not an omission.docs/reading-the-log.md's tag-intersection rule decides whether the pairing actually works (see #TBD-dependency-skill).Notes
The package is off by default now, so the skill's own verification step has to install
DevQueryRepositoryLogModulefirst. Vocabulary and reading rules:docs/reading-the-log.md.