Skip to content
Merged
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
281 changes: 223 additions & 58 deletions .dev-loop/INGEST_REPORT.md

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions log.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,3 +99,4 @@ Append-only. Format: `## [YYYY-MM-DD] <ingest|revise|lint|gap|contradiction|drif
## [2026-08-24] revise | frontend/accessibility/interactive-elements +popover/inert (0 new pages). Discovery origin: GeekNews topic 32793 → htmlcat.net (curated native-web listicle; NOT cited — feature-catalog items like clamp()/text-wrap/color-mix were deliberately skipped as MDN-derivable, and container queries + native <dialog> were found already covered by responsive-layout and this page). Ingested only the two decision-relevant gaps, sourced from MDN (both live-fetched this session): Do-this #4 extended with `popover` + `popovertarget` for non-modal surfaces (top layer, light-dismiss, Escape for free; never modal, no focus trap — modal stays <dialog>+showModal; Baseline newly available 2025-01), +1 edge-case row (overlay that cannot use <dialog> → `inert` on background containers, subtree drops from focus/click/a11y tree; Baseline widely available 2023-04), +1 Instead-of row (hand-rolled dropdown with outside-click listeners → popover="auto"). frontend/index.md load-when extended (overlay/background-disable triggers). last_verified → 2026-08-24; body 87 lines.
## [2026-08-24] ingest | GitHub-trending agent-skill practices (4 new pages, 1 amended page, 3 domain indexes updated). Distilled from six trending repos analyzed this session; each directive cited to a live-verified source file (all 9 cited repo paths confirmed via `gh api` before writing). New: qa/process/llm-review-pipelines (alibaba/open-code-review — deterministic file-selection/bundling/glob-rule-matching before the model, rules as matchable rule.json data not prompt prose, related-file bundles as isolated concurrent sub-reviews, deterministic re-location of model-emitted line anchors, precision-over-recall measured on a labeled PR set; the ~1/9-token claim flagged as vendor self-measured on AACR-Bench, not independently reproduced), backend/common/llm/progressive-disclosure-artifacts (book-to-skill — always-loaded core index + on-demand ~1K-token chunks, per-chunk budget from a content-type × usage-depth matrix, auxiliary views as separate files, grep/sed slice access for ≥50K-token originals; copyright edge case = synthesize-not-reproduce + keep private), security/dependencies/agent-skill-supply-chain (reverse-skill skill-supply-chain checklist + openwork skills-lock.json + book-to-skill's documented malicious re-upload: skill = arbitrary code, read SKILL.md+scripts and grep exfil patterns, resolve canonical owner vs lookalike, pin by source+hash, vet MCP auto-registration; publication-time gating for team marketplaces), security/agent-exposure/authorization-scope-persistence (reverse-skill scope-contract — persist authorization to a per-target file with a status field, default-deny on status != granted, --force cannot bypass the auth check, network_profile as its own field, re-read the gate at each dangerous step). Amended: backend/common/llm/binding-instructions-for-agents +Do-this #6 (pre-send self-check predicates for output-shape rules) + i-have-adhd source. Deliberately NOT ingested: block/buzz signed hash-chain audit log (platform-construction knowledge, off the wiki's usage context), openwork search+execute 2-tool gateway (README-only, in tension with agent-tool-granularity's primitives guidance, below the directive bar), airllm/airi/pascalorg-editor/AI-For-Beginners (out of domain or unverified at code level). Correction to the source podcast's claim: open-code-review's token figure is ~1/9, not "19%". Reciprocal related links added both ways (supply-chain, in-session-tool-exposure, evaluating-review-feedback, context-window-budget, agent-tool-granularity via binding-instructions, autonomous-decision-rulings).
## [2026-08-25] revise | pane-delivery-confirmation: fixed last-N window is defeated by a paste's own rendered tail — anchor the placeholder scan on the input box (#145)
## [2026-08-27] ingest | knowledge-flush of the harvested insight queue — 5 new pages, 5 amended pages, 4 domain indexes updated; 13 of 21 claimed candidates ingested, 2 dropped, 6 released for a later flush. New: databases/transactions/application-clock-vs-database-timestamps (app-produced `Date` compared against a `default now()` column — take the boundary from the DB via `RETURNING`, produce it once per decision and propagate it into the follow-up step rather than recomputing (a second `now` widens a `<= boundary` cleanup set), pick the safe error direction before choosing a margin, and separate "same clock" from "correct ordering" since `now()` is `transaction_timestamp()` so a later-committing transaction can carry an earlier stamp — close that window with a lock or SERIALIZABLE, not finer resolution; PostgreSQL functions-datetime + dml-returning live-fetched and quoted), infrastructure/ci-cd/changed-files-only-gates (count-and-branch-on-empty before invoking the tool, log the passed list not just its length, pass operands as an array/xargs because zsh does not word-split by default, prove the gate can fail with a probe placed on a non-ignored path; Prettier CLI + ignore docs and zsh FAQ live-fetched, then all seven cases measured locally against Prettier 3.7.4 after an independent cross-check refuted the first draft: the success sentence is NOT a pass signal — it is printed both for an ignore-filtered list at rc 0 and alongside an unmatched-pattern error at rc 2. The genuine silent vacuous passes are no-operands (rc 0), all-operands-ignore-filtered (rc 0), and unsupported-extensions-with-`--ignore-unknown` (rc 0), while an unmatched or word-split operand exits 2 unless `--no-error-on-unmatched-pattern` is set; the page carries the measured table), backend/common/change-impact/compiler-as-call-site-inventory (contextually typed object literals build a type without naming it, so a type-name grep and the truth are different sets — take the inventory from the compiler error list and bound it to the program, since a package whose `include` omits its own tests contributes zero errors from files that still build the value; TS handbook objects + tsconfig include/exclude live-fetched, incl. the documented fact that `exclude` does not stop transitive imports), testing/quality/mutation-harness-file-custody (key backups by flattened relative path not basename, byte-compare each restore before the next mutation, confirm restores by content because an untracked file's `git diff` is empty either way, and read the tree only after process-exit AND empty-backup-dir), infrastructure/containers/exec-added-processes-and-the-memory-budget (an exec'd process joins the container's cgroup but is invisible to the app's own semaphore — decide from `memory.max − memory.peak` headroom, and read `memory.events: max` as approaches-to-limit distinct from `oom_kill`; kernel cgroup-v2 admin guide live-fetched and quoted). Amended: testing/quality/tests-that-cannot-fail +1 never-fails row and +1 Instead-of row (a negative assertion whose fixture never supplies the triggering input is vacuous — the defect is in the fixture, so strengthening the expectation changes nothing; measured 116/116 green under the widening it claimed to catch), testing/quality/source-text-wiring-assertions (page sits at the 120-line cap, so the new nuance was merged in place into the existing negative/count edge row rather than added as a line — an `indexOf(marker)` slice collapses to `''` when the marker also appears in a comment above the code, making every assertion inside it vacuously green), backend/common/change-impact/widening-a-closed-value-table +Do-this #6/#7 and +1 Instead-of row (unifying two duplicate allowlists defaults to the union and silently widens each side — compute both set differences and rule on each element first, keep derived-with-explicit-difference when an element must legitimately differ, and record whether the merged set widened or narrowed), qa/process/evaluating-review-feedback +2 edge rows and +1 Instead-of row (a body-level finding cites no lines, so step 2 has nothing to open — grep the quoted string across the changed set before ruling, since the usual shape is that one sibling was fixed and another still carries the defect), infrastructure/containers/host-cgroup-visibility (self-monitoring row cross-linked to the new exec-preflight page). Dropped as not generalizable to this wiki: a Figma-MCP `inspect_node`→`get_dev_ready` children-fetch workaround (private MCP server, not publicly verifiable) and an `/rtb:review` remote-fallback runbook (hardcoded private tooling paths; the transferable part — a two-provider review gate degraded to one provider is not a passed gate — is already carried by qa/process/llm-review-pipelines). Released back to the queue for a later flush, each needing its own page rather than a row: plan-level carrier/seam field naming, `VAR="$(cmd 2>&1)"` stderr contamination in shell value extraction, tmux/CI monitor delta-vs-absolute anchoring, positional-order assertions on rendered SQL predicates, `.env` active-assignment preflight before a destructive DB command, and CI ticket-key extraction scoped by changed-file intersection.
4 changes: 2 additions & 2 deletions tests/wiki-lint-prohibitions.bats
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ setup() {

# --- normal: the real corpus is already compliant ---------------------------

@test "real wiki: exits 0 with 0 violations and 71 directive units" {
@test "real wiki: exits 0 with 0 violations and 72 directive units" {
cd "$REPO_ROOT" || return 1
run node "$CHECKER" wiki
[ "$status" -eq 0 ]
[[ "$output" == *"directives: 71"* ]]
[[ "$output" == *"directives: 72"* ]]
[[ "$output" == *"violations: 0"* ]]
}

Expand Down
105 changes: 105 additions & 0 deletions wiki/backend/common/change-impact/compiler-as-call-site-inventory.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
---
id: backend-common-change-impact-compiler-as-call-site-inventory
domain: backend
category: change-impact
applies_to: [typescript]
confidence: verified
sources:
- https://www.typescriptlang.org/docs/handbook/2/objects.html
- https://www.typescriptlang.org/tsconfig/#include
- https://www.typescriptlang.org/tsconfig/#exclude
- https://www.typescriptlang.org/docs/handbook/type-checking-javascript-files.html
last_verified: 2026-08-27
related:
[
backend-common-change-impact-call-site-enumeration,
backend-common-change-impact-cross-module-consumer-census,
backend-common-integrations-consumer-required-fields,
testing-quality-tests-that-cannot-fail,
qa-process-completion-claims,
]
---

# Using the Type Checker as the Inventory of Sites That Build a Value

## When this applies

You are adding a required field to a type and relying on "make it required and
the compiler lists every site that must be updated" as the complete inventory —
or you enumerated those sites by grepping the **type's name** and are about to
publish the count in a plan, brief, or task breakdown.

Enumerating callers of a function whose signature changes →
[backend-common-change-impact-call-site-enumeration].

## Do this

1. **Enumerate construction sites from the compiler's error list, and use a
grep only to cross-check it.** TypeScript types object literals from
context, so a value of the type can be built with the type's name nowhere in
the text — `dealViewer: { userId: ctx.user.userId }` constructs a `DealViewer`
and contains no occurrence of `DealViewer`. A type-name grep counts the sites
that *mention* the type; the sites that *build* it are a different set.

2. **Bound the claim to the files the compiler actually reads, and check that
boundary before quoting the count.** The program is `files` ∪ `include` ∪
everything reachable by import from them. A package whose `tsconfig.json`
says `include: ["src/**/*"]` never type-checks its own `__tests__/`
directory unless `src` imports it, so fixtures and expected-value literals
there contribute **zero** errors and are missing from the inventory.

3. **Run the sweep per package in a monorepo and add the results up.** Each
package carries its own `tsconfig.json`, so `include` differs between them;
one root type-check reports only what the root project references.

4. **Cross-check with a grep on the *property name*, not the type name.**
`grep -rn 'fieldName:'` reaches contextually-typed literals because the
property is the text that is actually present. Reconcile the two lists and
explain each difference:

| The site appears in | Read it as |
|---------------------|------------|
| Compiler errors and the property grep | Confirmed construction site |
| Compiler errors only | The literal spells the property differently (spread, computed key, helper) — read it and record the form |
| Property grep only | Outside the compiler's program — check that package's `include`, then treat it as a site the migration must handle by hand |
| Neither, but the value flows there at runtime | Built by a factory or spread from another object — enumerate that producer instead ([backend-common-integrations-consumer-required-fields]) |

5. **State the method next to the count.** "8 construction sites (tsc error
list, `packages/*` each, cross-checked with `grep 'dealViewer:'`)" is
checkable; a bare "8 sites" cannot be reviewed for the gaps above, and a
count published into a brief is inherited by everyone working from it.

6. **Re-run the type-check after wiring and require zero errors, then run the
tests.** Files outside the program fail only at runtime, so the test run is
the second half of the inventory, not a formality.

## Edge cases

| Case | Then |
|------|------|
| The new field is optional | The compiler reports nothing at all — every site keeps compiling with the field absent. Make it required for the sweep, collect the list, then relax it if the design calls for optional ([testing-quality-tests-that-cannot-fail]) |
| A test directory is excluded from the package's `tsconfig` | Its sites surface as failing tests after wiring, or pass silently if nothing asserts the field — enumerate it by property grep and fix it in the same change |
| `exclude` lists the directory | `exclude` "only changes which files are included as a result of the `include` setting" — an excluded file still enters the program when an included file imports it, so the boundary is "in the program", not "in `include`" |
| The literal is built with a spread (`{ ...base, userId }`) | The excess/missing check applies to the spread result, but the property grep misses it — grep the base object's factory as the producer |
| The value is cast (`as DealViewer`) or typed `any` | The assertion suppresses the error, so the site is absent from the inventory while being a real construction site — grep the type name **as well**, which is where a type-name search does pay |
| The repo type-checks with `skipLibCheck` or has pre-existing errors | The new errors are not separable by eye — capture the error list before and after and diff them |
| Sites live in another repository or a published package | The compiler cannot see them at all; make the field optional at the boundary and version the change ([backend-common-change-impact-call-site-enumeration]) |
| The project uses `checkJs: false` with JavaScript callers | `.js` construction sites are unchecked — enumerate them by property grep only |

## Instead of

| If you are about to | Do this instead | Why |
|---------------------|-----------------|-----|
| Report the number of construction sites from `grep "<TypeName>"` | Take the list from the compiler errors, cross-check with a property grep, and state the method | Contextually typed object literals build the type without naming it, so the grep and the truth are different sets — measured 3 vs 8 |
| Treat a clean `pnpm type-check` as proof every assembly site was updated | Confirm each package's `include` covers its tests, then run the tests too | A package excluding `__tests__/` contributes zero errors from files that still build the value |
| Add the field as optional to avoid breaking the build, then find the sites later | Make it required, collect the compiler's list, and decide optionality afterwards | An optional field produces no inventory at all; "later" has no signal to work from |
| Publish the count into worker briefs as soon as the grep returns | Publish the count with its method, after the compiler sweep | A wrong count in a brief is multiplied by the number of briefs, and each worker reads it as scope |

## Sources

- https://www.typescriptlang.org/docs/handbook/2/objects.html — excess property checking applies to fresh object literals assigned to a typed target; the checking follows from the **contextual type**, so it occurs on literals in which the type's name never appears (the basis for step 1)
- https://www.typescriptlang.org/tsconfig/#include — `include` "specifies an array of filenames or patterns to include in the program", defaulting to `**/*` when neither `files` nor `include` is set; the program is what `tsc` reads and therefore the limit of the inventory (step 2)
- https://www.typescriptlang.org/tsconfig/#exclude — "`exclude` *only* changes which files are included as a result of the `include` setting. A file specified by `exclude` can still become part of your codebase due to an `import` statement in your code" — the basis for the `exclude` edge-case row
- https://www.typescriptlang.org/docs/handbook/type-checking-javascript-files.html — `checkJs` governs whether `.js` files are checked, behind the JavaScript-callers row
- Field measurement 2026-08-24 (`rtb-unified`): a plan recorded "3 assembly sites" for `DealViewer` from `grep "DealViewer"`; the real count was 8, and the missing set included the production wiring `packages/orpc/src/routers/deal.ts:38`, `dealViewer: { userId: context.user.userId }`. The same error repeated for `ContractScopeActor`: 7 sites across 4 files by type-name grep versus roughly 22 across 11 files
- Field measurement 2026-08-25 (same repo): `packages/orpc/tsconfig.json` declares `include: ["src/**/*"]`. Making `DealViewer.firstTierScope` required produced 3 production and 13 api-test errors from `pnpm type-check`, and **zero** for `packages/orpc/__tests__/routers/deal.test.ts` — that file's 6 assembly and expectation sites appeared only as 6 failing tests once the router was wired
Loading
Loading