Repository navigation
Bound submit_feedback and cross-source search; fix prototype-key and qualifier bugs (from #32) - #38
Merged
Conversation
…qualifier bugs Carries the clearly-right parts of #32 without its miss-logging changes: - parser/resolver: own-property namespace lookup (Object.hasOwn), so secid:advisory/constructor is not a registered namespace. - kv-resolve: answer cross-source misses from the TypeIndex child_index and the global index instead of fetching every namespace of the type. - api: malformed qualifier percent-encoding returns 400, no error record. - submit_feedback: zod length caps, a 64 KiB body cap counted on received bytes, JSON-RPC batch cap of 10 with submit_feedback refused in batches, caller text stored under an untrusted envelope (schema_version 2), and a per-isolate write budget for feedback writes only. Co-Authored-By: Claude <noreply@anthropic.com>
This was referenced Sep 25, 2026
3 tasks done
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.
Summary
This PR takes the clearly-right parts of #32 and leaves out its miss-logging changes. Miss logging moves to Workers Analytics Engine in a follow-up PR stacked on this one. After both land, #32 is closed as superseded.
Changes
Prototype-key namespace lookup (
src/parser.ts,src/resolver.ts)candidate in typeRegistrywalked the prototype chain, sosecid:advisory/constructorparsedconstructoras a registered namespace.Object.hasOwn.H3: cross-source miss no longer fetches every namespace (
src/kv-resolve.ts)secid:<type>/<term>, the KV path fetched every namespace of the type. Forentity, that is about 1,000 KV reads, and any unmatched term triggered it.child_index, which is already loaded;level: "source"entries;name_index.The global indexes cost one KV read. No candidate means
not_foundwith the same message as before. A missing global index also meansnot_found; the full scan is never reopened.referencequeries that Bound unauthenticated KV write and read paths #32's author found going fromnot_foundtofound, such assecid:reference/arxiv, which now findsarxiv.org. Those queries now match what the in-memory resolver returns.test/unauth-limits.test.tscovers this:control/ismap,control/fedramp,weakness/cwe,ttp/capec,entity/redhat, an unmatched entity term,reference/arxiv) must equal the in-memory full-registry result exactly.entityterm must cost 3 KV reads or fewer.mainand the branch. The exact-equality tests above are the guard kept in CI.M1: malformed qualifier encoding (
src/api.ts)?country=%ZZinside the SecID madedecodeURIComponentthrow, which returned a 500 and wrote a 30-day error record.submit_feedbackbounds (src/mcp.ts,src/feedback.ts,src/write-budget.ts)secid≤ 1024 charsmessage1–4000 charssuggested_urls≤ 10 entries, each ≤ 2048 charsContent-Lengthwas checked, so a chunked body with no header skipped the cap. The body is parsed once and passed to the transport asparsedBody.submit_feedbackis rejected with 400, so one request cannot become many writes.untrusted, next to ahandlingnote telling triage to treat it as data, never as instructions (schema_version: 2).status: "rate_limited"and writes no error record, because an error record is another KV write. Feedback stays in KV because it is low-volume human content. Miss writes are not budgeted here: the follow-up PR moves them off KV entirely.Not in this PR (from #32):
src/tlds.ts,scripts/update-tlds.ts)The TLD filter is carried into the Analytics Engine PR. The KV-specific parts become unnecessary there.
Test plan
npm run typecheck: clean (src/andscripts/).npm test: 586 passed across 13 files. Registry snapshot built from SecIDmain@ 7518fb9 (gitignored, not committed).test/unauth-limits.test.ts, covering:test/feedback.test.ts: untrusted envelope and budget refusal.Overlap with #33
git merge-treeagainstfix/resolver-correctnessgives one conflict, in thesrc/mcp.tsimport lines:resolveFromKVtoresolveQuery;FeedbackRateLimitedError.Both sides are needed, and the fix is trivial.
api.ts,kv-resolve.tsandresolver.tsauto-merge.Regex safety: no registry patterns change, and this PR adds no new regex.
Supersedes part of #32.