Files
cleveragents-core/docs/reference/database_schema.md
T
freemo 9b30421b34
CI / lint (pull_request) Successful in 16s
CI / typecheck (pull_request) Successful in 27s
CI / security (pull_request) Successful in 21s
CI / quality (pull_request) Successful in 16s
CI / integration_tests (pull_request) Successful in 4m10s
CI / build (pull_request) Successful in 15s
CI / unit_tests (pull_request) Successful in 8m0s
CI / docker (pull_request) Successful in 40s
CI / coverage (pull_request) Successful in 6m22s
CI / lint (push) Successful in 13s
CI / typecheck (push) Successful in 27s
CI / security (push) Successful in 22s
CI / quality (push) Successful in 15s
CI / integration_tests (push) Successful in 4m16s
CI / build (push) Successful in 15s
CI / unit_tests (push) Successful in 8m2s
CI / docker (push) Successful in 39s
CI / coverage (push) Successful in 6m23s
feat(db): add spec-aligned action and plan tables with migrations, ORM models, and benchmarks
2026-02-13 13:05:20 -05:00

13 KiB

Database Schema Reference

This document describes the spec-aligned database tables created by the A5.alpha migrations (a5_003_spec_aligned_actions and a5_004_spec_aligned_plans).

These tables replace the legacy actions_v3 and lifecycle_plans tables with a normalized schema using namespaced names as action identity and child tables for arguments, invariants, and project links.

Migration Chain

Revision Description
a5_003_spec_aligned_actions Drops lifecycle_plans and actions_v3; creates actions, action_invariants, action_arguments
a5_004_spec_aligned_plans Creates v3_plans, plan_projects, plan_arguments, plan_invariants

Table: actions

The primary action definition table. Each row represents a reusable action template identified by its namespaced name.

Primary Key: namespaced_name

Column Type Nullable Default Description
namespaced_name String(255) No -- PK. Full namespaced name (e.g. local/code-review)
namespace String(100) No -- Extracted namespace component
name String(150) No -- Extracted short name component
description Text No -- Short description
long_description Text Yes NULL Detailed description
definition_of_done Text No -- Explicit testable completion criteria
strategy_actor String(255) No -- Actor for Strategize phase
execution_actor String(255) No -- Actor for Execute phase
review_actor String(255) Yes NULL Actor for reviewing results
apply_actor String(255) Yes NULL Actor for Apply phase
estimation_actor String(255) Yes NULL Actor for cost estimation
invariant_actor String(255) Yes NULL Actor for invariant reconciliation
automation_profile String(255) Yes NULL Default automation profile name
reusable Boolean No 1 Whether action persists after use
read_only Boolean No 0 Read-only mode
inputs_schema_json Text Yes NULL JSON Schema dict for input validation
state String(20) No 'available' available or archived
created_by String(255) Yes NULL Creator identifier
tags_json Text No '[]' JSON array of tag strings
created_at String(30) No -- ISO-8601 creation timestamp
updated_at String(30) No -- ISO-8601 last-update timestamp

Check Constraints:

  • ck_actions_state: state IN ('available', 'archived')

Indexes:

  • ix_actions_namespace on namespace
  • ix_actions_state on state
  • ix_actions_name on name

Table: action_invariants

Ordered invariant constraints attached to an action. Cascades on action delete.

Primary Key: id (auto-increment)

Column Type Nullable Default Description
id Integer No auto Surrogate PK
action_name String(255) No -- FK to actions.namespaced_name (CASCADE)
invariant_text Text No -- The invariant constraint text
position Integer No -- Display ordering
created_at String(30) No -- ISO-8601 timestamp

Foreign Keys:

  • fk_action_invariants_action: action_name -> actions.namespaced_name ON DELETE CASCADE

Indexes:

  • ix_action_invariants_action on action_name
  • ix_action_invariants_position on (action_name, position)

Table: action_arguments

Typed argument definitions for an action. Cascades on action delete.

Primary Key: id (auto-increment)

Column Type Nullable Default Description
id Integer No auto Surrogate PK
action_name String(255) No -- FK to actions.namespaced_name (CASCADE)
name String(100) No -- Argument identifier
arg_type String(20) No 'string' string, integer, float, boolean, list
requirement String(20) No 'required' required or optional
description Text Yes NULL Human-readable description
default_value_json Text Yes NULL JSON-encoded default value
min_value Float Yes NULL Min bound for numeric types
max_value Float Yes NULL Max bound for numeric types
validation_pattern String(500) Yes NULL Regex pattern for string validation
position Integer No -- Display ordering

Foreign Keys:

  • fk_action_arguments_action: action_name -> actions.namespaced_name ON DELETE CASCADE

Unique Constraints:

  • uq_action_arguments_name on (action_name, name)

Check Constraints:

  • ck_action_arguments_type: arg_type IN ('string', 'integer', 'float', 'boolean', 'list')
  • ck_action_arguments_requirement: requirement IN ('required', 'optional')

Indexes:

  • ix_action_arguments_action on action_name
  • ix_action_arguments_position on (action_name, position)

Table: v3_plans

The primary plan table. Each row is a plan instance created from an action, identified by a ULID. Plans reference actions by namespaced name and support hierarchical subplan trees via self-referencing foreign keys.

Primary Key: plan_id (ULID, String(26))

Column Type Nullable Default Description
plan_id String(26) No -- ULID primary key
parent_plan_id String(26) Yes NULL FK to v3_plans.plan_id (SET NULL)
root_plan_id String(26) Yes NULL FK to v3_plans.plan_id (SET NULL)
action_name String(255) No -- FK to actions.namespaced_name (RESTRICT)
namespaced_name String(255) No -- Plan's own namespaced name
namespace String(100) No -- Extracted namespace
phase String(20) No 'strategize' Current lifecycle phase
processing_state String(20) No 'queued' Current processing state
attempt Integer No 1 Retry attempt counter
description Text No -- Rendered description (from action template + args)
definition_of_done Text Yes NULL Rendered completion criteria
strategy_actor String(255) Yes NULL Strategize phase actor
execution_actor String(255) Yes NULL Execute phase actor
review_actor String(255) Yes NULL Review actor
apply_actor String(255) Yes NULL Apply phase actor
estimation_actor String(255) Yes NULL Estimation actor
invariant_actor String(255) Yes NULL Invariant reconciliation actor
automation_profile String(255) Yes NULL Resolved automation profile name
automation_level String(30) No 'manual' manual, review_before_apply, full_automation
reusable Boolean No 1 Copied from action
read_only Boolean No 0 Copied from action
inputs_schema_json Text Yes NULL JSON Schema dict (copied from action)
changeset_id String(26) Yes NULL Changeset ULID from Execute phase
sandbox_refs_json Text Yes NULL JSON sandbox references
validation_summary_json Text Yes NULL JSON validation summary
decision_root_id String(26) Yes NULL Root decision tree ULID
error_message Text Yes NULL Error message if errored
error_details_json Text Yes NULL JSON error details dict
cost_estimate_usd Float Yes NULL Estimated cost in USD
cost_actual_usd Float Yes NULL Actual cost in USD
token_count_input Integer Yes 0 Input token count
token_count_output Integer Yes 0 Output token count
created_by String(255) Yes NULL Creator identifier
tags_json Text No '[]' JSON array of tag strings
created_at String(30) No -- ISO-8601 creation timestamp
updated_at String(30) No -- ISO-8601 last-update timestamp
completed_at String(30) Yes NULL ISO-8601 completion timestamp
strategize_started_at String(30) Yes NULL Strategize phase start
strategize_completed_at String(30) Yes NULL Strategize phase end
execute_started_at String(30) Yes NULL Execute phase start
execute_completed_at String(30) Yes NULL Execute phase end
apply_started_at String(30) Yes NULL Apply phase start
applied_at String(30) Yes NULL Terminal apply timestamp

Foreign Keys:

  • fk_v3_plans_parent: parent_plan_id -> v3_plans.plan_id ON DELETE SET NULL
  • fk_v3_plans_root: root_plan_id -> v3_plans.plan_id ON DELETE SET NULL
  • fk_v3_plans_action: action_name -> actions.namespaced_name ON DELETE RESTRICT

Check Constraints:

  • ck_v3_plans_phase: phase IN ('strategize', 'execute', 'apply', 'applied')
  • ck_v3_plans_state: processing_state IN ('queued', 'processing', 'errored', 'complete', 'cancelled')
  • ck_v3_plans_automation: automation_level IN ('manual', 'review_before_apply', 'full_automation')

Indexes:

  • ix_v3_plans_phase on phase
  • ix_v3_plans_state on processing_state
  • ix_v3_plans_parent on parent_plan_id
  • ix_v3_plans_root on root_plan_id
  • ix_v3_plans_created on created_at
  • ix_v3_plans_action on action_name
  • ix_v3_plans_namespace on namespace
  • ix_v3_plans_phase_state on (phase, processing_state) (composite)

Table: plan_projects

Links plans to target projects. Composite primary key. Cascades on plan delete.

Primary Key: (plan_id, project_name)

Column Type Nullable Default Description
plan_id String(26) No -- FK to v3_plans.plan_id (CASCADE)
project_name String(255) No -- Target project namespaced name
alias String(100) Yes NULL Short alias for plan context
read_only Boolean No 0 Whether project is read-only for this plan
created_at String(30) No -- ISO-8601 timestamp

Foreign Keys:

  • fk_plan_projects_plan: plan_id -> v3_plans.plan_id ON DELETE CASCADE

Indexes:

  • ix_plan_projects_project on project_name

Table: plan_arguments

Resolved argument values for a plan instance. Cascades on plan delete.

Primary Key: id (auto-increment)

Column Type Nullable Default Description
id Integer No auto Surrogate PK
plan_id String(26) No -- FK to v3_plans.plan_id (CASCADE)
name String(100) No -- Argument name
value_json Text Yes NULL JSON-encoded argument value
value_type String(20) No 'string' Value type hint
position Integer No -- Display ordering

Foreign Keys:

  • fk_plan_arguments_plan: plan_id -> v3_plans.plan_id ON DELETE CASCADE

Unique Constraints:

  • uq_plan_arguments_name on (plan_id, name)

Indexes:

  • ix_plan_arguments_plan on plan_id
  • ix_plan_arguments_position on (plan_id, position)

Table: plan_invariants

Plan-level invariant constraints with scope provenance. Cascades on plan delete.

Primary Key: id (auto-increment)

Column Type Nullable Default Description
id Integer No auto Surrogate PK
plan_id String(26) No -- FK to v3_plans.plan_id (CASCADE)
invariant_text Text No -- The invariant constraint text
source_scope String(20) No 'plan' Origin scope: global, project, action, plan
source_name String(255) Yes NULL Name of the source entity
position Integer No -- Display ordering
created_at String(30) No -- ISO-8601 timestamp

Foreign Keys:

  • fk_plan_invariants_plan: plan_id -> v3_plans.plan_id ON DELETE CASCADE

Unique Constraints:

  • uq_plan_invariants_text on (plan_id, invariant_text)

Check Constraints:

  • ck_plan_invariants_scope: source_scope IN ('global', 'project', 'action', 'plan')

Indexes:

  • ix_plan_invariants_plan on plan_id
  • ix_plan_invariants_position on (plan_id, position)

Entity Relationship Diagram

actions (PK: namespaced_name)
  |-- 1:N --> action_invariants (FK: action_name)
  |-- 1:N --> action_arguments  (FK: action_name)
  |-- 1:N --> v3_plans          (FK: action_name, RESTRICT)

v3_plans (PK: plan_id)
  |-- self --> parent_plan_id   (SET NULL)
  |-- self --> root_plan_id     (SET NULL)
  |-- 1:N --> plan_projects     (FK: plan_id, CASCADE)
  |-- 1:N --> plan_arguments    (FK: plan_id, CASCADE)
  |-- 1:N --> plan_invariants   (FK: plan_id, CASCADE)

Source Location

  • Migration (actions): alembic/versions/a5_003_spec_aligned_actions.py
  • Migration (plans): alembic/versions/a5_004_spec_aligned_plans.py
  • ORM models: src/cleveragents/infrastructure/database/models.py
  • Repositories: src/cleveragents/infrastructure/database/repositories.py