Ivan's Blog
规则

persistent-state-migrations

Design and verify release-to-release migrations for durable application, file, queue, or device state.

目录

Persistent-state migrations

Use this project policy whenever a release creates, reads, transforms, replaces, or stops reading state that survives the running process. This includes database schemas, files, queues, device configuration, and embedded storage. Temporary caches and non-persistent fixtures are out of scope.

Workflow

  1. Record the state, source compatibility range, ordered operations, rollout signals, recovery path, and validation in assets/templates/persistent-state-migration-record.example.json.
  2. Keep structural changes, DML, and historical-data backfills separate, ordered, observable, and pauseable.
  3. Treat deployed migrations as immutable. A stopped release is repaired forward; program rollback does not silently reverse persisted state. Backup restore is separate disaster recovery.
  4. Test every declared earlier-version source state and the stopped-release repair path. Verify idempotent recognition and safe re-entry.

When public APIs also change, read the installed semver-change-governance policy and record the two compatibility contracts independently. This policy does not select tags, labels, or version identity.

Adoption preview

Before applying this policy to a target project, preview the writes to .agents/skills/persistent-state-migrations/ and skills-lock.json, then wait for explicit owner approval. Install it with npx skills add IvanLi-CN/style-playbook-skills --skill persistent-state-migrations --yes; the CLI detects the Agent and project layout.

Package resources

  • assets/templates/persistent-state-migration-record.example.json

手动安装

将指令保存为技能目录中的 SKILL.md,并保持下列资源的相对路径。阅读与下载不会执行安装。

下载 SKILL.md

公开资源

SKILL.md
SKILL.md
markdown · 36 行
预览方式
description
Design and verify release-to-release migrations for durable application, file, queue, or device state.
kind
policy-skill
name
persistent-state-migrations
policy_dependencies
[]
primary_topic
persistent-state-migrations
public_url_hosts
[]
schema_version
1
slug
persistent-state-migrations
visibility
public

Persistent-state migrations

Use this project policy whenever a release creates, reads, transforms, replaces, or stops reading state that survives the running process. This includes database schemas, files, queues, device configuration, and embedded storage. Temporary caches and non-persistent fixtures are out of scope.

Workflow

  1. Record the state, source compatibility range, ordered operations, rollout signals, recovery path, and validation in assets/templates/persistent-state-migration-record.example.json.
  2. Keep structural changes, DML, and historical-data backfills separate, ordered, observable, and pauseable.
  3. Treat deployed migrations as immutable. A stopped release is repaired forward; program rollback does not silently reverse persisted state. Backup restore is separate disaster recovery.
  4. Test every declared earlier-version source state and the stopped-release repair path. Verify idempotent recognition and safe re-entry.

When public APIs also change, read the installed semver-change-governance policy and record the two compatibility contracts independently. This policy does not select tags, labels, or version identity.

Adoption preview

Before applying this policy to a target project, preview the writes to .agents/skills/persistent-state-migrations/ and skills-lock.json, then wait for explicit owner approval. Install it with npx skills add IvanLi-CN/style-playbook-skills --skill persistent-state-migrations --yes; the CLI detects the Agent and project layout.

Package resources

  • assets/templates/persistent-state-migration-record.example.json
skills/policies/persistent-state-migrations/assets/templates/persistent-state-migration-record.example.json
skills/policies/persistent-state-migrations/assets/templates/persistent-state-migration-record.example.json
json · 100 行
{
  "schema_version": 1,
  "kind": "persistent-state-migration-record",
  "migration": {
    "description": "<durable-state change description>",
    "release_unit_description": "<release unit description>",
    "version_impact": "patch"
  },
  "durable_state": {
    "description": "<state retained across program versions>",
    "storage_implementation": "<not assumed>",
    "source_compatibility_range": {
      "from_program_versions": "<supported source program range>",
      "to_program_version": "<candidate program version>",
      "direct_major_skips_supported": false
    }
  },
  "database_migration": {
    "applicable": true,
    "ddl_structural_changes": [
      {
        "id": "ddl-001",
        "description": "<schema or structural change>",
        "order": 1,
        "observable": true,
        "pauseable": true
      }
    ],
    "dml_changes": [
      {
        "id": "dml-001",
        "description": "<current-data manipulation or not applicable>",
        "order": 2,
        "depends_on": [
          "ddl-001"
        ],
        "observable": true,
        "pauseable": true
      }
    ],
    "historical_data_backfill_or_transformation": [
      {
        "id": "backfill-001",
        "description": "<historical-data backfill or transformation or not applicable>",
        "order": 3,
        "depends_on": [
          "ddl-001",
          "dml-001"
        ],
        "observable": true,
        "pauseable": true
      }
    ]
  },
  "rollout_observability": {
    "operations_must_remain_separate": true,
    "operation_sequence": [
      "ddl-001",
      "dml-001",
      "backfill-001"
    ],
    "progress_signals": [
      "<per-operation observable signal>"
    ],
    "pause_points": [
      "<safe point between operations>"
    ]
  },
  "recovery": {
    "deployed_migrations_immutable": true,
    "program_rollback_state_behavior": "does-not-automatically-reverse-compensate-or-down-migrate",
    "faulty_release_recovery": "forward-repair-by-a-new-program-version",
    "backup_restore_role": "separate-disaster-recovery"
  },
  "validation": {
    "patch": {
      "required_test_evidence": [
        "public API is nonbreaking",
        "candidate-written state works in every supported earlier program within the same Minor",
        "deployed migration identity is recognized without rewrite"
      ]
    },
    "minor": {
      "required_test_evidence": [
        "public API remains compatible within the Major",
        "candidate reads and writes supported earlier-Minor state",
        "earlier-Minor programs are not required to read newly migrated state",
        "a forward-repair version handles state left by a stopped faulty release"
      ]
    },
    "major": {
      "required_test_evidence": [
        "current program upgrades and uses state from the immediately preceding Major",
        "direct major skipping is rejected or routed through an explicit intermediate upgrade",
        "a forward-repair version handles state left by a stopped faulty release"
      ]
    }
  }
}