Skip to content

Use the kit on the kit: close ADR-0035's named gap, and the stale claims found on the way - #38

Merged
StepenkoAnatoli merged 1 commit into
mainfrom
docs/close-the-named-gaps
Sep 21, 2026
Merged

StepenkoAnatoli merged 1 commit into
mainfrom
docs/close-the-named-gaps

Conversation

@StepenkoAnatoli

Copy link
Copy Markdown
Owner

Two gaps closed, and the second was found by asking the repository what it still admitted
to rather than by remembering.

1. Five documents said something that had stopped being true

ADR-0031, ADR-0033 and the delivery corpus all still said the runner-side install path
"has never executed." It has — twice (runs 35600022797, 35608301287), both with
install the vendor CLI and the CLI is a major this adapter supports succeeding.

Corrected in the live documents. The dated records are left alone: the preliminary note
and live-predicate-verification were true the day they were written and say so in their
titles, and a record that is quietly revised stops being a record.

Worth naming as a kit gap rather than only fixing: nothing detects a claim overtaken by
events.
corroboration now sees single-sourcing; nothing sees "this says X never
happened, and X happened."

2. ADR-0035's own open question — answered, uncomfortably

That ADR closed with a section headed "What is NOT measured, and is therefore not
claimed"
: what a signed-in user sees, as against the anonymous caller it had probed.

Collected through the collector itself, dispatched via bin/collect-remote.mjs (the
agent path) as run 35620262684:

"You must be logged in to a GitHub account to view workflow run information, including
for public repositories
."

Viewing logs, searching logs, downloading logs and downloading artifacts each require
only "read access to the repository."

On a public repository read access is universal. So any person with a free GitHub
account can open a collector run, read the logs — which echo the dispatched topic in the
env: group the runner prints — and download the artifact, which is the entire corpus.

The 401 and 403 ADR-0035 measured are refusals of anonymity, not of strangers. The
measurement was accurate about what it measured; the population it measured is not the
population that matters.

What changes, and what doesn't

  • The naming rules are demoted, not discarded — they cover the anonymous surface and
    nothing past it.
  • retention-days: 7 was already set and now has a recorded reason: it bounds the
    window and removes nothing. The comment says so, instead of leaving seven days looking
    like a tidy default.
  • Staying public stands. That was decided on plan grounds — a free private repository
    has its environment secrets and variables ignored, so going private breaks the collector
    rather than protecting it. Untouched. What changes is the caveat: not "the exposure is
    limited to shape"
    but "the exposure is total to anyone with an account, and the remedy
    is a paid plan, not a toggle."

The kit under its own new check

The corpus reports four corroboration warnings — three single-source, one
one-voice, all docs.github.com — and they are left standing rather than argued
away
. This is GitHub describing its own permission model: authoritative, and not a second
opinion. The check is right and the research is worth having, which is exactly the
judgement ADR-0036 said it would leave to a reviewer.

Verification

Committed at docs/decisions/2026-09-21-public-run-visibility/ per ADR-0030, ledger
included.

nested   PASS  0 blocking, 4 warning(s), 12 passing
handoff  OK — 3 ledger entries, chain verifies
repo     829 passed, 0 failed · preflight PASS

Cost: 4 credits.

🤖 Generated with Claude Code

…aims while doing it

Two gaps closed, and the second was found by asking the repository what it still admitted
to rather than by remembering.

1. STALE CLAIMS: FIVE DOCUMENTS SAID SOMETHING THAT STOPPED BEING TRUE

ADR-0031, ADR-0033 and the delivery corpus all still said the runner-side install path
"has never executed". It has, twice - runs 35600022797 and 35608301287, both with
`install the vendor CLI` and `the CLI is a major this adapter supports` succeeding.

Corrected in the live documents; the DATED RECORDS are left alone. The preliminary note
and live-predicate-verification were true on the day they were written and say so in their
titles, and a record that is quietly revised stops being a record. ADRs take dated
amendments instead, which is this repository's established pattern.

Worth naming as a kit gap rather than only fixing: nothing detects a claim overtaken by
events. `corroboration` now sees single-sourcing; nothing sees "this says X never
happened, and X happened".

2. ADR-0035's OWN OPEN QUESTION, ANSWERED - AND IT IS THE LESS COMFORTABLE ANSWER

That ADR closed with a section headed "What is NOT measured, and is therefore not
claimed": what a SIGNED-IN user sees, as opposed to the anonymous caller it had probed.
Collected through the collector itself, dispatched via bin/collect-remote.mjs - the agent
path - as run 35620262684.

  "You must be logged in to a GitHub account to view workflow run information, including
  for public repositories."

  Viewing logs, searching logs, downloading logs and downloading artifacts each require
  only "read access to the repository".

On a public repository read access is UNIVERSAL. So any person with a free GitHub account
can open a collector run, read the logs - which echo the dispatched topic in the `env:`
group the runner prints - and download the artifact, which is the entire corpus.

The 401 and 403 ADR-0035 measured are refusals of ANONYMITY, not of strangers. The
measurement was accurate about what it measured; the population it measured is not the
population that matters.

WHAT CHANGES, AND WHAT DOES NOT

The naming rules are demoted rather than discarded - they cover the anonymous surface,
listing-scrapers and a glance over a shoulder, and nothing past it. `retention-days: 7`
was already set and now has a recorded reason: it bounds the window and removes nothing,
and the comment says so instead of leaving seven days looking like a tidy default.

Staying public STANDS. That was decided on plan grounds - a free private repository has
its environment secrets and variables ignored, so going private breaks the collector
rather than protecting it - and this finding does not touch that. What changes is the
caveat: not "the exposure is limited to shape" but "the exposure is total to anyone with
an account, and the remedy is a paid plan rather than a toggle".

THE KIT UNDER ITS OWN NEW CHECK

The corpus reports four corroboration warnings - three single-source, one one-voice, all
docs.github.com - and they are left standing rather than argued away. This is GitHub
describing its own permission model: authoritative, and not a second opinion. The check is
right and the research is still worth having, which is exactly the judgement ADR-0036 said
it would leave to a reviewer.

Committed at docs/decisions/2026-09-21-public-run-visibility/ per ADR-0030, ledger
included. From the nested root: PASS 0 blocking, 4 warning(s), 12 passing, and handoff OK
- 3 ledger entries, chain verifies. Repository 829 passed, preflight PASS. Cost: 4 credits.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@StepenkoAnatoli
StepenkoAnatoli merged commit 6a281e8 into main Sep 21, 2026
3 checks passed
@StepenkoAnatoli
StepenkoAnatoli deleted the docs/close-the-named-gaps branch September 21, 2026 15:53
StepenkoAnatoli pushed a commit that referenced this pull request Sep 28, 2026
What changed: lib/http-transport.mjs hrefOf(attribute) decodes an href
attribute's entities. search uses it on result links and on the fallback
links, before the DuckDuckGo redirect is unwrapped. map reads the whole
attribute, decodes it, skips a link to a section of the same page, and
drops the fragment from the page any other link names.

Why: Arena break test 8. An href is HTML, so `?a=1&amp;b=2` means b=2.
Taken raw, search and map returned URLs whose second parameter was
"amp;b", and a scrape of one fetched a different page. map's pattern
`[^"'#]+` also refused any href containing '#', so `&#38;` and every link
to a section of another page (`/docs#limits`) were silently dropped.

What it touched: research-kit/lib/http-transport.mjs,
research-kit/test/transport.test.mjs, the http-transport.mjs row of
docs/ARCHITECTURE.md, the README test count (1159). No ADR: one remedy.

What you verified: reproduced on main (both kept `&amp;`; map dropped the
`&#38;` and `#section` links). The new test covers a result link, a
DuckDuckGo redirect with `&amp;rut=`, a bare link, and map's entity,
fragment, same-page and other-host cases. It is red on main and green with
the fix. Full suite 1159 passed from /home/user/Research-Kit; preflight
PASS.

What you got wrong and fixed: nothing to report.

Reported-by: Arena break test 8
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S1fT6wSqD2LwRjsUuRvDau
StepenkoAnatoli pushed a commit that referenced this pull request Oct 3, 2026
…r the link stands

What changed: `inline()` in lib/http-transport.mjs no longer decodes a link's label inside
the link pass; the label is kept as written and decoded once at the end with everything
else, and its emptiness is judged on the decoded text, so a `&nbsp;`-only link is dropped in
a list item as it was in a paragraph. `decodeEntities` decodes hex, decimal and named
references in one pass instead of three in turn. The regex oracle in
test/fixtures/regex-extract.mjs carries both rules.

Why: the review of the G3 fix (output-reliability audit) found the page-level pass still
decoding a link label on its own before the tag-stripping pass that follows it, so
`<p>See <a href="/x">limit &lt; 10 and burst &gt; 2</a> now.</p>` came out
`See [limit 2](/x) now.` and `<a>a &amp;lt; b</a>` came out `[a < b]` - the G3 defect,
alive in the one place its test did not look (a paragraph or a div). Two smaller findings
from the same review are folded in because they are the same rule: the emptiness test ran
on the undecoded label, so `<li><a>&nbsp;</a></li>` kept a `[ ](/x)`; and `&#38;lt;` was
decoded to `&lt;` and then to `<`, since the numeric passes ran before the named one.
Alternative set aside: decoding the label and escaping its `<` for the stripping pass, which
would make the converter's output depend on which pass a character came through.

What it touched: research-kit/lib/http-transport.mjs (`decodeEntities`, `inline`),
research-kit/test/fixtures/regex-extract.mjs (the oracle, same two rules),
research-kit/test/transport.test.mjs (one test: paragraph and div links, the double-encoded
label, the blank link, the numeric ampersand), docs/ARCHITECTURE.md (http-transport row),
CHANGELOG.md, research-kit/README.md (1548 tests). No new term.

What you verified:
- the new test red before the fix: `See [limit 2](/x) now.` - verified.
- `node research-kit/bin/selftest.mjs transport http-linear`: 106 passed, 0 failed, so
  the 3,000-page oracle equivalence still holds with the extended rules - verified.
- the full suite runs in the commit gate on this commit - verified by the gate before this
  commit is accepted.
- staged diff scanned for keys and the pasted token: 0 - verified.

What you got wrong and fixed:
- mistake: the new test expected `- item\n\npara` for a paragraph whose first child is a
  dropped blank link, but the converter leaves the space that followed the link, ` para`.
- where: research-kit/test/transport.test.mjs, the blank-link assertion.
- impact: a red assertion about behaviour this commit does not change; nothing delivered.
- cause: I wrote the expectation from the fix's intent, not from the converter's output.
- fix: the assertion matches the list item, the paragraph with an optional leading space,
  and the absence of any empty link.
- verified: `selftest transport http-linear` 106 passed, 0 failed.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S1fT6wSqD2LwRjsUuRvDau
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.

1 participant