Skip to content

refactor: trim A1 GitHub transport to what #638 asked for - #650

Merged
Tryanks merged 4 commits into
mainfrom
fix/a1-scope
Oct 8, 2026
Merged

Tryanks merged 4 commits into
mainfrom
fix/a1-scope

Conversation

@Tryanks

@Tryanks Tryanks commented Oct 8, 2026 •

Copy link
Copy Markdown
Owner

Summary

Corrective follow-up to #647 (phase A1, #638): it removes what #638 did not ask for and simplifies the rest.

secrets.json                     before (#647)                      after
  layout        {"version":1,"github":{…},"profiles":{…}}  {"<profile>":{…}, "@github":{host: token}}
  rollback      one-way: older builds read nothing             two-way: older builds keep "@github" as an unknown profile

services::github::api::execute
  before  unblock job ─► spawn "github-io" thread (+permit) ─► recv_timeout(deadline)
  after   unblock job ─► permit ─► ureq request with its deadline   (the job owns the permit)

removed   Refresh-credentials button · github_identity example · ureq=off log filter (app, headless)
          identity single-flight gates + 128 cap · InvalidPath guard · Anonymous{namespace}
          Credential::{fingerprint,source} getters · legacy-outbox secret purge
          GitHubSettings.status clears in SettingsStore::{load,save}
          second settings.json read in Credentials::new (AppState configures hosts)
docs      CONTRIBUTING → Verifying real behaviour: phone example --local (#649)

Refs #638, #649.

Evidence

  • Before: Settings → Source Control had a trailing "Refresh credentials" button (desktop, phone).
    After: re-entering the section already rescans gh (GitHubSettingsPanel::show), so the button is gone. Fresh TCODE_DATA_DIR, English, synthetic hostname, a fake gh with logins sample-user/sample-work, and a synthetic saved token for github.example.com:
Desktop light Phone light
Desktop light Phone light
  • Before: secrets.json became a versioned envelope on the first secret write after feat: add GitHub transport and Source Control settings #647, which older builds cannot read.
    After: the file stays the flat profile map. GitHub tokens sit under @github, a key no profile id can take: user ids are slugs of [a-z0-9-] and built-ins are fixed (Settings::allocate_profile_id, builtin_profile_id). github_secret_command_persists_separately_and_settings_never_replicate_it now asserts:
    • the written file still parses as BTreeMap<String, BTreeMap<String, String>> (the shape older builds read);
    • a legacy profile literally named github keeps its secrets;
    • an unreadable file is never overwritten.

Checks on the final commit:

cargo fmt --all --check                                         exit 0
cargo clippy --workspace --all-targets --locked -- -D warnings  exit 0 (only the existing block v0.1.6 future-incompat note)
cargo nextest run --workspace --locked                          Summary [56.215s] 1006 tests run: 1006 passed, 13 skipped (no LEAK/FAIL)
cargo nextest run -p tcode-services --test github, ×10          9 passed each run
cargo machete                                                   didn't find any unused dependencies
  • Live: gh auth token --hostname github.com exited 0 (stdout discarded). An uncommitted scratch example, since deleted, ran the authenticated GET /user through GitHubApi::verified_credential with the env tokens removed and got login=Tryanks.
  • Mobile, Web and other desktop OS builds are left to CI.

Tests deleted or rewritten (CONTRIBUTING, "When a test fails, or is met on the way"):

  • whole_response_result_deadline_includes_a_stalled_dns_resolver: deleted (step 2). It proved a result deadline around DNS that only the per-request thread provided. ureq 2 does not bound DNS (ureq-2.12.1/src/stream.rs:364, "TODO: Find a way to apply deadline to DNS lookup"). The system resolver bounds it instead, and that is carried in a comment at execute. The connect, TLS, write and body deadline stays covered by body_cap_and_deadline_cover_streaming_after_headers.
  • github_secret_command_persists_separately_and_settings_never_replicate_it: envelope assertions removed with the envelope (version, profiles, unsupported version). The flat-format, legacy-github-profile and fail-closed contracts remain.
  • secrets_keep_reconnect_delivery_keys_without_entering_the_persisted_outbox: the legacy-outbox purge assertions are removed with the purge. Restored entries are delivered from memory, and the next persist drops them from disk through the existing snapshot filter.

Test declarations: 1030 → 1029. Production Rust and locales: +77/−260 lines; docs: +6. Tests: +23/−99.

Merge Danger

Door: two-way

Blast Radius: credentials

  • Intermediate main builds: a profile that ran a main build between feat: add GitHub transport and Source Control settings #647 and this PR has the {"version":1,…} envelope. This build reads no provider secrets from it and refuses to write over it (settings_write_failed); it does not erase it. Fix by hand: move profiles.* to the root and github to @github. Check with jq 'has("version")' ~/.tcode/secrets.json. No release contains feat: add GitHub transport and Source Control settings #647 (git tag --contains ebd4f659 is empty).
  • Rolled-back builds: an older build lists @github among provider secret names (host names only, never values) and preserves it on writes.
  • DNS stall: a stalled DNS lookup now holds its caller's blocking job until the system resolver gives up, not only until the 30 s result deadline. The permit stays held either way.

@Tryanks
Tryanks marked this pull request as ready for review October 8, 2026 11:26
@Tryanks
Tryanks merged commit 1974084 into main Oct 8, 2026
7 checks passed
@Tryanks
Tryanks deleted the fix/a1-scope branch October 8, 2026 11:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant