Repository navigation
schema-migration skill: answer apso migrate's questions (plan flow), plus the 10-22 skill fixes and eval hook - #18
Merged
Merged
Conversation
…chema-designer composes them DRAFT for review — do not publish until content-reviewed (public repo). - references/data-modeling-principles.md: ported DB-engineering rigor (3NF, event-vs-counter, indexing/Big-O, review checklist), in correct .apsorc v2 format. - skills/schema-review/SKILL.md (category: data): audit/harden an existing schema; composes the principles. - schema-designer: references the principles + links schema-review. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…EADME Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…+ data-modeling-principles) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ths; add relational patterns
- Field types: varchar, string, timestamp and uuid are valid; moments in time
(*At) use timestamptz instead of date.
- Relationships are declared once (ManyToOne from the child). The CLI generates
the inverse side and does not dedupe, so the OneToMany twins created duplicate
foreign keys. Self-references are one nullable ManyToOne.
- file-storage and tagging-taxonomy default to real foreign keys instead of
entityType + entityId.
- Skills cite references via ${CLAUDE_PLUGIN_ROOT}; the bare relative path
resolved inside the skill folder and every read failed.
- New references/relational-patterns.md: Postgres design, .apsorc encoding and
missing guarantee per pattern, plus an anti-pattern table. Loaded by
schema-designer and schema-review.
- Evals: all cases use case.yaml with a refs symlink + add_dirs so skills can
read references; layered design/apsorc graders; CLI validator and
duplicate-side gate in the pre-commit hook; new schema-designer-invoicing
case. Release guard ignores evals/.
…-model requests - data-modeling-principles claimed Apso indexes foreign keys from the relationship. It does not (apso schema validate warns FOREIGN_KEY_NOT_INDEXED). The rule is now "index: true on every ManyToOne", and 60 ManyToOne examples across the skills and references carry it. - schema-designer validates with `apso schema validate --local` when the CLI is available, and its description triggers on "design the data model" requests that also match a domain skill. - New eval cases for comments/reactions, plan pricing (effective dating) and legal parties (supertype/subtype); every designer case checks FK indexes. Plain Claude passes the design graders but leaves FKs unindexed in 9 of 10 runs; with the plugin 0 of 10.
Plants duplicate relationship sides, a required self-reference and unindexed foreign keys next to general Postgres mistakes. With the plugin the review flags all three Apso traps in 3/3 runs; plain Claude misses them in 3/3 while catching the general ones (score 1.0 vs 0.5).
Verified against @apso/cli 0.43: getRelationshipForTemplate dedupes a plain OneToMany + ManyToOne pair, so it does not duplicate the foreign key as f669d62 said. The failure is a pair with different names (a to_name on the OneToMany), which gives the parent two collections over one foreign key and which the linter misses. "Declare once" stays (the docs say the same); the stated reason, the review grader and the catalog's CLI gap are corrected. A self-referencing OneToMany does add a second, required foreign key; that text was right and is unchanged.
A schema change reaches a deployed service's database only through a committed migration file (src/migrations/*-migration.ts for TypeScript); the CLI writes none, apso migrate only checks DDL on an empty database, and auto-generated SQL turns renames and type changes into drops. The new schema-migration skill writes the .apsorc change plus a hand-written migration with recipes for renames, required fields, type changes, enum swaps, unique constraints and drops, and explains expand/contract since the database changes before the new Lambda goes live. Five eval cases (rename field, rename entity, add required field, type change, enum replace). scripts/migration-check runs the agent's migration against seeded PGlite, checks the rows, and checks that the migrated database matches DDL generated from the final .apsorc. The pre-commit hook runs it for every case with a migration-check/ dir. Measured over 2 runs per case: plugin 10/10, plain Claude 0/10 (its files lack the -migration.ts suffix, so the deploy would skip them). The hook now retries a failing case once. Three full runs each failed one different LLM-judged case on a correct answer (enum-replace, custom-endpoints-override, schema-review-encoding); a real regression fails both times. Corrects deployment, api-builder and the schema guide, which said apso migrate --apply applies a migration and that deploy detects schema changes. Clarifies the flaky custom-endpoints-override case (1/3 before, 4/4 after): files must be written, and the judge's criteria are stated as separate, checkable points.
…seeded rows The skill no longer hand-writes migrations. apso migrate generate (CLI 0.43) produces TypeORM's migration from the deployed schema; the skill reviews it for the statements TypeORM gets wrong on populated tables (type change as DROP + ADD, entity rename as a new empty table, enum swaps that fail on removed values, NOT NULL adds and default backfills), patches only those, and verifies with apso migrate verify --seed. Eval prompts now hand the agent TypeORM's real output for each case. Fixes the earlier claim that the CLI writes no TypeScript migrations.
New eval cases hand the agent TypeORM's real output for three data moves, each of which loses or fails on seeded rows as generated: - extract-entity: Contact.phone to a PhoneNumber entity (phone dropped, table empty) - many-to-many: Contact to Company ManyToOne to ManyToMany (links dropped) - split-field: fullName to firstName/lastName (NOT NULL add fails on rows) The seeded checks pass on the patched migrations and fail on the raw ones. The skill gains a Moving data section and the verify --check and per-column --accept-loss flags.
… TypeORM output apso migrate (CLI 0.44) plans the change, asks about anything ambiguous (rename or drop, split, enum mapping, backfill, cast, relation) and writes the migration from the answers. The skill now answers those questions and verifies, and never hand-writes SQL beyond answer expressions. The 8 migration evals hand the agent apso migrate's real question output and plan file; the agent writes the answered plan. migration-check renders the migration from those answers with the CLI (APSO_CLI_BIN for an unreleased build), runs it against the seeded rows, and calls apso migrate sandbox --sql for the convergence DDL. allow-refusal also accepts a strict cast that rejects a value (22P02, 22003). A plan-answer grader replaces the TypeORM class name grader.
…kill # Conflicts: # plugins/apso/README.md # plugins/apso/references/architecture/taxonomy.md # plugins/apso/references/data-modeling-principles.md # plugins/apso/skills/schema-designer/SKILL.md # plugins/apso/skills/schema-review/SKILL.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Merge after @apso/cli 0.44.0 is published (the migration check runs
npx @apso/cli@latest migrate).schema-migration (new skill). The agent runs
apso migrate, answers its questions (rename or drop, split, enum mapping, backfill, cast, relation) in.apso/migration-plan.jsonor with--answer, and lets the CLI write the migration. It asks the user when intent is unclear, never answers drop on its own, and verifies withapso migrate verify --seed.8 migration evals. Each one hands the agent the real
apso migratequestion output and plan file for its case.scripts/migration-checkrenders the migration from the agent's answers with the CLI and runs it against seeded rows. A wrong answer fails: rename-field answered drop gives 'existing phone values kept in mobilePhone' failed. All 8 passed in the pre-commit run against a local CLI build; type-change passed on its retry.Also in this branch, never merged before: the 10-22 skill fixes (field types, relationship sides, index every foreign key, schema-review eval case) and the pre-commit eval hook with scripts/migration-check. Conflicts with #16 were resolved in favour of these newer versions.