Refresh current Claude prompt surface for v1.2.0#18
Conversation
|
Objective review findings from
Validation run for this review:
|
obey-agent
left a comment
There was a problem hiding this comment.
Staff-Level Re-Review — Approve
Verdict: Approve
Overview: Turn-around from the first review pass (CHANGES_REQUESTED on f911ab2). Re-reviewed against ee76685 — all five inline findings have concrete code responses backed by tests, and the race-detector suite passes cleanly. This is exactly the kind of review response I want to see: each point addressed with either the exact fix requested or a reasoned alternative documented in code.
Verification Done
Cloned the PR head at ee76685 into a fresh worktree:
go build ./...— cleango vet ./...— cleango test ./pkg/claude/...— all passgo test -race ./pkg/claude/...— clean, including the newTestRunPromptCtx_DoesNotMutateDefaultOptionsandTestRunPromptCtx_HandlesLargeStreamJSONMessages
Verified each of my five inline comments against current source.
Per-Finding Disposition
- Deprecated fields silent-ignore — Fully addressed. New
validateDeprecatedOptionsinoptions.go:358–375rejects all six fields (PermissionTool,MaxTurns,ConfigFile,DisableAutoUpdate,Theme,PermissionCallback) with clearNewValidationErrormessages.TestPreprocessOptions_RejectsDeprecatedFieldsinenhanced_test.go:88–128covers every case. Fail-loud option 1 — the stronger choice — was taken. --file/--betasarg shape — Partially addressed. The code now has intent-describing comments (// Variadic Cobra flag: one --betas flag followed by one or more values.) and unit tests asserting the expected shape (claude_test.go:873–883,:938–947). No integration test against a realclaudebinary was added, so if the upstream CLI's flag type doesn't accept this form the drift won't be caught automatically. Happy to land as-is given the author's domain knowledge, but an integration smoke test would make this resilient to upstream flag-type changes. Not blocking.bufio.Scanner64KB default — Fully addressed.structured_run.go:105–107now applies a 4MiB line cap with the exact pattern suggested.TestRunPromptCtx_HandlesLargeStreamJSONMessagesinexecution_hooks_test.go:394pipes a 128KB JSON message through a mock binary, locking in the behavior.v0.1.1version labeling — Fully addressed. File renamed fromRELEASE_NOTES_v0.1.1.mdtoPROMPT_SURFACE_NOTES_0.1.1.md. First line inside the doc clarifies0.1.1is a planning label and not a Go module tag. Option 2 from my comment, cleanly executed.SubagentConfig.ToRunOptionssilent behavior change — Fully addressed. Godoc onToRunOptions(subagent.go:55–58) now states explicitly that the method preserves the subagent inAgentsand does not flatten intoSystemPrompt/AllowedTools.PROMPT_SURFACE_NOTES_0.1.1.mdline 40 calls out the behavior change in a dedicated section. Both asks met.
Bonus: the PreprocessOptions thread-safety concern I raised in the same comment thread was also closed by the new prepareRunOptions clone-before-preprocess at every entry point (claude.go:54–67, also applied via buildStreamJSONRunOptions in structured_run.go:15–21). Regression test TestRunPromptCtx_DoesNotMutateDefaultOptions locks in that the caller's ParsedAllowedTools/ParsedDisallowedTools stay nil. The race detector is clean on the full test suite.
What's Done Well
- Fail-loud over silent-ignore on deprecated fields is the staff-level move. Every dropped field now gives a user immediate feedback on the first run.
- Clone-before-mutate is now the consistent contract across all entry points (
RunPromptCtx,RunFromStdinCtx,StreamPromptviabuildStreamJSONRunOptions). The helpersresolveRunOptions/prepareRunOptionsmake this obvious to future callers. - Regression tests at the exact failure surface — a 128KB mock JSON line for the bufio cap, a mutation-check for
defaultOptsfields — each finding has a test that would fire if the fix regressed. - Clear explanatory doc comments at the changed call sites and in the release notes. The
PROMPT_SURFACE_NOTES_0.1.1.mddisambiguation of planning label vs. module tag is particularly nice — exactly the kind of thing that prevents confusion downstream.
Remaining (Non-Blocking)
- Consider a single integration-style smoke test that invokes a stub
claudebinary asserting the received argv for--betasand--file. Would catch any future upstream flag-type drift and lock in the current intent at the CLI boundary.
Staff Standard
Yes. I would be comfortable submitting the response to this review as my own work. The diff quality, test discipline, and per-comment disposition are all staff-level. Approve for v1.2.0 tagging once ready.
obey-agent
left a comment
There was a problem hiding this comment.
Review — Refresh current Claude prompt surface for 0.1.1
Verdict: REQUEST_CHANGES — 4 inline comments posted. The mechanics of the prompt-surface refresh are well-executed, but two issues block merge as-is.
Semver — the headline concern
This is labeled 0.1.1 (patch), but it contains breaking runtime behavior changes. Callers on current 0.1.0 who set any of MaxTurns, ConfigFile, Theme, DisableAutoUpdate, PermissionTool, or PermissionCallback will receive a hard validation error after upgrading — their code compiled and ran fine before. That is a minor-version break at minimum (0.2.0), arguably a major one. The PROMPT_SURFACE_NOTES doc clarifies this is a planning label, not the release tag, but that needs to be resolved before tagging.
Options: (a) soft-warn and ignore deprecated fields, reserving errors for 1.0, or (b) bump to v0.2.0 with a migration guide.
Top 3 findings
-
Breaking behavior on deprecated fields (, ): silent success → hard runtime error is a semver violation for a patch release. See inline.
-
SubagentConfig.ToRunOptionshardcodes agent key (): always registers under"subagent", so any caller that previously set a custom agent name via the returned opts will silently mismatch. This is both a breaking change and a usability trap. See inline. -
False-negative validation for
IncludeHookEvents/IncludePartialMessages(): these flags are validated againstFormat != StreamJSONOutputinPreprocessOptions, butrunPromptWithStructuredHooksupgradesJSONOutput → StreamJSONOutputinternally — so valid option combinations are incorrectly rejected. See inline.
Minor issues
fmt.ErrorfinexecuteStreamJSON(): twofmt.Errorfcalls where the rest of the package uses typedClaudeError. Callers lose the ability to type-assert. See inline.- Missing Godoc on
EffortLevelconstants:EffortLowthroughEffortMaxhave no per-value comments, which renders poorly on pkg.go.dev. See inline.
What's good
The core mechanics are solid: cloneRunOptions prevents mutation of caller-owned DefaultOptions (confirmed by TestRunPromptCtx_DoesNotMutateDefaultOptions), executeStreamJSON correctly drains stderr before returning errors, the scanner buffer is sized to 4 MB to handle large messages, budget tracking is now automatic and synchronized (callback refactor in budget.go removes the goroutine race), and the test suite is meaningfully extended with lifecycle hook and budget-exceeded coverage.
obey-agent
left a comment
There was a problem hiding this comment.
Re-review — Refresh current Claude prompt surface for 0.1.1
Prior findings status:
-
Semver (hard deprecated-field errors) — Resolved.
validateDeprecatedOptionswas replaced withwarnDeprecatedOptions, which emits a one-timelog.Printfvia the injectabledeprecatedOptionWarningfhook and leaves deprecated fields intact.PreprocessOptionsno longer returns errors forMaxTurns,ConfigFile,Theme,DisableAutoUpdate,PermissionTool, orPermissionCallback. Runtime behavior is preserved for callers who set these fields; they get a one-time warning.TestPreprocessOptions_WarnsOnDeprecatedFieldslocks in the contract and the log-once behavior. -
SubagentConfig.ToRunOptionshardcodes"subagent"— Resolved.ToNamedRunOptions(agentName, parentOpts)was introduced.ToRunOptionsnow delegates to it with"subagent"as the synthetic default, and its godoc explicitly states the default key.subagent_test.gotestsToNamedRunOptions("security", nil)and assertsopts.Agent == "security",Agents["security"] != nil, andAgents["subagent"] == nil. -
False-negative validation on
IncludeHookEvents/IncludePartialMessages— Resolved.supportsStreamJSONOutputnow returns true forFormat == JSONOutput && PluginManager != nil, which matches the upgrade path insidebuildStreamJSONRunOptions.TestPreprocessOptions_AllowsInternalStructuredStreamFlagscovers all three flags (IncludeHookEvents,IncludePartialMessages,ReplayUserMessages) under the JSONOutput+PluginManager combination. -
fmt.ErrorfinexecuteStreamJSON+EffortLeveldocs — Resolved. All error paths inexecuteStreamJSONandstructured_run.gonow usenewWrappedClaudeErrorwith a typedErrorType, consistent with the rest of the package.EffortLowthroughEffortMaxall carry one-line godoc comments and render correctly on pkg.go.dev.
New findings: None. The latest commit ("Address second review round") is narrowly scoped to the four fixes above. No regressions or new issues observed on a fresh pass.
Verdict: Approve
Rationale: Every blocking and minor finding from the previous review is addressed cleanly, with tests covering the changed behavior. The deprecation path (warn-and-ignore) is the correct semver-safe choice for a published library at this stage. Code is consistent, the typed-error model is intact, and the stream-validation logic is now correct. Ready to merge.
lancekrogers
left a comment
There was a problem hiding this comment.
Re-review — Refresh current Claude prompt surface for v1.2.0
Verdict: APPROVE (maintains prior approval).
Re-review covering the commit pushed after the 2026-04-17 20:47 approval: e6981c0 — Correct release numbering to v1.2.0.
Scope of the new commit
Pure docs / release-packaging change: two files touched.
- Renames
docs/PROMPT_SURFACE_NOTES_0.1.1.md→docs/RELEASE_NOTES_v1.2.0.md. - Updates the README link (
README.md:509) to the new path. - Replaces the "Planning Label 0.1.1" framing with a proper
v1.2.0 - Prompt Surface Refreshheader, drops the "not a Go module tag" disclaimer, swapsgo test ./pkg/claude/...forjust release checkin the Verification section, and adds av1.1.0...v1.2.0compare link.
No Go source code was touched in this commit. go test ./pkg/claude/... and go test ./pkg/claude/dangerous still pass locally against the PR head SHA.
Verification against prior-review resolution
The version-mismatch concern I raised at docs/RELEASE_NOTES_v0.1.1.md:1 on the previous round is now addressed in two ways:
- First pass (pre-approval): the file was renamed to
PROMPT_SURFACE_NOTES_0.1.1.mdand reframed as an internal planning label — defensible but confusing for a public-SDK doc. - This commit (post-approval): the doc now follows the
v1.1.0 → v1.2.0tag progression, which is the right semver step for the surface described (additive new fields, documented behavior changes, no removed exported symbols). This is the correct final state.
No other prior findings were re-opened by this commit.
Semver sanity check
v1.2.0 is the right bump, with two caveats worth calling out in the notes (not blocking):
SubagentConfig.ToRunOptionsis a silent behavioral change for callers that inspected the returnedRunOptions.SystemPrompt/AllowedToolsdirectly. Documented, but the phrasing in the newBehavior Changessection reads as a neutral redesign — see inline comment.PermissionModeDelegateis now a hard validation error (pkg/claude/options.go:299), while other deprecated fields got the softer one-time-warning path. The rationale is defensible (no natural ignore semantics for a permission mode) but would benefit from one explanatory sentence — see inline comment.
Neither of these block the v1.2.0 tag; both are justifiable given that the upstream Claude CLI surface changed out from under us.
What's done well
- Clean, scoped commit: docs-only, no Go diff, easy to re-review.
- Correct tag progression (
v1.1.0...v1.2.0) — no accidental downgrade intov0.1.xterritory. - The new
## Full Changelogcompare link is the standard GitHub-release convention and will resolve correctly once the tag is pushed. just release checkis a real, wired-up recipe (.justfiles/releases.just:47-54) that runs lint + test + build, so the Verification claim is substantive, not aspirational.
Staff standard
The prior review already exercised the code paths; this commit is a clean packaging correction that finishes the release story. Approval stands. Inline nits (4 total this round) are phrasing / release-hygiene suggestions, none of them gating.
Release checklist reminder
After merge, to keep the compare link valid and the module properly published:
git tag v1.2.0 <merge-sha>
git push origin v1.2.0
gh release create v1.2.0 --notes-file docs/RELEASE_NOTES_v1.2.0.md
If .justfiles/releases.just prepare already encodes this, a one-line pointer in the notes would close the loop.
Summary
-p/--printflag surface and stop emitting removed flags-pscope and remove stale top-levelMaxTurnsusageTesting