From 072bf65ad60e677667cf2cf6ccac2edecb921798 Mon Sep 17 00:00:00 2001 From: Charles Kelsoe Date: Fri, 7 Aug 2026 11:50:28 -0400 Subject: [PATCH 1/4] CI and doc hardening: release lint, source-wide deprecated-API scan, VirusTotal links, brace-expansion floors, doc drift Repo and CI gaps from the handoff, none blocking but all real. - release.yml: run npm run lint before build. CI lints every PR, but a tag can be pushed at a commit CI never covered, so the release could cut an unlinted build. Runs before build because check-submission scans sources. - release.yml: give the VirusTotal step an id and fold its analysis URLs into the release notes. The scan ran before the release was created and its links were only in the workflow log; they now land on the release itself. Passed via env, guarded on a non-empty CHANGELOG-derived notes file. - ci.yml: the deprecated-API scan now covers every source .ts, not the main.ts entry point alone, so a deprecated call in any other module is caught. Sources rather than the minified bundle, which rewrites getLeaf(true) to getLeaf(!0). - package.json: raise the brace-expansion override floors to 1.1.18 / 2.1.4, the versions patched for GHSA-rgw5-rvv9-x895. The old floors (1.1.13 / 2.0.3) sat below the patch, so the override permitted a vulnerable resolution even though the current tree is already patched. - README.md: document Clear orphaned stars and the once-per-note broken-marker warning, both shipped but absent from the feature list. - copilot-instructions.md: the marker format escapes the opener as well as the terminator, and check-submission also rejects regex lookbehind. Both landed in #30/#31 and the instructions still described the old behavior. --- .github/copilot-instructions.md | 6 +++--- .github/workflows/ci.yml | 14 ++++++++++---- .github/workflows/release.yml | 30 ++++++++++++++++++++++++++++++ README.md | 4 +++- package.json | 4 ++-- 5 files changed, 48 insertions(+), 10 deletions(-) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 0308397..c36e311 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -111,7 +111,7 @@ it landed as a shock to the whole team - ID: 8-character lowercase base36 string. - Anchor text: the SELECTION capture caps at 80 visible characters, mid-truncated with `…`. `serialize()` enforces a separate 200-character ceiling on the escaped value, and the parser accepts any length so an anchor written by hand or by an older build is read rather than silently dropped. Two limits, two jobs: 80 is the capture budget, 200 is the format's. - Replies are sorted chronologically by timestamp on read; file order is the tiebreak for equal timestamps. -- The `-->` sequence cannot appear literally in any free-text field, because it closes the HTML comment wrapper. `parser.ts` escapes it as `--\>` on write and restores it on read, for the body, `[anchor=...]`, reply bodies, the addressed and resolved notes, and the `annoteca-original` fence. Anything that writes a marker must go through `serialize()`; do not hand-build one. +- Neither `` can appear literally in any free-text field, because `` closes the HTML comment wrapper. `parser.ts` escapes them as `\` is escaped by `serialize()`, not forbidden.** Every free-text field round-trips through `escapeTerminator` / `unescapeTerminator` in `parser.ts`. Do not add a caller-side check that rejects `-->`, and do not write a marker without going through `serialize()`. +- **`` are escaped by `serialize()`, not forbidden.** Every free-text field round-trips through `escapeOpener` and `escapeTerminator` (and their unescape twins) in `parser.ts`. Do not add a caller-side check that rejects either sequence, and do not write a marker without going through `serialize()`. An unescaped `