The research question
What must accompany a claim so another reader can check it? A research journal should let readers inspect how the conclusion was reached. A compelling headline is not a replacement for a reproducible method.
Our capstone assembles a miniature evidence package. It calculates a few statistics from a fixed synthetic ledger, records a SHA-256 fingerprint of the exact serialized dataset, and generates a Markdown report. The file is useful as a portfolio artifact precisely because it makes its limits visible.
Time: approximately 35 minutes. You need: standard-library Python. This script is self-contained and does not need the files from earlier editions.
Step 1 — Decide what your report will claim
Keep the scope narrow: This script reproduces the total of four synthetic net outcomes and records the input identity. That statement is testable. Our agent has learned to outperform the market is not supported by this exercise.
Choose four checks: unique close identifiers, agreement between the ledger and reported total, a clear synthetic-data label, and the expected fingerprint length. Keep the denominator visible. Four closes are four closes, regardless of how often a chart redraws them.
Step 2 — Build the evidence package
Save the following script as lab_07.py. It writes research_report.md, replacing an earlier exercise report with that name in the current directory.
import hashlib
import json
from decimal import Decimal
from pathlib import Path
rows = [
{"close_id": "s1", "net": "1.40"},
{"close_id": "s2", "net": "-1.60"},
{"close_id": "s3", "net": "0.40"},
{"close_id": "s4", "net": "-0.40"},
]
canonical = json.dumps(rows, sort_keys=True, separators=(",", ":"))
fingerprint = hashlib.sha256(canonical.encode("utf-8")).hexdigest()
net_values = [Decimal(row["net"]) for row in rows]
assert len({row["close_id"] for row in rows}) == len(rows)
assert sum(net_values) == Decimal("-0.20")
wins = sum(value > 0 for value in net_values)
report = f"""# Synthetic research report
## Question
What remains after the declared costs in a four-close teaching ledger?
## Method
Fixed source data, four unique closes, net values already include modeled costs.
This report does not add costs a second time.
## Results
- Closed examples: {len(rows)}
- Net total: {sum(net_values):.2f} currency units
- Positive net outcomes: {wins}/{len(rows)}
- Source SHA-256: {fingerprint}
## Evidence limits
Invented outcomes; no market feed, executable quotes, fills, or broker account.
No inference about future profitability follows from this fixture.
## Next experiment
Apply the same reporting contract to a new, separately specified synthetic fixture.
"""
Path("research_report.md").write_text(report, encoding="utf-8")
assert "No inference about future profitability" in report
assert len(fingerprint) == 64
print("unique_closes=4 net_total=-0.20 positive_net_outcomes=2/4")
print("source_fingerprint=64_hex_characters")
print("checks=4_passed report=research_report.md")
Expected terminal output:
unique_closes=4 net_total=-0.20 positive_net_outcomes=2/4
source_fingerprint=64_hex_characters
checks=4_passed report=research_report.md
The four passing checks cover this small report’s declared contract. They do not establish that the invented data describes a real market.
Step 3 — Inspect the generated Markdown
Open research_report.md. Find the full fingerprint, result denominator, and limitation paragraph. Copy the result into a draft article only with the method and limits nearby. If your headline says “Research lab: a cost model turns a small gross gain into a net loss,” the body should show enough detail to verify that statement.
A fingerprint helps identify the bytes used in the calculation. It does not prove when the data was collected, whether it was authentic, or whether someone omitted inconvenient rows before hashing it. Preserve the source and the collection method as well as the digest.
Step 4 — Run an adversarial editorial review
Ask a colleague—or use your own review checklist—to try to misunderstand the report. Could the word “profit” be mistaken for funded proceeds? Is a percentage missing a denominator? Is “AI confidence” presented as a measured likelihood? Does a figure mix paper and funded observations? Are outliers or rejected opportunities excluded without explanation?
Revise those ambiguities. Keep factual reporting separate from the next hypothesis. A good ending can say what failed, what remains unknown, and what test would reduce that uncertainty.
Step 5 — Make the publication workflow concrete
In Publish Haven, open your publication's Studio, create a guide, and paste the report into the article body. Add a clear summary and preview the page. Keep it as a draft while checking code formatting, links, and the synthetic-data label. Choose newsletter delivery separately if you intend to email it; publishing a page and sending an email are different decisions.
This lesson does not automatically create or send an article. Your file is a reviewable artifact first. If you share it, describe it as an educational lab and include the source code needed to reproduce it.
Troubleshooting
If a total differs, check whether the copied net values still match Edition 3 and whether you charged costs again. If the fingerprint changes after harmless-looking edits, compare the serialized data, including value strings and ordering. If Markdown appears as literal text in your editor, use the preview to check the final rendering.
Evidence and limits
This package is reproducible, but it is still a toy experiment. Reproducibility does not imply external validity. In a serious study, you would also preserve environment versions, observation timestamps, source provenance, candidate-selection rules, failed experiments, and review decisions.
Completion check: Another person can run the file, reproduce the reported values, and point to the sentence that prevents a synthetic result being mistaken for real returns.
Next edition: Turn the skill into something useful people can pay for.
Primary references
- Python hashlib documentation documents SHA-256 digests.
- Python JSON documentation documents sorted keys and separators used for this exercise's stable serialization. This is a chosen local format, not a universal canonical-JSON standard.