# Build with Arxo This route builds one small application end to end: a deadline checker. A user enters the event date that starts a period and the length of the period in days, and the application computes the day the period ends, checks a candidate end date, and shows the grounds of the answer. The law underneath is the German Civil Code: the day of the event is not counted, and a period measured in days ends with the last of those days. The canon `de.bgb.fristen` carries those provisions in executable form. Your application supplies the facts and the questions; Arxo Law executes the canon and returns an answer document with statuses, proof, and hashes. ## The app you get What you get is a local server integration over one pinned deadline scenario: two query kinds (compute the end date, check a candidate), follow-up questions for missing facts, shown grounds, saved captures, and a replay that compares result hashes. It is a reference for the integration pattern — fixed fields, explicit versions, no passthrough — not a ready product for arbitrary legal computations. One process, one canon, one form; everything wider is out of scope by design. The whole route develops one case: an event on 6 March 2026 starts a period of 14 calendar days. The command line runs the same two calls as the form — compute the end date, then check the candidate 20 March: ```text $ node --import tsx src/cli.ts evaluate --event 2026-03-06 --days 14 The period ends on 2026-03-20 rules: TagesfristEnde sources: No sources anchored in this canon build — the rule names above carry the provenance. $ node --import tsx src/cli.ts evaluate --event 2026-03-06 --days 14 --candidate 2026-03-20 Yes — the proposed date is established rules: TagesfristEnde ``` The route also keeps one promise about evidence: every answer shape the engine can return gets its own rendering, including the inconclusive ones. If your application cannot show "not established", it is not done. ## What to know and install Start with no prior Arxo knowledge; if you have ten minutes first, read [Quickstart](/guide/quickstart/) for the same canon in one file. You need Node.js 20 or newer with npm; Python 3.12 or newer only if you also want to run the Python mirror. All chapters run against these published versions: | Package | Version | |---|---| | `@arxo/law` | 0.3.3 | | `@arxo/canon-bgb-fristen` | 0.1.5 | | `arxo` (Python) | 0.2.0 | | `arxo-canon-bgb-fristen` (Python) | 0.1.1 | | Node.js | 20 or newer | | Python | 3.12 or newer | Two different numbers describe the canon. The package version (`@arxo/canon-bgb-fristen` 0.1.5, `arxo-canon-bgb-fristen` 0.1.1) counts releases of the package that delivers the canon to your SDK. The model version (`de.bgb.fristen@0.1.0`) names the canon itself, and it is what your application pins: both packages above carry the same model version 0.1.0. [Compatibility](/build/sdk/compatibility/) and [Versioning](/build/application/versioning/) cover the rules in full. Pin the model version in your model spec (`de.bgb.fristen@0.1.0`): an answer without a pinned version is not reproducible. The legal time of every call is `2026-09-17` and the calendar is `Europe/Berlin`. The deadline policy is declared by the canon itself: ```text de.bgb.fristen@0.1.0 urn:de:corpus:clir:bgb-fristen#BGB_FRISTEN_TAG ``` ## Where to run it Everything runs locally on your machine from a versioned archive; no repository checkout is needed. There are two ways through this section: - **Run the example.** Download the versioned starter, install its pinned tree, run the 63-check suite, and open the form at `http://localhost:8787/` — then read the nine chapters as a guided tour of the working app, one layer per chapter. Start here: [Start: install, run, and test](/build/start/). - **Find an SDK contract.** Skip the app and read the operation, shape, and version you need: the [SDK map](/build/sdk/) holds both facades, the query types, the result and error contracts, and the compatibility matrices with their probe record. The chapters assume the first route: a running reference application you inspect, exercise, and change — not code you write from nothing. ## Route map | Chapter | You learn to | |---|---| | [Start](/build/start/) | install, run, and test the example application | | [Bind input](/build/bind-input/) | turn form fields into canon facts | | [Calculate and check](/build/calculate-and-verify/) | compute the end date and check a candidate | | [Handle results](/build/handle-results/) | render every answer shape, conclusive or not | | [Collect missing facts](/build/collect-missing-facts/) | ask the user for exactly what the rules need | | [Show grounds](/build/show-grounds/) | present proof, sources, and hashes honestly | | [Save and replay](/build/save-and-replay/) | archive a capture and reproduce the answer | | [Change the model](/build/change-model/) | test whether a new model serves the same app contract | | [Troubleshooting](/build/troubleshooting/) | fix the failures you will actually meet | Each chapter opens with an "At a glance" block — the goal, what you need, the command to run, and the files involved — then walks through the subject itself, and ends with a test run and a few questions to check your understanding. ## TypeScript or Python The chapters walk through the TypeScript application. The archive also contains a finished Python implementation, `python/deadline.py`, with its own test file: it mirrors the calculate (collect), verify (truth), and explain (`why_not`) paths and the mapping of missing facts. A Python developer follows the TypeScript walkthrough and compares each step with the matching function in that file; the chapters do not repeat every step in Python. The two SDKs return the same statuses and the same values, but they are not byte-identical: a capture saved by one SDK is replayed by the same SDK only. Python additionally has no `questions`, no `unfold`, and no `focused_truth`, and the Python mirror does not use them. ## Scope limits This route teaches application code, not canon authoring. It does not write rules, and it does not change the canon. It shows one canon, one case shape, and two SDKs. Anything beyond that — a second canon, a new question, a changed model — is covered only as far as chapter 8, which shows exactly which files change and which stay untouched. ## How the files are organized The starter is complete on arrival: a form, an example API, and a command line, in TypeScript with a Python mirror. Its files fall into five roles: | Role | Files | |---|---| | The form, its validation, and follow-up questions | `public/index.html`, `src/input-schema.ts`, `src/missing.ts` | | Mapping form data to facts | `src/to-case.ts` | | Running the query | `src/query.ts`, `src/runtime.ts` | | Presenting the answer | `src/read-result.ts`, `src/to-view.ts` | | Saving and replaying | `src/capture.ts`, `src/replay.ts` | The server, the command line, batch runs, and the contract check sit on top of these roles. The full inventory: ```text deadline-app src/input-schema.ts validateFormInput/validateDraftInput, FormInput, DraftInput src/to-case.ts ADAPTER_VERSION 1.0.0, toFacts, toCaseInput, toDraftCaseInput src/query.ts buildCollect, buildTruth src/runtime.ts openModel singleton, evaluateCollect/evaluateTruth/explainWhy/explainDraft src/read-result.ts readCollect/readTruth, AppResult kinds value|claim|not-computed|unknown src/to-view.ts toViewModel src/capture.ts CAPTURE_FORMAT deadline-app.capture/1, captureEvaluation src/replay.ts replayCapture, verifyCaptureIntegrity src/missing.ts ASKABLE allowlist, missingFacts src/batch.ts runBatch src/check-contract.ts APP_PREDICATES, checkContract src/server.ts GET / form, POST /api/deadline/evaluate, POST /api/deadline/replay src/cli.ts evaluate/explain/batch/check-contract/replay public/index.html the form python/deadline.py the same flow in Python ``` Nothing is scaffolding you throw away: the file chapter 2 explains is the file chapter 8 tests when the model changes. ## Where each contract is defined Each contract has one canonical page; other pages summarize and link rather than restating it: | Contract | Canonical page | |---|---| | Answer shapes and statuses | [Handle results](/build/handle-results/) | | Errors: call vs content | [Results and errors](/build/sdk/results-and-errors/) | | Hashes: what each pins | [Show grounds](/build/show-grounds/) | | Capture and replay | [Save and replay](/build/save-and-replay/) | | Missing facts and verdicts | [Collect missing facts](/build/collect-missing-facts/) | | Versions and compatibility | [Compatibility](/build/sdk/compatibility/) | ## Next - [Start: install, run, and test](/build/start/)