Require ProcessDefinition transitions so the engine can branch or end by conditionKey, persist them in JDBC, and pin repository text files to LF.
Co-authored-by: Cursor <cursoragent@cursor.com>
- ApprovalStep now has candidates + ApprovalPolicy (ANY/ALL) instead of a single assignee; ApprovalStep.single(...) kept as a convenience factory for the single-approver case
- AssigneeResolver resolves per-candidate; TaskStatus gains SKIPPED for auto-skipped sibling tasks
- DefaultOrdoEngine creates one task per candidate and advances per-step according to policy (ANY: first approval wins and skips the rest, only rejects once everyone rejects; ALL: fail-fast on first rejection, only advances once everyone approves)
- Added ApprovalTaskRepository.findByInstanceIdAndStepId and JDBC/in-memory implementations
- Added V2 migration: ordo_approval_step.policy column + ordo_step_candidate table
- Updated ApprovalStepMapper/ApprovalTaskMapper/JdbcProcessDefinitionRepository for the new schema, handling null action for SKIPPED tasks
- Migrated all call sites (tests, ordo-example, rhizome demo) to ApprovalStep.single(...) and the 3-arg AssigneeResolver
- Added ANY/ALL policy test coverage; fixed JdbcTestSupport to apply the V2 migration and strip SQL comments before splitting on ';'
Lightweight linear approval engine (v0.1):
- ordo-api: domain model, OrdoEngine port, repository SPI with
conditional updates (insertIfAbsent, completeIfPending) and a
TransactionExecutor port for atomic multi-step writes
- ordo-core: DefaultOrdoEngine running register/start/approve/reject
inside a transaction boundary; in-memory engine and repositories
- ordo-storage-jdbc: thread-bound JDBC transactions, normalized V1
schema migration, Jackson-based ProcessContext JSON codec
- tests: unit tests plus H2 integration tests; PostgreSQL integration
tests run against a local instance via ordo.test.pg.* properties and
skip when unreachable
Co-Authored-By: Claude Code <noreply@anthropic.com>