Skip to content

feat(harness-ops): read Explore/Plan disallowed_tools literal under the parser reader, then flip the inventory default #5901

Open
12 of 12 issues completed

Description

@kyle-sexton

Summary

After #5891 (#5640 P4), the parser reader reads /builtin_agents/{Explore,Plan}/disallowed_tools partial (never wrong) on 2.1.284-2.1.287, so the inventory default stays --reader=regex (operator decision 2026-10-02). On all four builds the readers otherwise agree (value->value 0).

Two independent causes force partial:

  • The re-exporter chunk of the array (chunk-9y5qk6zx.js on 2.1.287, ARTIFACT_FAMILY_TOOL_NAMES) is loaded whole 13-14 times (import(...), import.meta.require(...), some stored as names: record properties).
  • The sink rule flags computed-key writes (~189 modules), computed-key defineProperty (~88) and related writes that cannot be proven not to land on a builtin prototype.

Fix

  • Follow namespace objects, including ones stored into record properties, to every read; accept only by-name reads that the existing flow proves safe.
  • Receiver/key-provenance analysis for computed-key writes so a write provably not on Array.prototype/Object.prototype clears the sink.
  • Then flip --reader default to parser (harness-ops major: needs Node.js and npm).

Related

#5640, #5891

  • After Explore and Plan resolve fully and --reader compare shows no value-to-value change, the owner decides whether to flip --reader to parser (2026-10-03 and 2026-10-26 records).

Activity

  1. added
    needs-triageNot yet classified. Floor until a type and one priority tier are set.
    on Oct 2, 2026
  2. kyle-sexton commented on Oct 3, 2026

    @kyle-sexton
    MemberAuthor

    Status from #5970 (draft):

    Removed: the namespace cause. Every whole load of the re-exporting chunk (13-14 per build) is now followed to its reads and passes on 2.1.284-2.1.288.

    Still blocking: the sink rule. On 2.1.288 these counts are lower bounds:

    Sink Modules
    Computed-key writes on unproven receivers 178
    Computed defines 92
    Prototype swaps 22
    Definer escapes 11
    Same-realm vm use 5
    Other string code 8

    The string code includes ajv's Function(...) running validators it generates at runtime and protobufjs's direct eval. Explore and Plan stay partial, and --reader compare shows 0 value->value on every build.

    Decision for the operator: the flip needs one of two things:

    • accept an unsound assumption: code generated at runtime never patches a built-in prototype;
    • build a reader that models those libraries, plus interprocedural receiver analysis for the computed writes.

    Recommended: keep regex as the default.

  3. kyle-sexton commented on Oct 3, 2026

    @kyle-sexton
    MemberAuthor

    Operator decision 2026-10-03: keep --reader=regex as the inventory default. The parser cannot prove the ajv Function and protobufjs eval string code harmless, and clearing those sinks would assume runtime-generated code never patches builtin prototypes, which could yield a wrong Explore/Plan disallowed_tools value. --reader compare --self-check stays the per-release divergence guard (2.1.288: 0 value->value, 4 wrong->unresolved). This issue stays open as the tracker for a library-aware reader; the flip needs a new decision.

  4. kyle-sexton commented on Oct 4, 2026

    @kyle-sexton
    MemberAuthor

    This was generated by AI during triage.

    Agent Brief

    Type: Feature
    Summary: Make the parser reader resolve the Explore and Plan disallowed_tools literals, then make parser the inventory's default reader.

    Current behavior:
    --reader=regex is the inventory default. Under --reader=parser, the Explore and Plan disallowed_tools lists read partial (never wrong); --reader compare shows no value-to-value change on 2.1.284 to 2.1.288. The namespace-load cause is removed. The remaining cause is the sink rule: computed-key writes and defines on unproven receivers, prototype swaps, definer escapes, same-realm vm use, and runtime-generated string code (ajv's Function(...), protobufjs's eval), which the parser cannot prove harmless. The operator decided on 2026-10-03 to keep regex as the default; --reader compare --self-check stays the per-release divergence guard.

    Desired behavior:
    A reader that models those libraries and proves computed writes do not land on a built-in prototype, so Explore and Plan resolve fully under the parser, followed by a default flip.

    Acceptance criteria:

    • Under the parser, Explore and Plan disallowed_tools resolve fully on the supported builds
    • --reader compare shows no value-to-value change on the supported builds
    • The default flip is made only under a new owner decision

    Out of scope:

    • Accepting the unsound assumption that runtime-generated code never patches a built-in prototype (rejected 2026-10-03)
    • The regex reader's own behavior

    Routing: human-gated (needs decision)

    Blocked by #5640's decision: what must be true before the parser becomes the default. #5640 is the decision carrier for that question and names this issue as a cluster member. I did not add a blocked-by edge.

    This issue also records its own standing answer: keep regex, and the flip needs a new decision. No agent work is open until the owner decides #5640's gate and whether a library-aware reader is worth building.

    Priority: low. The default is settled for now and the self-check guards each release, so nothing is waiting on this.

    Work class: structural (C4). The flip changes a runtime dependency and the inventory's default behavior (a harness-ops major release).

    Basis: verified, the 2026-10-03 operator-decision comment on this issue; #5640's triage comment naming this issue as a cluster member. Searched docs/out-of-scope/: no matching concept.

  5. 76 remaining items

  6. removed
    status: readyTriaged, unblocked, and fully specified; eligible to pick up.
    agent-readyFully specified and briefed; eligible for autonomous pickup from the frontier.
    on Nov 3, 2026
  7. added
    admission-deferredAdmitted but waiting for WIP room; the hourly work-unblock sweep labels it agent-ready.
    agent-readyFully specified and briefed; eligible for autonomous pickup from the frontier.
    and removed
    admission-deferredAdmitted but waiting for WIP room; the hourly work-unblock sweep labels it agent-ready.
    on Nov 3, 2026
  8. github-actions commented on Nov 3, 2026

    @github-actions
    Contributor
    No description provided.
  9. github-actions commented on Nov 3, 2026

    @github-actions
    Contributor
    No description provided.
  10. added
    status: confirmedA maintainer confirmed the item is real and in scope; ready to be worked.
    and removed
    agent-readyFully specified and briefed; eligible for autonomous pickup from the frontier.
    status: readyTriaged, unblocked, and fully specified; eligible to pick up.
    on Nov 3, 2026
  11. melodic-automation-lanes commented on Nov 3, 2026

    @melodic-automation-lanes
    Contributor

    The work-resolve-issue lane stopped on this issue (verify-unmet): the issue is a finished parent, but the run found one of its own done-when items unmet, which it names, so it parks until a listed human's decision comment sends it back.
    It removed agent-ready and status: ready and added status: confirmed, as admission parks a refusal no person answers, and it waits on no decision from a person. Once that step is done, a listed human's comment whose first line is **Decision recorded.** sends it back through intake triage.

    In the run's words:

    verify-unmet: (1) the done-when item 'After Explore and Plan resolve fully and --reader compare shows no value-to-value change, the owner decides whether to flip --reader to parser' lacks both preconditions and the owner's flip decision; (2) 'Under the parser, Explore and Plan disallowed_tools resolve fully on the supported builds' lacks a passing host run: the last one (2026-11-03, origin/main 39f54bf, build 2.1.316) read partial, 5 of 9 names; harness-ops 8.2.0 later bounds computed keys (gate a), but the returned-array hop (gate b, parser_helper.cjs:817) shows no change, and no run since 8.2.0 exists; (3) '--reader compare shows no value-to-value change on the supported builds' lacks a run on the current default branch: the last count (0 value->value, 2026-11-01 at 4eac1bc) predates 8.2.0, and this lane cannot run inventory.py against a Claude Code binary.

    What the run says it did not do:

    • Host run of inventory.py --reader compare --self-check --binary <build> --binary-only on the supported builds, which is the check for both acceptance criteria. It needs a Claude Code binary, node and npm, and this lane runs no interpreter, so the criteria stay unverified on the current…
    • Gate (b) from the 2026-11-03 host run (follow an array returned by an exported function to its importers' call sites) has no tracking issue, per the 2026-11-02 comment. Filing one is left to a person, since a verify-close run changes nothing.
    • git-read status lists untracked environment files (.bashrc, .bash_profile, .gitconfig, .idea, .mcp.json, .profile, .ripgreprc, .vscode, .zprofile, .zshrc). This run did not create or edit them, and they are not part of any change.

    Run: https://github.com/melodic-software/claude-code-plugins/actions/runs/41703709977

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

    priority: lowNice-to-have, cosmetic, or speculative; opportunistic.status: confirmedA maintainer confirmed the item is real and in scope; ready to be worked.work-class: structuralRefactors, migrations, contract changes; cross-cutting and hard to reverse.

    Fields

    Work status

    agent-ready

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions