Repository navigation
Point vendor claims, routing, and the release gate at carelink-api-research - #102
Merged
Merged
Conversation
…search Medtronic publishes no API documentation, so every claim this bridge makes about CareLink rests on the sibling research repo. That repo was well linked in a few places (README, docs/vendor-api, ARCHITECTURE) and unlinked everywhere else, which left contributors with no route from the docs they actually read. Docs: - ROADMAP: cite the research map for the reports-API host/gateway evidence, the carepartner identity namespace, and the discovery pin; add a Tracking footnote pointing at the research repo as the vendor-surface source of truth. - ARCHITECTURE: link the discovery-pin and reports-API sections to the research pages that carry their evidence. - ADR 0002: add a Notes pointer to the canonical version matrix. The ADR is authoritative for the pin; the matrix is re-verified there. - CHANGELOG: the 2026-10-08/09 research pass narrates ~10 findings whose evidence lives in the sibling repo — link it once. - README: link "drift sweep" to the workflow that does it. Contributor routing (issue triage was the real gap — both repos had zero cross-mentions, so misfiled reports had nowhere to go): - CONTRIBUTING: is it a bridge bug or a vendor observation? The test is "if Medtronic did nothing, would it still be broken?". Adds a release step running the vendor suite before tagging. - bug.yml and PR template: vendor-moved triage and a vendor-surface impact checkbox. - SECURITY.md: split the channels — client vulnerabilities here via private advisory, vendor exposures to the research repo redacted. Automation: - `npm run drift:check` runs the research repo's regression suite from a sibling clone; non-zero blocks a release. - `npm run links:check` + a CI job verify every cross-repo link still resolves. Those links float on `main`, so a docs/ renumber there would otherwise 404 silently — exactly the rot this repo's own findings-log documents. Verified: npm run typecheck clean; 323/323 tests pass; links:check exit 0 (and exit 1 on an injected broken link); drift:check wrapper corrected to honour run.sh's bash shebang, full sweep 44/44 pass.
Two defects found reviewing the cross-linking pass. Both would have shipped silently, which is worse than the bugs they were meant to catch. check-links.mjs — CI was a no-op for the links it exists to protect. --online only fetched URLs with no file path (the repo root), so every blob/tree link fell through to the sibling-clone branch. CI checks out this repo alone, so 17 of 19 links were skipped and the tool still printed PASSED. Injected a guaranteed 404: exit 0. Now --online verifies every URL. Offline mode additionally requires the target to be git-tracked, so a file that exists in a working tree but is untracked (or gitignored) no longer passes — that is the exact class of breakage that 404s on GitHub while resolving fine locally. Unverified links now report as unverified rather than good, and the misleading "skip … only checked with --online" message printed while --online was active is gone. CONTRIBUTING — the release gate ran after the release. Steps were: tag, gh release create, then drift:check, described as blocking the release and as running "before tagging anything". The release was already published by the time the check ran. Moved to step 3, ahead of the merge and tag. Verified after the fix: offline and --online both exit 1 on an injected 404 and exit 0 clean; typecheck clean; 323/323 tests pass.
Review of the previous commit found the link gate had a false pass in the
exact configuration CI uses, plus several smaller defects.
check-links.mjs:
- `?template=` URLs were folded into a normal HTTP check, and GitHub
returns 200 for a template that does not exist (it falls back to a
blank form or a login redirect). Every contributor-funnel link — five
of them — was being reported good regardless of whether the issue
form was real. Now the template name is resolved against the sibling
clone and required to exist, and online mode reports those links as
unverified rather than ok.
- A `blob/main/...#section` link failed the offline check with a message
blaming the research side for a rename, while passing online, because
the fragment was left in the path. Fragments and query strings are now
stripped before the path is resolved.
- The repo name had no boundary assertion, so a link to a
`carelink-api-research-archive` was truncated to `…research`, which
resolves — a silent false pass. Added `(?![\w.-])`.
- fetch had no try/catch and no timeout: one DNS blip failed CI with an
unhandled rejection indistinguishable from a broken link, and a hung
connection would hold the job for GitHub's 6-hour default. Now bounded
at 20s, with network errors counted separately and labelled, because
the sister repo's own rule is that a network failure looks exactly
like vendor drift.
- SCAN_DIRS listed '.' alongside its own subdirectories, so the tree was
walked ~1.85x and the reported file count was inflated. Scanning also
skipped extensionless files — including .gitignore, which carries a live
cross-repo URL in a comment and is exactly the file you'd edit
alongside a rename.
- Failure output now names the files that reference the broken URL.
drift:check:
- Missing `hurl` made run.sh exit 1, which CONTRIBUTING described as
"Medtronic moved something under us" — a maintainer on a clean machine
would have blocked a release over a missing binary. Now preflights
`hurl` and `jq`, exits 2 with install hints, and says plainly that a
missing tool is not vendor drift.
- CONTRIBUTING did not disclose that this sends ~60 live read-only
requests to Medtronic's production servers, nor that a network failure
is not drift. Both now stated, with the two-consecutive-reds rule the
sister repo uses.
docs:
- docs/vendor-api/README.md said the bridge matches on model prefix
"rather than family token". That is stale — it predates the CC880
family-token match in src/carelink/client.ts and contradicts it. The
sister repo had started citing it as endorsement of its own corrected
note, so a stale doc was laundering a false claim into two places.
Corrected to describe the actual matcher.
- ROADMAP quoted a heading ("What a client must use") that does not
exist; the real one is "What a client must actually use". Deep-linked.
- SECURITY.md routed vendor exposures to a blob URL for a repo whose own
security page insists private advisories are the only tracked channel,
and pre-suppressed by saying the findings "already track these" when
F1 is deliberately held back. Now routes to their advisory intake.
- PR template asked outside contributors to run drift:check, which needs
a second repo and two binaries. Now scoped to maintainers with an
explicit n/a.
- CONTRIBUTING gained the dual-cause tiebreaker: when a problem is both
vendor motion and a client weakness, file both.
Verified: typecheck clean; 323/323 tests; links:check exits 0 clean and
1 on an injected 404, in both offline and --online modes.
Final review round. The remaining defects were mostly reporting gaps and copy-paste damage from the previous commit's edits. check-links.mjs: - Offline failures computed the "referenced by" list and then never used it. Every failure message except the --online one omitted it, which is the worst mode to lose it: "no such path" and "not git-tracked" are precisely the cases where you need to know which of 93 files carries the stale link. All five offline paths now include it. - The --online summary told the user to "Run with --online" while the user was already running --online, because the message hardcoded the offline reason. It now distinguishes the two causes — unverified because there is no sibling clone, versus unverified because GitHub answers 200 for a template that does not exist — and gives advice matching the mode. - The repo-root fallback printed "(repo root, checked via origin remote)" for URLs like security/advisories/new that are not repo roots, while reporting every link verified. It now says the page itself is not verifiable offline. - Comment said 1,176 files where .gitignore says 1,170. Aligned. PR template: the drift:check line ended in a colon with nothing after it, a visible truncation artifact. Now has the input block, matching the sibling repo's research-gate exit convention. docs/vendor-api/README.md documented running the suite with none of the caveats CONTRIBUTING now carries for the same thing — no hurl/jq prerequisite, no mention that it sends live traffic to Medtronic's production servers, and no warning that a network failure is not drift. The README is where the release docs send someone, so it needs the same caveats, not fewer. SECURITY.md: routed vendor exposures to carelink-api-research's private advisory intake. Checked — that repo does not have private vulnerability reporting enabled, so this pointed the most sensitive possible report at a channel that does not exist. Now routes to their SECURITY.md and says explicitly never to report an exposure here, redacted or otherwise. Verified: typecheck clean; 323/323 tests; links:check exits 0 clean and 1 on an injected 404 offline and online.
Counted the actual hosts the suite touches: nine, not seven (eight appear in the .hurl suites, and 05-public-config.check.sh adds carelink.medtronic.eu). The "seven" figure came from the research repo's own drift-sweep.yml and was never right; it should not propagate into this repo's runbook as fact. "read-only" was also imprecise — run.sh sends two pinned POSTs in 04-deep-surface.hurl. Both are expected to be refused server-side and are documented in the research repo, but describing vendor traffic needs to be exact. Also: missing EOF newline on scripts/check-links.mjs, and a 95-column prose line in docs/vendor-api/README.md reflowed to the file's ~78.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Medtronic publishes no API documentation, so every claim this bridge makes about CareLink rests on a separate research repo. That repo was linked from a few places (README,
docs/vendor-api,ARCHITECTURE) and unlinked everywhere else — so a contributor readingROADMAP.md, an ADR, or an issue template had no route to the evidence behind the claim in front of them, and no way to know that a vendor change belongs in the research repo rather than here.Docs
docs/vendor-api/README.mdcarries the actual caveats for running the suite (see below), and its stale "model prefix rather than family token" sentence — which predated theCC880family-token match and contradictedsrc/carelink/client.ts— is corrected.Contributor routing
Issue triage was the real gap: both repos had zero cross-mentions, so a misfiled report had nowhere to go.
bug.yml/ PR template — vendor-moved triage and a vendor-surface impact checkbox.Automation
npm run drift:checkruns the research repo's regression suite from a sibling clone. It preflightshurl/jqand exits 2 with install hints, so a missing binary can never be misread as vendor drift.npm run links:check+ a CI job verify every cross-repo link still resolves. These links float onmain, so a docs renumber on that side would otherwise 404 silently — the exact rot this repo's own findings-log documents.Defects found in review
Three rounds of adversarial review. The link gate is worth calling out: in the configuration CI actually uses,
--onlineonly fetched URLs with no file path, so 17 of 19 links were skipped and it still printed PASSED — an injected guaranteed-404 returned exit 0. It now verifies every URL online, and offline it additionally requires the target to be git-tracked (a file present in a working tree but untracked 404s on GitHub). Also fixed:?template=links, which GitHub answers 200 for even when the template does not exist.Verification
typecheck clean · 323/323 tests ·
links:checkexits 0 clean and 1 on an injected 404, in both offline and--onlinemodes.🤖 Generated with Claude Code