Skip to content

Epic: Milestone, Stage, and Goal — Full Conceptual Alignment #84

@mdproctor

Description

@mdproctor

Overview

Tracks the work to fully align the Milestone, Stage, and Goal concepts into a
coherent, consistent family — grounded in CMMN 1.1, free of overlap, and
complete enough to support Stage-contained lifecycle tracking.

Not for the current port sprint. The `casehub-blackboard/` port (issue #76)
brings Stage and basic Milestone tracking. This epic captures what needs to be
tidied up and deepened once that foundation exists.

The Problem

Three gaps surfaced during the casehub-blackboard design session:

1. `Goal.terminal` creates overlap with `Milestone`

`Goal` has a `terminal` flag. A non-terminal Goal is "an observable checkpoint
with polarity." That is just a Milestone with a success/failure label — the
two concepts now overlap. If a Goal does not drive case completion, it is not
meaningfully different from a Milestone with a `GoalKind` annotation.

Options to resolve:

  • Remove non-terminal Goals entirely — Goals are always terminal; use Milestone
    for non-terminal checkpoints (possibly with an optional polarity annotation)
  • Make `GoalKind` an optional field on `Milestone` (collapsing the two)
  • Keep both, but define the boundary precisely and enforce it with a validator

2. `Milestone` has no stage containment

The CMMN 1.1 spec places Milestones inside Stages. casehub-engine's `Milestone`
class has no `parentStageId` — it is always top-level. This means:

  • Stage exit criteria cannot reference "has milestone X been achieved within
    this stage?"
  • Stage completion tracking based on contained milestones is impossible

casehub-poc's `Milestone` had `parentStageId` and was a proper Stage member.
That capability was not carried forward into casehub-engine.

3. `Milestone` lifecycle state lives in the EventLog, not the object

`api/Milestone` has no PENDING/ACHIEVED state. The `CasePlanModel` Javadoc
explicitly defers this to Phase 2. The result: milestone lifecycle state is
scattered across EventLog queries and plan model maps, rather than being
readable directly from the object.

casehub-poc's `Milestone` had `MilestoneStatus { PENDING, ACHIEVED }` on the
object and an `achieve()` method. Simpler and more direct.

What Full Alignment Looks Like

A consistent family across all three CMMN-derived concepts:

Concept Role Polarity Containable in Stage Lifecycle state
`Milestone` Neutral waypoint — marks where the case is None Yes (`parentStageId`) PENDING → ACHIEVED
`Goal` Outcome — what the case is trying to achieve SUCCESS / FAILURE No (always top-level) Drives COMPLETED / FAILED
`Stage` Container — groups PlanItems and Milestones N/A Yes (nested stages) PENDING → ACTIVE → COMPLETED / TERMINATED

Under this model:

  • You pass Milestones
  • You achieve Goals
  • You enter and exit Stages

There is no overlap. Non-terminal Goals are removed — they were Milestones.

Child Issues (to be created)

Area Work
`Goal.terminal` cleanup Remove or restrict non-terminal Goals; define the concept boundary clearly
Milestone stage containment Add `parentStageId` to `api/Milestone`; Stage holds milestone IDs; stage exit criteria can reference contained milestones
Milestone lifecycle state Add `MilestoneStatus { PENDING, ACHIEVED }` to `api/Milestone`; `CasePlanModel` promotes on `MilestoneReachedEvent`
CMMN 1.1 audit Review all three concepts against CMMN 1.1 §5.4.4 (Stage), §5.4.7 (Milestone), and Goal semantics; document decisions

Dependency

Depends on `casehub-blackboard/` (issue #76) being stable — Stage and
CasePlanModel must exist before Milestone containment and lifecycle promotion
can be wired in.

Metadata

Metadata

Assignees

Labels

epicTracks a large body of related workfuturePlanned work for future releases.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions