Continuity Walker
Inspiration
Big decisions increasingly get made from piles of records and documents written at different times by different people under different assumptions. Inconsistencies are inevitable, and they cost real time to untangle.
What it does
Continuity Walker is an evidence-backed consistency checker. It uses Jac to build agreements across nodes and surface contradictions, then suggests fixes before they go viral.
How we built it
Everything except one HTML file is Jac (66% of our codebase), including the HTTP server. One main.jac holds:
- Object-spatial schema:
Document,Segment,State,Violationnodes;Establishes,Requires,Transition,Supersedestyped edges. Typed-edge filters like[seg ->:Requires:->]are the queries. - Walkers:
Ingest,Auditor,ShowCanon,Score,Dump,Reset. The audit is literally a graph traversal. - Persistence: canon survives across runs and episodes with zero database code. Snapshots export, import, and merge as JSON, so teammates and judges can replay everything with zero LLM calls.
- byLLM:
extract_facts() -> SceneFactsandadjudicate() -> Verdictare typed LLM functions. Contract mode routes to contract-tuned twins of both; the screenplay prompts stay frozen.
The frontend is one HTML file, with Cytoscape rendering the graph.json a Dump walker writes. Extraction runs on deepseek-v4-flash, adjudication on claude-sonnet-5, both via OpenRouter.
Challenges we ran into
- Extraction wants to heal the holes it should expose. "Client shall continue to be entitled to the Net-30 discount" reads like it establishes Net-30. We had to prompt for referencing versus enacting, and exclude a clause's own establishes from its own requirement's evidence. A clause can't vouch for itself.
- Early audits flagged every location mismatch ("Kevin required at home, canon says grocery store"). But people move, phone lines don't fix themselves. So location mismatches got declined by rule, and multi-valued predicates like knowledge never flag, since you can know two things at once.
- Global canon collided. Final Destination 3 has a Kevin too, and he inherited Home Alone Kevin's timeline. Documents now declare canon scopes.
- A cheap judge is a bad judge. DeepSeek flagged "required true, canon says alive" as a contradiction; Sonnet never did. So we split the work: cheap model for bulk extraction, strong model for scarce verdicts, and we cache verdicts per evidence state so a finding only changes when canon changes.
- Hackathon grit: free-tier Gemini caps at 5 requests a minute, Jac f-strings mangle nested quotes, and episode titles with quotes broke our own dropdowns.
Accomplishments that we're proud of
- Confirmed: Home Alone's phone. Established down in the storm, never repaired, yet Kevin orders pizza by phone. Caught automatically, with the scene chain as proof.
- Confirmed: Game of Thrones S8. Dothraki wiped out at Winterfell (E3), charging at King's Landing (E5). Caught across episodes, since E5 gets audited against canon persisted from E3.
- Confirmed, twice: contracts. Amendment No. 2 relies on Net-30 terms that Amendment No. 1 changed to Net-45, and doubles service credits "per Exhibit B," which Amendment No. 1 deleted. The adjudicator's verdict: a contract changes only by written instrument, and nothing in the timeline restores it.
- Withdrawn, live on stage: add the classic Home Alone fan defense (only long-distance lines were down, a real 1990 distinction), or file a corrective amendment restoring the deleted exhibit. Re-audit, and the system withdraws its own findings in seconds. Reasoning, not pattern matching.
- Declined, four times: wording near-misses (rigged traps versus trapped) correctly rejected. Precision, not just recall. And
jac run main.jac scoreprints extraction accuracy against annotated ground truth, so we measure our weakest link instead of hiding it. - It's cheap and replayable: the full 139-scene film corpus costs about $0.10 to process, and the entire adjudicated canon ships as JSON snapshots any judge can import and replay with zero API calls.
What we learned
- Give the LLM a graph and it stops hallucinating memory. Two narrow byLLM calls plus a walker outperform a frontier model holding the whole script in context, and they produce evidence instead of vibes.
- The adjudicator is a judge, not an oracle. Confining it to the walker's evidence timeline ("did the timeline restore this term, yes or no?") turned flip-flopping answers into stable, high-confidence verdicts.
- The schema was never really about stories. Establishes and requires over subject-predicate-value triples covered contracts without touching a single node or edge type; only the prompts changed. That's when this stopped being a plot-hole toy and became a consistency engine.
What's next for Continuity Walker
Pointing the same walker at deposition transcripts (testimony that contradicts prior testimony), patient charts (discharge instructions requiring discontinued meds), and the one we want most: a continuity firewall for AI-generated fiction. Every LLM that writes stories needs something vetoing scene n against the canon of scenes 1 through n-1 before a reader ever sees it.
Built With
- anthropic-claude
- byllm
- css3
- cytoscape.js
- deepseek
- html5
- jac
- jaseci
- javascript
- litellm
- openrouter
- pypdf
- python
Log in or sign up for Devpost to join the conversation.