---
id: HF-TT-8
title: "Call-site sweep: hyperforge-hubs adopts every newtype"
status: Pending
type: implementation
blocked_by: [HF-TT-3, HF-TT-4, HF-TT-5, HF-TT-6, HF-TT-7]
unlocks: [HF-TT-9]
target_repo: hyperforge
severity: High
---

## Problem

HF-TT-3 through HF-TT-7 migrated `hyperforge-types` and `hyperforge-core` to newtypes, leaving transitional `NewtypeName::new(s)` casts at every seam where `hyperforge-hubs` (the activation implementations) calls core. Hubs still accept `String` in method signatures and convert internally. That defeats the type-level safety — a hub caller can pass the wrong string to a hub method and the cast silences the mistake. This ticket sweeps every hub method signature so the newtype appears in the hub's public surface, removes the transitional casts, and closes the last internal boundary where a raw `String` domain id could cross into the wrong-typed function.

## Context

`hyperforge-hubs` (post-HF-DC) holds the 7 activations: `HyperforgeHub`, `WorkspaceHub`, `RepoHub`, `BuildHub`, `ImagesHub`, `ReleasesHub`, `AuthHub`. ~74 methods distributed across these. Per HF-0, every method with a repo-name / package-name / version / path / credential / commit-ref / branch-ref / tag-ref parameter takes `String` or `&str` today.

HF-TT-3..7's commit messages each list a "transitional seam inventory" — the `RepoName::new(s)` calls the migration tickets introduced at hub-to-core boundaries. This ticket's unit of work is that inventory: every seam named by 3..7 is either removed (the hub method now takes the newtype) or moved further out (the hub accepts the newtype from the bin / wire layer; the cast moves to HF-TT-9's responsibility).

Wire format at the activation boundary (the Plexus RPC wire) stays byte-identical: method arguments are still strings on the wire. The newtype deserializes from the wire-string transparently because `#[serde(transparent)]` applies end-to-end. The type safety this ticket buys is Rust-internal — in-process callers of hub methods must construct the newtype rather than handing over a raw string.

File-boundary discipline: this ticket edits `crates/hyperforge-hubs/src/` exclusively. It does NOT touch `crates/hyperforge-types/`, `crates/hyperforge-core/`, or bins. This ticket is serial after 3..7 (all five must be Complete) and serial before 9 (bins depend on hubs' new signatures).

## Required behavior

| Before (hub method signature) | After |
|---|---|
| `async fn get_repo(&self, name: String) -> Result<Repo>` | `async fn get_repo(&self, name: RepoName) -> Result<Repo>` |
| `async fn list_packages(&self, org: String) -> Result<Vec<Package>>` | `async fn list_packages(&self, org: OrgName) -> Result<Vec<Package>>` |
| `async fn publish(&self, name: String, version: String)` | `async fn publish(&self, name: PackageName, version: Version)` |
| `async fn checkout(&self, branch: String)` | `async fn checkout(&self, branch: BranchRef)` |
| `async fn tag_release(&self, tag: String)` | `async fn tag_release(&self, tag: TagRef)` |
| `async fn set_secret(&self, key: String, value: String)` | `async fn set_secret(&self, key: CredentialKey, value: String)` (secret body stays String — not an id) |
| Internal `RepoName::new(s)` cast at hub-to-core seam | Removed; hub's caller already supplies `RepoName`. |

Wire compatibility: for every hub method whose signature changes, a wire-shape test in `crates/hyperforge-hubs/tests/wire_compat.rs` confirms that calling the method over the Plexus RPC wire with the same JSON payload produces the same response. Hub wire schemas (generated by `plexus_macros`) serialize `RepoName` transparently as a string, so no schema drift. Test fixture is a recorded request/response pair per activation, stored at `crates/hyperforge-hubs/tests/fixtures/wire/`.

Transitional-seam inventory: at ticket completion, `grep -rn 'RepoName::new\|OrgName::new\|WorkspaceName::new\|PackageName::new\|Version::new\|CommitRef::new\|BranchRef::new\|TagRef::new\|RepoPath::new\|WorkspaceRoot::new\|CredentialKey::new' crates/hyperforge-hubs/` returns zero results (or only results in wire-deserialization glue if any; those are flagged and justified in commit message).

## Risks

| Risk | Mitigation |
|---|---|
| A hub method accepts both a string id and a free-text field with the same raw type, and the compiler can't tell which to migrate. | Each ambiguous site gets an inline comment citing the field's semantic. S01's overloaded-fields list preempts most; new cases file a follow-up. |
| `plexus_macros` wire schema changes unexpectedly when signatures change. | Wire-compat fixtures assert identical schema JSON pre/post. If the schema diffs, ticket blocks until resolved. |
| A hub method has deprecation info or a child-gate annotation from HF-IR; those attributes must survive. | HF-IR hasn't run yet — no such annotations exist at this ticket's execution time. If they were added mid-epic (they won't be — HF-IR is gated behind HF-TT completion), this ticket breaks and surfaces the violation. |

## What must NOT change

- Wire format of any hub method — byte-identical request/response JSON.
- `plexus_macros`-generated schemas — byte-identical schema JSON.
- Activation namespaces.
- Method names.
- Files outside `crates/hyperforge-hubs/`.

## Acceptance criteria

1. Every hub method whose parameters were newtype-migrated in HF-TT-3..7 now accepts the newtype at the signature level.
2. Transitional casts removed from hub bodies: `grep` for `<Newtype>::new(` patterns across `hyperforge-hubs` returns zero (modulo glue code flagged in commit message).
3. Wire-compat tests pass: every migrated hub method's request/response JSON is byte-identical pre/post against the recorded fixture.
4. `plexus_macros`-generated schema JSON is byte-identical (verified by schema snapshot test).
5. `cargo build --workspace` green in hyperforge.
6. `cargo test --workspace` green in hyperforge.
7. File-boundary check: `git diff --stat` touches only `crates/hyperforge-hubs/` files + the wire-compat fixtures dir. No type-crate or core-crate edits.
8. Sibling-repo audit: consumer repos that use hub types as dependencies still build. Any that don't build are triaged in the commit message and become HF-TT-10's scope.
9. `hyperforge-hubs` minor version bumped; tag `hyperforge-hubs-v<version>` local, not pushed.

## Completion

Implementor commits the hub-surface migration, wire-compat fixtures, version bump, confirms workspace + consumer audit green, tags local, flips status to Complete in the same commit. Any consumer-repo build failures discovered here become HF-TT-10's input list.
