You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
feat(harness-ops): read Explore/Plan disallowed_tools literal under the parser reader, then flip the inventory default #5901
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).
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).
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.
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.
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.
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.
Activity
revert(harness-ops): keep the regex reader as the inventory default
chore(harness-ops): release 2.5.0, not a breaking change
docs(harness-ops): describe the parser reader as opt-in in extraction.md
feat(harness-ops): follow bindings across modules and guard builtin p…
chore(harness-ops): validate the native-surface registry against Clau…
feat(harness-ops): clear a sink whose computed key provably names no …
feat(harness-ops): record what still blocks the parser default and bu…
feat(harness-ops): count node:vm's same-realm runners as code built f…
kyle-sexton commentedon Oct 3, 2026
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:
vmuseThe string code includes ajv's
Function(...)running validators it generates at runtime and protobufjs's directeval. Explore and Plan stay partial, and--reader compareshows 0 value->value on every build.Decision for the operator: the flip needs one of two things:
Recommended: keep
regexas the default.fix(harness-ops): fail closed on every vm load and on loads the parse…
fix(harness-ops): count a destructured require or an aliased import.m…
feat(harness-ops): follow whole-module loads and computed keys in the…
kyle-sexton commentedon Oct 3, 2026
Operator decision 2026-10-03: keep
--reader=regexas the inventory default. The parser cannot prove the ajvFunctionand protobufjsevalstring code harmless, and clearing those sinks would assume runtime-generated code never patches builtin prototypes, which could yield a wrong Explore/Plandisallowed_toolsvalue.--reader compare --self-checkstays 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.kyle-sexton commentedon Oct 4, 2026
This was generated by AI during triage.
Agent Brief
Type: Feature
Summary: Make the parser reader resolve the Explore and Plan
disallowed_toolsliterals, then make parser the inventory's default reader.Current behavior:
--reader=regexis the inventory default. Under--reader=parser, the Explore and Plandisallowed_toolslists read partial (never wrong);--reader compareshows 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-realmvmuse, and runtime-generated string code (ajv'sFunction(...), protobufjs'seval), which the parser cannot prove harmless. The operator decided on 2026-10-03 to keepregexas the default;--reader compare --self-checkstays 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:
disallowed_toolsresolve fully on the supported builds--reader compareshows no value-to-value change on the supported buildsOut of scope:
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.76 remaining items
github-actions commentedon Nov 3, 2026
github-actions commentedon Nov 3, 2026
melodic-automation-lanes commentedon Nov 3, 2026
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-readyandstatus: readyand addedstatus: 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:
What the run says it did not do:
inventory.py --reader compare --self-check --binary <build> --binary-onlyon 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…Run: https://github.com/melodic-software/claude-code-plugins/actions/runs/41703709977