Skip to content

feat: add GitHub transport and Source Control settings - #647

Merged
Tryanks merged 5 commits into
mainfrom
feat/github-transport
Oct 8, 2026
Merged

Tryanks merged 5 commits into
mainfrom
feat/github-transport

Conversation

@Tryanks

@Tryanks Tryanks commented Oct 8, 2026

Copy link
Copy Markdown
Owner

Summary

Settings → Source Control
  per-host settings patch / write-only token command
  runtime single settings writer → secrets.json
  HostCx::unblock → services::github
    saved token → bound environment token → gh keyring
    header quota ledger / generation-leased host pause
    eight I/O permits → ureq → typed REST / GraphQL answer
    aliased variables / bounded cursor paging
version_check → same transport, anonymous version-check namespace

Closes #638.

Adds host-bound credentials, SHA-256 fingerprints and cached verified identity; 30-second whole-response result deadlines, bounded 8 MiB responses, ordered error classification, conditional reads, and cancellation-safe permits. Quota comes exclusively from server headers. Source Control shows host enablement, multiple gh accounts, write-only token controls and the active credential source in both locales. Release assessment behavior remains unchanged and runs independently of Source Control enablement. The wire note is added without a protocol bump.

Provider secrets and GitHub tokens share the existing single writer, with separate namespaces in a versioned secrets envelope. Literal legacy profile IDs, including github, remain readable and migrate on the next write. Secret commands retain reconnect delivery keys in memory but never enter the persisted outbox.

sha2 is a new direct services dependency, already present in the workspace lockfile. Genuine SHA-256 fingerprints/document hashes justify this edge; implementing cryptography locally would be less reliable. No additional HTTP or test dependency was added.

Evidence

  • Before: release checks used their own HTTP path; Source Control had no settings surface or shared GitHub credential/quota owner.
    After: release checks and authenticated calls share the transport; ten real-client HTTP/process fixture tests cover mapping, precedence, errors, reserve/interactive admission, free 304s, 401 refresh, generation ordering, pinned identity, body/deadline bounds, dropped waiters and GraphQL paging. Runtime and client tests independently cover the real settings writer and reconnect/persistence boundary.
  • Before: the reconnect regression failed at request.key.is_some() with the initial unkeyed secret policy; the storage regression lost the legacy provider named github with a flat reserved namespace.
    After: both pass with keyed in-memory secret delivery and unambiguous versioned storage, including independent updates and fail-closed unsupported files.

Checks on final commit 722f6ad1:

cargo fmt --all --check
  exit 0 (no output)
cargo clippy --workspace --all-targets --locked -- -D warnings
  Finished `dev` profile [unoptimized + debuginfo] target(s) in 9.87s
PATH=/tmp/638-nextest:$PATH cargo nextest run --workspace --locked
  Summary [60.766s] 1007 tests run: 1007 passed, 13 skipped
cargo machete
  cargo-machete didn't find any unused dependencies in this directory. Good job!

Focused final validation: 14 passed, 284 skipped. GitHub stress validation: ten iterations of ten tests, all 100 executions passed without LEAK warnings. Desktop and phone example builds passed. Mobile/Web and other desktop OS builds remain for CI; no live enterprise host was available. Existing dependency block v0.1.6 emits a future-incompatibility notice.

Live: gh auth token --hostname github.com exited 0 with stdout discarded. cargo run -p tcode-services --example github_identity --locked returned GET /user succeeded: login=Tryanks, id=49746336, source=Gh. No token was printed or committed.

Screenshots use fresh mktemp profiles, English, synthetic projects/accounts/hosts and no live profile data. Captured from the shared desktop shell and phone example with --local:

Desktop light Desktop dark
Desktop light Desktop dark
Phone light Phone dark
Phone light Phone dark

Test audit: declarations 1,018 → 1,030; no existing tests deleted or rewritten. Rust production lines +1,922/−59; test lines +1,489/−0; test-support lines 0. An independent review found no remaining findings. Existing version assessment tests remain intact.

Failed/new tests were settled under CONTRIBUTING as follows:

  • secrets_keep_reconnect_delivery_keys_without_entering_the_persisted_outbox and github_secret_command_persists_separately_and_settings_never_replicate_it: step 3, demonstrated pre-fix failures repaired at the client/storage owners.
  • Initial secret_commands_cross_the_live_wire_without_entering_the_persisted_outbox: step 1, submissions now exercise an attached transport; its authored case was subsequently strengthened and renamed to the keyed reconnect test above, preserving offline refusal and legacy-outbox purge.
  • whole_response_result_deadline_includes_a_stalled_dns_resolver: step 1, the HTTP fixture now accepts EOF from a timed-out connection and keeps serving the next request, as the real server would.
  • LEAK warnings in maps_hosts_and_keeps_saved_environment_and_enterprise_credentials_in_their_boundaries, aliases_and_pager_send_values_as_variables_and_report_unread_tail, latest_arrival_can_restore_quota_but_an_older_success_cannot_clear_a_new_refusal, and pinned_verified_identity_is_cached_per_fingerprint_and_refuses_another_host: dependency investigation steps 1–4, macOS Nextest 0.9.133 capture-pipe inheritance race. Read the dependency source and upstream fix, then repeated unchanged tests using checksum-verified official Nextest 0.9.146 in /tmp; no assertions, leak timeout or repository runner configuration were relaxed.

Upstream takes precedence where issue wording differs: githubQuota.ts:85–92 admits background requests at the 10% floor, and GitHubApi.ts:329–335 returns NOT_FOUND only when all GraphQL errors are NOT_FOUND. Both behaviors are preserved and exercised.

Merge Danger

Door: one-way

The next secret write upgrades the flat provider map to a versioned envelope. Binary-only rollback to an older build cannot read that envelope; rollback requires restoring the old file or flattening its profiles section. Legacy entries are preserved during migration, including names that collide with envelope keys.

Blast Radius: credentials

Changes shared secret storage and secret command persistence as well as GitHub requests and version checks. Raw REST responses explicitly flag truncation; JSON and GraphQL success reject truncated bodies. A timed-out DNS/TLS job can remain blocked in the OS, but keeps its permit until it exits, so outstanding I/O stays bounded to eight jobs.

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.

Source control: GitHub API transport, credentials and settings (A1)

1 participant