Add SafeSkill security badge (73/100 — Passes with Notes)#1
Conversation
| @@ -1,5 +1,7 @@ | |||
| # rosetta | |||
|
|
|||
| [](https://safeskill.dev/scan/tikoci-rosetta) | |||
There was a problem hiding this comment.
Optional: this badge image is loaded from a third-party host (img.shields.io), so viewing the README triggers an external request (availability + visitor IP logging). If you prefer to avoid third-party requests, consider committing a local SVG or using a GitHub-hosted asset.
| [](https://safeskill.dev/scan/tikoci-rosetta) | |
| [SafeSkill: 73/100 (passes with notes)](https://safeskill.dev/scan/tikoci-rosetta) |
| @@ -1,5 +1,7 @@ | |||
| # rosetta | |||
|
|
|||
| [](https://safeskill.dev/scan/tikoci-rosetta) | |||
There was a problem hiding this comment.
Optional: the badge hard-codes a specific scan score (73/100) and status/color. This can become stale over time; consider a generic “SafeSkill scan” badge or a dynamic badge endpoint that reflects the latest scan result.
| [](https://safeskill.dev/scan/tikoci-rosetta) | |
| [](https://safeskill.dev/scan/tikoci-rosetta) |
|
we should review the report that was produced, not advertise. perhaps there scan identified something useful. however, it conflating our build code (e.g. parsing HTML, schemas, etc,) in CI with code that is actually part of the MCP server that's shipped. |
Audit ran from `lsp-routeros-ts` against `canonicalize.ts` to validate "vendor it for prose extraction" — found zero crashes across 50 inputs but several wrong-but-quiet failure modes when fed arbitrary text (MCP input, doc snippets, scheduler one-liners with markdown noise). Audit doc: https://github.com/tikoci/lsp-routeros-ts/blob/main/docs/canonicalize-audit.md This commit ships only the safe, low-risk fixes — those that don't change the API surface and don't regress the existing 61 tests: 1. **Tokenizer: BOM strip + backtick/ZWSP as whitespace.** Leading U+FEFF is dropped before parsing. Backtick (`) and U+200B are skipped in both the outer tokenize loop AND the word-inner loop (the missing word-loop break was why an earlier single-line fix didn't actually clean trailing markdown markers). Closes audit findings #5 and #9. 2. **`GENERAL_COMMANDS` expansion.** Adds `clear`, `unset`, `reset-counters`, `reset-counters-all`. Each cross-checked against the production `commands` table: every occurrence is `type='cmd'` with no path collisions. Closes the universal-verb portion of audit finding #4. Notably NOT added: `info`, `warning`, `error`, `debug`. The DB shows `/error` is itself a top-level cmd, `info` is a *dir* at `/interface/wireless` (and arg under `/ip/pool/used/reset/info`, etc.), and `debug` is an arg under several `print` paths. Adding them universally would mis-resolve real paths. Their resolution needs a path-aware backend — tracked as audit hardening H4 (pluggable `isVerb` resolver, with rosetta wiring it to a SQL query against `commands`). 3. **`src/canonicalize.fuzz.test.ts` (new file).** 37 expect-style tests + 9 `test.todo` markers, ported from the throwaway probe scripts. Three patterns: - "no throw" probes — crash-resistance safety net for malformed input (unclosed quotes/brackets, stray `]`, etc.) - regression tests for the shipped fixes (H7, expanded verbs, backtick whitespace) - **anchor tests** documenting current known-bad behaviour for audit findings #1, #3, #4, #7, #8 — flip these when a hardening lands rather than discovering the regression elsewhere - `test.todo` for the unshipped H1–H8 hardenings — `bun test` output is the running scorecard Test count for the canonicalize pair went 61 → 98 pass / 9 todo / 0 fail. Original 61 tests unchanged. Audit also includes a "Two backends, one parser" alignment section covering the rosetta-DB / LSP-live-inspect / static-JSON tradeoff — recommended next step is the `isVerb` callback option (H4) so each consumer can wire its own backend without forking the parser. Tracking issue with the full H1–H8 roadmap will follow this commit. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Addresses the Codex POV review on PR #113: P1 #1 — db-sync could report success without installing its selected release. downloadDb's lock-contention path reused any schema-compatible DB before honoring urlsOverride. When an explicit override is passed (db-sync), it now skips the reuse shortcut, waits for the lock to release, re-acquires it, and downloads the requested release. P1 #2 — "newest release matching this checkout's schema" is now actually implemented. db-sync passes the whole ordered candidate list (newest first) to downloadDb, which validates each schema and walks down to the newest release that matches — so an older checkout still resolves a compatible DB below a newer, higher-schema release. P1 #3 — incomplete provenance no longer produces grounding ok. New `provenance_incomplete` status: a DB claiming release identity but missing any of the four CI stamps (release_tag/source_commit/built_at/ schema_version), or a stamped-but-unparseable version, now fails closed. built_at is thus load-bearing, not informational. P2 #4 — "ok" is described as schema/release-compatible, not "matches the code": softened the routeros_stats description + verdict docs; noted a release DB is built from an ancestor commit. P2 #5 — the TUI stats screen now renders the grounding verdict line, so the "TUI inherits the verdict" claim holds. Tests: paths.test.ts gains provenance_incomplete cases; db-sync anchor asserts the ordered-list handoff; query.test.ts provenance test is now db_meta-deterministic. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
searchVideos() limited transcript rows before the caller deduped them by video, so a video with several matching segments consumed the top-`limit` rows and hid distinct videos ranked just below the cutoff — "firewall filter" returned 8 unique videos of 10 while limit 20 found 15. runVideosFtsQuery now picks the best-ranked segment PER VIDEO before applying LIMIT. fts5 snippet() can't run alongside a window function, so it's two bounded steps: a ROW_NUMBER() window query selects one segment per video ordered by rank, then a second MATCH fetches excerpts for just those rowids. Live DB: "firewall filter"/"vlan bridge" now fill 10/10 unique at limit 10; changelog target stays #1. Adds a dedup regression test (one video with 3 matching segments must not crowd out another). Also switches the videos_fts excerpt to snippet(..., -1, ...) so it reflects whichever column (title or description) matched. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Top Findings
bin/rosetta.js:24)scripts/build-release.ts:16)scripts/build-release.ts:94)scripts/build-release.ts:110)scripts/build-release.ts:115)View full report on SafeSkill
About SafeSkill
SafeSkill is a free, open-source security scanner for AI tools, MCP servers, and Claude Code skills. We scan for code exploits, prompt injection, and data exfiltration risks.
False positive? We take accuracy seriously. If any finding above is incorrect, please open an issue and we will fix it immediately.