Community-to-dedicated migration
Goal
Shyware deployments should be able to start on a shared community chain, then move to dedicated or self-hosted infrastructure without losing:
- canonical integrity
- attestation continuity
- recovery/reconcile correctness
- tenant namespace ownership
The invariant itself does not depend on who hosts the deployment. Migration is therefore a continuity problem, not a new trust model.
The same logic works in both directions:
community -> dedicated/self-hosteddedicated/self-hosted -> community
as long as the tenant namespace, checkpoint lineage, and authority structure remain continuous.
Two migration types
1. Service-layer migration
The tenant takes over:
- API hosting
- private surface hosting
- Cockroach or other off-canonical storage
- reconcile/recovery service
But the canonical ledger remains on the same chain.
This is the easier path. The chain does not change; only the operator-facing service tier moves.
2. Ledger migration
The tenant leaves a shared community chain and moves to:
- a tenant-dedicated shyware-hosted chain, or
- a fully self-hosted chain
This requires a formal cutover so the tenant can prove that the new chain continues from the old attested state rather than restarting from an unverifiable snapshot.
Integrity-preserving cutover
An integrity-preserving ledger migration should follow this sequence:
- Freeze the tenant namespace on the source chain.
- Commit a final tenant-scoped checkpoint attestation on the source chain.
- Export tenant canonical state and tenant off-canonical service state.
- Bootstrap the destination deployment from that checkpoint.
- Publish a cutover record linking destination genesis to the source checkpoint attestation.
The migration proof is the pair:
- source final checkpoint
- destination bootstrap statement referencing that checkpoint
If both are signed and publicly available, third parties can verify that the tenant did not lose or rewrite canonical history during migration.
Required artifacts
Source-side artifacts
- tenant identifier / namespace
- final checkpoint height
- final checkpoint time
- final checkpoint attestation
- tenant-scoped canonical record roots
- tenant-scoped aggregate counters
Off-canonical export
- reconcile/recovery store
- mailbox / dispatch / receipt state for messaging deployments
- operator policy metadata
- tenant manifest
These must be exported separately from canonical state. The migration should never imply that off-canonical recovery state was itself part of canonical consensus.
Destination bootstrap artifacts
- destination chain or namespace identifier
- bootstrap timestamp
- imported tenant manifest
- imported tenant canonical roots / counters
- bootstrap signature by the destination operator or validator set
- explicit reference to the source checkpoint attestation
Tenant-scoped checkpoints
For community-chain deployments, the checkpoint should be tenant-scoped rather than chain-global. That lets one tenant migrate without requiring whole-chain rotation for every other tenant.
The checkpoint should cover at least:
- tenant namespace
- first-canonical-record root
- second-canonical-record root
- tenant attestation schedule state
- tenant aggregate counts or conservation counters
Messaging profiles such as shychat may also include:
- mailbox commitment root
- delivery-window close state
- receipt continuity counters
What is implemented today
Today the repo supports:
- deployment posture in
shyconfig - community vs dedicated vs self-hosted manifest modeling
- Cockroach-backed Scytale mailbox / dispatch / receipt state
- tenant-scoped checkpoint generation
- signed export bundles
- import tooling for destination restores
- bundle verification against checkpoint digests and signatures
The operator tooling is currently exposed through:
node scripts/shyware-migration.js checkpoint --tenant TENANT --out checkpoint.json
node scripts/shyware-migration.js export --tenant TENANT --out bundle.json
node scripts/shyware-migration.js bootstrap --in bundle.json --out bootstrap.json
node scripts/shyware-migration.js verify --in bundle.json
node scripts/shyware-migration.js verify-cutover --bundle bundle.json --bootstrap bootstrap.json
node scripts/shyware-migration.js import --in bundle.json --tenant TENANT
The bootstrap statement binds a destination deployment to a source tenant checkpoint, and the cutover verifier checks that the published destination bootstrap material is consistent with the signed source export bundle. That gives the migration path a formal continuity layer rather than a bare data copy.
Recommended product path
For community tenants
- launch on
community.shyware.fyi - get a tenant manifest and tenant subdomain
- keep tenant off-canonical state isolated from other tenants
For growth-stage tenants
- move service hosting first
- then migrate ledger tenancy if needed
- if economics or staffing change later, move back to
communitywith the same tenant-scoped checkpoint/export/import ceremony
For regulated tenants
- prefer
hosted_dedicatedorself_hosted - use a signed cutover ceremony rather than ad hoc export/import
Bring Your Own Ledger (self-hosted)
Self-hosted operators run the full community server stack from github.com/ShywareLLC/community. The repo contains everything needed: the ABCI state machine, API server, signing layer, ZK verifier, and optional analytics companion.
What you run
| Binary | Module | Purpose |
|---|---|---|
shyvoting-abci | github.com/ShywareLLC/community | ABCI state machine + BFT consensus |
shyvoting-api | github.com/ShywareLLC/community | REST API + off-chain receipt store |
shyvoting-affinities | github.com/ShywareLLC/community/analytics | Optional affinity analytics surface |
shyvoting-affinities is a separate Go module (ShywareLLC/community/analytics/) and is not a dependency of the core runtime. Include it only if you are operating a public analytics surface on top of your deployment.
go.work for local development
The community repo uses a Go workspace. If you clone ShywareLLC/community standalone:
git clone git@github.com:ShywareLLC/community.git
cd community
go work init .
go work use ./analytics
go work use ./embodiments/shyvoting
# add other embodiments as needed
Infrastructure
Signing infrastructure (ShywareLLC/community/infra/) is provisioned via Terragrunt. Each deployment needs only a thin terragrunt.hcl wrapper pointing at the shared modules — see Infrastructure provisioning.
Operator-separation requirement
The ABCI node and the reconciling authority (CockroachDB) must be operated by different entities for anonymity-to-operator to hold.
The canonical ledger makes submission_id → payload public. The RA holds identity_hash → submission_id off-chain. A single organization operating both can join them without any collusion event, eliminating anonymous-to-operator assurance.
For BYOL deployments, the valid RA options are reconcile_authority.operator: "shyware" (Shyware hosts your RA as a separate contracted service — Shyware ≠ your organization as the ledger operator) or reconcile_authority.operator: "independent_third_party". Setting operator to ledger_operator or omitting the field is rejected by assertVotingManifest at config load time.
Note that the community-tier collapse case is the mirror image: a community-tier deployment with reconcile_authority.operator: "shyware" would mean Shyware operates both the canonical chain and the RA — equally prohibited.
See Architecture → The operator-separation requirement for the full configuration table and three-party chain analysis.
Migrating back to community
Self-hosted operators can migrate back to the community chain at any time using the same checkpoint/export/import ceremony described above. Bring Your Own Ledger does not lock you in.
Design principle
Migration should preserve the invariant by preserving:
- the tenant's canonical roots
- the tenant's attestation continuity
- the tenant's authority structure
It should not depend on trusting the source operator's database alone.