Unify signing identity resolution across all transport callers
Background
Every command that calls HttpTransport must pass a SigningIdentity resolved against the actual target remote URL, not the repo's default hub URL. The two can differ — e.g. when a named remote points to staging while the repo's [hub] url is localhost:1337.
The current codebase has inconsistent patterns across callers. ls-remote had a concrete bug (HTTP 401 on staging) because it called get_signing_identity(root) before resolving the remote URL. Fix shipped in feat/test-merge-6. The remaining callers need auditing.
Callers and current pattern
ls_remote.py — get_signing_identity(root, remote_url=url) after URL resolution — FIXED fetch.py — get_signing_identity(root, remote_url=url) — correct clone.py — get_signing_identity(root, remote_url=url) — correct pull.py — get_signing_identity(root) no remote_url — needs audit push.py — get_signing_identity(root) no remote_url — needs audit release.py — needs audit domains.py — needs audit
Also spotted
proposalType returned by the hub still uses 'state_merge' — legacy value not covered by migration 0070 which only handled mergeStrategy. Needs its own migration and enum cleanup.
Proposed phases
Phase 1 — Audit all callers. Read each, verify remote_url is forwarded to get_signing_identity. Document broken ones.
Phase 2 — Fix callers. Resolve URL first, then call get_signing_identity(root, remote_url=url). Add regression tests matching TestSigningIdentityForwarding in test_cmd_ls_remote.py.
Phase 3 — proposalType canonical cleanup. Migration 0071 to rename state_merge to merge. Update enum, service, MCP tools, templates.
Phase 4 — Integration test. Verify ls-remote, fetch, pull, push against a non-default hub URL produce no 401s.
Closing as duplicate. Consolidated into #20 with full audit results and accurate phase breakdown.