The cheaper plan has five seats. Your team has eight people.
A training coordinator is choosing software for an eight-person workshop. One plan costs $25 a month; another costs $30. Both offer the spreadsheet export the team needs. The cheaper plan looks worth considering until you check its five-seat limit.
That is the decision in this fictional worked example. The coordinator has five short notes, including an outdated price. The useful result is a recommendation they can explain from those notes, with the unanswered questions left visible. You can follow the whole decision on this page. Python is optional.
Here is the comparison the finished brief needs:
| Current plan | Monthly price | Seats | CSV export |
|---|---|---|---|
| Cedar | $30 | 10 | Yes |
| Maple | $25 | 5 | Yes |
CSV is a common format for opening a table in a spreadsheet. Cedar fits the supplied seat and export requirements. Maple's supplied plan cannot accommodate all eight people. Neither conclusion tells the coordinator whether the contract terms are acceptable.
Start with the notes
An assistant needs the decision question and the relevant material. For this exercise, the complete source pack is small enough to read yourself:
| Note | Date | What it establishes |
|---|---|---|
| S1: workshop requirements | October 1, 2026 | Eight people; remote workshop; CSV export required. |
| S2: current Cedar card | October 2, 2026 | $30 per month; ten seats; CSV export included. |
| S3: old Cedar card | August 1, 2026 | $20 per month. Replaced by the current card. |
| S4: current Maple card | October 2, 2026 | $25 per month; five seats; CSV export included. |
| S5: procurement note | October 3, 2026 | Data-storage region unknown; annual contract not approved. |
The table contains everything you need for the manual exercise. The names and prices are invented. None of these records establishes a real product's current terms.
For five notes, writing the comparison yourself is a sensible baseline. An assistant might help organize a longer or recurring report, but this example does not measure that benefit. Its question is narrower: can you trace the recommendation to current evidence?
Ask for a brief with room for unanswered questions
If you want to use an assistant, copy the source table and this task together:
Recommend an option for the eight-person workshop using only these five notes. Compare the current prices, seat limits and CSV export. Cite the note beside each factual statement. Explain why the old Cedar price is excluded. Keep data-storage region and cancellation terms unanswered. Leave the purchase decision and annual contract approval to the coordinator.
The word "only" sets the exercise's source boundary. It does not guarantee that an assistant will follow it. Read the returned draft against the notes.
A useful finished recommendation says, in substance:
Review Cedar with procurement before buying. Its supplied plan has ten seats and CSV export at $30 per month [S2], enough for the eight-person requirement [S1]. Maple's supplied five-seat plan is too small [S4]. Confirm where data is stored and what the cancellation terms are before deciding.
Notice the two different reasons for uncertainty. S5 explicitly says the storage region is unknown. Cancellation terms are absent from every note. A plausible answer to either question would still need a source.
Check the number behind the sentence
A citation helps you find a record. You still need to check what it supports.
Suppose the draft recommends Cedar at $20. S3 really contains that number, so merely checking that the citation exists would miss the error. The record is outdated. The current price comes from S2.
Now deliberately change the current price in your own draft to $29. Find a note that supports it. There is none. Repair the price to $30 and keep both unanswered questions. That small exercise demonstrates the distinction between a readable recommendation and a supported one.
A person must also review the judgment. Cedar fits the stated requirements, but the notes do not cover every competing product, security requirement or purchasing term. The brief prepares a decision; it does not make the purchase.
Use this approach on your own documents
Begin with a small decision you can check. Label and date the source notes, mark replaced versions, and write down what the decision requires. Keep a comparison table beside the prose. For each statement you plan to rely on, ask which current source supports it and whether that source actually answers the question.
The checked research brief companion has the supplied documents and editable examples. You can finish the exercise above without downloading it.
You have completed the reading exercise when you can explain the seat mismatch, identify the supported Cedar price, repair the $29 mistake and name the two missing answers. The next useful investigation is to compare an assistant's actual draft with your manual table, retaining its mistakes and the review work. That comparison still needs real observations.
Optional: run the factual checker
The following program checks selected fields against the supplied fictional records. It does not call a model or judge arbitrary prose. Its output is a readable brief and an eight-row claim table. A claim row records a fact, its source label and its date.
You need Python 3.12 or newer, a terminal and a text editor. Check python --version; use python3 if that is your installed command. No packages, credentials or paid account are required. Create an empty folder and save the complete program as lab.py.
import csv
from pathlib import Path
SOURCES = {
"S1": {
"title": "Oak workshop requirements",
"date": "2026-10-01",
"status": "current",
"facts": {"learners": 8, "format": "remote", "required_export": "CSV"},
},
"S2": {
"title": "Cedar plan card",
"date": "2026-10-02",
"status": "current",
"facts": {"monthly_usd": 30, "seat_limit": 10, "csv_export": True},
},
"S3": {
"title": "Cedar old plan card",
"date": "2026-08-01",
"status": "superseded",
"facts": {"monthly_usd": 20},
},
"S4": {
"title": "Maple plan card",
"date": "2026-10-02",
"status": "current",
"facts": {"monthly_usd": 25, "seat_limit": 5, "csv_export": True},
},
"S5": {
"title": "Procurement note",
"date": "2026-10-03",
"status": "current",
"facts": {"annual_contract_approved": False, "data_region": "unknown"},
},
}
# The selection is the factual part of a recorded AI-authored working draft.
# Recommendation language remains a human review item.
SELECTION = [
("learners", 8, "S1"),
("format", "remote", "S1"),
("required_export", "CSV", "S1"),
("monthly_usd", 30, "S2"),
("seat_limit", 10, "S2"),
("csv_export", True, "S2"),
("monthly_usd", 25, "S4"),
("seat_limit", 5, "S4"),
]
QUESTIONS = ["data_region", "cancellation_terms"]
OUTPUT = Path("output")
def same_value(left, right):
return type(left) is type(right) and left == right
def validate(selection):
seen = set()
checked = []
for key, value, source_id in selection:
identity = (key, source_id)
if identity in seen:
raise ValueError("duplicate claim")
seen.add(identity)
source = SOURCES.get(source_id)
if not source:
raise ValueError("unknown source")
if source["status"] != "current":
raise ValueError("superseded source")
if key not in source["facts"]:
raise ValueError("source does not contain claim")
if not same_value(value, source["facts"][key]):
raise ValueError("claim value differs from source")
checked.append((key, value, source_id))
return checked
def unknown_questions():
current = [item["facts"] for item in SOURCES.values() if item["status"] == "current"]
result = []
for key in QUESTIONS:
values = [facts[key] for facts in current if key in facts]
if not values or all(value == "unknown" for value in values):
result.append(key)
else:
raise ValueError("question already has a current answer")
return result
def negative_checks():
cases = [
[("monthly_usd", 20, "S3")],
[("monthly_usd", 29, "S2")],
[("cancellation_days", 30, "S5")],
[("csv_export", 1, "S2")],
[("learners", 8, "S1"), ("learners", 8, "S1")],
]
for case in cases:
try:
validate(case)
except ValueError:
pass
else:
raise AssertionError("unsupported claim accepted")
return len(cases)
def display(value):
if type(value) is bool:
return "yes" if value else "no"
return str(value)
def main():
checked = validate(SELECTION)
unknown = unknown_questions()
if OUTPUT.exists():
raise SystemExit("output already exists; use a clean folder")
OUTPUT.mkdir()
rows = ["# Checked workshop-tool brief", "", "## Verified facts"]
for key, value, source_id in checked:
rows.append(f"- {key}: {display(value)} [{source_id}]")
rows += [
"",
"## Decision for a person",
"Review Cedar before purchase. It fits the supplied seat and export requirements. Maple does not fit eight learners on the supplied plan.",
"",
"## Unanswered questions",
]
rows.extend(f"- {key}" for key in unknown)
rows += ["", "No purchase, contact or live lookup was performed."]
(OUTPUT / "brief.md").write_text("\n".join(rows) + "\n", encoding="utf-8", newline="\n")
with (OUTPUT / "claims.csv").open("x", encoding="utf-8", newline="") as handle:
writer = csv.writer(handle, lineterminator="\n")
writer.writerow(["claim", "value", "source_id", "source_date"])
for key, value, source_id in checked:
writer.writerow([key, display(value), source_id, SOURCES[source_id]["date"]])
print(f"NEGATIVE CHECKS: {negative_checks()} passed")
print("CHECKED BRIEF: fictional sources; no purchase or live lookup")
print(f"claims={len(checked)}")
print("sources=" + ",".join(sorted({source_id for _, _, source_id in checked})))
print("unknown_questions=" + ",".join(unknown))
print("decision=review Cedar before purchase")
print("SAVED: output/brief.md,output/claims.csv")
if __name__ == "__main__":
main()
Run python -I lab.py from that folder. The -I option isolates Python from user path customizations. The program creates a new output folder and refuses to overwrite an existing one.
Expected complete stdout:
NEGATIVE CHECKS: 5 passed
CHECKED BRIEF: fictional sources; no purchase or live lookup
claims=8
sources=S1,S2,S4
unknown_questions=data_region,cancellation_terms
decision=review Cedar before purchase
SAVED: output/brief.md,output/claims.csv
Open output/brief.md and output/claims.csv. The CSV must have eight data rows using current sources S1, S2 and S4. S5 explains the explicit unknown for data region; it is not counted as a verified fact row.
The five seeded negative cases cover an old price, an altered price, an invented cancellation fact, a number substituted for a Boolean, and a duplicate claim. These are deliberate exercise errors, not observed mistakes from a model. Python distinguishes 1 from True here by checking the type as well as the value.
For a visible failure, use another clean folder and change Cedar's selected price from 30 to 29. The run must stop with claim value differs from source and create no output folder. Restore 30 to repair it. Selecting the old S3 price must fail with superseded source.
Troubleshooting: If Python is unavailable, check the installed command and version. If output already exists, preserve that result and use a fresh folder. If a claim is rejected, compare it with its current source before changing the check. The checker expects the structured facts shown here; it cannot extract or verify passages from arbitrary PDFs.
Technical completion check: match all seven stdout lines, inspect both files, count eight CSV rows, retain the two unanswered questions and confirm that the altered and outdated prices fail without writing output.
What was observed
The original authoring record, dated October 21, 2026, contains one AI-authored teaching draft from Codex in ChatGPT using these five records. Its raw working output was:
Oak needs a remote tool for eight learners and CSV export. Cedar's current plan supports ten seats, CSV export and costs $30 per month. Maple costs $25 but its supplied five-seat plan is too small. The old Cedar price is superseded. The records do not establish the storage region or cancellation terms. Review Cedar with procurement before purchasing.
The underlying model identifier, token usage and provider charge were unavailable. This retained same-session draft is not a separate API benchmark or independent reader test. The checks demonstrate agreement with the supplied facts; they do not establish a model ranking, time savings, source truthfulness or a complete deployed assistant.
For the broader method, Anthropic's context engineering guide discusses selecting useful context. Python's CSV documentation explains the table-writing mechanism used in the program. This lesson fits the practical assistant learning path; earlier lessons are optional background.