Skip to content

feat(blueprint): build out the BSM — membership, job attribution, wired deploy#14

Merged
drewstone merged 1 commit into
mainfrom
feat/blueprint-bsm
Jun 13, 2026
Merged

feat(blueprint): build out the BSM — membership, job attribution, wired deploy#14
drewstone merged 1 commit into
mainfrom
feat/blueprint-bsm

Conversation

@drewstone

Copy link
Copy Markdown
Contributor

What & why

SurplusBSM (the blueprint's on-chain manager) only customized slashing — every lifecycle hook was the permissive base default, it tracked no operator set, and the deploy left it unwired. This builds it into a real manager and wires it up.

Changes

Membership — both instance models, one code path. The manager tracks each service's operator set + per-operator stake exposure:

  • fixed — operators approve a request (onApprove/onReject staging); the set is frozen at onServiceInitialized.
  • dynamic — same init, plus onOperatorJoined/onOperatorLeft mutate the live set.

canJoin/canLeave never block the protocol (the Tangle core enforces stake/timing); the manager records so the rest of the system has an authoritative set. onServiceTermination clears it. Membership is an instance-level setting chosen at request time — the manager supports both without configuration.

Slashing hardened. challengeDefault is still permissionless (a default is on-chain fact) but now slashes only an operator that is actually a member of the named, active service — a caller can no longer aim a default's slash at an address outside the service.

Job attribution. onJobCall/onJobResult accept (as before) and emit attribution events. The on-chain jobs are market-making control/telemetry (list instrument, status, tick), not value transfer, so the manager records who produced what rather than adjudicating results on-chain.

Wiring. Deploy.s.sol now bootstraps the manager (onBlueprintCreated) and calls setSettlement, mirroring what the Tangle runtime does — so the manager is functional from block 0 for standalone/local/testnet deploys. Verified on a live anvil deploy: settlement() reads back the deployed settlement, tangleCore()/blueprintOwner() set.

Manifest (blueprint.toml): reference the manager ([blueprint.manager]), document the membership models ([blueprint.membership]), fix the stale "next step" comment, and mark jobs 1/2/3 as reserved positional placeholders — they hold workflow_tick at compact index 5 (blueprint.rs WORKFLOW_TICK_JOB_COMPACT), so they must not be removed without fixing that index.

Verification

  • forge test: 107 passed — 13 BSM tests covering fixed membership (frozen at init, rejected approvals excluded), dynamic join/leave (set + exposure updates), the onlyFromTangle gate, the slash membership guard (NotServiceOperator), post-termination rejection (ServiceNotActive), and job-result attribution events.
  • Live deploy read-back confirms the BSM↔settlement wiring.

Notes

  • This does not touch the settlement contract or market mechanics; it's additive on the manager + deploy + manifest.
  • Bonding-at-registration is intentionally not added: onRegister accepts, and economic security comes from the settlement contract's collateral≥liability invariant + this slashing path. The membership set is the slashing-relevant state, and that's what's now tracked.

…tion, wired deploy

The blueprint service manager only customized slashing; every lifecycle hook was
the permissive base default, it tracked no operator set, and it was deployed
unwired. Build it into a real manager.

- Membership (works for BOTH instance models): track each service's operator set
  and per-operator stake exposure. Fixed — frozen at onServiceInitialized from
  the approvers (onApprove/onReject staging). Dynamic — onOperatorJoined/Left
  mutate the live set. canJoin/canLeave never block the protocol; the manager
  records so the rest of the system has an authoritative set. onServiceTermination
  clears it.
- Slashing hardened: challengeDefault now slashes only an operator that is
  actually a member of the named (active) service — a caller can no longer point
  a default's slash at an address outside the service.
- Job hooks: onJobCall/onJobResult accept (as before) and emit attribution events
  (the on-chain jobs are MM control/telemetry, not value transfer).
- Wiring: Deploy.s.sol bootstraps the manager (onBlueprintCreated) and calls
  setSettlement, mirroring the Tangle runtime so it's functional from block 0 for
  standalone/local/testnet deploys (verified: settlement() reads back correct).
- Manifest: reference the manager, document that membership is an instance-level
  setting with both models supported, and mark jobs 1/2/3 as reserved positional
  placeholders (they hold workflow_tick at compact index 5).

forge: 107 tests pass (13 BSM, incl. fixed+dynamic membership, the slash
membership guard, and post-termination rejection).
@drewstone drewstone merged commit 9b1f663 into main Jun 13, 2026
5 checks passed
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.

1 participant