Cuts the promoted range's bullets from [Unreleased] into a stamped
## [v0.52.28] section (41 bullets, v0.52.0..v0.52.28). Companion to the
v0.52.28 stable tag pushed by the promotion engine.
Co-authored-by: nesquena-hermes <nesquena-hermes@users.noreply.github.com>
Measure-only TTFT (ttft_ms) on the metering session + _firstTokenMs diagnostic. Computed once
on first token (no hot-path latency), all mutation under existing GlobalMeter._lock, existing
token/usage/cost metering unchanged. Codex SAFE (16-stream concurrency probe, no leak/None-deref)
+ stream-gate GREEN all modes + 22 tests.
Local (non-gateway) _resolve_approval_legacy collapsed 'once'+'session' into approve_session()
→ 'approve once' silently persisted session-wide. Narrowed to choice=='session' only; 'once'
still resolves the current call but doesn't persist. Codex SAFE (adversarial: once resolves
current+no residue+next re-prompts, session/always/deny unregressed, gateway consistent, tests
non-vacuous + parked-thread probe of all 4 choices).
In the local (non-gateway) approval path, _resolve_approval_legacy grouped
"once" together with "session" and called approve_session() for both.
approve_session() records the pattern in the session-wide allowlist that the
guard later consults, so a single "Approve once" click silently approved every
later matching tool call for the whole session -- a destructive tool could then
run with no approval card.
Only "session"/"always" persist now. "once" falls through: the
resolve_gateway_approval() call below still unblocks the parked agent thread for
every choice, so the current tool call proceeds, but nothing is written to
_session_approved and the next matching guarded call re-prompts.
Adds tests/test_issue6017_approve_once_no_persist.py, asserting is_approved is
False after "once" and True after "session".
Fail-soft git worktree unlock before remove (agent locks worktrees it creates; git refuses
--force remove on locked → orphan accumulation). Dirty-guard still runs first. Codex SAFE,
13 tests pass. Shipped solo (unbundled from #6013 which has a full-suite test-interaction).
WebUI-created worktrees are locked at creation by the agent
(cli._setup_worktree locks with --reason 'hermes pid=...'), but
remove_worktree_for_session never unlocked, so git refused every removal
with "use 'remove -f -f' to override or unlock first" — force=true
included, since a single --force cannot override a lock.
Mirror the agent's own _cleanup_worktree ordering: fail-soft
'git worktree unlock' right before the remove, after all
dirty/untracked/unpushed/stream/terminal guards have passed. Those
guards remain the real safety layer; force keeps meaning 'override
dirty working state', never 'override a foreign lock'.
Tests: locked worktree now removes cleanly without force; unlock is
fail-soft when the worktree was never locked; existing mocked
call-order assertions updated for the leading unlock call.
Fixes#6023
MEDIA tokens (image/video/audio/pdf/diff/csv/excalidraw) render inline in real time
during streaming incl split-across-chunk markers. Codex SAFE r4 (both prose regressions
closed — ownership preserved + fade retained, normal prose byte-identical to master, all
4 original findings fixed, security clean, no ReDoS), stream-gate GREEN all modes (hide_all
RED was load flake, isolated re-run clean). 227 tests + 18 real-SMD subtests pass. 4-round
convergence on the crown-jewel render + security path.