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
213 changes: 170 additions & 43 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 @@ -43,3 +43,4 @@ Append-only. Format: `## [YYYY-MM-DD] <ingest|revise|lint|gap|contradiction|drif
## [2026-08-06] revise | Union-merged amendments from the same 15 PRs into 24 existing pages (largest: tests-that-cannot-fail — 7 PRs: per-assertion mutation granularity, restore-mechanism-by-commit-state, suite-total-drop detection; portable-shell-scripts — 8 PRs: POSIX inline set-- reordering, ${VAR:-} vs ${VAR-} colon semantics, quote-by-what-the-text-is; test-data-and-isolation — 6 PRs: env-derived write paths, absent-variable cases, exec-bit fixtures, leak attribution; change-impact/call-site-enumeration — 8 unique additions from 7 path-variants: rename-in-place, same-type reorder, *args forwarding, two-searches-agree fallacy, codemod, coverage completion check). All non-canonical cross-page ids remapped to canonical pages; every added line traced to its source PR hunk (fabricated worker output was detected by orphan-line verification and replaced with true PR content).
## [2026-08-06] dedup | Cross-PR duplicate clusters collapsed: client-side rate limiting (8 PR versions at 3 paths → 1), call-site enumeration (7 versions at 7 paths → additions folded into the already-merged canonical page), stderr/exit-0 diagnostics (4 versions at 4 paths → 1), macOS sysroot (2→1), env-var off switch (2→1), completion predicates (2→1), robots.txt (2→1), harness-mediated results (2→1), leaked test artifacts (2→1), orchestration category naming (orchestration vs agent-orchestration → agent-orchestration). Kept distinct after trigger comparison: differential-testing vs differential-run-agreement (setup vs interpretation), unset-versus-empty-parameters vs env-var-off-switches (semantics vs design, cross-linked), import-time-side-effects vs test-level-choice edge (tactics vs level choice, cross-linked). Merged-main near-dup scan (Jaccard over title+trigger, 141 pages): 0 pairs — no duplication among previously merged content.
## [2026-08-06] ingest | Reconciled post-consolidation flush PRs #42–#43 (created against pre-#44 main). Folded unique content: platforms/filesystems/permissions-and-exec-bits (+`sh "$SCRIPT"` interpreter-invocation rows — stubs need no exec bit, avoids EDR chmod+x heuristics), platforms/shells/command-text-inspected-before-execution (+gate-AUTHOR step 8: parse all three POSIX quoting forms, expand only ~/$HOME/${HOME}; red-then-green bats evidence), testing/quality/checks-that-cannot-pass (+vacuously-green pre-implementation test row), platforms/processes/tool-diagnostics-without-a-failing-exit-code (+repeat-suppression edge, +clang reproduction source), infrastructure/ci-cd/secrets-handling (+independent credential channels row: gh token vs git SSH vs API token, git push --dry-run / author:@me probes), testing/mocking/what-to-mock (+ESM read-only-bindings DI rows, +PATH-emptied tripwire negative-proof). Dropped as duplicates of the #44 state: #42's rate-limit row (already in timeouts-and-retries + client-side-rate-limiting), #42's warning-only-diagnostics page (same trigger as tool-diagnostics-without-a-failing-exit-code), #42's leak-attribution row (already in test-data-and-isolation).
## [2026-08-09] ingest | knowledge-flush of 5 queued insights → 2 new pages, 3 dropped as in-flight duplicates. New: backend/common/errors/diagnostics-from-a-shared-code-path (a rejection message emitted from a path two constructs share takes its subject as a caller-supplied parameter, and its *repair* is checked by executing it from each emitting path — the subject fails visibly, the repair does not; rated like rustc `Applicability`, asserted once per emitting path). New: qa/deliverables/exclusivity-and-absence-claims (falsify an "only way" / "cannot be expressed" / "exactly N forms" claim before writing it, and publish the rule that generates the forms rather than the enumeration — an enumeration records what the author knew and goes stale when a producer is added). Sources live-verified this session: rustc-dev-guide diagnostics + `rustc_errors::Applicability`, NN/g error-message guidelines, Dijkstra EWD303, SEP Popper, Google docguide. Dropped (already carried by open PRs, equal or better form): guardrail read-only worktree escalation → #47/#51 (worktree-isolated-workers), Orca terminal/dispatch binding taxonomy → #51 (pane-delivery-confirmation), tmux in-band question menu → #64 (unattended-worker-questions). Reciprocal related-links added to 6 existing pages.
2 changes: 1 addition & 1 deletion wiki/backend/common/api-design/error-responses.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ sources:
- https://www.rfc-editor.org/rfc/rfc9110
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status
last_verified: 2026-07-10
related: [backend-common-errors-exception-handling]
related: [backend-common-errors-exception-handling, backend-common-errors-diagnostics-from-a-shared-code-path]
---

# Choosing Status Codes and an Error Body Shape for an API
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ sources:
- https://kubernetes.io/blog/2023/04/24/openapi-v3-field-validation-ga/
- https://json-schema.org/draft/2020-12/json-schema-validation
last_verified: 2026-08-05
related: [security-input-validation-at-trust-boundaries, infrastructure-config-environment-config, backend-common-api-design-error-responses, qa-process-acceptance-criteria]
related: [security-input-validation-at-trust-boundaries, infrastructure-config-environment-config, backend-common-api-design-error-responses, qa-process-acceptance-criteria, backend-common-errors-diagnostics-from-a-shared-code-path]
---

# Accepting a Declaration the System Does Not Enforce
Expand Down
Original file line number Diff line number Diff 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]
related: [qa-process-regression-scope, backend-python-language-mutable-state-traps, testing-data-test-data-and-isolation, backend-common-errors-diagnostics-from-a-shared-code-path]
---

# Enumerating Call Sites Before Changing a Callee's Contract
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
---
id: backend-common-errors-diagnostics-from-a-shared-code-path
domain: backend
category: errors
applies_to: [general]
confidence: verified
sources:
- https://rustc-dev-guide.rust-lang.org/diagnostics.html
- 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]
---

# A Rejection Message Emitted From a Code Path Two Constructs Share

## When this applies

You are writing or reviewing a rejection/validation message produced by one
function that more than one caller reaches — a reference checker shared by a
guard and an assignment, a validator shared by request and response, a policy
check shared by two config blocks — and the message names one caller's construct
in literal text, or tells the author what to write instead. Also when a user
reports a rejection whose wording names a construct they did not write.

## Do this

1. **Make the message's subject a parameter the caller supplies.** The shared
function formats; each call site passes its own construct name. A construct
name written literally inside a shared body is correct for exactly one caller
and silently wrong for every other one.
2. **Verify each part of the message against the path that emits it**, because
the parts fail with different visibility:

| Part the message carries | Verify by |
|--------------------------|-----------|
| The subject — the construct being rejected | Reading one emitted message per call path; a wrong subject is visible on first read |
| A named repair ("use `input.<field>` instead") | Executing the repair as written from each call path and requiring the result to be accepted |
| A pointer to another rule or section | Confirming that rule admits this caller's construct at all |

3. **Treat the repair as the part most likely to be wrong, and check it per
path.** A repair is advice the author will follow literally; when it is
illegal on one of the emitting paths, following it lands the author in a
second, unrelated rejection. NN/g's rule is that the message must describe a
solution sufficient to fix the problem — on the path the reader is on.
4. **Rate the repair by whether it holds on every path that can emit it.**
Present it as *the* fix (and allow any auto-apply tooling to use it) only when
it is valid on all of them; otherwise branch it. `rustc` encodes the same
distinction as `Applicability` — `MachineApplicable` for a suggestion that can
be applied mechanically, `MaybeIncorrect` for one that "may or may not be a
good one" — and instructs authors to "be conservative when choosing the level".
5. **Assert the message once per emitting path, not once per message.** A single
test on one caller leaves the other caller's subject and repair unasserted, so
parameterizing the subject and breaking the other path's advice both stay
green ([backend-common-change-impact-call-site-enumeration] enumerates the
paths).
6. **When the repair differs by path, branch on the parameter that already
distinguishes them** — pass the repair alongside the subject, so each caller
states the fix that is legal for it.

## Edge cases

| Case | Then |
|------|------|
| The two callers reject for the same reason but repair differently | Pass the repair text as a second caller-supplied parameter; keep one rejection rule and two suggestions |
| The suggested form is legal at parse time but rejected by a later rule on this path | The advice is still wrong — run it end to end on that path, not just past the check that emitted it |
| Only one caller exists today | Parameterize the subject anyway when the function is named for the *check* rather than the construct; the second caller is what makes the literal wrong, and it arrives without touching this file |
| The message is localized or templated | Pass the subject as a named placeholder argument rather than concatenating it, so translators receive a slot instead of a sentence fragment |
| The shared function genuinely cannot know the subject | Have callers pass a context value carrying subject and repair together, so a new caller cannot compile without supplying both |
| A repair is valid everywhere except one rarely reached path | Branch it — a suggestion that is wrong on one path is `MaybeIncorrect` for all of them, and rating it that way costs the reader on every path |

## Instead of

| If you are about to | Do this instead | Why |
|---------------------|-----------------|-----|
| Write the construct's name into the shared function's message text | Take the subject as a parameter each call site fills | The literal is right for the caller you had in mind and misnames every other one |
| Fix the misnamed subject and ship | Also execute the repair from each emitting path and require acceptance | The subject is checked by reading; the repair is only checked by running, so it is the part that stays wrong |
| Soften the repair into something true on every path ("check the syntax") | Branch the repair on the parameter that distinguishes the callers | A repair that carries no action returns the reader to guessing, which is what the message existed to prevent |
| Assert the message text in one test and call the wording covered | Assert subject and repair once per emitting path | One assertion cannot distinguish "both paths right" from "one path never exercised" |

## Sources

- https://rustc-dev-guide.rust-lang.org/diagnostics.html — suggestions carry a confidence level and "Be conservative when choosing the level"; `MachineApplicable` = "Can be applied mechanically", `MaybeIncorrect` = "Cannot be applied mechanically because the suggestion may or may not be a good one", `Unspecified` = "we don't know which of the above cases it falls into"
- https://doc.rust-lang.org/stable/nightly-rustc/rustc_errors/enum.Applicability.html — the enum tools read to decide whether a suggestion is auto-applied or shown for review
- https://www.nngroup.com/articles/error-message-guidelines/ — an error message offers constructive advice: the described solution must be sufficient for the user to fix the problem
- Field incident 2026-08-09 (`linkly`, `impl/lnpl/lower.py`): `_Scope.check_reference` is called from both the guard path and the assignment path and hardcoded "guard condition" into three messages. The `set`-target rejection additionally advised writing `input.<field>`, which `_derive_assignment` rejects for `set` targets by a separate rule — an author following the advice hit a second, unrelated rejection. After threading subject/target through as parameters the suite went 1864 → 1872 (the 8 new per-path assertions, no other change), and an independent audit exercised each branch as its own mutation
1 change: 1 addition & 0 deletions wiki/backend/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ Match your situation to a "load when" line; load only matching pages.
| Page | Load when |
|------|-----------|
| [exception-handling](common/errors/exception-handling.md) | Writing a catch block or deciding where errors are handled/logged/translated in a service — catch placement, log-once, wrapping with cause preserved, typed results for expected outcomes; one fault producing duplicate alerts |
| [diagnostics-from-a-shared-code-path](common/errors/diagnostics-from-a-shared-code-path.md) | Writing or reviewing a rejection/validation message emitted by one function several callers reach (a check shared by two syntaxes, request and response, two config blocks) — especially when the message names a construct in literal text or tells the author what to write instead; a user reports a rejection naming a construct they did not write |
| [async-failure-handling](common/errors/async-failure-handling.md) | Handing work to in-process async (@Async, unawaited futures/promises) — deciding fire-and-forget vs consumed future vs durable job; side effects silently never happening with no error logs; unobserved futures; async work enqueued inside a transaction |

### auth
Expand Down
2 changes: 1 addition & 1 deletion wiki/debugging/methodology/hypothesis-testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ sources:
- https://www.debuggingbook.org/html/Intro_Debugging.html
- https://sre.google/sre-book/effective-troubleshooting/
last_verified: 2026-07-10
related: [debugging-methodology-reproduce-first, debugging-methodology-isolate-by-bisection]
related: [debugging-methodology-reproduce-first, debugging-methodology-isolate-by-bisection, qa-deliverables-exclusivity-and-absence-claims]
---

# Testing a Suspected Cause Before Changing Code
Expand Down
2 changes: 1 addition & 1 deletion wiki/debugging/signals/reading-error-messages.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ sources:
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors
- https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
last_verified: 2026-07-10
related: [debugging-signals-stack-traces, debugging-methodology-hypothesis-testing]
related: [debugging-signals-stack-traces, debugging-methodology-hypothesis-testing, backend-common-errors-diagnostics-from-a-shared-code-path]
---

# Reading an Error Message Before Acting on It
Expand Down
Loading
Loading