4. Run the application and publish checked output
The BookRec library makes a proposal. GND checks that proposal against the selected rules. Only then does the CLI move the candidate to its output path. This chapter makes that control flow visible with both the CLI and Python.
The important branch in the supplied publish function is small:
# Excerpt: candidate and output are paths prepared by publish().
report = api.check(model, candidate, unredacted=True)
if report["exit_code"] == 0 and report["acceptance_ready"]:
candidate.replace(output)
The surrounding function writes a temporary JSON file, refuses an existing output path, prints the report, and removes rejected temporary files. The recommender never gets to declare its own result accepted.
Continue from chapter 3. All examples use the invented catalogue, so the CLI prints unredacted checker details for learning purposes.
Ask for Ada's recommendations
(cd bookrec-project && python -m bookrec.cli recommend --model model.orm.yaml --input seed.population.json --output recommendations.json --user ada --limit 2)
Expected: exit 0, a checker report with one genre warning, and a new
bookrec-project/recommendations.json. The algorithm chooses unread,
age-appropriate books in alphabetical order. Ada gets cosmos and map;
Ben's existing night recommendation stays in the population. Ada's science
recommendation is legal under the current advisory genre policy.
import json
from pathlib import Path
from gnd import api
path = Path("bookrec-project/recommendations.json")
output = json.loads(path.read_text())
ada = [row["book"] for row in output["facts"]["recommendation"] if row["user"] == "ada"]
assert ada == ["cosmos", "map"]
assert {"user": "ben", "book": "night"} in output["facts"]["recommendation"]
report = api.check("bookrec-project/model.orm.yaml", path)
assert report["acceptance_ready"] and report["counts"]["warning"] == 1
assert not list(path.parent.glob(".bookrec-*.json"))
print("Published:", ada, "with one advisory warning.")
The library's filters make this particular proposal reasonable. GND is the independent acceptance boundary: if an implementation bug emits forbidden facts, the checker can reject them without trusting the library's filtering.
Exercise an application refusal
The CLI only knows readers with supplied preference facts. An unknown reader is refused before a candidate is published.
(cd bookrec-project && python -m bookrec.cli recommend --model model.orm.yaml --input seed.population.json --output ghost.json --user ghost)
from pathlib import Path
assert not Path("bookrec-project/ghost.json").exists()
print("Unknown reader produced no output file.")
Exit 3 here is an application-level unknown-user refusal. The checker also uses 3 for malformed inputs, so retain the command and diagnostic context when interpreting a number. An application's exit meanings belong to its declared interface, not to a guess based on the integer alone.
Call the library from Python
The library returns ordinary dictionaries. It does not publish files or hide a network call. This example selects preferred genres and passes the resulting facts to the same checked-publication function used by the CLI.
import json
from pathlib import Path
import sys
sys.path.insert(0, str(Path("bookrec-project").resolve()))
from bookrec.library import recommend
from bookrec.cli import publish
seed = json.loads(Path("bookrec-project/seed.population.json").read_text())
proposal = recommend(seed, user="ada", limit=2, preferred_only=True)
assert [r["book"] for r in proposal["facts"]["recommendation"] if r["user"] == "ada"] == [
"map", "river"
]
assert publish("bookrec-project/model.orm.yaml", proposal,
"bookrec-project/preferred.json") == 0
assert seed["facts"]["recommendation"] == [
{"user": "ada", "book": "map"}, {"user": "ben", "book": "night"}
]
print("Library preserved input and published preferred recommendations.")
In your own app, call the stable Python API at the
boundary where candidate data would enter storage or another system. A checker
report is an input to your publication policy. This example requires both exit
0 and acceptance_ready: true and refuses to overwrite existing output files.
It is a small local-file example; database transactions, concurrency and service
request handling remain ordinary application engineering.
Ask an agent to improve the algorithm
Implement a better ranking in BookRec's authored extension. Preserve the model and the checked-publication boundary. Demonstrate the before and after recommendation facts and checker reports. Run gnd-conformance only when I explicitly select that skill; do not turn a warning into a hard rule yourself.
The prompt deliberately distinguishes application tuning from changing the
requirements. If your question needs a recorded development experiment,
explicitly select gnd-dev-session, define its acceptance contract and coverage
floors, and retain its outcome separately from ordinary checker reports. This
chapter's direct calls are not a claim that an experiment session was run.
Exercise: Change limit=2 to limit=1 with a new output filename. Predict
which book Ada receives and whether the genre warning remains. Then try
preferred_only=True; the first book becomes map.