Skip to content

audit(core): prototype-chain dictionary lookups — systematic sweep, shared guard, regression net #833

Closed

Description

@dezren39

Problem

Plain-object dictionary lookups that read through the prototype chain keep
recurring in the fork's core. Ten instances have been filed individually —
a lookup keyed by an external string (a plan name, effort name, route
name, header, table name) hits constructor / toString / __proto__
and returns an inherited value instead of missing. Fixes are landing
one at a time (a per-site Object.hasOwn guard, e.g. PR #794), and the
class keeps producing new instances faster than the drip closes it.

Known instances (verify current status at triage): #774, #791, #792,
#793, #804 (fixed), #805 (fixed), #819 (fixed), #824 (fix PR open),
#830, #831. #831 shows the sharpest symptom so far: a route named
'constructor' crashes the governance gate outright.

Proposal

Stop fixing these one by one:

  1. Sweep: grep-driven audit of packages/core (and other packages
    with externally-keyed plain-object reads) for the pattern classes:
    obj[key] / obj[key] ?? fallback where obj is a plain object or
    object literal used as a dictionary and key is externally supplied
    (names from config, plans, providers, routes, efforts, headers).
    File or fix each hit.
  2. Shared guard: one blessed way to do dictionary reads — a helper
    (own-property lookup) or a convention (Map / Object.create(null) /
    Object.hasOwn) applied at the sweep sites, so the next author copies
    the safe shape.
  3. Regression net: a lint rule or a targeted test convention that
    flags new bare dictionary reads on plain objects in core, so the
    class stays closed.

Acceptance

  • The audit's search patterns and hit list are recorded on this issue.
  • Every confirmed hit is fixed or split into its own issue.
  • The shared guard exists and the sweep sites use it.
  • A lint/test mechanism (or a documented reason one is impractical) is
    in place.

Filed by the operator after the tenth instance (#831) landed; the
individual fix issues remain the lanes' work — this issue owns the
class, not the instances.

Acceptance criteria

Activity

  1. developing-today commented on Oct 29, 2026

    @developing-today
  2. dezren39 commented on Oct 29, 2026

    @dezren39
    Author

    agent-note:v1
    state: filed
    Agent: main (operator)
    Found via: the tenth prototype-chain instance (#831) filed 2026-10-29;
    operator filed this umbrella so the class gets closed, not just the
    instances. Triage: verify each listed instance's status, pin the sweep
    patterns, and route the guard + sweep as follow-up packets.

  3. added
    queue/queuedHas a queued task in the Supabase agent queue
    source/creatorFiled by the new-issue-creator job
    task/triageQueue packet kind: verify, reproduce, and route this item
    priority/highImportant and time-sensitive
    app/corePackage: core (pkgs/ or apps/ in this repo)
    effort/mMedium: expected under 1 day of work
    kind/debtTechnical debt worth paying down deliberately
    work/assignedAn agent holds this item via the queue (claimed task)
    queue/claimedA queue worker has claimed the task for this item
    and removed
    queue/queuedHas a queued task in the Supabase agent queue
    on Oct 29, 2026
  4. dezren39 commented on Oct 29, 2026

    @dezren39
    Author

    agent-note:v1
    state: picked-up
    Agent: repo-worker-opencode (queue task 3141, triage)
    Found via: queue claim repo-health-opencode-pilot
    Next: verify instance statuses, pin sweep patterns + packages/core hit list on this issue, route guard/regression-net follow-ups. No hard-stop labels present.

  5. dezren39 commented on Oct 29, 2026

    @dezren39
    Author

    agent-note:v1
    state: triaged
    Agent: repo-worker-opencode (queue task 3141, triage)
    Verified at: 2026-10-29, laptop primary main 71608cb (includes PR #843)

    Instance status — all ten verified fresh (2026-10-29)

    Issue State Fix in flight / landed
    #774 AISDKNative package tables CLOSED (status:done) landed
    #791 ModelRouteSchedule day names CLOSED PR #794 MERGED
    #792 ShellParse ARITY CLOSED landed
    #793 MessagingTemplate vars CLOSED landed
    #804 ConfigVariable {env:} CLOSED landed
    #805 CodeMode headers CLOSED landed
    #819 ModelRouteLimits windows CLOSED landed
    #824 QuotaSnapshot per-plan max-age OPEN, status:in-review, queue/parked Two competing PRs open: #825 and #835 (both for #824 — a duplicate pair; the shepherd for that task should close one)
    #830 QuotaBurnRate priors OPEN, status:in-review, queue/parked PR #837 OPEN
    #831 ModelGovernance route/variant OPEN, status:in-review PR #838 OPEN

    Class is still expanding beyond the original ten: #839 (codemode std.pick — also with a duplicate PR pair #859/#861) and #856 (PR #858) were filed after this umbrella.

    Sweep patterns pinned (packages/core/src, grep)

    • P-A uppercase plain-object tables, externally-keyed bracket read, no guard:
      grep -rnE '\b[A-Z][A-Z_0-9]{2,}\[[a-zA-Z_]' packages/core/src --include='*.ts'
    • P-B in-operator membership on plain objects (prototype-inclusive):
      grep -rnE ' in [a-zA-Z_.()]+' packages/core/src --include='*.ts' (high noise; only real for variable-length external keys)
    • P-C Record bracket read with ?? fallback — prototype values are not nullish, so the fallback never fires (the most dangerous shape):
      grep -rnE '\[[a-zA-Z_.]+\] \?\?' packages/core/src --include='*.ts'
    • Guard census baseline: 96 Object.hasOwn uses in 49 files under packages/, 34 in packages/core/src; Object.create(null) appears nowhere in core; no shared helper exists.

    Hit list from this sweep

    New confirmed hits — split into their own issues:

    1. variant.ts:30 PROTOCOLS[model.package] — plain Record, external package name, truthiness-only guard → split filed as fix(core): Variant PROTOCOLS table reads through the prototype chain — a model package named "constructor" resolves to the Object function #862.
    2. model-plan.ts:247 store.pools[poolID] ?? {} — Schema.Record from the store file, external poolID → split filed as fix(core): ModelPlan setPool pools lookup reads through the prototype chain — a pool named "constructor" never takes the ?? {} fallback #863.
    3. wellknown.ts:88 variables[name] ?? process.env[name] ?? "" — name from a remote manifest, same symptom as fix(core): ConfigVariable {env:} substitution reads through the prototype chain — "{env:constructor}" injects the Object function source and ":-" fallbacks are ignored for prototype names #804 in a different file → split filed as fix(core): WellKnown {env:} substitution reads through the prototype chain — "{env:constructor}" injects the Object function into remote-config URLs/headers #864.

    Already-tracked hits still unguarded on main (fixes in flight, listed above): quota-snapshot.ts:84 (#824), quota-burn-rate.ts:132-133 (#830), session/model-governance.ts:200,219,234 (#831).

    Candidates needing confirmation (routed to the guard/sweep follow-up, not split):

    Examined and safe, with reason (do not re-file):

    • form.ts:479,482 + model-route-limits.ts:66,69 MONTH_NUMBERS — regex capture is constrained to (jan|feb|…) prefixes.
    • model-route-limits.ts:100,133 UNITS / RELATIVE_UNITS — key constrained by the amount regex (ms|s|m|h|d).
    • session/runner/publish-llm-event.ts:674 INPUT_FAILURES — key is the closed union InputFailureReason, internal only.
    • session/compaction.ts:444 SHRINK_STEPS, model-route-schedule.ts:315 DAY_LABELS, model-route.ts weights — numeric indexes.
    • model-route-schedule.ts:171 SHORT_DAYS — key from Intl weekday formatting, trusted.
    • ripgrep/binary.ts:97 PLATFORM — key is ${process.arch}-${process.platform}, internal.
    • shell/scan.ts:1606 BASH_ANSI_ESCAPES — single-char key (guarded by in; no single-char prototype member); scan.ts:2280 POWERSHELL_ESCAPES — single-char key, ?? char fallback sound for the same reason.
    • database/v1-migration.bun.ts:924-928 RENAMED_TOOLS — names derived from Object.keys(RENAMED_TOOLS) (own keys only).

    Routing

    Triage verdict: the class is real, per-site drip is working for filed instances (7/10 closed, 3/10 with PRs open), but the sweep found 3 new sites in one pass — the guard + net follow-up is the load-bearing item, not more instance fixes.

  6. dezren39 commented on Oct 29, 2026

    @dezren39
    Author

    agent-note:v1
    state: done (triage)
    Agent: repo-worker-opencode (queue task 3141)
    Result: triage verdict + instance statuses + sweep patterns/hit list recorded in comment 6494535137 above. Splits filed: #862 (task 3393), #863 (task 3394), #864 (task 3396); guard + regression net: #865 (task 3397). This umbrella stays open — #865 owns closing the class. Noted for the #824 shepherd: PRs #825 and #835 are a duplicate pair.

  7. added
    meta/enrichedIntake review done: acceptance criteria, links, and normalized labels added
    and removed
    queue/claimedA queue worker has claimed the task for this item
    work/assignedAn agent holds this item via the queue (claimed task)
    on Oct 29, 2026
  8. dezren39 commented on Oct 30, 2026

    @dezren39
    Author

    Intake review (fleet monitor, 2026-10-29 run):

  9. dezren39 commented on Oct 30, 2026

    @dezren39
    Author

    agent-note:v1
    state: done — closing umbrella
    Agent: issue sweep (issue-sweep-rotating)
    Session/ID: issue-sweep-rotating run 2026-10-29 20:24 CDT (correction pass)

    Closing #833 — acceptance verified complete 2026-10-29

    All four acceptance points are met, so this umbrella is complete. (Correction note: an earlier sweep entry this run briefly recorded #864/#865 as still open from a stale read; fresh gh api reads show both closed/completed — the backlog entry has been corrected.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    app/corePackage: core (pkgs/ or apps/ in this repo)effort/mMedium: expected under 1 day of workkind/debtTechnical debt worth paying down deliberatelymeta/enrichedIntake review done: acceptance criteria, links, and normalized labels addedpriority/highImportant and time-sensitivesource/creatorFiled by the new-issue-creator jobstatus:donetask/triageQueue packet kind: verify, reproduce, and route this item

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions