feat(gc): expire keep-tagged exited sessions after a max age (parity with pty#173) - #12
Merged
Conversation
`keep=true` bought a dead session immortality against `pty gc`'s sweep. Agents tag the session they are debugging right now and never come back to untag it, so the exemption turned the registry into an append-only log (740 of 911 sessions on one host, upstream). `pty gc --keep-max-age <dur>` (default `7d`, `0` sweeps the dead keep backlog on this pass) now bounds it. Only exited/vanished sessions are candidates — a running session is never swept whatever its age. Age anchors on `exitedAt`, falling back to `createdAt` for a `vanished` session that never wrote one, the same precedence `pty list --older-than` uses; a record with neither never expires except under `0`. A unit-less non-zero value is rejected rather than guessed at, since `--keep-max-age 7` is ambiguous between seconds and days. Swept keep sessions are reported apart from the plain sweep — `Removed (keep expired after 7d): <name>` and an `N keep-expired sessions` term in the footer — so the reason is visible instead of looking like the tag was ignored, and the retained line now names the window it is counting down. Port of compoundingtech/pty#173 (merged 86dcc5eb7): same flag name, default, duration grammar, and output wording, with the help text and completions vendored from it byte for byte. agent-identity: dev3.direct.omp.v6c4mkm2 agent-persona: generalist agent-supervisor: unavailable agent-tool: OMP agent-tool-version: 18.1.2 agent-runtime: OMP 18.1.2 tooling-profile: dotfiles@7534055
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
keep=trueexempted a dead session frompty gc's sweep for ever. Agents tag the session they are debugging now and never come back to untag it, so the exemption turns the registry into an append-only log — 740 of 911 sessions on one host, which is what prompted the upstream fix (compoundingtech/pty#173, merged86dcc5eb7).Change
Ports #173 exactly: same flag name, default, duration grammar, and output wording, so a shell user cannot tell the two binaries apart.
pty gc --keep-max-age <dur>(Ns|Nm|Nh|Nd, default7d; bare0sweeps every dead keep session on this pass). Both spellings,--flag Vand--flag=V. A unit-less non-zero value is rejected —--keep-max-age 7is ambiguous between seconds and days.registry::is_keep_expired+DEFAULT_KEEP_MAX_AGE_MSinpty-core(crates/pty-core/src/registry/tags.rs), besideis_keep_requested. Age anchors onexitedAt, falling back tocreatedAtfor avanishedsession that never wrote one — the anchor precedencepty list --older-thanalready uses. A record with neither timestamp, or an unparseable one, never expires except under0: retaining an unaged record is the recoverable failure, deleting it is not.is_gone()gate is unchanged, so a runningkeepsession survives--keep-max-age 0. Exit-time retention in the daemon is untouched and still unconditional.GcResult.keep_expiredis disjoint fromremoved, so the CLI printsRemoved (keep expired after 7d): <name>(Would remove …under--dry-run) plus anN keep-expired sessionsterm in the footer, and the retained line now names its window:Kept (keep tag): <name> — swept once dead for 7d, or remove the keep tag to reap it now.crates/pty/tests/fixtures/help/{gc,usage}.txt— vendored byte for byte from Node) and all three completion scripts carry #173's wording.docs/parity.md§12 records the flag as kept, §13 records #173 as merged-and-ported;docs/conformance.mdregenerated.Gates and evidence
cargo test -p pty-core --test registry_tags— 6 pass, including the newkeep_expiry_window(anchor precedence, unaged record, inclusive boundary,0sweeps everything).PTY_TEST_BIN=target/debug/pty cargo test -p pty-conformance --test gc_keep_expiry— 8 pass, mirroring #173's eight cases 1:1 with/// node:line refs: young kept; expired swept alongside a same-age untagged session with the two footer terms distinct; both flag spellings;0on a just-exited session;createdAtanchoring; a running keep session surviving0; two non-mutating dry runs then the real removal; unit-less flag rejected on stderr with exit 1.cargo test -p pty --test cli_gc --test help --test completions --test cli_dispatch, and-p pty-conformance --test gc --test gc_parent_child --test exit_reap— all green (exact-stdout expectations updated for the new retained-session line).Removed: stale,Removed (keep expired after 7d): old,Kept (keep tag): young — swept once dead for 7d, …,Cleaned up 1 stale session, 1 keep-expired session.;--dry-runidentical withWould …and nothing removed;--keep-max-age 0then sweepsyoung;--keep-max-age 7→pty gc: --keep-max-age expects a duration like 12h, 7d, or 0 (got "7"), exit 1.cargo test --workspace --no-fail-fast: 6 red binaries —daemon_geometry(3),daemon_lifecycle(1),daemon_roles(2),interactive_theme(1),fixtures_protocol(1) — proven pre-existing by re-running each with this branch's changes stashed: identical failures (pty daemon: the listener failed: Invalid argument (os error 22)on this host).registry_listfailed once under full-suite load and passes alone both with and without the change — the load-sensitive class README.md §"Reading a single failure from a full run" describes. Everything gc/keep-related is green.cargo clippy -p pty-core -p pty --all-targetsnames nothing in the changed code (the onegc.rshit,== falseat :572, is pre-existing and outside this diff).Intentionally left
cargo fmt. The tree has 1,080 pre-existing rustfmt deviations and norustfmt.toml; formatting would touch ~180 unrelated files. New code follows its neighbours and rustfmt where the two agree.crates/pty-conformance/tests/gc_keep_expiry.rsis written to run against either binary, but the installed Nodeptyis 0.12.0, which predates #173. Noted indocs/parity.md§13.docs/conformance.mdregeneration also picks up 4 pre-existing unmapped tests the committed copy predated (648 → 660 tests, of which 8 are this PR's).--idle-days/--fast-fail-*flags stay dropped and accepted-and-ignored, perdocs/parity.md§12.Refs compoundingtech/pty#173, schickling/dotfiles#2412.
Posted on behalf of @schickling
agent_identitysessionagent_personaagent_supervisoragent_toolagent_tool_versionagent_runtimetooling_profile