Files
DeepSeek-Reasonix/go.mod
T
84988e8cdb fix(cli): TUI diagnostics, keyring timeout, Reasonix-home paths / 启动诊断、keyring 超时与 home 路径加固 (#7663)
* fix(cli): harden TUI diagnostics, keyring migration, and home paths

Problem:
- Interactive TUI freezes left zero-byte cli-tui logs and unrecoverable
  terminals on Windows ConPTY and stuck D-Bus startups (#7435, #7507).
- Global hooks/doctor/capdiag could miss the real Reasonix home on Windows
  AppData and REASONIX_HOME isolation (#7411, #7331).
- Legacy keyring migration blocked startup when Secret Service hung.
- #7600's automatic HOME rewrite risked breaking isolation contracts.

Root cause:
- Diagnostics started after heavy work and never flushed milestones/heartbeats.
- Hooks resolved global settings via derived ~/.reasonix rather than the exact
  Reasonix home used by the rest of the product.
- Keyring probes ran unbounded per key with file import ordered after D-Bus.
- Subprocess HOME rewriting conflates service HOME with Reasonix isolation.

Fix:
- Start TUI diagnostics before config/controller work; record milestones and
  flush immediately; 1s heartbeat with 10s stall → goroutine dump + Program.Kill.
- Unify hook/capdiag/doctor on exact ReasonixHomeDir; public paths show
  <reasonix-home>.
- Legacy credential migration: files first, then shared 1s keyring budget with
  empty-success markers; timeout leaves no marker for retry.
- Doctor warns when process HOME ≠ account home without REASONIX_HOME; do not
  auto-rewrite subprocess HOME (#7600 not adopted).

Verification:
- go test ./internal/cli ./internal/config ./internal/hook ./internal/capdiag ./internal/doctor -count=1

Co-authored-by: Zhiyao Wen <[email protected]>
Co-authored-by: zhaotian1 <[email protected]>

* fix(cli): isolate keyring probes and tighten migration markers

Problem:
- In-process keyring timeouts could leave hung D-Bus goroutines and
  collapse found/absent/error/timeout into a single false, risking wrong
  migration-done markers (#7507 audit).
- Keyring markers also skipped legacy credential *file* import.
- doctor HOME warning leaked absolute account paths into shareable reports.
- lint failed on an unused diagnostics mutex; CodeQL flagged SHA-256 of env
  names as secret-like storage.

Root cause:
- Timeout wrappers cannot cancel platform keyring calls in-process.
- skip() treated keyring markers as global migration completion.
- redactHome only knows the process HOME, not the OS account home.

Fix:
- Run legacy keyring batch probes in an isolated helper child with a shared
  1s deadline; parent Kill+Wait on timeout (no parent goroutine leak).
- Four-state outcomes: found / absent / error / timeout; write markers only
  on confirmed absent.
- File import always runs first; markers only filter keyring probes.
- Marker paths use sanitized env names under legacy-keyring-checked/.
- doctor reports HOME mismatch without embedding either path.
- Watchdog WaitGroup drains before closing the diagnostic log file.

Verification:
- go test ./internal/config ./internal/doctor ./internal/cli ./internal/hook ./internal/capdiag -count=1
- go vet ./internal/cli ./internal/config ./internal/doctor

* fix(cli): keyring four-state to metal and secret-free helper

Problem:
- Platform keyring probes still returned (string, bool), so D-Bus/unlock
  failures were treated as absent and could write migration markers.
- The isolated helper printed keyring secrets on stdout, making any
  process that can launch reasonix a credential oracle.
- Watchdog Close waited only 2s, so a stuck Stack/Sync/Kill could write
  a closed diagnostic file.
- Marker names folded distinct keys onto "_" collisions.

Root cause:
- Four-state status stopped at the batch layer; the Secret Service path
  collapsed every error to false.
- Helper was designed as a value RPC instead of an in-child store step.
- Close used a timed wait instead of joining the watchdog fully.

Fix:
- legacyKeyringProbe returns found/absent/error at the platform layer
  (ErrNotFound/empty search → absent; transport/unlock/session errors →
  error).
- Helper stores found secrets via StoreCredentialLines and emits only
  key+status metadata on stdout (no value field).
- Parent never receives secret Values from the helper path; markers only
  on confirmed absent.
- Watchdog WaitGroup is joined fully before closing the log file.
- Marker basenames use base64.RawURLEncoding of the env name.

Verification:
- go test ./internal/config ./internal/cli ./internal/doctor -count=1
- New tests: error does not write marker; helper JSON has no secrets;
  RawURL marker collision-free; four-state in-process outcomes

* fix(cli): drop keyring helper oracle; atomic store-if-absent

Problem:
- The REASONIX_LEGACY_KEYRING_HELPER entrypoint let any process that can
  launch reasonix dump keyring secrets into a caller-controlled
  REASONIX_HOME/.env (disk oracle after stdout was scrubbed).
- Legacy import could overwrite a concurrent settings write or tombstone
  because presence was checked outside the credential lock.

Root cause:
- Migration used an external helper to bound D-Bus hangs, which reopened
  a secret export surface via StoreCredentialLines + controllable home.
- store used unconditional StoreCredentialLines after a TOCTOU check.

Fix:
- Remove the helper entrypoint entirely (main + env dispatch).
- Linux/BSD Secret Service probes use godbus CallWithContext under a
  shared 1s batch deadline so stuck D-Bus calls cancel in-process.
- Found secrets are written only via storeCredentialIfAbsentAndNotCleared
  (same advisory lock re-checks missing/not-cleared before write).
- Channel-forced tests cover user-value and tombstone races without sleep.

Verification:
- go test ./internal/config ./internal/cli ./internal/doctor -count=1
- REASONIX_LEGACY_KEYRING_HELPER=1 reasonix --version is a normal version
  print (no helper path, no oracle home writes)

* fix(cli): private ctx-bound D-Bus keyring and real probe races

Problem:
- dbus.SessionBus left process-global godbus workers that failed goleak
  under Ubuntu/race/coverage.
- GetProperty and session Close used non-context call paths, so a stuck
  bus could still hang CLI past the 1s migration budget.
- Race tests called store-if-absent directly and never forced the
  production probe→store window.

Root cause:
- Shared SessionBus + GetProperty(Background) escaped the batch ctx.
- Channel tests interleaving happened outside lookupLegacyKeyringBatch.

Fix:
- Open a private ConnectSessionBus per probe, race Dial/Auth/Hello
  against the shared ctx, and always Close the connection.
- Resolve Collections and Close sessions only via CallWithContext(ctx).
- Drive store-if-absent races through a blocking probe stub inside
  lookupLegacyKeyringBatch (user write and tombstone cases).
- go mod tidy promotes godbus to a direct dependency.

Verification:
- go test ./internal/config -count=1
- go test -race ./internal/config -count=1
- go test ./internal/control -count=1

* fix(cli): bind keyring bus connect to batch context

Problem:
- ConnectSessionBus had no dbus.WithContext, so a stuck Auth/Hello after
  Dial could keep the connect goroutine and late reaper parked forever
  even though the caller returned at 1s.

Root cause:
- Connection lifecycle was only raced externally; godbus never received
  the migration ctx to Close the transport on deadline.

Fix:
- SessionBusPrivateNoAutoStartup(dbus.WithContext(ctx)) then Auth+Hello,
  so cancel closes the transport and unblocks Auth/Hello I/O.
- Avoid dbus-launch (NoAutoStartup): missing session address fails closed
  instead of hanging in CombinedOutput.
- Outer select still bounds the caller; late *Conn is always closed.
- Document residual: pure Dial hang before newConn remains a godbus limit.

Verification:
- go test ./internal/config -count=1
- go test -race ./internal/config -count=1
- go test ./internal/control -count=1
- GOOS=linux go test ./internal/config -c

* ci: allow Windows smoke runner variance

Problem: The Windows smoke step regularly takes 7-9 minutes and the current run exceeded its 10-minute job budget even though vet and build succeeded.

Root cause: The job-level timeout leaves too little headroom for hosted Windows runner variance.

Fix: Raise only the pull-request Windows smoke job budget to 15 minutes while retaining the per-package 3-minute Go test timeout.

Verification: YAML parse; git diff --check; go test ./internal/cli ./internal/config -count=1.

---------

Co-authored-by: Zhiyao Wen <[email protected]>
Co-authored-by: zhaotian1 <[email protected]>
2026-08-06 14:39:56 +08:00

67 lines
2.3 KiB
AMPL

module reasonix
go 1.25.0
toolchain go1.26.5
require (
charm.land/bubbles/v2 v2.1.0
charm.land/bubbletea/v2 v2.0.7
charm.land/lipgloss/v2 v2.0.4
git.sr.ht/~jackmordaunt/go-toast/v2 v2.0.3
github.com/BurntSushi/toml v1.6.0
github.com/alecthomas/chroma/v2 v2.27.0
github.com/atotto/clipboard v0.1.4
github.com/aymanbagabas/go-udiff v0.4.1
github.com/bmatcuk/doublestar/v4 v4.10.0
github.com/charmbracelet/colorprofile v0.4.3
github.com/charmbracelet/x/ansi v0.11.7
github.com/godbus/dbus/v5 v5.2.2
github.com/joho/godotenv v1.5.1
github.com/kevinburke/ssh_config v1.6.0
github.com/larksuite/oapi-sdk-go/v3 v3.9.5
github.com/mattn/go-runewidth v0.0.24
github.com/pkg/sftp v1.13.10
github.com/rivo/uniseg v0.4.7
github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2
github.com/spf13/pflag v1.0.6
github.com/tree-sitter/go-tree-sitter v0.25.0
github.com/tree-sitter/tree-sitter-javascript v0.25.0
github.com/tree-sitter/tree-sitter-python v0.25.0
github.com/tree-sitter/tree-sitter-rust v0.24.2
github.com/tree-sitter/tree-sitter-typescript v0.23.2
github.com/yuin/goldmark v1.8.2
github.com/zalando/go-keyring v0.2.8
go.uber.org/goleak v1.3.0
golang.org/x/crypto v0.53.0
golang.org/x/image v0.43.0
golang.org/x/mod v0.37.0
golang.org/x/net v0.56.0
golang.org/x/sys v0.46.0
golang.org/x/term v0.44.0
golang.org/x/text v0.39.0
gopkg.in/yaml.v3 v3.0.1
mvdan.cc/sh/v3 v3.13.1
)
require (
github.com/charmbracelet/ultraviolet v0.0.0-20260601155805-6cf7526a1b3f // indirect
github.com/charmbracelet/x/term v0.2.2 // indirect
github.com/charmbracelet/x/termios v0.1.1 // indirect
github.com/charmbracelet/x/windows v0.2.2 // indirect
github.com/clipperhouse/displaywidth v0.11.0 // indirect
github.com/clipperhouse/uax29/v2 v2.7.0 // indirect
github.com/danieljoos/wincred v1.2.3 // indirect
github.com/dlclark/regexp2/v2 v2.2.1 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/kr/fs v0.1.0 // indirect
github.com/lucasb-eyer/go-colorful v1.4.0 // indirect
github.com/mattn/go-pointer v0.0.1 // indirect
github.com/muesli/cancelreader v0.2.2 // indirect
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
golang.org/x/sync v0.21.0 // indirect
)