Found during the architecture audit (sub-agent review). AGENTS.md designates graphforge-api the public API.
Finding (MEDIUM)
The CLI bypasses the facade into storage internals, creating a second parallel path for the same operations the bindings use:
cli/Cargo.toml:18 — production dep cli → storage
cli/src/hub_clone.rs:2061-2075 — calls graphforge_storage::{resolve_project_generation, plan_complete_portable_v2, export_complete_portable_v2, verify_portable_v2} directly
cli/src/hub_fixture_artifacts.rs:11 — repack_verified_expanded_portable_v2
cli/src/portable_cli.rs:472 — StorageAllocationLifecycle
- The facade already exposes the same ops (
api/src/portable.rs:254 verify_portable_v2, re-exported api/src/lib.rs:170)
The duplicate path can diverge behaviorally from the facade used by Python/Node.
Acceptance criteria
Architecture review decision
Co-design this with #1021. The API facade should own portable-v2 orchestration while a dedicated portable/OCI protocol crate may own network transport. Moving the registry client into graphforge-discovery is not assumed.
Additional acceptance criteria:
Found during the architecture audit (sub-agent review). AGENTS.md designates
graphforge-apithe public API.Finding (MEDIUM)
The CLI bypasses the facade into storage internals, creating a second parallel path for the same operations the bindings use:
cli/Cargo.toml:18— production dep cli → storagecli/src/hub_clone.rs:2061-2075— callsgraphforge_storage::{resolve_project_generation, plan_complete_portable_v2, export_complete_portable_v2, verify_portable_v2}directlycli/src/hub_fixture_artifacts.rs:11—repack_verified_expanded_portable_v2cli/src/portable_cli.rs:472—StorageAllocationLifecycleapi/src/portable.rs:254verify_portable_v2, re-exportedapi/src/lib.rs:170)The duplicate path can diverge behaviorally from the facade used by Python/Node.
Acceptance criteria
graphforge-api(facade re-exports or new facade methods)Architecture review decision
Co-design this with #1021. The API facade should own portable-v2 orchestration while a dedicated portable/OCI protocol crate may own network transport. Moving the registry client into
graphforge-discoveryis not assumed.Additional acceptance criteria:
graphforge-apiexposes the complete supported portable workflow without leaking storage-internal types