Skip to content

refactor: switch shared types to common; delete duplicated pkg/*#152

Closed
TeoSlayer wants to merge 5 commits into
mainfrom
web4-cleanup-after-common-extraction
Closed

refactor: switch shared types to common; delete duplicated pkg/*#152
TeoSlayer wants to merge 5 commits into
mainfrom
web4-cleanup-after-common-extraction

Conversation

@TeoSlayer
Copy link
Copy Markdown
Owner

Summary

Phase 3 of the common-extraction migration.

  • Sweeps every web4 .go file (cmd/* + pkg/* + tests) to import from pilot-protocol/common instead of TeoSlayer/pilotprotocol/pkg/*.
  • Adds replace github.com/pilot-protocol/{sibling} => ../{sibling} for every migrated sibling so the local checkout drives the build.
  • Deletes web4/pkg/{coreapi,protocol,driver,config,logging,urlvalidate,secure,registry/client,registry/wire} and web4/internal/ipcutil (now duplicated in common).

What stays in web4

  • pkg/daemon (the daemon engine — handshake/runtime/libpilot are tightly coupled to it as plugins; their coupling stays)
  • pkg/registry (registry server)
  • cmd/daemon, cmd/pilotctl

Test plan

  • go build ./... passes
  • cmd/daemon builds (14.4 MB binary)
  • cmd/pilotctl builds (13.5 MB binary)
  • Verify release.yml's BINS list — gateway/registry/beacon/rendezvous/nameserver/updater no longer build from web4 (they were extracted to siblings); needs follow-up to update release.yml or restore the cmd/* dirs.

Depends on

  • pilot-protocol/common Phase 1 PR (the actual package additions)
  • All 16 sibling migrate-to-common PRs (so they can be resolved by the orchestrator)

🤖 Generated with Claude Code

teovl added 4 commits May 28, 2026 12:50
Drop a TODO at the top of release.yml enumerating which secrets need to
be re-created on `pilot-protocol/` before the repo transfer, since
GitHub secrets do not survive a repo transfer.

Currently the only expected secret is GITHUB_TOKEN (auto-issued).
HOMEBREW_TAP_TOKEN was removed in #122 when update-homebrew.yml was
dropped, and NPM_TOKEN / PYPI_TOKEN / COSIGN_KEY are placeholders for
the auto-publish (PILOT-203) and binary-signing (PILOT-114) work that
hasn't landed yet.

This is documentation only — no behavior change. The comment block is
load-bearing for the org migration; deleting it before the new org has
its secrets configured will silently break the next release.
Two new jobs run after the existing release job:

publish-manifest builds public/.well-known/latest.json from the tag's
checksums.txt, then repository_dispatches it to pilot-protocol/website,
which commits the JSON to main and triggers the Cloudflare deploy. The
single canonical manifest at pilotprotocol.network/.well-known/latest.json
is consumed by install.sh, the Homebrew formula bump workflow, and the
SDK release helpers — one shockwave per release.

shockwave fans out repository_dispatch(event_type=upstream-release)
to homebrew-pilot, sdk-node, sdk-python, and sdk-swift so each consumer
can run its own bump workflow. Per-target dispatch is soft-fail with a
summary so a missing token on one repo does not block the others.

Both jobs require a new SHOCKWAVE_DISPATCH_TOKEN secret with
repository_dispatch scope on each downstream repo (prefer a GitHub App
token over a PAT). When the secret is absent the steps emit a clear
::warning:: and exit 0 so existing release flow is not broken.
…ver templates

Adds a central release orchestrator that handles bidirectional dependency
propagation: when any package in the constellation ships a release, the
set of downstream nodes that need a bump is computed automatically and
each gets a dispatch in topological order.

Files:

  .github/deps.json
    Canonical dependency graph. 25 nodes: hub (web4), 15 Go siblings, 1
    Go app, 1 FFI fan-in (libpilot), 3 SDKs, 1 brew tap, 1 surface
    (website), 3 freeloaders (cosift, pilot-ca, wallet). Each node
    declares its depends_on edges and a bump_policy (stable_only,
    auto_commit_main, open_pr_instead_of_main). This is the single
    source of truth — changes to the graph are PR-reviewed diffs here.

  .github/workflows/orchestrator.yml
    Receives package-released dispatches from any node. Computes the
    reverse-transitive closure of the released package (BFS by depth
    in deps.json), filters per-receiver stable_only when the upstream
    is a prerelease, then fan-outs bump-upstream dispatches to each
    affected repo. Supports workflow_dispatch with a dry_run flag for
    rehearsal.

  .github/workflows/_template-emit-release.yml
    Reusable workflow that any sibling adopts: at the end of its own
    release.yml it calls this with the node name, and it dispatches
    package-released to the orchestrator. One token per sibling
    (ORCHESTRATOR_DISPATCH_TOKEN) covers the hop.

  .github/workflows/_template-bump-upstream.yml
    Generic receiver template for Go-sibling repos: receives
    bump-upstream, runs go mod edit -require=<module>@<version> +
    go mod tidy + go build sanity check, then either commits to main
    or opens a PR based on BUMP_MODE. SDK repos will need their own
    package-manager-specific variants.

Closure smoke-tests pass:

  web4      → 22 targets (every depending node, ordered by depth)
  policy    → 4 targets  (libpilot + 3 SDKs)
  handshake → 4 targets  (libpilot + 3 SDKs)
  libpilot  → 3 targets  (3 SDKs)
  sdk-node  → 0 targets  (leaf)
  cosift    → 0 targets  (freeloader)

This SUPERSEDES the direct shockwave fan-out in PR #151's release.yml
once orchestrator adoption rolls out — the four hardcoded repos there
become entries in deps.json instead. Keeping #151's direct fan-out for
now as the bootstrap path (orchestrator needs SHOCKWAVE_DISPATCH_TOKEN
set before it can do anything).
Phase 3 of the common-extraction migration. With common containing
coreapi, protocol, driver, registry/{client,wire}, config, logging,
urlvalidate, secure, ipcutil, web4 no longer needs to host the same
types. This commit:

  - sweeps every web4 .go file (cmd/* + pkg/* + tests) to import
    github.com/pilot-protocol/common/X instead of
    github.com/TeoSlayer/pilotprotocol/pkg/X for the migrated set
  - adds 'replace github.com/pilot-protocol/{sibling} => ../{sibling}'
    for every sibling so the local checkout (with its own migrated
    imports) drives the build, not the cached v0.1.0 from before the
    extraction
  - DELETES web4/pkg/{coreapi,protocol,driver,config,logging,urlvalidate,
    secure,registry/client,registry/wire} and web4/internal/ipcutil

What stays in web4:
  - pkg/daemon (the daemon engine itself; tightly coupled to handshake,
    runtime, libpilot which keep their pkg/daemon import)
  - pkg/registry (the registry server — only cmd/registry uses it,
    and cmd/registry has migrated to a sibling)
  - cmd/daemon, cmd/pilotctl (binaries built here; other binaries
    moved to their sibling repos)

The locally-circular sibling↔web4 dependency is now broken for the
shared-type packages, which is what 14 of 16 siblings cared about.
handshake/runtime/libpilot remain co-built with web4 because they
extend the daemon engine — that coupling is structural, not accidental.

cmd/daemon and cmd/pilotctl both build cleanly post-migration.
@TeoSlayer TeoSlayer requested a review from Alexgodoroja as a code owner May 28, 2026 22:59
@hank-pilot
Copy link
Copy Markdown
Collaborator

hank-pilot commented May 28, 2026

🤖 Hank — CI status

Classification: real
Run: https://github.com/TeoSlayer/pilotprotocol/actions/runs/26607571003
At commit: beeae07

The build/test failure is a genuine code defect:

github.com/pilot-protocol/common@v0.2.0: replacement directory ../common does not exist
pkg/daemon/daemon.go:33:2: github.com/pilot-protocol/trustedagents@v0.1.0: replacement directory ../trustedagents does not exist
FAIL    github.com/TeoSlayer/pilotprotocol/pkg/daemon [setup failed]

@matthew-pilot — fix or comment.

Auto-classified at 2026-05-28T23:50:00Z. Re-runs on next push or check completion.

@TeoSlayer
Copy link
Copy Markdown
Owner Author

Superseded by #155 which folds in this cleanup plus the daemonapi adapter pattern.

@TeoSlayer TeoSlayer closed this May 28, 2026
TeoSlayer pushed a commit that referenced this pull request May 29, 2026
…t types

Wraps *Daemon with a daemonAPIAdapter that satisfies daemonapi.Daemon
without changing the daemon engine's internal *Connection-typed
signatures. cmd/daemon passes d.DaemonAPI() to daemonapi.LoadAll;
plugins receive the adapter and never see the concrete daemon types.

Why an adapter rather than touching every internal signature: the
daemon's own code does dozens of calls like 'conn, err := d.DialConnection(...)'
where the returned *Connection is then passed back through other
typed methods. Coercing those onto daemonapi.Connection (which is
interface{}) would have meant type-assertions at every call site
inside pkg/daemon. The adapter contains the type-assertions in one
file, keeps the daemon engine's internal typing intact, and presents
the daemonapi shape externally.

Also done in this commit:

  - pkg/daemon/contract.go: rewritten as type aliases to daemonapi
    (TrustChecker, HandshakeService, PolicyManager, PolicyRunner,
    WebhookManager, plus the *Record / WebhookStats structs). The
    aliases preserve daemon-local short names so existing pkg/daemon
    code keeps compiling unchanged.

  - pkg/daemon/eventbus_impl.go: Event is now a type alias to
    daemonapi.Event so Bus().Subscribe() returns the channel type
    daemonapi.EventBus requires.

  - pkg/daemon/zz_daemonapi_conformance.go: defines the adapter +
    Compile-time 'var _ daemonapi.Daemon = daemonAPIAdapter{}'
    assertion. When the interface grows or a method signature
    changes, this assertion fails with a precise error.

  - pkg/daemon/daemon.go: Bus() return type changed to
    daemonapi.EventBus.

Includes the import sweep + duplicate-package deletion that was
on the parallel web4-cleanup-after-common-extraction branch (PR #152):

  - All TeoSlayer/pilotprotocol/pkg/X imports → pilot-protocol/common/X
  - pkg/{coreapi,protocol,driver,config,logging,urlvalidate,secure,
    registry/client,registry/wire} and internal/ipcutil DELETED.
  - go.mod gains replace directives for every sibling so dev builds
    resolve against local checkouts.

Builds: go build ./... passes for the entire web4 module.
Plugins (handshake/runtime/libpilot) still build against the old
pkg/daemon API in their current branches — Phase 3 of this refactor
migrates them off.
TeoSlayer added a commit that referenced this pull request May 29, 2026
…on extraction (#155)

* refactor(daemon): satisfy daemonapi.Daemon via adapter; alias contract types

Wraps *Daemon with a daemonAPIAdapter that satisfies daemonapi.Daemon
without changing the daemon engine's internal *Connection-typed
signatures. cmd/daemon passes d.DaemonAPI() to daemonapi.LoadAll;
plugins receive the adapter and never see the concrete daemon types.

Why an adapter rather than touching every internal signature: the
daemon's own code does dozens of calls like 'conn, err := d.DialConnection(...)'
where the returned *Connection is then passed back through other
typed methods. Coercing those onto daemonapi.Connection (which is
interface{}) would have meant type-assertions at every call site
inside pkg/daemon. The adapter contains the type-assertions in one
file, keeps the daemon engine's internal typing intact, and presents
the daemonapi shape externally.

Also done in this commit:

  - pkg/daemon/contract.go: rewritten as type aliases to daemonapi
    (TrustChecker, HandshakeService, PolicyManager, PolicyRunner,
    WebhookManager, plus the *Record / WebhookStats structs). The
    aliases preserve daemon-local short names so existing pkg/daemon
    code keeps compiling unchanged.

  - pkg/daemon/eventbus_impl.go: Event is now a type alias to
    daemonapi.Event so Bus().Subscribe() returns the channel type
    daemonapi.EventBus requires.

  - pkg/daemon/zz_daemonapi_conformance.go: defines the adapter +
    Compile-time 'var _ daemonapi.Daemon = daemonAPIAdapter{}'
    assertion. When the interface grows or a method signature
    changes, this assertion fails with a precise error.

  - pkg/daemon/daemon.go: Bus() return type changed to
    daemonapi.EventBus.

Includes the import sweep + duplicate-package deletion that was
on the parallel web4-cleanup-after-common-extraction branch (PR #152):

  - All TeoSlayer/pilotprotocol/pkg/X imports → pilot-protocol/common/X
  - pkg/{coreapi,protocol,driver,config,logging,urlvalidate,secure,
    registry/client,registry/wire} and internal/ipcutil DELETED.
  - go.mod gains replace directives for every sibling so dev builds
    resolve against local checkouts.

Builds: go build ./... passes for the entire web4 module.
Plugins (handshake/runtime/libpilot) still build against the old
pkg/daemon API in their current branches — Phase 3 of this refactor
migrates them off.

* fix(daemon): satisfy daemonapi.Daemon contract after common@v0.4.3 bump

The latest common (v0.4.3) added Sign to daemonapi.Daemon, Info to
daemonapi.Connection, and tightened PortAllocator.Bind to return
daemonapi.Listener instead of *Listener. PR #155's adapter (written
against earlier daemonapi) no longer satisfied the interface, breaking
`go build ./...` for cmd/daemon and tests/testenv.

Changes:
- Add *Daemon.Sign(msg) []byte — forwards to identity.Sign with nil
  guard for pre-bootstrap and in-memory test cases.
- Add *Connection.Info() daemonapi.ConnectionInfo — endpoint snapshot
  for plugin consumption (struct copy, holdable across goroutines).
- Add portAllocatorAdapter + listenerAdapter wrappers so Bind returns
  the daemonapi.Listener interface and Accept/Port/Close go through
  channel/field-shaped engine methods.
- Wire d.DaemonAPI() once in cmd/daemon/main.go and tests/testenv.go,
  thread the shared value into runtime.New / NewPolicyRuntime /
  NewHandshakeRuntime instead of passing engine-typed *Daemon.
- Bump go.mod to latest sibling pseudo-versions / betas.

Verified: go build ./... + go vet ./... clean; pilot-daemon binary
runs and prints --help.

* deps: bump siblings to latest stable + pin common v0.4.4 + rendezvous v0.2.2

Coordinated bump after the common@v0.4.4 (admin-token on PolicySet) and
rendezvous@v0.2.2 (per-network list_nodes open to members per PILOT-347)
landed.

Resolves the conflict that has kept #155 in DIRTY state:
- pkg/driver/* deletions match #155's intent (driver moved to common)
- go.mod / go.sum rewritten to the latest stable sibling tags
- internal/ipcutil import in pkg/daemon test switched to common/ipcutil

Daemon + pilotctl build green; the 3 previously-failing pkg/daemon
broadcast tests (TestBroadcastDatagramSkipsSelf,
TestBroadcastDatagramMemberDeliversToOnePeer,
TestManagedEngineBootstrapDoesNotDeadlockWithPersist) now pass against
rendezvous v0.2.2's relaxed per-network list_nodes.

* fix(test): switch ipcutil import from internal/ to common/ for #155

The previous rebase patched the import locally but didn't commit it.
zz_ipc_write_deadline_test.go's 'github.com/TeoSlayer/pilotprotocol/internal/ipcutil'
needs to be 'github.com/pilot-protocol/common/ipcutil' now that
internal/ipcutil was deleted in this PR's refactor.

---------

Co-authored-by: Teodor Calin <teodor@vulturelabs.io>
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.

3 participants