{"_id":"@argszero/cordis-plugin-goal-ask-guard","_rev":"2-a849abbbb221b135f657bdcd5b0bcb01","name":"@argszero/cordis-plugin-goal-ask-guard","dist-tags":{"latest":"0.1.1"},"versions":{"0.1.0":{"name":"@argszero/cordis-plugin-goal-ask-guard","version":"0.1.0","keywords":["deepseek","dsh","cordis","plugin","goal","ask-user-question","guard","autonomous-round"],"license":"MIT","_id":"@argszero/cordis-plugin-goal-ask-guard@0.1.0","maintainers":[{"name":"argszero","email":"argszero.reg@gmail.com"}],"homepage":"https://github.com/argszero/cordis-plugin-goal-ask-guard#readme","bugs":{"url":"https://github.com/argszero/cordis-plugin-goal-ask-guard/issues"},"dsh":{"bundle":{"patch":"./cordis.patch.yml"}},"dist":{"shasum":"dc60b75065286074aa301d6d392663f334aeaec4","tarball":"https://registry.npmjs.org/@argszero/cordis-plugin-goal-ask-guard/-/cordis-plugin-goal-ask-guard-0.1.0.tgz","fileCount":6,"integrity":"sha512-41S/yFvy/Zy0DMbhqfK0p8BtP6M2h5gFfDFlTPkmWeJQTyz51HDic+n/Qhf+GuGqw46s6hKGYuqIg5Ovk5obCw==","signatures":[{"sig":"MEUCIQDioQkEYT2kWI1DMoBMusxowPYmkQhCqO3uEccawOd8GgIgV0dguoRZzUlfeY2xTAUK5miuUVvrGQKSaOFCWGjA7As=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":14511},"main":"lib/index.js","type":"module","types":"lib/index.d.ts","engines":{"node":"^22.19 || >=24"},"exports":{".":{"types":"./lib/index.d.ts","default":"./lib/index.js"}},"gitHead":"715f761a674f274aca64c74317561d96685ad01b","scripts":{"test":"tsc -p . && node --test \"test/*.test.js\"","build":"tsc -p .","prepack":"tsc -p ."},"_npmUser":{"name":"argszero","email":"argszero.reg@gmail.com"},"repository":{"url":"git+https://github.com/argszero/cordis-plugin-goal-ask-guard.git","type":"git"},"_npmVersion":"11.17.0","description":"Deny ask_user_question during autonomous goal rounds for the dsh harness: an agent-scoped ctx.tools.guard() on the agent/created + agent/inbox/claimed seam, as interim mitigation for #6074 (a nested ask during a goal run is not model-visible in code mode,","directories":{},"_nodeVersion":"26.5.0","dependencies":{"@types/node":"^22.20.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^7.0.2","@deepseek-ai/cordis":">=4.0.0 <5"},"peerDependencies":{"@deepseek-ai/cordis":">=4.0.0 <5"},"peerDependenciesMeta":{"@deepseek-ai/dsh-tools":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/cordis-plugin-goal-ask-guard_0.1.0_1788998140324_0.15961767703046248","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@argszero/cordis-plugin-goal-ask-guard","description":"Deny ask_user_question during autonomous goal rounds for the dsh harness: an agent-scoped ctx.tools.guard() on the agent/created + agent/inbox/claimed seam, as interim mitigation for #6074 (a nested ask during a goal run is not model-visible in code mode,","version":"0.1.1","type":"module","main":"lib/index.js","types":"lib/index.d.ts","exports":{".":{"types":"./lib/index.d.ts","default":"./lib/index.js"}},"peerDependencies":{"@deepseek-ai/cordis":">=4.0.0 <5"},"peerDependenciesMeta":{"@deepseek-ai/dsh-tools":{"optional":true}},"dsh":{"bundle":{"patch":"./cordis.patch.yml"}},"scripts":{"build":"tsc -p .","test":"tsc -p . && node --test \"test/*.test.js\"","prepack":"tsc -p ."},"engines":{"node":"^22.19 || >=24"},"keywords":["deepseek","dsh","cordis","plugin","goal","ask-user-question","guard","autonomous-round"],"license":"MIT","publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/argszero/cordis-plugin-goal-ask-guard.git"},"devDependencies":{"@deepseek-ai/cordis":">=4.0.0 <5","typescript":"^7.0.2"},"dependencies":{"@types/node":"^22.20.1"},"gitHead":"55c47dfb53acc389545262fb0754c66338db2514","_id":"@argszero/cordis-plugin-goal-ask-guard@0.1.1","bugs":{"url":"https://github.com/argszero/cordis-plugin-goal-ask-guard/issues"},"homepage":"https://github.com/argszero/cordis-plugin-goal-ask-guard#readme","_nodeVersion":"26.5.0","_npmVersion":"11.17.0","dist":{"integrity":"sha512-qRONebCokGEXNnaytrdltb55jMs/gVgrQubGhZBrRnJoziicnJ46IOFjtGJIRR0Z59hTGVqy1ucSbsPN3Dud5g==","shasum":"99ecc215fb2ed9f474e40293e33e8779ce60a2e5","tarball":"https://registry.npmjs.org/@argszero/cordis-plugin-goal-ask-guard/-/cordis-plugin-goal-ask-guard-0.1.1.tgz","fileCount":6,"unpackedSize":20398,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIHaq0cHQNmLUt2KWMsan4oKprn0e1GW3WfgCk/JBsc3LAiEAsfWVT8CfOSn+MC2H07ft82gTcYf0we4P/l/XGx5oDNc="}]},"_npmUser":{"name":"argszero","email":"argszero.reg@gmail.com"},"directories":{},"maintainers":[{"name":"argszero","email":"argszero.reg@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/cordis-plugin-goal-ask-guard_0.1.1_1789000600605_0.3282566641378133"},"_hasShrinkwrap":false}},"time":{"created":"2026-09-09T23:55:40.128Z","modified":"2026-09-10T00:36:41.020Z","0.1.0":"2026-09-09T23:55:40.454Z","0.1.1":"2026-09-10T00:36:40.779Z"},"bugs":{"url":"https://github.com/argszero/cordis-plugin-goal-ask-guard/issues"},"license":"MIT","homepage":"https://github.com/argszero/cordis-plugin-goal-ask-guard#readme","keywords":["deepseek","dsh","cordis","plugin","goal","ask-user-question","guard","autonomous-round"],"repository":{"type":"git","url":"git+https://github.com/argszero/cordis-plugin-goal-ask-guard.git"},"description":"Deny ask_user_question during autonomous goal rounds for the dsh harness: an agent-scoped ctx.tools.guard() on the agent/created + agent/inbox/claimed seam, as interim mitigation for #6074 (a nested ask during a goal run is not model-visible in code mode,","maintainers":[{"name":"argszero","email":"argszero.reg@gmail.com"}],"readme":"# @argszero/cordis-plugin-goal-ask-guard\n\nDeny `ask_user_question` during **autonomous goal rounds** for the **dsh** harness\n(deepseek-harness). It registers an **agent-scoped** `ctx.tools.guard()` that\ndisallows the interactive ask while a goal continuation round is admitted, then\nunregisters it when the round ends.\n\nThis is the **interim community-side mitigation** for discussion **#6074**. The\nin-tree fix (an agent-scoped guard inside `goal-round-driver`) is being\nprepared upstream; until it lands, this plugin covers the same gap without\ntouching core.\n\n## Why (#6074)\n\nDuring an autonomous same-session goal run, `ask_user_question` is still\ncallable — the `dsh-user-questions` gate only rejects **live subagents**\n(`DELEGATED_CALLER`), so nothing stops an interactive ask during an autonomous\nround. In **Code Mode**, a nested answer is silently discarded (only program\nlogs/return re-enter model context), so the model can loop for 30+ goal rounds\nwaiting on a decision the user was never given in a model-visible way.\n\n## What it does\n\n- On `agent/created`, resolves the agent-scoped `tools` service.\n- On `agent/inbox/claimed` of a **goal-continuation** message\n  (`source.kind === 'goal'`), installs an agent-scoped `ctx.tools.guard()`.\n- The guard returns a **denial reason** for `ask_user_question`, mirroring the\n  in-tree `goal-round-driver` text: it tells the model the decision can't be\n  answered mid-round and directs it to record the need via\n  `update_goal(blocked)` with a concrete `blocked_reason` — so the requirement\n  gets recorded instead of busily retried. A guard's denial is a catchable\n  `ToolCallError` in Code Mode, so the model sees the reason and can pivot —\n  unlike `restrict()`, which only hides the tool from the menu.\n- Closes the goal-round window (and unregisters the guard) on **all** the sites\n  the in-tree driver clears on: `turn/end` (routed **per-agent** via\n  `session/event`, so another agent's turn-end doesn't clear this one),\n  `agent/disposed`, `agent/session-start`, `agent/inbox/inserted` (competing),\n  and `agent/inbox/discarded` (superseded). Each clear-site listener is itself\n  unregistered on close, so long-running hosts don't accumulate listeners.\n\nUser-initiated `ask_user_question` **outside** a goal round passes through\nuntouched.\n\n> **v0.1.1** — aligned with the in-tree semantics from the author's review of\n> v0.1.0: added `agent/session-start` + `inbox/inserted` + `inbox/discarded` to\n> the clear sites, made `turn/end` per-agent via `session/event`\n> (`session.id → agent`) instead of a global listener, unregistered the\n> clear-site listeners on window close, and adopted the exact in-tree\n> `GOAL_ROUND_ASK_DENIAL` text (which points at `update_goal(blocked)`).\n\n## Install / mount\n\n```sh\nnpm install @argszero/cordis-plugin-goal-ask-guard\n```\n\nMount it in a dsh profile:\n\n```yaml\n# cordis.patch.yml (or an overlay)\n- insert:\n    - id: goal-ask-guard\n      name: '@argszero/cordis-plugin-goal-ask-guard'\n```\n\nTune via config:\n\n```yaml\n- set:\n    - id: goal-ask-guard\n      config:\n        toolName: ask_user_question   # the interactive-ask tool to deny\n        denyOnUnknownGoalRound: true  # deny if `round` is missing (defensive)\n```\n\n## Config\n\n| Field | Default | Description |\n|-------|---------|-------------|\n| `toolName` | `ask_user_question` | The tool name to deny during autonomous goal rounds. |\n| `denyOnUnknownGoalRound` | `true` | When a goal-source message omits `round` (some producers may), still treat it as a goal round and deny. |\n\n## Seam\n\n- `ctx.tools.guard(guard)` — public core primitive\n  (`packages/core/tools/src/index.ts:1100`; `ToolGuard` at `:704`), which returns\n  a string reason to deny; registered on an **agent-scoped** context it applies\n  only to that agent.\n- `agent/inbox/claimed` (`packages/core/agent-loop/src/inbox.ts:114`) — emitted\n  per claimed message; goal rounds carry `source.kind === 'goal'`.\n- `session/event` (`turn/end`) routed to the agent by `session.id`; the\n  `agent/inbox/*` + `agent/session-start` + `agent/disposed` clear sites.\n- The goal-round window closes on all the driver's clear sites.\n\nVerified against dsh **0.1.5-alpha.2**.\n\n## License\n\nMIT\n","readmeFilename":"README.md"}