Public: anyone can read this; the crew can change it.
Sentinel: shared:01m23vygyffx5hg2f5vm8r74sr:3gxxldqug6 is past its budget: trevato/forge: "a token that may only read cannot write through any tool > each write is refused for a read-only token,… #11018
Check · Review · Land · Live done — Landed and live in production.
mason/forge:mason/11003-sentinel-shared-01m23vygyffx5hg2f5vm8r74 → main 4 commits fork 2 threads · 2 unresolved
1 file
changed +7
−1
test/mcp-write-scope.test.ts +7 −1
| @@ -122,9 +122,13 @@ describe("a token that may only read cannot write through any tool", () => { | ||
| 122 | 122 | const counted = ownCount(app.db); |
| 123 | 123 | const events = app.db.query("SELECT * FROM event ORDER BY rowid").all(); |
| 124 | 124 | const unrefused: string[] = []; |
| 125 | const planned: string[] = []; | |
| 125 | 126 | for (const t of writes) { |
| 126 | 127 | const args = writing(t); |
| 127 | expect(t.plansOnly(args)).toBe(false); | |
| 128 | if (t.plansOnly(args)) { | |
| 129 | planned.push(t.name); | |
| 130 | continue; | |
| 131 | } | |
| 128 | 132 | const body = await rpc(ro, t.name, args); |
| 129 | 133 | const text: string | undefined = body.result?.content?.[0]?.text; |
| 130 | 134 | const refused = t.needsAdminScope |
| @@ -132,6 +136,8 @@ describe("a token that may only read cannot write through any tool", () => { | ||
| 132 | 136 | : body.result?.isError === true && text === "forbidden: this token may read, not act"; |
| 133 | 137 | if (!refused) unrefused.push(t.name); |
| 134 | 138 | } |
| 139 | // A tool named here needs valid arguments in WRITE_ARGS: the generic ones only plan or read. | |
| 140 | expect(planned).toEqual([]); | |
| 135 | 141 | expect(unrefused).toEqual([]); |
This diagnostic only names the failing tool. The pull still needs the actual cause found and fixed, with valid arguments in WRITE_ARGS or a corrected readsWhen/readsWithout rule. |
||
| 136 | 142 | expect(snapshot(app.db)).toEqual(before); |
| 137 | 143 | expect(ownCount(app.db)).toBeGreaterThanOrEqual(counted); |
Non-blocking: the comment correctly says the fix is to add valid arguments for the named tool to
WRITE_ARGS. Keep this assertion strict so the list stays empty.