mirror of
https://github.com/Twigpine/zero.git
synced 2026-11-11 18:00:54 -10:00
fd4231bf474ee8b8564a2da71d1c04be39239faf
4
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
ac823643ac |
fix(tui): apply the posture's effort fill on models the catalog cannot vouch for
Three defects found by running the real binary, all in what the posture reports or applies. 1. THE FILL SILENTLY DID NOT HAPPEN on a custom endpoint. /effort zeromaxing left the effort at "auto" while --exec-profile zeromaxing on the SAME model sent reasoning_effort:"high" on the wire. Same posture, same model, two answers — the fifteenth instance of one rule applied to one of two call paths. The fill site used reasoningEffortAllowed, which returns false both for a model KNOWN to lack the level and for a model the catalog has never heard of. The headless path already distinguishes them (an unknown model forwards the requested effort "since no support claim can be made for it"), and so does the TUI's own model-SWITCH site, which takes a ringKnown flag for exactly this reason. Only the profile-fill site conflated them. profileEffortApplies now fills when the model lists the level OR when no catalog entry exists, and declines only when an authoritative empty ring says the model has no reasoning controls. A model name that is empty is a third case and still declines — there is nothing to make a support claim about. That last distinction was caught by the pre-existing fast-posture test, which the first version of this fix broke. THE HOLE THAT HID IT: every test asserted a surface against its OWN expectation — the TUI tests against the TUI's rule, the CLI tests against the CLI's. Both suites were green while the two paths disagreed, because nothing compared them against each other for the same model. A unit test on either helper could not have caught it. TestProfileEffortFillAgreesWithTheHeadlessPath is that missing comparison, run across a catalog reasoning model, an inferred one, a catalog model with an authoritative empty ring, and an unknown endpoint. 2. THE OUTPUT CONTRADICTED ITSELF: "reasoning effort: unchanged — already at the highest level" and "NOT raised to high: the active model does not support that level", in the same card. Both cannot be true. The fixed clause lived in Delta while the refusal lived in a separate line, so they were only ever consistent by coincidence. Delta now renders every clause from one DeltaState, with the effort clause a single switch over EffortTransition. A contradiction is unrepresentable rather than merely unlikely, and the separate line is gone. 3. THE BUDGET CLAUSE compared against thorough — "(thorough uses 160)" — which is information about two profiles, not about the user. It now states the caller's own transition, "turn budget: 80 → 320", with distinct renderings for an already-at-320 session and an unknown current budget. |
||
|
|
e885d79205 |
fix(execprofile): describe the posture's delta against the caller's own state
Two corrections to what zeromaxing tells the user, both cases of documentation
describing behaviour that is not happening.
1. --spec-reasoning-effort zeromaxing stays rejected — it is a run posture and
has no meaning for a spec draft — but the generic "Expected low, medium, or
high" read like a bug to anyone who had just learned the name works on
--reasoning-effort. It now says why it does not apply and names both flags
that do what the user was reaching for. A genuinely unknown value keeps the
plain message: the explanation is specific to the posture name, not a new
blanket wording.
2. Delta's self-correct clause described the change from THOROUGH, not from the
caller. Telling a user sitting on the LSP-only default that self-correction
is "already armed" while silently moving them to the full project test plan
is exactly the failure this posture's honesty rules exist to prevent. Delta
is now a function of the caller's actual state and renders one of three
transitions, in /selfcorrect's own vocabulary:
self-correct: lsp -> tests (the common case)
self-correct: unchanged (tests) (genuinely unchanged)
self-correct: lsp (your /selfcorrect choice ...) (user override wins)
The third exists because the TUI lets a user turn it back off after selecting
the posture; reporting a raise there would be a third way to describe
behaviour that is not happening. The budget and effort clauses stay fixed —
effort genuinely is caller-independent, since "high" is the ceiling every
provider accepts.
The headless path captures self-correct BEFORE applyExecProfile, which arms it
as a side effect; reading it afterwards would make every run report "unchanged".
The TUI reads its LIVE state rather than selection-time state, so a later
/selfcorrect off stops the status claiming a raise the session no longer has.
A unit test on the transition helper cannot catch the capture being read at the
wrong moment, because it never runs the code that captures — so the ordering is
pinned by a test that drives the real exec path and reads stderr. That gap was
found by mutation, not by review.
|
||
|
|
843131f025 |
feat(execprofile): add the zeromaxing posture rung
zeromaxing is thorough with double the turn budget again: 320 tool-turns, effort high, self-correction armed. It fills only what the caller left unset, exactly as the other profiles do, so an explicit flag and a --mode preset both still win — precedence stays enforced by ordering, not by a new check. ONE NAME. /effort zeromaxing, /profile zeromaxing, --exec-profile zeromaxing and --reasoning-effort zeromaxing all name the same thing, and nothing else does. No aliases: "max", "deep" and "deepmode" resolve to nothing, asserted by test, because a second spelling is a second thing to keep in step. "max" is RESERVED and untouched. ValidReasoningEffort still accepts ReasoningEffortMax, so /effort max and --reasoning-effort max behave exactly as they did — parsed as a raw provider level, rejected by the flag parser, and unsupported by every current model. That spelling stays free for a real provider rung; claiming it for a Zero posture would burn it. HONEST DELTA, stated to the user rather than left in a commit message: the turn budget is the ONLY mechanical change over thorough. Effort is already at the ceiling and self-correction is already on. execprofile.Delta carries that sentence to /effort, /profile and the exec selection notice. ReasoningEffort is "high", pinned by test rather than by comment. TestZeromaxingReasoningEffortStaysHigh explains why: every level above "high" falls through the providers' effort mappers into their default arm — anthropic and gemini both compute a thinking budget of 0 (extended thinking DISABLED) and the openai mapper drops the field entirely. Raising it would silently turn reasoning off while the UI claimed a higher posture. Raising the real ceiling means teaching the providers those tiers first. The raised budget propagates to spawned sub-agents. Deliberate — this is a maximal posture — so it is asserted by test and stated in Delta rather than left to be discovered. SelectionRefusal is the single authority both selection paths consult. The headless exec path and the TUI paths already apply a profile's knobs through different code with different state; letting each decide SELECTION independently is how a rule gets applied to one call path and omitted from its sibling. Config gating follows mergeProjectConfig's tighten-only template: a project .zero/config.json may set profiles.disableZeromaxing (DISABLE) but can never clear it, so a cloned repo cannot switch a cost multiplier on for whoever opens it — an attempted enable is dropped silently, exactly like an ignored network "allow". |
||
|
|
378d538e24 |
perf(agent): execution profiles with one-shot posture escalation (PR10b+PR10c) (#740)
* perf(agent): execution profiles, --exec-profile, bench passthrough, TUI /profile (PR10b+10c) * fix(execprofile): harden profiles against review findings - fast escalates on critical-risk mutations, not high: the sandbox marks every shell command high before command analysis, so a high trigger spent the one-shot on the first go test of any task - escalation can now restore the provider-default effort a profile displaced (PostureEscalation.RestoreDefaultEffort; a plain empty target means leave untouched) - TUI /turns while a profile is active pins the budget: disarms the escalation turn target (mirroring exec's explicit --max-turns rule) and profile reverts use touched bits instead of value equality, so explicit choices survive even when they coincide with profile values - spec-draft runs get the same escalation policy as the main run instead of the displaced budget with no safety net - bench validates and canonicalizes --exec-profile before spawning: an unknown name previously produced an exit-0 report full of millisecond usage-error walls - turn summary prints exec-profile alongside mode; zero exec rejects an inline-empty --exec-profile=; balanced trace label documented and pinned as deliberate attribution * fix(execprofile): explicit effort choices disarm the escalation effort restore An explicit effort set AFTER profile selection could be cleared by a mid-run escalation (the effort analog of the /turns pin, introduced by RestoreDefaultEffort): TUI /effort and Ctrl+T now disarm the restore on a policy clone, and the spec-draft path only arms it when no explicit --spec-reasoning-effort governs the draft. * fix(execprofile): address review findings on the profile surfaces - --use-spec projects away a profile's self-correct knob instead of silently arming an option the draft runner ignores (the explicit --self-correct --use-spec combination is already a parse-time error) - RunTurnBench canonicalizes and validates ExecProfile at the library boundary, so a direct caller's casing/whitespace cannot fork report labels and an unknown name fails before anything runs - reverting a profile whose displaced budget was zero clears ZERO_MAX_TURNS (SetMaxTurnsEnv ignores zero, so sub-agents would have kept the removed profile's budget) - the TUI effort-disarm test fails instead of skipping when the catalog stops filling low effort * fix(tui): reconcile an active profile's effort fill on model switch The fill is per-model, not a session preference: fast selected on a model without low fills nothing, and switching to a model that supports it should behave like selecting the profile there; the reverse switch must not keep sending a level the destination does not support. Both switch paths (the /model command and the cross-provider picker) now re-derive the fill, leaving explicitly touched efforts alone and keeping the escalation's effort restore in step. Also: the revert-env test asserts key removal via LookupEnv, and applyProfileTurnBudget's pinned-budget parameter is named and documented as covering mode presets, not just the flag. * fix(tui): void profile effort bookkeeping when the model-switch drop erases it The /model path's pre-existing unsupported-effort drop ran before the profile reconciliation and left contradictory state behind: a dropped touched override kept blocking the profile from governing, and a dropped profile fill left a stale applied value with the effort restore still armed. The drop itself is load-bearing (the TUI run path forwards the effort to the provider unfiltered), so instead of preserving a known-unsupported level, the voided choice now resets the profile's effort bookkeeping and the reconcile re-derives from scratch. The whole sequence lives in one ring-parameterized helper driven by the switch target's authoritative ring, unit-tested against synthetic rings for both the void-then-refill arc and the supported-override survival. * fix(tui): only drop an explicit effort when the target ring is authoritative A nil ring meant both a catalog model with no effort controls and a live-discovered custom model the catalog cannot vouch for. The drop now requires an authoritative ring (a resolved catalog entry, whose ring may legitimately be empty); an unknown ring preserves an explicit preference, matching the cross-provider picker's behavior, while the profile's own fill still applies only where support is known. |