Skip to content

feat: add token behavior sealed trait, builder, and proto (16-type TDEG matrix)#118

Closed
ottobot-ai wants to merge 12 commits into
scasplte2:mainfrom
ottobot-ai:feat/token-behavior-scala
Closed

feat: add token behavior sealed trait, builder, and proto (16-type TDEG matrix)#118
ottobot-ai wants to merge 12 commits into
scasplte2:mainfrom
ottobot-ai:feat/token-behavior-scala

Conversation

@ottobot-ai

Copy link
Copy Markdown
Collaborator

Summary

Implements the complete 16-type token behavior system using a 4-boolean TDEG matrix in Scala, achieving cross-language equivalence with the TypeScript SDK (PR #45).

Trello Card

🎲 SDK: 16-type token behavior matrix implementation

Deliverables

  1. TokenBehavior — Sealed trait with 16 case objects (TDEG model) in modules/models/
  2. TokenBehaviorBuilder.toStateMachineDefinition(behavior) — Factory producing StateMachineDefinition
  3. TokenBehavior.isOperationAllowed(behavior, op): Boolean — Operation legality API
  4. TokenOperation — Enumeratum enum for 8 operation types
  5. token.proto — New domain proto under ottochain/v1/ with TokenBehaviorType + TokenOperationType enums
  6. TokenBehaviorSuite — 58 TDD tests, all passing

Key Design Decisions

Decision Choice Rationale
Module modules/models/ Same as StateMachineDefinition; pure data, no IO
Proto New token.proto Establishes domain-proto convention (future: identity, market, governance)
Expiry guard sequenceNumber Fixes TypeScript $ordinal latent bug (defaults to 0 in JLVM)

4-bit TDEG Encoding

Bit 3 (8): T = Transferable
Bit 2 (4): D = Divisible
Bit 1 (2): E = Expirable
Bit 0 (1): G = Governable

TokenBehavior.value = T×8 + D×4 + E×2 + G×1

16 named presets: SOULBOUND_RECEIPT(0) → GOVERNED_EXPIRABLE_FUNGIBLE(15)

Test Coverage (58 tests, all passing)

  • Group 1: Predicates (6 tests) — isTransferable, isDivisible, fromFlags, etc.
  • Group 2: Structure for all 16 types (16 tests) — valid StateMachineDefinition with correct states
  • Group 3: Transition presence by flag (12 tests) — T/D/E/G flag → correct transitions
  • Group 4: Wire format correctness (6 tests) — StateId wrappers, metadata fields, guards
  • Group 5: Operation legality (8 tests) — all operations vs all behaviors
  • Group 6: Named preset factories (5 tests) — nft, fungibleToken, stablecoin, license, soulboundBadge
  • Group 7: Structural equivalence (5 tests) — unique values/names, round-trip, EXPIRED state presence

References


Implemented by @work (OttoBot) | 2026-02-26

@ottobot-ai ottobot-ai changed the title feat: TokenBehavior sealed trait + builder + proto (16-type TDEG matrix) feat: add token behavior sealed trait, builder, and proto (16-type TDEG matrix) Feb 26, 2026
@ottobot-ai ottobot-ai force-pushed the feat/token-behavior-scala branch 2 times, most recently from 356214b to 4ee7da5 Compare February 26, 2026 16:43
@ottobot-ai ottobot-ai added the tier-2-review Needs human review before merge label Mar 4, 2026
ottobot-ai and others added 11 commits March 23, 2026 12:12
* chore: add fork-specific CODEOWNERS and PR template

* fix: don't pass --l0-token-identifier to ML0

ML0's run-genesis command doesn't accept --l0-token-identifier (it's a
DL1/CL1 flag). The entrypoint was passing it to all metagraph layers
(ml0|cl1|dl1 case), causing ML0 to print usage and exit immediately.

Only pass the flag for CL1 and DL1.
Bumps [docker/login-action](https://github.com/docker/login-action) from 3 to 4.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](docker/login-action@v3...v4)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [docker/metadata-action](https://github.com/docker/metadata-action) from 5 to 6.
- [Release notes](https://github.com/docker/metadata-action/releases)
- [Commits](docker/metadata-action@v5...v6)

---
updated-dependencies:
- dependency-name: docker/metadata-action
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4 to 7.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](actions/upload-artifact@v4...v7)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6 to 7.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](docker/build-push-action@v6...v7)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 3 to 4.
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](docker/setup-buildx-action@v3...v4)

---
updated-dependencies:
- dependency-name: docker/setup-buildx-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
)

PR scasplte2#136 removed --l0-token-identifier for all ML0 modes to fix the
genesis crash, but ML0 run-validator REQUIRES it. Without it, validator
nodes fail with 'Missing expected flag --l0-token-identifier'.

Fix: only skip the flag for ML0 run-genesis mode. All other metagraph
modes (ML0 run-validator/run-rollback, CL1, DL1) continue to receive it.
…asplte2#135)

* chore: remove vestigial proto module, add SDK compatibility tests

Rebased onto latest upstream/main (v0.7.11). Resolves merge conflict
caused by upstream modifications to messages.proto — since the entire
proto module is being removed, the modified file is deleted as intended.

No functional change from original PR scasplte2#135; the proto module had zero
.dependsOn() references and the ScalaPB codegen was never used at runtime.

Co-authored-by: OttoBot <ottobot@kd5ujc.xyz>

* fix: correct SdkCompatibilitySuite JSON fixtures

StateId serializes as plain string 'idle', not {'value': 'idle'}.
Updated test fixtures and assertions to match actual codec behavior.

* chore: trigger CI
Implements the 16-type token behavior system using a 4-boolean TDEG matrix.

## Deliverables
- TokenBehavior sealed trait with 16 case objects (modules/models/)
- TokenBehaviorBuilder.toStateMachineDefinition(behavior) factory
- TokenBehavior.isOperationAllowed(behavior, op) legality API
- TokenOperation enum (8 operations)
- token.proto with TokenBehaviorType + TokenOperationType enums
- 58 TDD tests — all passing

## Key Design
- 4-bit encoding: T=Transferable(8), D=Divisible(4), E=Expirable(2), G=Governable(1)
- States: ACTIVE (initial), BURNED (terminal), EXPIRED (terminal, E=1 only)
- Expiry guard uses sequenceNumber (fixes TypeScript $ordinal latent bug, AC4)

- Cross-language equivalence with TypeScript SDK PR scasplte2#45

## References
- Trello: https://trello.com/c/6996301447b41cda59369256
- Spec: scasplte2#114
- TypeScript reference: ottobot-ai/ottochain-sdk PR scasplte2#45

Co-authored-by: OttoWork <ottobot@kd5ujc.xyz>
@ottobot-ai

Copy link
Copy Markdown
Collaborator Author

⚠️ Merge conflict — manual resolution required

PR size: 1,764 lines (too large for automated conflict resolution)
Base branch: main

@scasplte2 — please rebase manually when ready.

@ottobot-ai

Copy link
Copy Markdown
Collaborator Author

Closing in favor of the asset-model RFC (docs/proposals/asset-model.md).

This PR's 4-bit TDEG / 16-type TokenBehavior (JSON-Logic application layer) is superseded by the RFC's 5-bit T/S/C/E/G model (32 types) with structural enforcement in consensus — a different type system (D splits into S=splittable + C=combinable; behavior moves from the app layer into the combiner/L1), so this is a redesign rather than a refresh.

Salvage into RFC task #1 (TokenBehavior + AssetPolicy types): the token.protoasset.proto domain-proto convention, and the 58 TDD tests as a seed for the task-#8 law tests. SDK #80 warrants the same treatment. Reopenable if we change course.

@ottobot-ai ottobot-ai closed this Jun 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-manual-rebase tier-2-review Needs human review before merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants