tscircuit / tscircuit/solver-utils

Pipeline output queries report inherited Object properties as completed-stage outputs

Open Beginner friendly
#40 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
1
Forks
3
PR merge metrics
No merged PRs in 30d

Description

On main a72b99f60680ffbe56a4c72e113ca52c9469921e, a newly constructed pipeline with no stages and no outputs reports that constructor, toString, and __proto__ have produced output.

pipelineOutputs starts as {}. hasStageOutput() uses in, which includes inherited properties, while getStageOutput() performs an unrestricted property lookup. Consequently the two methods disagree with the empty own-output set returned by getAllOutputs().

Reproduction

Save as tests/output-lookup-repro.test.ts and run with bun test tests/output-lookup-repro.test.ts:

import { test } from "bun:test"
import { strict as assert } from "node:assert"
import { BasePipelineSolver } from "../lib/BasePipelineSolver"

class EmptyPipeline extends BasePipelineSolver<Record<string, never>> {
  pipelineDef = []
}

for (const name of ["constructor", "toString", "__proto__"]) {
  test(`no output exists for ${name}`, () => {
    const pipeline = new EmptyPipeline({})
    assert.deepEqual(Object.keys(pipeline.getAllOutputs()), [])
    assert.equal(pipeline.hasStageOutput(name), false)
    assert.equal(pipeline.getStageOutput(name), undefined)
  })
}

Actual results before any step runs:

Name hasStageOutput typeof getStageOutput Expected
constructor true function false / undefined
toString true function false / undefined
proto true object false / undefined

An ordinary missing name correctly returns false/undefined. A control pipeline with a real stage returning numeric zero correctly returns true/0 after solve(); zero-valued outputs should remain valid.

A correction should distinguish own output entries from inherited Object properties. This report only concerns output-existence and output-value queries; it does not claim a security exploit or prescribe a redesign of stage names or solver-instance storage.

Executed verification

The complete actual BasePipelineSolver.ts and BaseSolver.ts files were checked against Git blob SHAs 83219bde45df9b6e456dfb175a37d5c5147a9b3c and e071bf8c1fe3e2fb4eae73bbaa4e282871d15f02. TypeScript 5.8.3 transpilation and Node 22.16.0 execution reproduced six incorrect query results across the three names, with two passing controls (ordinary missing output and an actually completed zero-valued output).

The unavailable graphics-debug import was supplied with a throwing visualization-only stub; it was called zero times. Constructors, stepping, output production and output queries used the original solver implementations. No full Bun suite, dependency-resolved typecheck or rendering run is claimed here. Prepared with ChatGPT assistance and the account owner's authorization.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with lib/BasePipelineSolver.ts and run the supplied reproduction using bun test tests/output-lookup-repro.test.ts. Trace hasStageOutput(), getStageOutput(), and getAllOutputs() for constructor, toString, and proto; done means inherited properties report false/undefined while a real zero-valued output still reports true/0.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
tooling
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
84/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.