refactor(tracker): adopt asyncssh tracker_factory API - #4
Merged
Conversation
Rework the idle auto-stop integration onto the redesigned asyncssh forward-tracker API (fork v2.23.0+forward-tracker.3, agreed in upstream PR ronf/asyncssh#807). Externally observable behavior is unchanged. - activity.py: ActivityTracker becomes the per-daemon aggregate and a tracker factory via make_tracker(); the asyncssh-facing hooks move to a per-connection _IdleConnectionTracker(asyncssh.SSHPortForwardTracker) with _opened/_closed idempotency guards so a connection counts exactly once even if connection_lost fires twice. - ssh.py: open_local_forwards takes tracker_factory (was tracker) and forwards it as forward_local_port(tracker_factory=...). - manager.py: pass tracker_factory=activity_tracker.make_tracker. - pyproject.toml: bump asyncssh fork pin to v2.23.0+forward-tracker.3. - tests: rewrite activity/ssh-transport/idle-watchdog/manager fakes for the factory + per-connection pair. - docs/specs: add revision-history note recording the API shift.
AlexMKX
force-pushed
the
feature/forward-tracker-factory
branch
from
June 24, 2026 07:41
b870cb0 to
de380f3
Compare
AlexMKX
added a commit
that referenced
this pull request
Aug 10, 2026
…27) Three committed documents carried the literal path `/home/<user>/Projects/.../worktrees/tunstrap-issue15-spike`, publishing a username and an unrelated sibling project from a public repository. The sweep went wider than the three files named in the report -- other absolute home paths were sitting in a recipe example and in four test fixtures -- and all of them are now placeholders. The second half mattered more. Three live citations pointed into `docs/artifacts/`, which `.gitignore` excludes, so no reader could resolve them. One of the three justifies a production decision: `envrender.py` cites the measured provider precedence to explain why `KUBE_CONFIG_PATH` and `KUBE_CONFIG_PATHS` are never exported together, the rule that otherwise silently hides every cluster but the first. The Terragrunt recipe cited the same file at consumers. That measurement is a result, not scratch work, so it is now a committed document under `docs/specs/` and both citations point at it. Its source-corroboration section is scoped as inference rather than presented as verified source reading, because that is what it is. The e2e baseline citation was a different case and is not promoted. Its claim -- plan, mutate only the kubeconfig, apply the saved plan, zero mismatch -- has no test behind it, so removing the citation as "self-evident from the assertions" would have erased the only provenance a live manual measurement had. The recipe now says plainly that finding #4 comes from the unpublished spike and is not automated. Edits to frozen plan and spec documents are redactions and repoints only. One of them initially had its `docs/artifacts/` prefix stripped rather than resolved, which silenced the guard while leaving the citation dangling and added a false "now committed" claim about files that are not in the repo; it names the real spec now. The guard test enforces the property rather than a spelling. Matching the literal string `docs/artifacts/` is exactly what prefix-stripping evades, so it resolves path-like references and fails on any that `git check-ignore` excludes, plus bare `*-findings.md` names that resolve to nothing. It carries a documented allowlist marker so the next author has a route other than rewording around a regex, and it builds its own message sentinels by concatenation so it does not flag itself once tracked. Verification note: the e2e tier could not be run green for this commit -- `tofu init` fails with `registry.opentofu.org requires authentication credentials` while resolving the kubernetes and helm providers. That reproduces on an unmodified HEAD, so it is an upstream registry problem rather than a regression here; this change is documentation plus one test, and the only production edit is two docstring citations.
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.
What
Reworks the idle-auto-stop integration onto the redesigned asyncssh forward-tracker API. Externally observable behavior is unchanged — this is an integration-layer refactor to match the new upstream-agreed API shape.
Pairs with asyncssh fork
v2.23.0+forward-tracker.3(branchfeat/forward-tracker), the API agreed with the upstream maintainer in ronf/asyncssh#807.Why
The original
ForwardTracker(Protocol)(single object per listener,connection_made(orig_host, orig_port)/connection_lost(orig_host, orig_port, exc),tracker=kwarg) was redesigned during upstream review into a class hierarchy with a per-connection factory:asyncssh.SSHForwardTracker(parent, no-opconnection_lost+forward_local_bytes+forward_remote_bytes)asyncssh.SSHPortForwardTracker—connection_made(forwarder, orig_host, orig_port)(TCP)asyncssh.SSHPathForwardTracker—connection_made(forwarder)(UNIX)tracker_factory=kwarg, invoked once per accepted connectionChanges
activity.py—ActivityTrackeris now the per-daemon aggregate and the factory viamake_tracker(). The asyncssh-facing hooks move to a per-connection_IdleConnectionTracker(asyncssh.SSHPortForwardTracker)with_opened/_closedidempotency guards (a connection counts exactly once even ifconnection_lostfires twice). Public contract (make_tracker,note_connection_made,note_connection_lost,is_idle,seconds_since_activity) preserved.ssh.py—open_local_forwards(..., tracker_factory=...)(wastracker=), forwarded asforward_local_port(tracker_factory=...).manager.py— passestracker_factory=self.activity_tracker.make_tracker.pyproject.toml— asyncssh fork pin bumpedv2.23.0+forward-tracker.1→.3.test_activity/test_ssh_transport/test_idle_watchdog/test_manager_*fakes rewritten for the factory + per-connection pair.docs/specs/2026-05-21-auto-stop-idle-design.md— revision-history note recording the API shift.Verification
pytest tests/unit→ 213 passedactivity.py10.00/10connection_lostfixed) + RP/OP code-health-check → PASS (RP 32.3 / OP 29.0, max CC 4, MI grade A)