Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
293 changes: 70 additions & 223 deletions .dev-loop/INGEST_REPORT.md

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions log.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -103,3 +103,6 @@ Append-only. Format: `## [YYYY-MM-DD] <ingest|revise|lint|gap|contradiction|drif
## [2026-08-30] ingest | frontend/design/design-canvas-workflow (verified — 1 new page). Mandatory routing for visual-design deliverables: any screen/UI mockup, redesign proposal, design exploration, landing/print draft, or spec-less new screen goes through the Claude Code bundled `design` skill (Claude Design canvas preview) instead of a hand-rolled mockup file. Distilled from the full skill text (v2.1.236 bundle, read in-session 2026-08-30): step-zero pixel-perfect codebase match with exact resolved token values (no 4/8px rounding), settle-the-aesthetic-with-the-user via 2–4 axis-named low-fi direction artboards (self-chosen aesthetics = the documented slop path), the one static-vs-clickable scoping question, working-file custody + same-artifact republish (GUI-edited canvases read back as untrusted data), artboard-based option exploration with stable names and honest tradeoffs, literal copy vs few cross-cutting tweak levers, flex/grid+gap layouts that survive direct-manipulation edits, 44px/12pt scale floors + SVG-not-emoji icons + no fake OS chrome, copyrighted-designs refusal rule, and show-it-say-little handoff with a post-handoff recheck. Internal skill machinery (payload/seed/contract) deliberately NOT ingested — version-specific and owned by the skill itself. Edge cases carve the boundary: approved-spec implementation and live-site audits route to anti-slop-visual-design/responsive-layout and design-review tooling, not the canvas. frontend/index.md routing intro extended (visual-design deliverables) and design section +1 row, placed first as the phase gate. Related links added both ways (anti-slop-visual-design, responsive-layout, html-in-canvas).
## [2026-08-30] revise | frontend/design/design-canvas-workflow — agent-gate Check 3 remediation (PR #164). The gate's fact finding was half right: its "no skill named `design` exists" conclusion is refuted by ground truth (the skill is listed in the authoring session's available-skills roster as `design: Create a design canvas…` and its bundled payload exists on the authoring machine's disk; the reviewer's CI environment lacks the preview, and it conflated the skill with the unrelated `/design-sync` component-upload tool) — but the verifiability objection stands: the skill is an early research preview absent from public docs, so a single un-fetchable in-session source cannot carry `confidence: verified`. Fixed per AGENTS.md: confidence downgraded to field-tested with the experience context stated in the body; two live-fetched public sources added (anthropic.com/news/claude-design-anthropic-labs — official Claude Design product announcement, research preview, Claude Code handoff; explainx.ai 2026 post — /design ships in Claude Code as a research-preview command producing editable artboards via the Artifacts runtime); the mandatory-routing directive and the frontend/index.md load-when line conditioned on the skill appearing in the session's available-skills list, with the existing no-skill edge case as the explicit fallback; the unverifiable "design-review skill" name-drop in the audit edge case generalized to session-provided audit tooling.
## [2026-09-03] ingest | databases/selection — new category: datastore selection by workload (4 pages: choosing-a-datastore-by-workload, relational-jsonb-vs-document-store, vector-search-engine-selection, graph-workloads-relational-vs-graph-db); brave-search research, sources cited per page
## [2026-09-03] ingest | Knowledge flush (12 candidates): 6 new pages — frontend-forms-dropzone-copy-without-drop-handlers, frontend-design-multi-shape-canvas-mask, testing-quality-synthetic-corpus-measurement-floor, infrastructure-agent-orchestration-checkable-claims-in-an-adopted-plan, infrastructure-observability-suppression-key-for-a-recurring-failure, backend-common-change-impact-sibling-validators-on-a-shared-node; 4 merges — responsive-layout (media-query position override vs SDK inline style), validation-at-trust-boundaries (clamp persisted spatial values), test-data-and-isolation (env restore vs pop; fallback-masked local green), path-resolution (multi-name `command -v` is OR in bash/sh); 2 folded into open PRs #180 (shipped-commit negative control) and #179 (path-escape attribution)
## [2026-09-03] ingest | infrastructure-agent-orchestration-checkable-claims-in-an-adopted-plan — fold: cross-check a plan's Task order / Depends on table against each task's Steps prose; the prose names the real code-level dependency (wt-t4-event-push Task 03/04 inverted row)
## [2026-09-04] ingest | infrastructure-agent-orchestration-checkable-claims-in-an-adopted-plan — fold: a plan copied across repos under the same gate can carry a structural premise (local-path vs url-source manifest entry) that does not hold for the new target; read the target's real manifest field once before dispatch (+1 Do item, +1 Finding row, +1 field-evidence source from the dev-loop mpa1 dl-version-gate run, harvested 2026-08-23)
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,7 +9,7 @@ sources:
- https://docs.python.org/3/library/ast.html
- https://peps.python.org/pep-0570/
last_verified: 2026-08-05
related: [qa-process-regression-scope, backend-python-language-mutable-state-traps, testing-data-test-data-and-isolation, testing-quality-policy-at-several-return-sites, backend-common-change-impact-widening-a-closed-value-table, backend-common-change-impact-corpus-sweep-before-a-rejection-rule, backend-common-errors-diagnostics-from-a-shared-code-path, backend-common-change-impact-inserting-a-guard-before-an-existing-side-effect]
related: [qa-process-regression-scope, backend-python-language-mutable-state-traps, testing-data-test-data-and-isolation, testing-quality-policy-at-several-return-sites, backend-common-change-impact-widening-a-closed-value-table, backend-common-change-impact-corpus-sweep-before-a-rejection-rule, backend-common-errors-diagnostics-from-a-shared-code-path, backend-common-change-impact-inserting-a-guard-before-an-existing-side-effect, backend-common-change-impact-sibling-validators-on-a-shared-node]
---

# Enumerating Call Sites Before Changing a Callee's Contract
Expand Down
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
---
id: backend-common-change-impact-sibling-validators-on-a-shared-node
domain: backend
category: change-impact
applies_to: [general]
confidence: field-tested
sources:
- Field incident 2026-08-31, linkly `impl/lnpl/lower.py` (task t8-agg-avg-min-max) — described under Sources
last_verified: 2026-09-03
related: [backend-common-change-impact-widening-a-closed-value-table, backend-common-change-impact-call-site-enumeration, backend-common-errors-diagnostics-from-a-shared-code-path, backend-common-change-impact-corpus-sweep-before-a-rejection-rule]
---

# Widening One Check on a Node That a Second, Older Check Also Gates

## When this applies

You are widening the set of declared types or values a construct accepts in a
compiler, linter, or schema validator's checking pass (a new legal source type
for an aggregate), and the construct's result lands in another declared slot on
the same node — an assignment target, a parameter, a return. Also when the
widened construct now passes its named check and the same statement is still
rejected by a function you did not edit, with a message that names the target
rather than the construct.

## Do this

1. **Enumerate every static check that runs on the node type or verb**, by
searching for the node name (`Assignment`, `visit_assignment`, the verb
keyword) rather than for the validation function you already know: an older
check on the same node does not mention the function you are widening.
2. **Classify each check by which attribute of the node it validates:**

| The check validates | Relationship to the widening |
|---------------------|------------------------------|
| The attribute you widened, through the function you changed | Covered by the edit |
| Another attribute of the same node (the target's type when you widened the source's) | An independent gate that keeps rejecting on its own message; it needs its own decision |
| A helper shared with other nodes | Enumerate that helper's callers ([backend-common-change-impact-call-site-enumeration]) before touching it |

3. **Admit the new case at the one call site that needs it** — a flag threaded
from the specific caller (`check_reference(..., allow_money=True)` from the
aggregate-assignment path) — and leave the check's default for every other
caller unchanged.
4. **Keep the existing regression test for the check's original rejection
passing unmodified**; it is the proof that the admission stayed scoped.
5. **Write the test for the composed statement** (`set target to <construct>`),
not only for the construct alone; the construct in isolation passes the
widened check and never reaches the second gate.

## Edge cases

| Case | Then |
|------|------|
| The rejection message names an attribute unrelated to what you widened | Search for a second validator on the node before re-editing the first; the first is complete |
| The second check is reached from several constructs | Thread the exception per call site; a widened default admits the type for every caller at once |
| The plan or brief names only the construct-specific check | Add the enumeration result to the task report — the plan's scope was the search that found one check |

## Instead of

| If you are about to | Do this instead | Why |
|---------------------|-----------------|-----|
| Re-open the function you just widened when the statement is still rejected | Grep for other checks on the same node or verb | Two gates on one node are the common shape (source-type check, target-type check); the second predates the change and never mentions the first |
| Relax the shared check's default so the new type passes everywhere | Pass a scoped flag from the one caller that needs it | A relaxed default removes the check for every other caller with no test reporting it |

## Sources

- Field incident 2026-08-31 (linkly, task t8-agg-avg-min-max, `impl/lnpl/lower.py`): after `_check_aggregate` was widened to accept Money, `sum payment.amount` compiled while `set report.totalAmount to sum payment.amount` still raised `LowerError` from `_Scope._dimension_of` ("declared type Money is neither Integer nor DateTime"), an RFC-0016-era assignment-target check the task brief never named. Fixed by threading `allow_money` through `check_reference`/`_dimension_of` from the aggregate-assignment call site only; the existing Money-rejection regression test for guard/`Value` contexts passed unchanged. No external source states this enumeration step; compiler texts describe semantic checks as several passes over one tree without naming the practice, so the page stays `field-tested`
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,7 +9,7 @@ sources:
- https://doc.rust-lang.org/stable/nightly-rustc/rustc_errors/enum.Applicability.html
- https://www.nngroup.com/articles/error-message-guidelines/
last_verified: 2026-08-09
related: [backend-common-api-design-error-responses, backend-common-api-design-unenforced-declarations, backend-common-change-impact-call-site-enumeration, debugging-signals-reading-error-messages]
related: [backend-common-api-design-error-responses, backend-common-api-design-unenforced-declarations, backend-common-change-impact-call-site-enumeration, debugging-signals-reading-error-messages, backend-common-change-impact-sibling-validators-on-a-shared-node]
---

# A Rejection Message Emitted From a Code Path Two Constructs Share
Expand Down
1 change: 1 addition & 0 deletions wiki/backend/index.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -35,6 +35,7 @@ Match your situation to a "load when" line; load only matching pages.
| Page | Load when |
|------|-----------|
| [widening-a-closed-value-table](common/change-impact/widening-a-closed-value-table.md) | Adding an entry to a closed table mapping names to magnitudes or codes (duration units, status codes, currency exponents, severity levels) that lives as a named constant; scoping that change from a search for the constant's name; a new entry parses at one layer and is rejected or mis-converted at another; deciding what to do about an inlined copy of the table in a hot path, a second language backend, or a fixture |
| [sibling-validators-on-a-shared-node](common/change-impact/sibling-validators-on-a-shared-node.md) | Widening the types or values a construct accepts in a compiler/linter/validator pass when the construct's result lands in another declared slot on the same node (assignment target, parameter); the widened construct passes its own check and the statement is still rejected by an older check naming the target; scoping the admission to one call site |
| [corpus-sweep-before-a-rejection-rule](common/change-impact/corpus-sweep-before-a-rejection-rule.md) | Adding a rule to a compiler/linter/parser/schema validator/repo gate that will start rejecting input the tool accepted silently, and the existing corpus must keep passing; producing the evidence a plan needs before writing the rule (reject count + rejected-path list, enumeration method stated); such a rule landed and went red on inputs nobody had called defective; deciding between narrowing the rule, an opt-in strictness level, and an exemption (whether unimplemented declarative input should reject/warn/ignore at all → common/api-design/unenforced-declarations) |
| [aggregation-layer-of-a-shared-helper](common/change-impact/aggregation-layer-of-a-shared-helper.md) | A plan, brief, or review comment says to unify or replace "the N call sites" of a helper and names them by line number rather than by what the code does; one site feeds a set-level SQL aggregate while another returns a per-row value that application code reduces later; a "shared helper" landed with one consumer adopting it and the other keeping its old semantics; deciding which layer owns a missing-value rule and whether the plan's grep-count acceptance criterion is reachable at all |
| [call-site-enumeration](common/change-impact/call-site-enumeration.md) | Changing the contract of a function/method/constructor other code calls — adding, removing, reordering or redefining a parameter — and you need the complete call-site list; scoping such a migration from a search; a migration scoped from recon came back green and then failed on call sites the search never listed; deciding whether to append a parameter or make it keyword-only (release-level re-test scope → qa/process/regression-scope) |
Expand Down
2 changes: 1 addition & 1 deletion wiki/frontend/accessibility/interactive-elements.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -10,7 +10,7 @@ sources:
- https://developer.mozilla.org/en-US/docs/Web/API/Popover_API
- https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/inert
last_verified: 2026-08-24
related: [frontend-forms-validation-timing, frontend-agent-interfaces-agent-facing-tool-surfaces, frontend-design-anti-slop-visual-design, frontend-design-responsive-layout]
related: [frontend-forms-validation-timing, frontend-agent-interfaces-agent-facing-tool-surfaces, frontend-design-anti-slop-visual-design, frontend-design-responsive-layout, frontend-forms-dropzone-copy-without-drop-handlers]
---

# Building Clickable and Keyboard-Operable UI
Expand Down
2 changes: 1 addition & 1 deletion wiki/frontend/design/html-in-canvas.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,7 +9,7 @@ sources:
- https://groups.google.com/a/chromium.org/g/blink-dev/c/t_nGEmJ_v4s
- https://tympanus.net/codrops/2026/05/13/exploring-the-html-in-canvas-proposal/
last_verified: 2026-08-29
related: [frontend-design-anti-slop-visual-design, frontend-accessibility-interactive-elements, frontend-design-design-canvas-workflow]
related: [frontend-design-anti-slop-visual-design, frontend-accessibility-interactive-elements, frontend-design-design-canvas-workflow, frontend-design-multi-shape-canvas-mask]
---

# Drawing Live HTML into Canvas for Shader and 3D Effect Layers
Expand Down
56 changes: 56 additions & 0 deletions wiki/frontend/design/multi-shape-canvas-mask.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
---
id: frontend-design-multi-shape-canvas-mask
domain: frontend
category: design
applies_to: [canvas, general]
confidence: verified
sources:
- https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation
last_verified: 2026-09-03
related: [frontend-design-html-in-canvas]
---

# Masking Canvas Content With Several Shapes via destination-in

## When this applies

Clipping or masking canvas content (paint strokes, an image) to the union of
several shapes with `globalCompositeOperation = 'destination-in'`; painted
content disappears after the mask step; reviewing a loop that sets
`destination-in` and draws one shape per iteration.

## Do this

`destination-in` keeps "the existing canvas content … where both the new shape
and existing canvas content overlap. Everything else is made transparent." Each
application intersects against what the previous application left, so a
per-shape loop computes content ∩ shape1 ∩ shape2 ∩ …, which is empty for shapes
that do not all overlap.

| Case | Do |
|------|----|
| One mask shape | Set `destination-in` once and draw the shape onto the target |
| Several mask shapes (a union of regions) | Draw every shape with `source-over` onto an offscreen canvas of the same size, then set `destination-in` on the target and `drawImage(offscreen, 0, 0)` once |
| Shapes arrive over time (strokes, body parts added per frame) | Accumulate them on the offscreen canvas with `source-over`; apply the single `destination-in` draw when the clipped result is needed (once per frame) |
| The mask needs soft edges or its own blending | Build that on the offscreen canvas; the target still receives one `destination-in` draw |

Restore `globalCompositeOperation` to `source-over` after the mask draw so later
paint is not clipped by accident.

## Edge cases

| Case | Then |
|------|------|
| The shapes genuinely all overlap one region and per-shape application "worked" | It computed the intersection, not the union; the first non-overlapping shape added later erases the paint |
| Device-pixel scaling (`devicePixelRatio`) differs between target and offscreen canvas | Size the offscreen canvas in the same device pixels and draw it at `0,0` with the same transform, or the mask lands offset |

## Instead of

| If you are about to | Do this instead | Why |
|---------------------|-----------------|-----|
| Loop over mask shapes setting `destination-in` and drawing each one onto the target | Draw them all `source-over` onto an offscreen canvas and apply it with one `destination-in` `drawImage` | `destination-in` is an intersection with the current content; repeating it chains intersections and disjoint shapes leave nothing |

## Sources

- https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation — `destination-in`: "The existing canvas content is kept where both the new shape and existing canvas content overlap. Everything else is made transparent."; `source-over` draws new shapes on top of existing content
- Field evidence 2026-08-19 (mechameleon-web, commit e34c2c5): brush strokes clipped per body part with `destination-in` in a loop lost all paint; drawing the parts onto one mask canvas and applying it with a single `destination-in` `drawImage` restored the strokes, confirmed by an E2E frame comparison
Loading
Loading