Resource Lifecycle¶
This page explains how a resource changes over time in SpecStar.
It focuses on the practical lifecycle of a resource: create, update, modify, switch, delete, restore, and migrate.
If you are looking for terminology, read Core Concepts first. If you want the component view, see Architecture.
Why this matters¶
The lifecycle model is what gives SpecStar its built-in support for:
- revision history
- rollback and restore flows
- draft editing
- safe schema evolution over time
Resource structure¶
Each resource consists of three conceptual layers:
| Layer | Description |
|---|---|
| Resource | Logical entity identified by resource_id |
| Revision | Version of the resource data |
| Metadata | Resource-level metadata (meta) |
The API can return these layers separately:
1. Create a resource¶
A resource is created using:
ID generation¶
| Field | Behavior |
|---|---|
| resource_id | generated UUID |
| revision_id | {resource_id}:1 |
| parent_revision_id | None |
Default status¶
The initial revision status is configured when the model is registered:
If not configured, the default is:
Both stable and draft are supported. Use draft when you want an editing workflow that relies on in-place modify operations before promoting or replacing the current revision.
Example¶
resource_id = 550e8400-e29b-41d4-a716-446655440000
revision_id = 550e8400-e29b-41d4-a716-446655440000:1
Revision graph after creation:
2. Understand the revision model¶
Revisions form a directed graph similar to Git history.
Normal updates append new revisions:
Each revision stores:
revision_idparent_revision_idschema_versionstatuscreated_timeupdated_time
Revision metadata is stored in RevisionInfo.
3. Update creates a new revision¶
Update creates a new revision.
Behavior:
| Field | Behavior |
|---|---|
| revision_id | new revision |
| parent_revision_id | previous HEAD |
| meta.created_time | unchanged |
| meta.updated_time | updated |
| info.created_time | new |
| info.updated_time | same as created_time |
Example:
4. Modify edits the current draft in place¶
Modify updates the current revision in-place.
Behavior:
| Field | Behavior |
|---|---|
| revision_id | unchanged |
| parent_revision_id | unchanged |
| meta.created_time | unchanged |
| meta.updated_time | updated |
| info.created_time | unchanged |
| info.updated_time | updated |
This mode is typically used for draft editing workflows.
5. Revision status¶
Revisions have a status defined by:
Current values:
6. Switch the current revision¶
SpecStar allows changing which revision is considered current (HEAD).
Example:
Switch to r2:
If a new update occurs:
This behavior is similar to Git branching from an older commit.
7. Resource metadata¶
Resource-level metadata is stored separately from revision data.
Example fields:
resource_id
current_revision_id
schema_version
created_time
updated_time
created_by
updated_by
is_deleted
rev_status
rev_created_by
rev_updated_by
rev_created_time
rev_updated_time
The rev_* fields mirror key attributes of the current revision so that filtering and sorting by revision properties is efficient. SpecStar keeps them in sync on every write.
Metadata is accessed via:
8. Revision metadata¶
Revision-level metadata is stored in RevisionInfo.
Important fields:
revision_id
parent_revision_id
schema_version
status
created_time
updated_time
created_by
updated_by
data_hash
Accessed via:
9. Soft delete and restore¶
SpecStar uses soft deletion.
Behavior:
| Field | Behavior |
|---|---|
| meta.is_deleted | set to True |
| meta.updated_time | updated |
| revisions | unchanged |
Deletion does not create a new revision.
Revision history remains intact.
A soft-deleted resource can be restored.
Behavior:
| Field | Behavior |
|---|---|
| meta.is_deleted | set to False |
| meta.updated_time | updated |
No new revision is created.
10. Schema migration¶
Each revision stores a schema_version.
When reading a revision:
- SpecStar attempts to decode using the current schema
- If decoding fails, the error is ignored (not treated as 404)
Resources can be migrated explicitly using:
# Migrate the current revision
resource_manager.migrate(resource_id)
# Migrate a specific (non-current) revision
resource_manager.migrate(resource_id, revision_id="item:abc:1")
Migration process (current revision):
- read existing revision data
- run migration logic
- update revision schema_version
- update resource meta schema_version
- write migrated data back
Migration process (specific revision):
- locate the revision's actual schema_version in the resource store
- read its data using the correct schema_version key
- run migration logic
- update the revision's schema_version
- write migrated data back
- does not update resource meta schema_version
Note:
migrate()only migrates one revision at a time. Old revisions that were created before a schema upgrade remain at their original schema_version until explicitly migrated.
Switch and unmigrated revisions¶
When migration is configured, switch() checks whether the target revision
has been migrated to the resource's current schema_version.
- If the target revision is still at an older schema_version,
RevisionNotMigratedErroris raised. - You must migrate the revision first before switching to it.
from specstar import RevisionNotMigratedError
try:
resource_manager.switch(resource_id, old_revision_id)
except RevisionNotMigratedError:
# Migrate the old revision first
resource_manager.migrate(resource_id, revision_id=old_revision_id)
resource_manager.switch(resource_id, old_revision_id)
Migration can also be executed across resources using search-based migration APIs.
Summary¶
A typical lifecycle looks like this:
Deletion does not remove revision history:
Restoration flips the deletion flag back:
Schema changes are handled through explicit migrations, and switching to older revisions may require those revisions to be migrated first.