Repository navigation
Description
Filed by the #2792 Phase 3 closing audit (queue task 4373, 2026-10-31). The audit swept the repo's TS/JS/mjs for plain-object tables indexed by a dynamic key (vendored assets excluded). The sites below are indexed by keys spelled from outside the process — live request input, ingested API/config data, documents, or issue text — with only an undefined / ?? / truthiness miss guard, so a prototype spelling (constructor, __proto__, toString, …) resolves to an inherited member instead of taking the site's miss path. Same class as #2787 / #2734 / #2781 / #2790 / #2757; the fix at each site is the #2792 rule: Object.hasOwn(table, key) at the read site (or a Map / null-prototype table), with the shared probe matrix asserted equal to unknown-key behaviour. Each site is small; they are grouped here because the audit is one pass — split per site if triage prefers.
pm-stack/aggregator — ingested-data keys
src/aa.ts:350—AA_EFFORT_ORDER[effort.toLowerCase()] ?? 50: effort names from ingested AA data;constructoryields the Object constructor instead of the 50 default (numeric context → NaN risk).src/aa.ts:859—AA_PLAN_FACTS[providerId](used asfact?.note): provider ids from provider config/data; a prototype-spelled id yields a function as the "fact".src/aa.ts:886—AA_GO_CAPS[norm] ?? null: normalized provider id, same shape.src/aa.ts:998—CAI_CREATORS[slug.toLowerCase()] ?? slug: creator slug from data; prototype spelling yields a function as the creator string.src/derive.ts:760-761—PRIORITY_ORDER[(priority ?? "normal").toLowerCase()] ?? 2: priority strings derive from issue/label data; prototype spelling defeats the?? 2fallback and poisons the sort comparator with a function (NaN ordering).src/quota-current.ts:283—TURSO_WINDOW_META[w.name]guarded byif (!meta …) continue: window names from Turso data;constructorpasses the truthiness guard and emits a metric with undefined label/limit/unit. (Sibling of aggregator(quota-gather-map): plain-object lookups return prototype members as window metadata — a window named 'constructor'/'__proto__' gets a fabricated windowSeconds, and a Turso window with such a name fabricates a snapshot record with no unit/limit #2781, different file.)src/sources/live.ts:127—KANEO_PROJECT_REPOS[p.slug] ?? fallback: project slugs from the Kaneo API.src/sources/live.ts:446—TITLE_REPO_ALIASES[m[1].toLowerCase()]: keys regex-captured from issue titles.src/quota-extract.ts:367,386—POOL_DOOR_PROVIDER_ID[poolId] ?? …,POOL_DOOR_PROVIDER_IDS[poolId] ?? …: pool ids from ingested quota data; prototype spelling returns a function where a provider-id string/array is expected.
bin/ proxies — live request / document keys
bin/antigravity-ls-proxy.mjs:125-136—MODEL_MAP[cand](?.enumand a direct read): candidate model names from live request traffic.bin/muse-proxy.mjs:260—CLI_FLAG_PLAN[sub]: CLI flag tokens spelled by the caller.:1064DIRECT_TOOL_ALIASES[name],:1068DIRECT_TOOL_NAMES[name] || name: tool names from client requests —constructorresolves to the Object constructor as a tool name/alias.bin/opencode-route-proxy.mjs:178—BUILTIN_PROVIDERS[id] || null(and:169cfg.providers[def.instanceOf], a JSON.parse'd config object): provider/instance ids from config and requests.bin/provider-catalog-sync.mjs:364—BRANDS[tok.toLowerCase()]truthiness return: tokens from catalog documents.
Acceptance
- Each site above either gains an own-key guard at the read site (miss semantics unchanged for genuinely unknown keys) or is dispositioned in a comment with evidence that its key cannot be prototype-spelled.
- Probe matrix (
constructor,__proto__,toString,hasOwnProperty,valueOf, + case variants where the site normalises case) asserted equal to unknown-key behaviour at each fixed site, per design(own-key lookups): a plain object is not a map for untrusted keys — one own-key rule for every dynamic lookup #2792 corollary 2. - No behaviour change for real keys at any site.
Related: epic #2792 (Phase 3 audit), #2787 (the rule's embodiment). Sites the audit dispositioned internal-only (allowlist-guarded dispatch repo tables, mcpx OPS literals, regex-bounded MONTHS, aggregator render enums, fixture tables) are named in the closing-audit comment on #2792 and are NOT in scope here.
Acceptance criteria
- Every site listed in the body (aggregator
src/aa.tssites and the bin proxy sites) reads its table withObject.hasOwn(table, key)(or a Map / null-prototype table), per the design(own-key lookups): a plain object is not a map for untrusted keys — one own-key rule for every dynamic lookup #2792 rule. - A prototype-spelling probe (
constructor,__proto__,toString) at each site behaves identically to an unknown key (the site's miss path), asserted by tests using the shared probe matrix. - No behavior change for legitimate keys: existing aggregator/proxy tests pass in CI.
Activity
dezren39 commentedon Oct 31, 2026
Intake review
Fleet monitor intake pass (2026-10-31).
Related: Filed by the #2792 Phase 3 closing audit (queue task 4373); same bug class as #2787 / #2734 / #2781 / #2790 / #2757, rule established by #2792. No merged PR found referencing #3106 — verified live.
Notes: Well-evidenced as filed (file:line per site, fix shape named). It had kind/priority but no acceptance criteria, effort, or status; now set. Grouped-site filing is reasonable; the body itself offers per-site splitting if triage prefers.
Risks: Low per site — the miss-path change is the point. The one caution: any site where an inherited-member result is accidentally load-bearing would surface as a behavior change; the probe-matrix tests should catch it.
Suggested approach: One small-fix pass over the listed sites with the shared probe matrix asserted per site; split per site only if the diff grows.
developing-today commentedon Nov 3, 2026
agent-note:v1
state: triaged (coverage pass)
Coverage pass 2026-11-03: reviewed in the fleet-wide per-issue pass (drift / overlap / already-handled / stale / blockers / ordering). Verdict: still live; queued in repo-health-code-pilot as triage at priority 40 (priority/normal). If this is already handled at current main, the triage closes it with evidence; if it needs splitting, the triage files the split.
Found via: coverage pass 2026-11-03
61 remaining items
dezren39 commentedon Nov 5, 2026
🤖 Agent note · handed off
dezren39 commentedon Nov 5, 2026
🤖 Agent note · handed off