Skip to content

Software paper for the v3 substrate; README demotes the v1 technical note - #34

Merged
lukefwalton merged 1 commit into
mainfrom
claude/archive-retrieval-substrate-jkpz9g
Oct 8, 2026
Merged

lukefwalton merged 1 commit into
mainfrom
claude/archive-retrieval-substrate-jkpz9g

Conversation

@lukefwalton

Copy link
Copy Markdown
Owner

What & why

paper.md and paper.bib are the software paper for the v3 substrate, in the Journal of Open Source Software form (Summary, Statement of need, State of the field, Software design, Research impact statement, AI usage disclosure, Acknowledgements, References). 1,720 body words against the 1,750 cap; 22 citations, all resolving to paper.bib; 0 em-dashes, 0 contractions, 0 tell-words. The README's "formal write-up" is now the earlier technical note on the v1 engine, and the paper is named as the write-up for v3; both keep their DOIs, and the README says to cite the software DOI until the paper has a venue.

What the paper claims, and no more: a disclosure-typed retrieval contract in which the one representation a consumer can receive for each fragment is fixed before any query, forbidden representations are uninhabitable in the consumer-facing type, and the drafting of a released description is separated from the authority to release it. What it declines to claim: that the type bounds what a sequence of hits reveals (the contract names that residue and assigns it to rate limiting and policy); that the type is what keeps text off the wire in deployment (the strip is); that a served gist is re-linted where the text is blank (a served index is trusted to descend from a validated private one); that the deployment serves semantic (it serves locator; semantic is exercised by tests and demo); and that the software is evidence for the answerability working paper's empirical claim (it shows the feasibility of one architectural claim).

The AI usage disclosure reports the default branch as of this commit (169 commits, 69 authored by the coding agent, every change reviewed in a PR with the automated review, the offline tests, and the gold evaluation as the gate) and names the runtime model components. Refresh the counts before submission. The paper is not submitted: the venue is decided at the Phase 6 checkpoint (JOSS needs six months of public history with activity and demonstrated research use; the fallbacks are JORS, then SoftwareX).

Review record

The draft went through the corpus's two standing reader seats (locate-the-paper, earn-the-inference) before this commit. Their reports are banked below; they quote the pre-adjudication draft, so some quoted sentences no longer exist. The adjudication:

Seat finding What changed
Locate: page 1 fits three candidate papers (disclosure tool / answerability materials / cite-or-refuse engine); the home conversation is named only on page 2; the missing case only on the last page Statement of need now poses the missing case on page 1 (a private fragment that still does work: found, located, described, none of its text travels) and names the home (selective disclosure in retrieval-augmented systems); the answerability lineage is kept as the question's origin, in one sentence chain, and bounded
Locate: the MCP premise and the external-model instance are never joined The MCP sentence now sits in the opening beside the external-caller framing; the Impact statement names the MCP server as the instance
Locate: the Summary prints at one altitude; two cores (build time vs the type) Summary leads with policy fixed before any query and the one crossing; provenance and the inventory are one sentence each; the novelty sentence names the three conjuncts as one contract
Earn 1: a five-word lint does not license "cannot quote" Summary no longer says it; body: "a tripwire, not a classifier ... catches nothing shorter"
Earn 2: a bound on the form of a hit is not a bound on disclosure "The type fixes the form of a hit; what a sequence of hits reveals ... is a residue the contract names and assigns to the consumer's rate limiting and the author's policy, none included"; the Impact statement says the endpoint is rate-limited
Earn 3: a type lacking a field does not keep undeclared properties or data out The private index's validator refuses private + text in data, where types do not reach; "In deployment the strip keeps text off the wire; the type states and checks the contract and binds a consumer holding the private index"
Earn 4: a branded type does not make a served gist linted "The lint cannot run where the text is blank, so a served index is trusted to descend from a validated private one"
Earn 5: the need premise ("none states, in a checkable form") is stronger than the paper's own survey Sentence removed; the gap is now that neither exclusion nor filtering lets a private fragment contribute while none of its text travels, and a prompt is a promise, not a property of the data
Earn 6: the deployment is offered as evidence of a mechanism it does not serve Impact statement: private material is served at locator; semantic is exercised by tests and demo and reaches the deployment only as a policy change and a rebuild; the feasibility boundary sentence
Earn 7: "runs keyless" overstates "Tests and demo run keyless"
Earn, independent variation (a)/(b): build-time resolution is not what prevents leakage The paper no longer credits timing with the guarantee; the contrast with SD-RAG is "fixed before any query, nothing generated in response to one, and the served artifact holds nothing else"
Earn (c): authorization by policy is authorization without inspection "Release by policy authorizes a class of machine drafts the author need not have read; release by edit or review authorizes text the author has seen"

Declined: reporting canary-sweep coverage numbers (none exist yet and none will be invented); dropping the answerability lineage (it is the question's origin; it is bounded instead); renaming the package.

Seat report: locate-the-paper (on the pre-adjudication draft)

LOCATE-THE-PAPER REPORT: "Answer Engine: a disclosure-typed retrieval substrate for an author-owned archive"
Files read (nothing else): (the draft) and (the draft)

Four names: the body supplies all four, page 1 does not. Page 1 plus the last page fits three different papers.

What the whole manuscript gives for each, and where it sits:

  1. Question (page 1, Statement of need ¶2, sentence 1). Can the amount of a retrieved archive fragment that may reach a language model be made a property of the data? That means fixed at build time, carried on the wire, and impossible to express in the type when forbidden. The alternatives are leaving the material out, filtering the output, or trusting a prompt.

  2. Home conversation (page 2 only, State of the field ¶2–¶3). Selective disclosure, declassification and information-flow control for RAG and agent systems (SD-RAG, MNC, Rasul et al., Siddiqui et al.). The older lineage is language-based information-flow control (Goguen–Meseguer, Sabelfeld–Myers). Page 1 names a different home.

  3. Missing case (last page and State of the field ¶1; never posed as a puzzle on page 1). An unpublished fragment should still help answer a query: search finds it, and it comes back as a location, or as a description the author has released. None of its text reaches the model. Access control that works on whole chunks can only drop it or show it.

  4. Argument. By construction:

    • project() is the only path into EvidenceHit, a discriminated union. Its locator variant carries provenance only. Its semantic variant accepts only a branded LintedGist, which only the lint can construct.
    • Build-time resolution can only downgrade.
    • The served index is checked to have been stripped.
    • A gold set and a canary sweep act as a gate, and there is a production deployment that includes an external MCP client.
    • The leakage the type cannot block (what a sequence of queries learns, close paraphrase) is named and assigned to rate limiting, policy, veto and canaries.

    This is the mechanism the paper claims. It is easy to identify and is the best-placed of the four: Summary sentences 3–4 put it on page 1.

Candidate papers that page 1 plus the last page currently support:

  • A. A disclosure-control tool for RAG over corpora that mix public and private material. Signals: the subtitle, Summary S2–S5, Statement of need ¶2 S1. This is the paper the body writes and the novelty sentence claims, but its home conversation is not on page 1.
  • B. The working materials of the author's answerability program. Signals: Statement of need ¶2 S2–S3, impact statement S4. Its home is Walton 2026a–d plus Shoemaker 2011. In this manuscript the "line of work on answerability in generative systems" consists entirely of four of the author's own Zenodo deposits. The manuscript never states what case B's missing case would be.
  • C. A citation-grounded answer engine that cites or refuses. Signals: the name "Answer Engine", the tags, Summary S6–S7, the abstention contrast in State of the field ¶1, the last page's only number (refusals), and the reference list's title for the technical note. Its home is attributed question answering, verifiability and abstention (Bohnet, Rashkin, Liu, Kadavath, Zhang).

More than one candidate is the finding. Working from page 1, an editor cannot tell whether to send this to an information-flow/privacy reviewer, a RAG-tooling reviewer, or a philosophy-of-AI reader.

Payload
The compressed idea ("don't trust the model or an output filter with what must stay private; make the forbidden state impossible to express") sounds like three known things:

  • the typed-design rule "make illegal states unrepresentable";
  • standard advice for permission-aware RAG (enforce access at retrieval, not in the prompt);
  • language-based information-flow control, which the paper itself cites as lineage.

The obvious version is to exclude private chunks, or filter them with access-control lists. That version is also decided before the model sees anything, stored with the data, and checkable.

What the obvious version cannot show is a private item that still contributes to an answer. It is found, located and cited, and can be described in words the author released, with none of its text on the wire. That payload is in the paper:

  • impact statement: "embedded for search, served as where to listen, never what was said";
  • impact statement: an unpublished novel whose chapters are "served as locators";
  • State of the field ¶1: the contrast with access control over "whole chunks".

It is not on page 1 as the reason the obvious version fails. Page 1 lists the exposure levels as features (Summary S2). It states the gap as a matter of checkability (Statement of need ¶1 S5), and exclusion already passes that test.

The sharpest instance is split across the two ends. Page 1 says MCP lets "any client model" call the search tool, and lists the operator's options, two of which (filter the output, trust a prompt) assume the operator controls the model's output and prompt. The last page reports an external model that "receives hits at the exposure the author set, with no synthesis on the server". The paper never puts these side by side.

Hierarchy: mostly a pile at one level, with a partial spine in the Statement of need.

  • The Statement of need does run condition, then gap, then question (¶1 into ¶2 S1).
  • ¶2 S2 then sets a frame above the question that is wider than the contribution. It names three junctures ("what evidence may enter an answer, what must stay out, when to decline"), and the disclosure type covers one of them ("what must stay out"). The other two are served by candidate C's parts: the consumer that cites or refuses, and the gold set.
  • Page 1 has no contrast. The last page's implication is about the author's own program.
  • The contribution prints at one level throughout:
    • The Summary gives the policy axes, the type exclusion, the single projection, gist drafting, provenance and a seven-item inventory at equal weight. Provenance (S6) gets the same weight as the core type exclusion (S3).
    • The novelty sentence lists three conjuncts with no ranking, and places the novelty in their combination after conceding each part to prior work.
    • Two different elements are each presented as the core. State of the field ¶2 picks build time ("where the decision lives"). The title picks impossibility in the type ("disclosure-typed").
  • A core, condition, contrast, implication order does exist, but only spread across the paper: Statement of need ¶2 S1, then ¶1, then State of the field ¶2, then the leakage sentences in Software design and impact S1–S2. No single page shows it.

Fork: presentation.
All four things are in the body (question in Statement of need ¶2 S1; home in State of the field ¶2; case in impact S1–S2 with State of the field ¶1; argument in Software design), but page 1 and the last page credit the question to the author's answerability program and leave the deciding case as deployment detail; if the answerability paper (candidate B) is the one intended, its home conversation is missing rather than misplaced.

Pinpoints

  1. The two ends and the body name different homes.

    • Statement of need ¶2: "The question comes from a line of work on answerability in generative systems [@walton2026a; @walton2026b; @walton2026c; @walton2026d], in Shoemaker's sense of the term [@shoemaker2011], which argues that the junctures at which an evaluative frame enters force (what evidence may enter an answer, what must stay out, when to decline) should be held outside the model, where they can be checked rather than trusted."
    • Statement of need ¶2: "answer-engine is that argument's materials: the runnable link between the design theory and a live deployment, cited as such in the working paper [@walton2026d]."
    • Impact statement: "The software is cited as the materials of the answerability working paper [@walton2026d], documented in a technical note [@walton2026note], and archived under a concept DOI [@walton2026software]."
    • Against these, State of the field ¶2: "Two recent lines of work come closest, and the difference from each is where the decision lives." and "The older lineage is language-based information-flow control [@goguen1982; @sabelfeld2003], where a forbidden flow is made inexpressible rather than filtered."
    • Where the terms fall: "answerability" and Shoemaker appear only in Statement of need ¶2 and the impact statement. "Selective disclosure" and "information-flow" appear only in State of the field ¶2–¶3. The two homes never share a section of running text.
    • Self-citations are 6 of 25 references. The last page's case for why it matters stays inside the author's work: "No use by other research groups is claimed."
  2. The page-1 gap is one the obvious version already passes.

    • Statement of need ¶1: "The operator's options have been to leave such material out of retrieval, to let it in and filter the output afterwards, or to trust a prompt." and "None of them states, in a form that can be checked, how much of a retrieved item is allowed to travel."
    • The case appears only on the last page. Impact statement: "...where published passages are public and unpublished transcript text is private: embedded for search, served as where to listen, never what was said."
    • The contrast appears only on page 2. State of the field ¶1: "...their access controls decide which whole chunks a caller may retrieve."
    • On page 1 the mechanism appears only as a feature. Summary: "...how much of it may travel (text; a short semantic description; a locator that says only where the moment is; or none)."
  3. The MCP premise and the external-model instance are never joined.

    • Statement of need ¶1: "...and the Model Context Protocol [@MCP2026] now lets any client model call a search tool directly."
    • Impact statement: "The same deployment exposes a retrieval-only endpoint and an MCP server through which an external model receives hits at the exposure the author set, with no synthesis on the server, and it carries an unpublished novel as a private entity whose chapters are served as locators."
  4. Two different cores; the novelty is an unranked combination.

    • Title: "Answer Engine: a disclosure-typed retrieval substrate for an author-owned archive"
    • State of the field ¶2: "Two recent lines of work come closest, and the difference from each is where the decision lives."
    • State of the field ¶3: "Prior work has applied access control, selective disclosure, redaction, and information-flow control to retrieval-augmented and agentic systems." and "To the author's knowledge, no retrieval package combines those concerns in a disclosure-typed retrieval contract: a fragment's permitted representation resolved before any query, forbidden representations uninhabitable in the consumer-facing type, and the drafting of a description separated from the authority to release it."
  5. The Summary prints at one level.

    • Summary: "The combination private + text is not a member of the type, so it cannot be written down."
    • At the same weight: "Every hit carries provenance (creators, date, version, identifiers, and a structural locator such as p. 184 or 12:30–14:05), so a caller can cite and reason about what it found with no synthesis on the server."
    • And the inventory sentence: "The package ships the contract types, the ingest helpers (fragmenting, policy resolution, gist drafting), the retrieval core with plugin seams, ..."
  6. Candidate C is signalled by the name, the tags and the last page.

    • The name "Answer Engine" sits against the subtitle "retrieval substrate" and the Summary's "with no synthesis on the server".
    • The tags list "citation grounding" and "provenance" beside "information disclosure".
    • Summary: "...a teaching-sized synthesis consumer that cites or refuses..."
    • State of the field ¶1: "...calibration and abstention studies [@kadavath2022; @zhang2024] treat refusal as a behaviour to elicit from the model..." The novelty sentence never returns to this contrast.
    • Impact statement: "A gold suite of 311 queries, 28 of which must refuse, gates every change to that deployment." The last page's only number counts refusals, not disclosure.
    • "Route" in Software design ("required behaviours (answer, route, refuse)") is never defined and never counted. If "route" is the locator case, the behaviour that would show the title's claim has no number on the last page.
    • paper.bib, walton2026note, titles the same software differently: "Answer Engine: A Small Reference Implementation for Citation-Grounded Answerability".
  7. Page 1 promises a test; the last page reports a gate.

    • Statement of need ¶2: "The research question the software exists to test is whether that disclosure can be made a property of the data rather than a filter on the output: resolved once at build time, stored on the fragment, carried on the wire, and unrepresentable in the type when it is forbidden."
    • The paper's answer, with its limits, sits only mid-body. Software design: "A sequence of queries still learns something per query, which fragment answered and roughly how well; the contract names that residue and assigns its bound to rate limiting and to the author's policy, not to the type." and "Close paraphrase, names, and spoilers are owned by policy, veto, and the evaluation's canaries, and the contract says so rather than claiming otherwise."
    • The last page gives the gate sentence and no outcome. I am only noting where the answer sits, not judging it.
  8. The scope of the phenomenon shifts.

    • Title: "...for an author-owned archive". Summary: "...searching a body of work its author owns..."
    • Statement of need ¶1: "For a personal or institutional archive that is often false: a podcast transcript the host never published, a manuscript under contract, a notebook." and "The operator's options have been..."
    • "Institutional" and "operator" appear only here; everywhere else the policy-holder is "the author". Who the user is decides which home applies: a creator's own archive, or access-controlled RAG in an institution.

What I am not saying

  • I do not demand four management-journal paragraphs or any departure from JOSS house form.

  • I do not restyle sentences or propose wording.

  • I do not diagnose AI authorship; the AI disclosure and the conflict-of-interest note are out of scope.

  • I do not recut or reorder sections.

  • I do not ask for simpler ideas, or for the answerability frame or Shoemaker to be dropped.

  • I do not audit the decisive inference. That means I do not judge:

    • whether project() and the type really make disclosure a property of the data, given the leakage the paper names;
    • whether the five-word lint is enough;
    • whether novelty by combination clears JOSS's bar.

    That belongs to another seat.

Seat report: earn-the-inference (on the pre-adjudication draft)

Contribution granted: answer-engine is a TypeScript retrieval package that makes three moves. It resolves and stores each fragment's permitted representation (public or private; text, semantic, locator, or none) before any query. It strips private text from the served index. Hits reach a consumer only through project(), into a union type with no variant for private text, and model-drafted descriptions of private fragments are kept apart from the author's authority to release them.

Decisive step:
The central distinction is original and well placed against SD-RAG and MNC: what may travel about a private fragment is fixed in the artifact before any query, not decided on text already in the pipeline.

The step that carries the conclusions is in Software design, "One crossing": "project() is the only path from them to EvidenceHit, a discriminated union on exposure whose locator variant carries provenance and nothing else and whose semantic variant carries a branded LintedGist that only the lint can construct."

  • The Summary turns this into "that type has no field in which a private fragment's text could ride," and from there into handing results to a model "without handing over more than the author released."
  • The Research impact statement turns it into "served as where to listen, never what was said."

The inference: one constructor, plus a consumer type with no slot for private text, means that what reaches a model about a private fragment is exactly what the author released.

For that to go through, three things must hold:

  • (i) The line the type draws is the line the data crosses. Nothing reaches a model except EvidenceHit values, and those values carry only their declared fields. The paper says project() is "the only path from them to EvidenceHit." It does not say what makes EvidenceHit the only path to a model, when retrieve() hands the fragments themselves "to the process that holds the index."
  • (ii) What a hit reveals just by being returned (which fragment, its rank, its rounded score) is nothing beyond what was released.
  • (iii) A LintedGist carries nothing beyond what was released.

The paper withdraws (ii) two sentences later: "A sequence of queries still learns something per query, which fragment answered and roughly how well." It withdraws (iii) in the next paragraph: "Close paraphrase, names, and spoilers are owned by policy, veto, and the evaluation's canaries." It asserts (i), and in the deployment what (i) is meant to secure is secured by the strip, not by the type.

So the step earns two things: in the served deployment no hit carries private text, and whatever is released about a private fragment was fixed before any query. It does not earn "no more than the author released," and it does not earn "never what was said."

Jumps, if any:

  1. A lint, therefore no quotation.

    • The Summary says "linted against the text so they cannot quote it."
    • The design licenses only that a gist shares no run of five words with its fragment or its entity. A four-word quotation passes. So does a longer one broken by a changed word in every five.
    • The body is calibrated ("a tripwire, not a classifier"). The Summary states what only a classifier could conclude.
  2. A bound on the form of a hit, therefore a bound on what is disclosed.

    • Summary: "without handing over more than the author released." Impact: "never what was said." Software design: "Nothing is decided or generated at query time."
    • Exposure is decided before any query. Which private fragment answers a query is decided at query time, from its private vector.
    • That leaves a dilemma the paper never resolves. If choosing locator releases relevance per query (the reading that lets "the author's policy" act as a bound at all), then "no more than the author released" holds. But the author has then released, query by query, a signal about what was said, and "never what was said" holds only of the text. On the other reading, the residue is more than was released.
    • The bound is "assign[ed] ... to rate limiting." But the package puts HTTP and transport in consumers, which is where rate limiting would sit. The Impact statement then offers an MCP endpoint, where an external model can run sequences of queries most cheaply, without saying any limit is applied.
    • Naming where a bound belongs does not supply the bound.
    • The lineage sentence has the same gap. Goguen and Meseguer is the lineage of noninterference, in which a private input's influence on a public observation is exactly the forbidden flow. The paper's residue sentence describes that influence. The package borrows the lineage's move (make the forbidden thing inexpressible rather than filtering it) but not its property.
  3. The type lacks a field, therefore nothing rides.

    • Summary: "that type has no field in which a private fragment's text could ride" and "The combination private + text is not a member of the type, so it cannot be written down."
    • In TypeScript, a value typed as the locator variant can carry properties the type does not declare, and serialization emits them. The compiler flags extra properties only on a fresh object literal, not on a spread or on assignment from a variable.
    • Policies are written in data files that types do not govern.
    • So the validator is what keeps private + text out of the data. What keeps text off the wire is how project() builds each value, and in deployment the fact that the text is no longer there.
    • The type states the contract in a checkable form, which is what the Statement of need asked for. On its own it is not what excludes the data.
  4. A branded type, therefore served gists were linted.

    • The paper pairs "a branded LintedGist that only the lint can construct" with "The private index … re-earns every lint at each load; the served index is the same file after a strip that blanks text …, and a load-time check verifies that the strip happened."
    • In the served process, the text the lint compares against has been blanked, so the lint cannot be re-run there. The load-time check verifies the strip, not the lint.
    • In that process, a LintedGist certifies only that the file came through the build pipeline intact. The paper does not state that premise, and the check it describes does not test it.
    • Naming the type does not make a served gist linted.
  5. The Statement of need's premise is stronger than the paper's own survey.

    • Statement of need: "The operator's options have been to leave such material out of retrieval, to let it in and filter the output afterwards, or to trust a prompt. None of them states, in a form that can be checked, how much of a retrieved item is allowed to travel."
    • State of the field describes SD-RAG as one that "carries its constraints in the data model and applies sanitization and disclosure controls to retrieved material before it reaches the generator." That is a fourth option, with a stated form. The contrast the paper draws with it concerns timing, not whether it can be checked.
    • The premise holds only on a narrow reading, "a permitted representation stated before any query," which is the paper's own feature restated as the field's lack.
    • The novelty sentence is hedged and calibrated. This premise is not.
  6. A deployment, therefore the mechanism is shown live.

    • The Statement of need offers the software as "the runnable link between the design theory and a live deployment."
    • The private material the Impact statement describes is all served as locators: transcripts "served as where to listen," the novel's "chapters are served as locators." Nothing says any private fragment is served at semantic in production.
    • So the third leg of the novelty claim ("the drafting of a description separated from the authority to release it") has no reported live instance, and neither do the lint and canaries that protect it.
    • The reported figures (311 queries, 28 that must refuse) gate answer behaviour (answer, route, refuse). The paper does not say how many cases test exposure. The disclosure gate, the canary sweep, has no reported coverage or result.
    • The statement is honest about reach ("No use by other research groups is claimed"). The overreach is in what the deployment is offered as evidence of.
  7. Minor: keyless.

    • The Summary says "It runs keyless from a clone."
    • The body licenses only "A fixed gold set … runs keyless at the retrieval tier," and the AI disclosure names text-embedding-3-large as a runtime component.
    • A new query needs an embedding, unless a lexical retrieval path is meant, and the paper does not say one is.

Independent variation, if relevant:

(a) The typed wire versus the stripped artifact. The paper presents these as one mechanism ("One crossing"; "Two artifacts, one validator").

  • Strip without the typed wire. A server returning untyped JSON from the served index leaks no private text, because none is there. The headline guarantee survives removing the type. What the projection still does in deployment is round scores and drop the per-plugin breakdown, which is work on the residue channel the paper says the type does not bound.
  • Typed wire without the strip. In a process holding the private index, the guarantee rests entirely on "the only path," which is asserted with no mechanism given.
  • So the "disclosure-typed" element bears the weight only in the configuration the paper does not describe as served.
  • The trade-off line "a vector store would not change the contract" is true of the type. It is not evidently true of the strip and load-time check. Those carry the guarantee in deployment, and the paper gives them no counterpart once the index is no longer a file the server loads.

(b) The typed wire with query-time resolution.

  • The guarantee against leaking private text needs only two things:
    • the layer, which is set per entity and which fragments "never change";
    • a strip of private text.
  • Since private + text is forbidden at every exposure, that strip needs no exposure decision at all. Resolve exposure at query time by a deterministic lookup, keep the same EvidenceHit, and the guarantee is unchanged.
  • What build-time resolution adds is that unreleased gists are absent from the served artifact. Released content cannot be shaped by queries because gists are drafted at ingest, not because of when exposure is resolved.
  • The SD-RAG contrast ("The decision is still made at query time, on text already in the pipeline") bundles two conditions that come apart. A process holding the private index decides at build time but has the text in the pipeline at query time. On private text, what separates the deployment from SD-RAG is the second condition, not the first.

(c) Authorization with inspection versus without ("Authorship and authorization are separate").

  • Release "by the entity's policy" authorizes a class of model drafts the author need not have read. Release by "the author's edit … or review" authorizes text the author has seen. The separation holds in both cases.
  • The Statement of need's thesis is that junctures be "held outside the model, where they can be checked rather than trusted." For the paraphrase boundary, that holds only in the second case.
  • Under policy release, the paraphrase boundary is drawn by the drafting model and accepted; that is what "owned by policy" amounts to. The canary sweep finding nothing among the phrases the author listed does not show that unlisted private phrases are absent.
  • Authorizing a class of drafts does not give the author control of their content.

Space:
The proposition the paper has already paid for is that the consumer type has no private-text variant and exposure is resolved before any query. It is true by construction once the union is shown. It is stated four times: in the Summary, the Statement of need, the novelty sentence, and Software design. JOSS sections overlap by design, so the repetition is not itself the problem. The problem is that every restatement repeats the build-time-and-type point, while the premises the decisive step needs get a clause or nothing:

  1. What makes project() the only route to a model, and keeps undeclared properties off its values.
  2. What constructs a LintedGist in the served process, where the text the lint needs has been blanked.
  3. What bounds the named residue in the deployment, given that rate limiting sits outside the package and the MCP endpoint is offered as impact.
  4. Whether any private fragment is served at semantic, and what the canary sweep covers and found.
  5. What the "test" found. The software is said to exist "to test" whether disclosure "can be made a property of the data rather than a filter on the output."

On the paper's own text, that answer is split:

  • For the form a hit takes: yes, and in the served artifact literally so.
  • For what a sequence of hits tells: no, and the contract assigns it elsewhere.

The paper never states this answer. The Summary and Impact read as an unqualified yes, and the remainder sits in one sentence in the middle of "One crossing." That sentence is among the most careful in the paper, and it is the one the conclusions most need.

What you are not saying:

  • I am not asking for more literature, more theory, or blanket qualification. The novelty sentence is hedged, distinguishes each neighbour it surveys, and holds against them.
  • I am not saying the type does no work. It is the checkable statement of the contract that the Statement of need asks for.
  • I am not saying the residue must be eliminated. Naming it is the paper's best move.
  • I am not saying the code has the TypeScript extra-property gap; I have not read the code. I am saying the paper credits the type with work that, in TypeScript, the implementation of project() and the strip would have to do.
  • I do not restyle, diagnose AI, recut, or offer replacement prose. Each item above is a candidate for adjudication, not a rule.

Checklist

  • npm test passes without an API key (the offline CI gate) — no hidden
    dependency on live calls (117 pass, 0 fail, 2 skipped)
  • npm run typecheck passes
  • No change that makes the eval pass by special-casing a question (no code or eval change)
  • A boundary stays structural (a type, not a checker someone must remember),
    if this touches the no-leak path (not touched)
  • Touched the prompt / retrieval / validation / repair? Ran the relevant
    npm run eval subset (not touched)
  • Read against .github/STANDARDS.md — the rubric a PR is judged by

🤖 Generated with Claude Code

https://claude.ai/code/session_01F2ti456guy1bXVmjA3fBTV


Generated by Claude Code

paper.md and paper.bib are the software paper for the v3 substrate, in
the Journal of Open Source Software form (Summary, Statement of need,
State of the field, Software design, Research impact statement, AI usage
disclosure, Acknowledgements, References; 1,720 words). It states what
the package contributes and no more: a disclosure-typed retrieval
contract in which the one representation a consumer can receive for each
fragment is fixed before any query, forbidden representations are
uninhabitable in the consumer-facing type, and the drafting of a released
description is separated from the authority to release it. It names what
the type does not fix (the residue a sequence of hits reveals; the strip,
not the type, keeps text off the wire in deployment; the served index is
trusted to descend from a validated private one) and it bounds what the
deployment shows: feasibility of one architectural claim in the
answerability papers, not evidence for the working paper's empirical
claim. The deployment serves private material at `locator`; `semantic`
is exercised by tests and demo.

The AI usage disclosure reports the default branch as of this commit:
169 commits, 69 authored as Claude, every change reviewed in a pull
request with an automated review, the offline tests, and the gold
evaluation as the gate. Refresh those numbers before submission.

README: the "formal write-up" is now the earlier technical note on the
v1 engine; the paper is the write-up for v3. Both citations keep their
DOIs. The paper is unsubmitted; the README says to cite the software DOI
until it has a venue.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01F2ti456guy1bXVmjA3fBTV
@surmado-code-review

Copy link
Copy Markdown
Contributor

Automated Checks (advisory, non-blocking)

✅ All checks passed.


Standards Compliance

  • The visible diff is documentation-only (paper.bib is new; the snippet does not show runtime code), so there is no direct standards-impacting change to the no-leak path, eval gate, or served/private index behavior in what I can see.
  • [UNVERIFIED] Because the snippet here does not include the paper.md / README.md hunks, the main standards check for this PR is claim discipline, not behavior:
    • docs should keep the repo’s own distinctions intact around the boundary, especially:
      • the strip keeps private text off the wire in deployment;
      • LintedGist / authored metadata are linted/trusted, not structural proofs;
      • semantic vs locator exposure claims should match what the deployment actually serves;
      • custody should be named, not overstated.
    • The PR description suggests you were careful about exactly those points, which is good; I’d still have the reviewer spot-check the final wording in paper.md and README.md against .github/STANDARDS.md and docs/CONTRACT.md before merge.

Summary

This PR appears to add the v3 software paper (paper.md + paper.bib) and update README.md so the older technical note is framed as the v1 write-up while the new paper becomes the formal v3 write-up/citation path. No library behavior seems to change; the main risk is documentation drift or overclaim in externally-facing descriptions of the disclosure contract.

Reviewer: most of the risk is in the factual accuracy of paper.md / README.md about the disclosure boundary and citation guidance — the code path itself does not appear touched.

What to pay attention to

  • paper.md
    This is now an external-facing description of the substrate, so wording matters more than usual docs text. I’d verify every sentence about project(), the served/private artifacts, gist linting, and deployment exposure levels matches the actual contract language in the repo.

  • README.md
    Check that the DOI/citation story is internally consistent: software DOI now, paper citation later, and the v1 technical note is demoted without implying it describes the v3 architecture.

  • paper.bib
    This is hand-maintained metadata and easy to drift. Worth a quick pass that keys, titles, DOIs/URLs, and manuscript citations all resolve cleanly in the actual paper render.

Things I noticed

  • No red flags in the diff shown. paper.bib is additive, and nothing visible here suggests a standards, runtime, or logging regression.
  • 🟡 [UNVERIFIED] The important review surface is in paper.md / README.md, but those hunks are not visible in the snippet. I therefore cannot independently confirm the final text avoids the specific overstatements called out in the PR description (type vs strip, lint implying “cannot quote,” deployment serving semantic, etc.).

Good patterns

  • Good restraint in the PR description: it explicitly narrows the paper’s claims instead of marketing the boundary more strongly than the code supports. That matches the repo’s standards well.
  • Including full bibliographic metadata in paper.bib (rather than placeholder refs) makes the manuscript much easier to validate and archive.

Suggested improvements

  • If you have not already, do one final manuscript render/check before merge so citation resolution is validated end-to-end, not just by inspection of paper.bib.
  • Do a last consistency sweep on time-sensitive facts called out in the PR text (AI-usage counts, venue status, citation guidance), since those can go stale immediately.

Questions for the author

  • The PR text notes the AI-usage disclosure counts should be refreshed before submission. Are the counts in paper.md intended to be tied to this merge, or are you planning a separate pre-submission refresh so the paper does not age as soon as it lands?

Surmado Code Review (v1.5-mt, review #1 on 8f1e6ef) is an automated review, designed to work alongside human judgment.

Want to change your STANDARDS.md or YML? Edit it directly, or tune it with our AI agent Scout.

Comment /rerun-review on this PR to re-review the current code with your latest STANDARDS.md and config — costs 1 additional PR credit (limit 3/hour per PR).

Copy link
Copy Markdown
Owner Author

Both suggestions done, no push needed.

Render: paper.md rendered end to end with pandoc 3.9 and citeproc, once with the default style and once with JOSS's own apa.csl: zero warnings, all 22 citations resolve, the reference list prints every entry with its DOI. Source body is 1,720 words; the rendered text (citations expanded to author-year) is 1,763, against JOSS's "significantly longer than 1750 may be asked to reduce" language.

Counts: the AI-usage numbers are tied to this commit's git log on main and the paper says "at the time of writing"; the plan is a pre-submission refresh (venue is decided at the Phase 6 checkpoint, no earlier than March 2027), not a number that has to stay current while the paper sits in the repo.

Wording spot-check against docs/CONTRACT.md and STANDARDS.md: the paper credits the strip, not the type, with keeping text off the wire in deployment; names LintedGist as what the lint constructs and says a served index is trusted to descend from a validated private one rather than re-linted; says the deployment serves locator and that semantic reaches it only as a policy change and a rebuild; and names the residue (which fragment answered, roughly how well) as assigned to rate limiting and policy rather than bounded by the type. The README demotion keeps both DOIs and says to cite the software DOI until the paper has a venue.


Generated by Claude Code

@lukefwalton
lukefwalton merged commit fa86081 into main Oct 8, 2026
3 checks passed
@lukefwalton
lukefwalton deleted the claude/archive-retrieval-substrate-jkpz9g branch October 8, 2026 02:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants