Workout History And Corrections
Why Power Oracle stores completed workouts as stable records and how to correct or void them without polluting athlete history.
Power Oracle now distinguishes between:
- the real completed workout
- the computed version of that workout currently treated as canonical
That separation exists to protect athlete history.
If an agent later learns that a stored completed workout was modeled incorrectly, it should not overwrite the old record in place. It should either:
- create a corrected revision that supersedes the old canonical version
- void the current canonical version if the stored record should no longer count and a replacement is not yet known
Why This Exists
Without a stable workout record, bad earlier submissions can pollute:
- athlete workout history
- trends
- comparisons
- percentiles and benchmarks
The workout-plus-revisions model lets Power Oracle keep an audit trail while still giving default reads one clean current truth.
What Gets Stored In MVP
completedworkouts create stored workout records and canonical revisionsplannedrequests compute results but do not create stored workout history in MVPhypotheticalrequests compute results but do not create stored workout history in MVP
That keeps actual athlete history separate from planning and simulation.
Current States
canonical: the current accepted version of a completed workoutsuperseded: an older version replaced by a newer canonical revisionvoided: a version that should no longer count and currently has no canonical replacement
Default history and analytics use only canonical completed workouts.
Public read routes expose the same current truth set:
GET /v1/athletes/{athlete_uuid}/workoutslists active canonical completed workouts with pagination and filters.GET /v1/athletes/{athlete_uuid}/workouts/{workout_id}returns one active canonical workout detail record.GET /v1/athletes/{athlete_uuid}/curvecomputes the power-duration curve from active canonical completed workouts.
These routes are public and uuid-gated. They do not require x402, L402, or bearer auth.
Normal Create Flow
Call POST /v1/compute-power with a completed request.
The response now includes:
workout.workout_idworkout.revision_idworkout.revision_numberworkout.revision_status
Agents should store workout_id and revision_id if they may need to correct the workout later.
Correct A Stored Workout
Use POST /v1/workouts/\{workout_id\}/revisions.
Send:
supersedes_revision_id- optional
correction_reason - a full replacement
compute_request
Example:
{
"supersedes_revision_id": "11111111-1111-1111-1111-111111111111",
"correction_reason": "User confirmed the thrusters were 75 lb, not 95 lb.",
"compute_request": {
"athlete_uuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
"evaluation_context": "completed",
"performed_date": "2026-03-20",
"duration_seconds": 133,
"user": {
"height": { "value": 70, "unit": "in" },
"body_mass": { "value": 180, "unit": "lb" }
},
"splits": []
}
}
If the supplied supersedes_revision_id is no longer the current canonical revision, the route returns 409 Conflict.
Void A Stored Workout
Use POST /v1/workouts/\{workout_id\}/void when the current canonical workout should stop counting and you do not yet have a corrected replacement.
This route is free and public.
Send:
supersedes_revision_idvoid_reason
Example:
{
"supersedes_revision_id": "11111111-1111-1111-1111-111111111111",
"void_reason": "The stored workout does not reflect what the athlete actually performed."
}
Voiding removes the workout from default history and analytics until a valid replacement exists.
Billing
POST /v1/compute-poweris paid in productionPOST /v1/workouts/\{workout_id\}/revisionsis also paid in productionPOST /v1/workouts/\{workout_id\}/voidis free
Default Read Behavior
Power Oracle should treat the following as the default truth set:
- canonical completed workouts only
That means:
- superseded revisions are excluded
- voided workouts are excluded
- planned and hypothetical requests are excluded
- list, detail, and curve reads all use this same active canonical set
Use audit-oriented reads only when you explicitly want revision history.
