Context Engineering: The Discipline That Ate Prompt Engineering

Context Engineering: the discipline that ate prompt engineering

The prompt was never the product. The context was.

Every serious LLM application you admire — the coding agent that reads your repo before touching a line, the research assistant that runs fifty tool calls before it writes, the support bot that answers from your own docs — is decided long before the model runs. It is decided in what the model can see.

That skill has a name now: context engineering. The term broke out in June 2025 — endorsed by Shopify CEO Tobi Lütke, amplified by Andrej Karpathy, later formalized in an arXiv survey covering 1,400+ papers — and it is not hype vocabulary. It names the difference between a demo and a product.

The mental model most people still carry — typing instructions into a chatbot — is stale. This article is the full map: where the term came from, why one-shot prompts stopped being enough, the measured evidence, the mechanics, a 14-pattern playbook with code, and the honest counter-theses. By the end you will know what changed, why it changed, and what to do about it on Monday morning.


What context engineering is

Start with the definitions that converged, independently, within weeks of each other in mid-2025:

"Context engineering is building dynamic systems to provide the right information and tools in the right format such that the LLM can plausibly accomplish the task." — Harrison Chase (LangChain), June 2025
"Context Engineering is the discipline of designing and building dynamic systems that provides the right information and tools, in the right format, at the right time, to give a LLM everything it needs to accomplish a task." — Phil Schmid, June 2025
"context engineering is the delicate art and science of filling the context window with just the right information for the next step." — Andrej Karpathy, June 2025

Four authors, one idea, same month. Strip the wording and every definition contains the same four moves:

  1. Context is a system output, not a string. You don’t write the context; you build the thing that assembles it — code that selects, formats, and updates the window per request.
  2. It is dynamic, assembled per request. No static template survives contact with a real task. The window’s contents are the output of a system that runs before the LLM call.
  3. It covers information and tools. Tool definitions, descriptions, and schemas live in context. Designing them is part of the same discipline.
  4. The bar is "plausibly accomplish the task" — not "nicely phrased request."

Karpathy’s full quote goes further: context engineering is "just one small piece of an emerging thick layer of non-trivial software that coordinates individual LLM calls (and a lot more) into full LLM apps. The term ’ChatGPT wrapper’ is tired and really, really wrong."

The coining, precisely

The term was not coined in June 2025 — it was endorsed into existence there.

The prompt-engineering lineage it subsumes

Context engineering did not appear from nowhere. It is the agents-era endpoint of a lineage running straight through the prompt-engineering canon:

  1. GPT-3 (May 2020). In-context learning: tasks specified "purely via text interaction." The prompt becomes the interface; the prompt-engineering era begins.
  2. Chain-of-Thought (Jan 2022). Demonstrations become a designed artifact: eight CoT exemplars "achieves state of the art accuracy on the GSM8K benchmark of math word problems, surpassing even finetuned GPT-3 with a verifier."
  3. Zero-shot CoT (May 2022). The apex of the "magic words" era: MultiArith 17.7% → 78.7% and GSM8K 10.4% → 40.7% from one added phrase, "Let’s think step by step."
  4. DSPy (Oct 2023). The first big break with hand-tuned strings: "existing LM pipelines are typically implemented using hard-coded prompt templates, i.e. lengthy strings discovered via trial and error." DSPy compiles pipelines against a metric, not taste. ICLR 2024 spotlight.
  5. 2025: the agents era. Multi-turn tool loops, accumulated tool feedback, hundreds-of-turn conversations — and the failure rate moved from the model to the context.

Each step broadened what "the prompt" meant — instructions, then exemplars, then compiled pipelines, then the whole window. Context engineering is that trajectory, generalized.---

Why one-shot prompts stopped being enough

The shift is not fashion. Three structural changes made the single prompt structurally insufficient.

Agents changed the unit of work

The unit of work changed from a request to a trajectory. An agent interleaves LLM calls and tool calls over many turns; tool feedback accumulates; conversations run hundreds of turns. There is no single prompt to perfect, because the "prompt" is now the whole trajectory’s context, curated at every step.

Anthropic’s multi-agent research system: the lead agent saves its plan to memory "since if the context window exceeds 200,000 tokens it will be truncated and it is important to retain the plan." That is the moment a prompt stops being a prompt.

The window is an attention budget, not a buffer

Transformer attention computes n² pairwise relationships. Training distributions contain far more short sequences than long ones, so models have "less experience with, and fewer specialized parameters for, context-wide dependencies." The consequence:

"good context engineering means finding the smallest possible set of high-signal tokens that maximize the likelihood of some desired outcome" — Anthropic, Effective context engineering for AI agents, Sep 2025

Every token competes for a finite attention budget. Or as Drew Breunig puts it: "context is not free. Every token in the context influences the model’s behavior, for better or worse."

Failures became context failures

As models improve, the residual failure cause shifts. Harrison Chase’s diagnosis — the model either "just messed up," or it "was not passed the appropriate context" — tips decisively toward the second cause as models get better. The failure diagnosis moved from the model to the context.


The evidence: what happens when you get context wrong

The field has measured what happens when you fill the window. These numbers are why the discipline exists.

Attention is positional: Lost in the Middle

Liu et al., TACL 2023 — the U-shaped curve:

"Long context" is marketing against a measured ceiling

Irrelevant context is an active cost

The economics: KV-cache is the money layer

Manus (Yichao "Peak" Ji, Jul 2025): the agent runs ~50 tool calls per task at a ~100:1 input-to-output token ratio. Prefill dominates. Therefore:

"the KV-cache hit rate is the single most important metric for a production-stage AI agent. It directly affects both latency and cost." — Manus

Cache pricing (Anthropic docs): cache write 1.25× base input; cache read 0.1× base (0.025× on the newest models); 1-hour TTL 2×. At a 100:1 prefill/decode ratio, the 10× cache-read discount applies to the dominant cost term — roughly an order of magnitude on the biggest line item. Prefix hygiene is an economic rule, not a style preference: even a per-second timestamp "kills your cache hit rate" — keep the prefix stable, append-only, deterministically serialized; mask (don’t remove) tools mid-run.

Tokens buy performance — which is why isolation works

Anthropic’s multi-agent research system (Jun 2025):

That is the isolation dividend: workers burn tokens privately, the orchestrator stays small.


The four levers — and the failure modes they answer

The taxonomy the field converged on (LangChain’s write/select/compress/isolate) maps one-to-one onto measured failure modes:

The failure taxonomy itself is Drew Breunig’s (June 2025): poisoning, distraction, confusion, clash. His framing line: "longer contexts do not generate better responses. Overloading your context can cause your agents and applications to fail in surprising ways."

Lever 1 — Retrieval (select): pull in only what the task needs

Origin: Lewis et al. 2020 — pair the generator with "a dense vector index of Wikipedia, accessed with a pre-trained neural retriever": non-parametric memory fetched at query time, instead of relying on parameters or a giant window.

Modern form — just-in-time retrieval: Anthropic: agents "maintain lightweight identifiers (file paths, stored queries, web links, etc.) and use these references to dynamically load data into context at runtime using tools." Why it works: pre-fetching everything burns the attention budget on mostly-irrelevant data; metadata is itself high-signal for deciding what to fetch. And the Lost-in-the-Middle saturation result is the ceiling on brute-force retrieval — past ~20 relevant documents, extra context barely moves accuracy.

Modern form 2 — agentic search beside embeddings: Anthropic on Claude Code: "primitives like glob and grep allow it to navigate its environment and retrieve files just-in-time, effectively bypassing the issues of stale indexing and complex syntax trees." An index built ahead of time goes stale and discards the metadata signals — folder names, naming conventions, timestamps — that tell an agent why a file matters. Practical hybrid: small stable core up front + JIT fetches + search primitives. Don’t rip out the vector store on dogma — measure.

Lever 2 — Memory (write): externalize state, then recite it

Manus’s todo.md: "By constantly rewriting the todo list, Manus is reciting its objectives into the end of the context" — pushing the plan into the recency end of attention, exactly where Lost-in-the-Middle says models still attend well.

The file system as the ultimate context: "we treat the file system as the ultimate context in Manus: unlimited in size, persistent by nature, and directly operable by the agent itself." And the irreversibility argument: "you can’t reliably predict which observation might become critical ten steps later" — so compression must be restorable: drop a page’s content, keep the URL; drop a document, keep its path.

Anthropic structured note-taking: "Structured note-taking, or agentic memory, is a technique where the agent regularly writes notes persisted to memory outside of the context window. These notes get pulled back into the context window at later times." Evidence: Claude playing Pokémon maintains tallies and maps across thousands of steps; "After context resets, the agent reads its own notes and continues multi-hour training sequences or dungeon explorations." Shipped as a file-based memory tool; combined with context editing it "improved performance by 39% over baseline" (Anthropic, Sep 2025).

Lever 3 — Compaction: summarize before you reset

Anthropic: "Compaction is the practice of taking a conversation nearing the context window limit, summarizing its contents, and reinitiating a new context window with the summary." The implementation detail that matters: preserve "architectural decisions, unresolved bugs, and implementation details" while discarding redundant tool outputs. The cheapest first move: "One of the safest lightest touch forms of compaction is tool result clearing" — once a tool has been called deep in history, the raw result is rarely needed again, but its conclusions are.

Tune the compaction prompt on real traces: maximize recall first (capture everything relevant), then iterate toward precision. The warning that belongs in every how-to: overly aggressive compaction loses "subtle but critical context whose importance only becomes apparent later." Cognition went further — calling compression "hard to get right" — and fine-tuned a small model specifically to compress agent history into "key details, events, and decisions."

Lever 4 — Sub-agent isolation: explore wide, return summaries

Anthropic: "Each subagent might explore extensively, using tens of thousands of tokens or more, but returns only a condensed, distilled summary of its work (often 1,000-2,000 tokens)." That is a 10–50× compression at the handoff — the isolation dividend. "The essence of search is compression: distilling insights from a vast corpus. Subagents facilitate compression by operating in parallel with their own context windows."

The honest counterweight — Cognition (Walden Yan), "Don’t Build Multi-Agents": "Share context, and share full agent traces, not just individual messages" and "Actions carry implicit decisions, and conflicting decisions carry bad results." Cognition’s rule: default single-threaded, because "running multiple agents in collaboration only results in fragile systems." Anthropic ships multi-agent only where tasks are breadth-first and parallelizable, at 15× token cost. Both positions are evidence-backed. The reconciling rule: isolate context only for read-only, parallelizable subtasks whose outputs compress cleanly into a summary or artifact — never split decisions that must stay consistent.---

The playbook: 14 patterns

The master question, asked every turn: would its absence change the next action? The patterns implement it.

1. Context is a budget — curate the smallest sufficient set of high-signal tokens

The master pattern; the rest implement it. Ask of every candidate context item: would its absence change the next action? If not, it stays out. Anthropic: context "must be treated as a finite resource with diminishing marginal returns."

2. Treat the window like RAM; the LLM is the CPU

Lance Martin: "The LLM is like the CPU and its context window is like the RAM, serving as the model’s working memory." Load the small working set; page the rest in and out via tools; swap to disk (files) when it overflows.

3. Retrieve just-in-time, not up-front

Keep lightweight identifiers (paths, queries, links) in context; fetch data via tools when the task demands it. Hybrid: small stable core up front + JIT fetches + agentic search primitives. Don’t rip out the vector store on dogma — measure on your evals.

4. Agentic search beside embeddings

Give the agent grep/glob/SQL primitives and let it explore. An index built ahead of time goes stale and discards the metadata signals that tell an agent why a file matters. Hybrid usually wins; measure.

5. Structured note-taking outside the window

Agent-maintained notes with fixed sections — State / Decisions / Next steps / Open questions — re-read after compaction or context resets. Evidence: memory tool + context editing "improved performance by 39% over baseline" (Anthropic, Sep 2025).

6. Compaction: summarize before you reset

Preserve decisions, unresolved bugs, and key state; discard stale tool results first. Tune for recall first, then precision. "Overly aggressive compaction can result in the loss of subtle but critical context whose importance only becomes apparent later."

7. Sub-agents: explore wide, return summaries

The orchestrator prompt must demand distillation ("return findings + file paths + confidence, not transcripts") or the sub-agent will happily paste 10k tokens back. Workers explore at 10k+ tokens; return 1–2k-token distillates. Default single-threaded; quarantine only what parallelizes.

8. Tools are context: design the agent-computer interface

Tool descriptions, parameter names, and response schemas steer every call. Anthropic on their SWE-bench agent: "spent more time optimizing our tools than the overall prompt." Docstring-quality tool docs; unambiguous parameters (user_id, not user). The rule of thumb from Building effective agents: "think about how much effort goes into human-computer interfaces (HCI), and plan to invest just as much effort in creating good agent-computer interfaces (ACI)."

9. Consolidate tools; return high-signal responses

Fewer, purpose-built tools that bundle multi-step workflows: schedule_event, not list_users + list_events + create_event. "More tools don’t always lead to better outcomes." Return high-signal fields (names over UUIDs); paginate, filter, truncate with sensible defaults; expose concise/detailed response formats; cap responses (Claude Code caps tool responses at 25,000 tokens).

10. Choose output formats the model can write without fighting

Give the model tokens to "think" before it writes itself into a corner; keep formats close to natural text (markdown over heavily-escaped JSON); avoid exact-counting formats (diff headers, escaped code blocks). Models are next-token predictors; formats that fight the training distribution produce escape errors and truncated writes.

11. Workflows before agents; add autonomy only when it pays

Anthropic’s taxonomy: workflows (LLMs orchestrated through predefined code paths — chaining, routing, parallelization, orchestrator-workers, evaluator-optimizer) vs agents (the LLM dynamically directs its own process and tool use in a loop). "find the simplest solution possible, and only increasing complexity when needed." OpenAI converges from the other side: single agent first; multi-agent orchestration only on genuinely parallel work or tool overload. Agents cost latency, money, and compound errors; most production wins were boring workflows.

12. The loop: ground truth from the environment every step

"They are typically just LLMs using tools based on environmental feedback in a loop." Define exit conditions up front (final output, no tool calls, error, max turns); route to humans at fixed thresholds — OpenAI names the two triggers: exceeded retry/failure limits, and high-risk or irreversible actions.

13. Memory as files: CLAUDE.md-style project memory

Persist instructions and learnings as structured markdown the agent reads at session start; @path imports expand referenced files at launch. Target under 200 lines and prune regularly — "Longer files consume more context and reduce adherence." Memory files are advisory context, not enforcement: for must-always-happen rules, use hooks (deterministic), not prose.

14. Operating discipline: verify, clear, scope, prune

Give the agent a runnable verification (tests/build/screenshot) so the loop closes without you; /clear between unrelated tasks; scope investigations; plan before multi-file changes (explore → plan → code → commit). The one-line constraint behind most Claude Code best practices: "Claude’s context window fills up fast, and performance degrades as it fills."


Before / after: three worked examples

The patterns are cheap to read and easy to not do. Three before/after pairs, one per core lever.

Example 1 — bad context build vs good context build

Before — dump everything into the window every turn:

# Dumps the whole DB, all docs, and full chat history into every call
def build_context(user_id, question, history):
    all_rows = db.execute("SELECT * FROM orders").fetchall()      # thousands of rows
    all_docs = [f.read() for f in DOCS_DIR.glob("*.md")]          # entire doc corpus
    return {
        "system": SYSTEM_PROMPT + "\n".join(all_docs),
        "messages": history + [{"role": "user", "content": f"{question}\n\nData: {all_rows}"}],
    }
# Symptoms: context rot, huge cost, model misses the 3 rows that matter.

After — smallest sufficient set, identifiers first, JIT load:

# Lightweight identifiers in context; the agent fetches only what it needs
TOOLS = [order_search, doc_grep, kb_search]   # consolidated, filtered tools

def build_context(user_id, question):
    return {
        "system": SYSTEM_PROMPT + f"""
## Environment
Customer {user_id}. Orders live in the `orders` table; call `order_search`
with filters instead of asking for full dumps. Product questions: grep the
docs with `doc_grep` before answering.
""",
        "messages": summarize(history, keep="decisions, open issues") + [
            {"role": "user", "content": question},
        ],
    }
# The agent runs order_search(status="open", user_id=...) -> 3 rows, not 30,000.

Example 2 — naive RAG vs agentic search

Before — one-shot vector retrieval:

# Pre-computed index; stale after every doc change; top-k = noise
def answer(question):
    chunks = vector_store.search(embed(question), k=12)   # blind 12 chunks
    return llm(f"Answer using:\n{’’.join(chunks)}")       # hope the answer is in there

After — agentic search: identifiers + tools the model navigates itself:

# Hybrid: stable overview up front, targeted retrieval just-in-time
TOOLS = [glob_files, grep_docs, read_file]    # primitives, like Claude Code’s glob/grep

SYSTEM = """You answer questions about the codebase.
Start from OVERVIEW.md (already in context). Then:
1. glob_files(pattern=...) to locate candidates - names and folders are signals.
2. grep_docs(query=...) for targeted lines; follow references as needed.
3. Read only the files you need. Stop when you can cite exact lines."""

def agent_loop(question, max_turns=10):
    msgs = [{"role": "user", "content": question}]
    for _ in range(max_turns):
        resp = llm(SYSTEM, msgs, tools=TOOLS)
        if resp.tool_calls:
            msgs += [resp, run_tools(resp.tool_calls)]   # environment ground truth
        else:
            return resp.text

Example 3 — unstructured memory vs structured note-taking

Before — freeform transcript blob:

# One long transcript blob; grows forever; compaction loses specifics
memory = f"{memory}\nUser: {msg}\nAssistant: {resp}"   # append-only chat log
session = llm(f"Here is everything so far:\n{memory}\nContinue the task.")

After — structured notes outside the window, re-read on resume:

# NOTES.md with fixed sections; write as you go; compact the transcript
NOTES_TEMPLATE = """# NOTES
## State
- Task: migrate payments to API v2; 3/12 endpoints done
## Decisions
- Keep webhook signatures in env var WEBHOOK_SECRET (do not log)
## Next steps
- Migrate /refunds endpoint; then update integration tests
## Open questions
- Rate-limit policy for sandbox keys?
"""

def save_notes(state, decisions, next_steps, questions):
    write_file("NOTES.md", render(NOTES_TEMPLATE, locals()))   # agent writes notes

def resume():
    notes = read_file("NOTES.md")               # re-read after compaction/reset
    summary = compact(history, keep="decisions + last 5 files")
    return f"{summary}\n\nNotes:\n{notes}"

The same pattern is what Claude Code does with its todo list and what the memory tool formalizes: a file-based store the model reads and writes across sessions.


Tips & tricks: the do / don’t list

Do

  1. Ask "would its absence change the next action?" of every context item — curate the smallest sufficient set.
  2. Keep lightweight identifiers in context; load data just-in-time via tools.
  3. Give agents raw navigation primitives (grep/glob/SQL) alongside any vector index.
  4. Have the agent maintain structured notes for anything longer than a few turns.
  5. Compact by preserving decisions and open bugs while clearing stale tool results.
  6. Prompt-engineer tool descriptions like docstrings for a new hire; consolidate multi-step workflows into single tools; return high-signal fields over UUIDs.
  7. Expose response-format/verbosity params; add pagination + filtering + truncation defaults.
  8. Keep project-memory files under 200 lines with @path imports; prune regularly.
  9. Give the agent a runnable verification so the loop closes without you.
  10. Start with workflows / a single agent; escalate to multi-agent only when measured outcomes demand it.
  11. Invest in the agent-computer interface like you would in a user interface.
  12. Keep the prompt prefix stable and append-only for cache economics — mask, don’t remove, tools mid-run.
  13. Put the needle at the edges: key facts first or last, never mid-window.

Don’t

  1. Stuff every edge case into the system prompt — curate diverse canonical examples instead.
  2. Hardcode brittle if-else logic in prompts, nor float so high there are no concrete signals — find the right altitude.
  3. Build bloated tool sets with overlapping functionality; if a human can’t say which tool to use, the model can’t either.
  4. Return raw API dumps from tools — paginate, filter, truncate, and steer with actionable error messages.
  5. Force JSON-escaped code or line-counted diffs as output formats.
  6. Let memory files grow past ~200 lines or contradict themselves — adherence collapses.
  7. Mix unrelated tasks in one session; after two failed corrections, /clear and restart with a better prompt.
  8. Run unscoped "investigate everything" explorations in the main context — scope them or push them to sub-agents.
  9. Treat memory-file instructions as enforcement — use hooks for must-always-happen rules.
  10. Build an agent where a deterministic workflow suffices.
  11. Assume bigger windows fix anything — advertised window ≠ effective window.
  12. Assume context engineering fixes prompt injection — it does not; architecture and least privilege do.---

The honest counter-theses

An article that only sells the new term is marketing. The skeptic case is real, and named authors made it.

"It’s just prompt engineering rebranded"

Simon Willison’s honest account of why the rebrand happened — the old term lost control of its meaning:

"I’ve spoken favorably of prompt engineering in the past - I hoped that term could capture the inherent complexity of constructing reliable prompts. Unfortunately, most people’s inferred definition is that it’s a laughably pretentious term for typing things into a chatbot!" — Simon Willison, June 2025
"It turns out that inferred definitions are the ones that stick. I think the inferred definition of ’context engineering’ is likely to be much closer to the intended meaning." — Simon Willison

Addy Osmani defends the term but states the skeptic case plainly: "Prompt engineering was about cleverly phrasing a question; context engineering is about constructing an entire information environment so the AI can solve the problem reliably." And Hidde de Smet, writing in 2026: "In 2024, phrasing mattered enormously. In 2026, Claude and GPT understand vague intent much better. The ’prompt wizard’ era is over." The skill survived; the branding churned.

The Bitter Lesson counter-thesis

Rich Sutton, 2019: "The biggest lesson that can be read from 70 years of AI research is that general methods that leverage computation are ultimately the most effective, and by a large margin." Hand-built context machinery — curated retrieval, hand-written summaries, bespoke memory schemas — is exactly the kind of built-in human knowledge the Bitter Lesson warns gets steamrolled by scale: "We have to learn the bitter lesson that building in how we think we think does not work in the long run."

Anthropic makes the same observation from inside the paradigm: "We’re already seeing that smarter models require less prescriptive engineering, allowing agents to operate with more autonomy." The honest position: context engineering may be a transitional craft — indispensable now, potentially eroded as models learn to self-manage context.

Security: context engineering does not fix prompt injection

Retrieved and offloaded context is untrusted input. Willison’s lethal trifecta — private data + untrusted content + external communication — and the mechanism: "LLMs are unable to reliably distinguish the importance of instructions based on where they came from. Everything eventually gets glued together into a sequence of tokens and fed to the model." His verdict: "we still don’t know how to 100% reliably prevent this from happening."

OWASP LLM01 (2025): RAG and fine-tuning "do not fully mitigate prompt injection vulnerabilities." And memory makes it worse: "Prompt injection ends when the session closes. Memory poisoning persists across sessions" (WorkOS) — because "an agent treats its own memories as ground truth." A single adversarial memory write "can exert long-term influence over agent behavior" (Dash et al., arXiv 2606.04329), and existing prompt-injection defenses "fail to cover memory poisoning attacks." The defense is architecture and least privilege, not context curation.

Cognition vs. Anthropic: the sharpest live debate

Cognition (coding agents, reliability-first): default single-threaded, share full traces — "running multiple agents in collaboration only results in fragile systems." Anthropic (research agents, breadth-first): multi-agent bought +90.2% on their eval — at 15× token cost — and only for parallelizable, high-value tasks: "some domains that require all agents to share the same context or involve many dependencies between agents are not a good fit for multi-agent systems today."

This is a domain bet, not a contradiction — and both sides agree on the open problem: cross-agent context passing is unsolved. Cognition: "I don’t see anyone putting a dedicated effort to solving this difficult cross-agent context-passing problem."


When plain prompt engineering is still the right frame

Context engineering is a reframe, not a replacement. Plain prompting stays the right frame when:


Open questions

Honesty about what is not settled:


The bottom line

The prompt was never the product. The context was.

Prompt engineering asked what words. Context engineering asks what configuration of context is most likely to produce the desired behavior — system prompt, retrieved passages, tool schemas, memory files, compaction policy, sub-agent boundaries — curated every turn, because the window is a budget and every token pays rent.

Prompt engineering didn’t die — it was demoted to a subset. LangChain: "prompt engineering is a subset of context engineering. Even if you have all the context, how you assemble it in the prompt still absolutely matters." OpenAI’s prompt-engineering guide is still live and maintained; Anthropic keeps prompting best practices as "the living reference." Clarity, structure, examples, chaining, evals — those skills transferred, unchanged.

The context, though, is code. Write it like code: version it, curate it per turn, measure it with evals, treat every token as a cost center. The model is only as good as the context you feed it — and the context is a system you build.

That is the discipline that ate prompt engineering.


Sources

Verification note: every quote in this article is verbatim from a primary page fetched and quote-checked against the fetched text on 2026-09-18 (research ledger: 46 verified sources, 0 fabricated). Two candidate items failed verification and were excluded.