Proposed — not in force yet — an open question, so citing it as settled is what the reference report catches.

12 of 141 decisions. Back to the full index.

#TitleSummaryStatus
ADR-126A reference may name several schemesscheme: on a reference takes a list as well as a string, and a code passes if it belongs to any scheme listed. A string is a list of one, so no config changes meaning. A converse is a field of the same name on every scheme listed, each naming the declaring scheme back; a chain walks the relation only when its own scheme is the sole target. Rejected: a field per target family, a loose requires field, a refinement predicate language, and letting a chain walk a union that includes its scheme.Proposed
ADR-127A logic core in clingo, behind a procedural shellThe parts of luria that decide things about the record’s graph — converse pairs, invariants, chain edges, config consistency, and which acknowledgement answers for a citation — move from hand-written Python walks to Answer Set Programming rules evaluated by clingo, over facts the Python extracts. Python keeps parsing, rendering, editing, git and the network, and turns derived facts into findings, edits and pages. The move is one subsystem at a time, each held to byte-identical luria lint and luria index output against the last release on every real record. Rejected: a full rewrite, Cypher or an embedded graph database, SQLite recursive CTEs, a hand-rolled Datalog evaluator, and staying in Python.Proposed
ADR-128Configuration is the only source of relation semanticsNo relation is supplied by the code: the successor and influenced_by become ordinary declared references, roles point at declarations instead of creating them, references may target declared remotes, the facts give every reference value a declared type, and relations.lp no longer infers a type from an absence. luria upgrade explicit-relations writes down what older versions supplied. Rejected: emitting the built-ins as facts, an explicit any-scheme target, and undeclared roles with the old defaults.Proposed
ADR-129 v2A chain may walk a named path patternA record may declare named path patterns in Cypher’s pattern syntax, such as (b:CLAIM)<-[:concludes]-(i:INF)<-[:premise_of]-(a:CLAIM). Node labels are schemes, edge types are reference fields, and a hop holds when the relation does as held/4 reads it. luria parses patterns with its own lark grammar for the subset and lowers them to clingo rules over the record’s facts, so the logic core stays the one engine. A chain names a pattern in relation or sibling as it names a field: the pattern’s two ends are the step, and its named inner nodes render as “through”. A partial match is no step and luria derives nothing from it. The subset is checked against the schemes at load and is stratified by construction. Rejected: a field list on the scheme, clingo rule bodies as queries, a graph engine, grand-cypher over networkx, Raqlet, GraphGlot as the parser, and built-in open ends.Proposed
ADR-132A named path pattern may render a page of its matchesA pattern with an output: (and optional title:) renders there as a view luria supplies, luria:pattern.md.j2: one row per match, one column per named node. It is a list, never a finding; report: true is the separate lint consumer, a pattern may have both, and acknowledged matches stay listed. Every path luria renders is checked against every other at load. Rejected: a renderer of its own, closing the issue as served by views, a reports: family, fixed placement, and grouping rows.Proposed
ADR-133A pattern page nests its matches as an outline, and patterns may share oneA pattern page renders as an outline by default: each match is the path of its named nodes, matches merge by shared prefix, and each node is written by the step renderer chain pages use, with facet_by as on a chain. layout: table keeps ADR-132’s flat table. Patterns naming one output merge by position into one outline, which draws claim, argument and undercutter at fixed depth with no change to chains. Reverses ADR-132’s deferral of grouping. Rejected: grouping by the first column only, OPTIONAL MATCH, and a pages: family. Unbounded-depth threads stay a chain’s.Proposed
ADR-135A pattern node may test its own field for inequality or membershipThe path-pattern subset of ADR-129 gains one comparison per node, written inside the node in Cypher’s inline node predicate: (p:CLAIM WHERE p.status <> 'Active'), (o:CLAIM WHERE o.status IN ['Proposed', 'Active']) and (n WHERE NOT n.status IN [...]). The comparison tests the node’s own field, so it stays local to the node and readable in the line. It lowers to the status/2 and value/4 literals the property map already uses, plus negation over facts, so every program stays stratified. A document without the field matches no comparison, as with Cypher’s null. Rejected: a list-valued property map ({status: ['Proposed', 'Open']}), a path-level WHERE clause with AND/OR, = as a second spelling of the map, nested WHERE NOT, and keeping the subset and a script beside it.Proposed
ADR-136luria repair writes what the committed sources imply; link —fix writes what the working tree’s change impliesluria repair runs in CI on every pull request and on the default branch, and luria link --fix runs only where an author runs it, so a write that lives only in the second piles up wherever nobody runs it. Nucleation carried 812 one-sided converse pairs that way. The rule: a write belongs in repair when its answer is a function of the committed sources and the configuration alone, so any checkout of a commit computes the same edits, a second run computes none, and the lint can name repair as the remedy. It belongs only in link --fix when it needs what a checkout does not have, namely the author’s uncommitted change against HEAD, which ADR-084’s completion reads. A judgement belongs in neither (ADR-119). link --fix may also run a repair, as it does the linking, but no repair waits on it. Applied here, ADR-137’s normalization of a directed pair is a repair. Rejected: everything mechanical into repair (it would run ADR-084’s HEAD-relative completion in CI, where HEAD is the tree), splitting by how often a write is needed, and a third command.Proposed
ADR-137A directed converse pair stores its primary side; the derived side is computedSupersedes ADR-084 for directed pairs. A converse pair marks its derived side with derived: true on that side’s reference. Only the primary side is stored, and every reader gets the derived side from relations.edges(). The derived field may still be written, and luria repair moves what is written there. Where the primary side already holds the edge, the derived entry is dropped. Where it does not, the entry becomes the primary entry on the other document. A move that would assert a directed relation both ways, break a document’s contract, or name no document is reported and left as filed. With nothing stored twice there is no HEAD baseline to consult for a directed pair, so a deletion is final. Symmetric relations, and pairs that declare no direction, keep ADR-084’s rule. The latter are reported as undirected-relations rather than refused. one-sided-relations now covers only those two kinds, and a hand-filed derived entry is derived-relations. Fired on Nucleation: 2,626 derived entries dropped, 62 moved, 1,256 files, the relation graph unchanged at 10,815 edges. Rejected: primary: true on the forward side, refusing undirected pairs, completion run in CI, and keeping both sides stored.Proposed
ADR-138luria repair prunes acknowledgements that excuse nothing only when asked, and checks the findings did not moveluria repair --prune_stale removes the codes in inactive-ok, unresolved-ok and mention-ok directives that answer for no site, and deletes a directive left naming nothing. Removing them provably changes no finding, and the repair checks it: it re-scans after writing and restores every file if any citation’s standing moved. It is opt-in, because ADR-119’s line still holds: an uncited directive may mean its citation moved, and whether to move or delete the directive is a judgement. The flag is a person making that judgement for the whole tree. A record can make it once for good with repair.prune_stale: true in luria.yaml, as it can every repair flag, so CI prunes without the workflow passing it. Rejected: pruning in the default repair, as #385 first proposed; a lint check that relation-field citations need no excuse (they are already blanked, so such a directive is already reported); and leaving it to hand-written scripts, which on Nucleation misread the report and had to be run twice.Proposed
ADR-139The record description is rendered from a template luria ships, with its prose in the template and its facts from the configdocs/record.md was built from Python strings: a header constant, eight section introductions in a tuple, and a markdown table assembled in each section function. It is now luria:record.md.j2, rendered in the sandbox ADR-130’s views use. record_doc.context gives the template facts read from the loaded config and no prose. The template holds every heading, introduction, table and empty-state line, so the page’s text is edited in one place, and a section with nothing to show is left out by the template, heading and all. The output was byte-identical on luria’s record, nucleation’s, a fresh init, and three fixtures covering every empty and partial case. Rejected: registering the page as a view luria supplies, which would link it and so send the luria decisions its prose cites to the project’s own; letting a project override the template, deferred until one asks; and keeping the strings.Proposed
ADR-141luria unconcretize records the given-back code under formerly: by default, and —noformerly turns it offADR-140 had luria unconcretize record no alias, because the number goes back to the pool. The owner reversed that. By default the old code is now recorded under the document’s formerly:, as concretize records a temporary one, so a citation the rewrite cannot reach still finds the document once it is numbered again. --noformerly records none, which is what a collision wants. The alias is safe even then, because a code resolves by number before any alias, so a live document outranks one; the flag is about whose history the document carries, not about resolution. The rewrite now also leaves other documents’ formerly: blocks alone. Rejected: keeping no alias by default, a config key in place of the flag, and refusing the alias when the code is held.Proposed