git tools silently ignore unknown parameters #39
Labels
No labels
Agent
Ignore
Agent
In Progress
Agent
Planned
Agent
Planning
Agent
Ready
Agent
Triage
Compat
Breaking
Kind
Bug
Kind
Documentation
Kind
Enhancement
Kind
Feature
Kind
Security
Kind
Testing
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Reviewed
Confirmed
Reviewed
Duplicate
Reviewed
Invalid
Reviewed
Won't Fix
Status
Abandoned
Status
Blocked
Status
Need More Info
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
lucas/omp-deck#39
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Implementation: #42
Problem
Calling
git_logwith{"rev": "53bb57a..origin/main", "max_count": 20}(revisgit_show's parameter name;git_logusesref) is not rejected. The tool silently ignoresrevand returns HEAD's history ("ref": "HEAD"), which looks like a valid answer to the range question. The result is wrong and no error is reported.Root cause:
validateToolArgumentsin@oh-my-pi/pi-ai) passes unknown root keys through toexecuteunchanged. Verified:{rev:"a..b", max_count:20}arrives ingit_log'sparamsas-is. All git tools then ignore keys they don't read..strict()does not fix this. The harness's coercion pass deletes the unrecognized key and retries validation, so the call still succeeds with{}. This was verified as well. So the rejection has to happen inside each tool'sexecute.Decision: reject unknown parameters in all 8 git tools (
git_status,git_diff,git_log,git_show,git_fetch,git_branch,git_commit,git_push) with an error that names the valid parameters. Do not add arevalias. Leavegit_log'srefoutput field unchanged.Plan
Approach
Add a shared guard in
apps/server/src/bridge/git-tools/validate.ts, next toassertRefLike:Collect
Object.keys(params)that are not inknown, in input order. If there are none, return. Otherwise throwValidationErrorwith exactly this message:unknown parameter(s): rev. Valid parameters: ref, max_count, skip, …(unknown keys joined with", ". Valid keys joined with", "in schema order. Ifknownis empty, which is the case forgit_status, the second sentence isThis tool takes no parameters.).guarded()inrun.tsalready turnsValidationErrorinto afail(message)tool error, so no change is needed there.Wire it into every git tool (
status.ts,diff.ts,log.ts,show.ts,fetch.ts,branch.ts,commit.ts,push.tsinapps/server/src/bridge/git-tools/). The omptype zod shim does not expose.shape, so keep the key list in one place:z.object({...})intoconst shape = {...};, thenconst schema = z.object(shape);. Descriptions and validators stay unchanged. Forstatus.ts, useconst shape = {};.guarded(...)callback inexecute, callassertKnownParams(params, Object.keys(shape));. This runs beforeplan*(),resolveRepo, or any git call. Instatus.tsthe parameter is currently named_params, so rename it toparams..strict()for the reason given in the Problem section.Critical files & anchors
apps/server/src/bridge/git-tools/validate.ts:ValidationError,assertRefLike(around line 24). Put the new helper here.apps/server/src/bridge/git-tools/run.ts:guarded(around line 244), which convertsValidationErrorinto a tool error.apps/server/src/bridge/git-tools/log.ts:schema(line 11) andexecute(line 36). This is the reported case.Verification
apps/server/src/bridge/git-tools/validate.test.ts(bun:test, same style as theassertRefLikeblock) for adescribe("assertKnownParams")block:assertKnownParams({ ref: "x", max_count: 1 }, ["ref", "max_count"])does not throw.assertKnownParams({ rev: "a..b", max_count: 20 }, ["ref", "max_count"])throwsValidationErrorwith messageunknown parameter(s): rev. Valid parameters: ref, max_count.assertKnownParams({ x: 1 }, [])throws with messageunknown parameter(s): x. This tool takes no parameters.bun test src/bridge/git-toolsandbun run typecheckfromapps/server.apps/server, that confirms the harness path still delivers the key and that the tool now rejects it): Expected result:isError: true, with text startingunknown parameter(s): rev. Valid parameters: ref, max_count, skip,. The same call with{ref:"HEAD~1", max_count:1}returns one commit and no error.Decision:
mainnow also hasgit_rebase(apps/server/src/bridge/git-tools/rebase.ts), added after this plan was written. It has the same silent-pass-through problem, so I'm applying the sameshapehoist +assertKnownParamsguard to it as well — 9 tools instead of the 8 listed. Everything else follows the plan as written.