Ink → Blaze: a focused prior-art pass
Status: proposed second pass for Blaze v0.1, not a new v1 milestone. Ink is prior art, not a dependency or embedded runtime. The normative design and paired mini-story contain the proposed grammar and exact lowering. No compiler ships here.
Evidence and decision matrix
Research is pinned to Ink commit 35c63e52f1d36060930dc7ed3cfba38ea224b528. The links below are immutable; line spans identify the relevant evidence, not a claim that every Blaze recommendation is already implemented by Ink.
| Study area | What Ink demonstrates | Blaze decision / timing |
|---|---|---|
| 1. Knots and stitches | Named sections and local subsections avoid naming every content line. Nested weaves supply finer structure. | Steal restraint. Module + conversation/local node suffice initially. Story/act/thread/mission are organizational vocabulary, not a mandatory ontology. Two levels are useful evidence, not proof of universal sufficiency. |
| 2. Weaves and gathers | Local alternatives rejoin without global destinations for each branch; nesting preserves readable forward flow. | Adapt now: one choices: gather id(target) [...] expression. Share one explicit edge across existing choice records; do not create a prose interpreter. Nested weaves and implicit text fall-through wait. |
| 3. Diverts and tunnels | A divert changes destination; tunnels remember a continuation and return. | Adapt destination only: current nextNodeId within a conversation. Tunnels/call stack wait; a general cross-conversation goto does too. An AK outcome can enable later content without suspending the world. |
| 4. Includes | INCLUDE combines files into a shared story namespace. | Adapt more strictly: typed imports/exports, aliases, entry-root containment and an import DAG. Explicit assembly; no auto-emission. Literal runtime IDs remain possible, so symbol privacy is not full runtime encapsulation. |
| 5. Entry/exit contracts | Knots, diverts and tunnels provide flow addresses/continuations, not AK capability contracts. | Adapt in documentation now: input symbols/external IDs, real entry gates, explicit outputs, parent conditions and verification. No new contract grammar or mission lifecycle. |
| 6. Tags | Host-readable metadata separate from prose, including dynamic tags. | Steal separation; avoid authority leakage. Only existing typed presentation fields now; comments/docs for author metadata. No arbitrary tag-to-effect callback or new @camera/@music syntax. |
| 7. Conditions/state | Choice conditions and read counts make narrative availability readable. | Adapt ergonomics: existing tagged all/any/not and typed AK predicates. Preserve visibility versus availability. No Ink variables or second evaluator. |
| 8. Visits/read counts | Ink automatically records visits and uses content addresses in expressions. | Avoid automatic counters. Existing visited_room, decision_recorded, knowledge and flags can express authored facts, but their meanings are not interchangeable. No generated state. |
| 9. Threads / parallel flows | Threads splice content/choices and collapse unchosen forks; multiple flows retain runtime contexts. | Avoid runtime machinery. Neither means independently acting AK characters. Existing characters/tasks/world state remain authoritative; “thread” may label an owned module. |
| 10. Diagnostics | Compiler checks actual links, names and loose ends; source evidence below. | Steal actionable locations; adapt semantics. Deterministic symbol/type/owner errors now; no false error for legal stay-put dialogue. Reachability/impossible-entry proofs are not promised. |
| 11. Source → output | Parsed objects retain source structure; later generation/resolution lower to runtime containers. | Steal staged lowering: located AST → typed resolved compiler IR → WorldBundle + provenance → validator → JSON. Do not copy Ink bytecode, VM or save format. |
| 12. Visual graph projection | Source-level structures are distinct from runtime containers; debugging can inspect the generated hierarchy. This is architecture evidence, not a claim of an Ink editor feature. | Design for later projection: module/conversation/node vertices; typed import, initial-entry and nextNodeId edges; gather provenance groups edges. Conditions annotate edges, not speculative reachable-state claims. No editor or serialized graph authority now. |
Material changes to the first-round design
- One local convergence shorthand. The initial field-for-field floor remains complete, but authors can declare a shared continuation once. This saves repeated wiring; it does not make all branching prose cheap in the way Ink does. Explicit stable runtime identities and AK interaction boundaries constrain the gain.
- Explicit internal IR. Resolved ownership/references and source provenance are now a named compiler boundary rather than incidental parser bookkeeping. It is not a new runtime contract, public serialization or platform-sized deliverable.
- A measurable locality requirement. Grace's PR review approved the first-round direction but correctly challenged modularity as a proxy for agent context reduction. #159/#161 must account for actual source/contracts read, dependency chasing, bytes and escalation; needing most of the world is a locality failure even if functional verification succeeds. See the receipt contract.
Unchanged: pinned oracle and original four witnesses, typed canonical declarations, immutable asset boundary, stable IDs, meaningful order, deterministic World runtime, check/build only, no visuals/editor implementation and no expansion of #156 into a rule engine. New examples are not part of the oracle.
Local flow, ownership and module contracts
Ink is strongest where many tiny prose alternatives naturally converge. Blaze borrows that intent, not its evaluation mechanism. Use gather for a flat group of choices with one continuation; use plain records/nextNodeId for mixed destinations. The paired source and JSON show the same map/mine story and explicitly different interaction timing. There is no runtime-equivalence claim between Ink and Adventure Kit.
For bounded ownership, keep a source file such as stories/act-1/surveyor/climb-mountain.blaze, exporting only intended typed symbols. Directories may nest freely under the entry root. Keep companion interface docs small, listing imported symbols, literal external IDs and owners, entry gates, output effects and parent observations. A parent must explicitly select exported content into its world; imports alone do not start a mission. The existing reunion example demonstrates real StoryBeat preconditions/owned persistent outputs; the normative interface model describes surveyor-style contracts without pretending new mission syntax exists.
A documented “requires route knowledge” does nothing unless an AK-supported gate actually checks it. “Provides summit notes” is not guaranteed unless all relevant accepted completion branches grant knowledge to the appropriate recipient. An abandoned outcome must be explicitly authored. Entry/exit contracts and strict runtime-ID encapsulation can become a future language extension only with an explicit lowering proof; do not smuggle them in through metadata.
Compiler diagnostics worth borrowing
Pinned source evidence:
- Divert.cs missing target reports unresolved flow destinations.
- FlowBase.cs duplicate variable declarations and apparent loose ends catch problems in Ink's flow model.
- Weave.cs explicitly gathers and validates local loose ends.
Blaze should report a compact span, stable code, related declaration/owner and a likely fix. Its diagnostic table distinguishes v0.1 errors from future analysis. In particular: no nextNodeId is legal stay-put, external entries complicate reachability, and impossible-entry proofs need a bounded state model. Unconsumed exit/stale rule-version errors cannot be promised before those constructs exist. No new analyzer subsystem is required.
Explicitly not borrowed
No Ink runtime, mutable independent variables, arbitrary external functions, second inventory/location/knowledge model, RNG, save format, visit ledger, parallel flow contexts or tunnel stack. No implied execution of annotations. Compilation may only express existing AK behavior; missing runtime capability is an explicit deferred design problem, never a hidden compiler workaround.
