@gallopsystems/agent-skills 1.12.0 → 1.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -10,7 +10,9 @@ doctl databases ca <db-id> # cluster CA certi
|
|
|
10
10
|
|
|
11
11
|
- **The connection URI contains live credentials** — treat command output as a secret. Don't echo it into logs; pipe it directly to where it's needed.
|
|
12
12
|
- **Check `Version`** and keep CI/local database versions in sync with production — a test suite running `postgres:15` against a pg-18 production cluster hides version-specific behavior.
|
|
13
|
-
- Connections use port 25060 with `sslmode=require`. **TLS trap**: some clients (e.g.
|
|
13
|
+
- Connections use port 25060 with `sslmode=require`. **TLS trap**: some clients (e.g. `pg-connection-string` as bundled with `pg` >= 8.16) silently treat `require` as `verify-full`, which rejects DO's self-signed CA under the default trust store (`SELF_SIGNED_CERT_IN_CHAIN`). Two non-obvious parts:
|
|
14
|
+
- **An ssl option set in code does NOT override an `sslmode` already in the URI.** Passing `ssl: { rejectUnauthorized: false }` while the connection string still ends in `?sslmode=require` keeps failing — the URI's `sslmode` wins. The fix has to land in the URI itself: drop/replace `sslmode`, append `uselibpqcompat=true` (restores libpq semantics: encrypt but don't verify), or supply the CA from `doctl databases ca <db-id>` explicitly.
|
|
15
|
+
- **When you can't edit the URI** — specifically, when you bind App Platform's generated `${db.DATABASE_URL}` straight into an env var in the app spec, it always carries `?sslmode=require` and you don't author the string — append the param to the bound value: `value: ${db.DATABASE_URL}&uselibpqcompat=true`. This only applies to that bound-pipethrough case; if you declare the connection-string env var yourself, just put the right params (or none) in from the start and an in-code ssl option is enough.
|
|
14
16
|
|
|
15
17
|
## Spaces
|
|
16
18
|
|
|
@@ -964,6 +964,53 @@ await db.schema.createIndex("idx_order_user_id").on("order").column("user_id").e
|
|
|
964
964
|
.addColumn("price", sql`numeric(10, 2)`)
|
|
965
965
|
```
|
|
966
966
|
|
|
967
|
+
### Migration Ordering Is Append-Only — Out-of-Order Timestamps Break Prod Deploys
|
|
968
|
+
|
|
969
|
+
Kysely's migrator enforces a **strict append-only ledger**: it refuses to run any
|
|
970
|
+
unexecuted migration whose timestamp sorts *before* the last-executed one
|
|
971
|
+
(throwing `Corrupted migrations: previously executed migration ... is missing`).
|
|
972
|
+
This bites when two branches each add a migration, and the one that merges *second*
|
|
973
|
+
carries the *earlier* timestamp:
|
|
974
|
+
|
|
975
|
+
```
|
|
976
|
+
branch A merges first → 1700000200000_drop_thing (runs in prod)
|
|
977
|
+
branch B merges second → 1700000100000_add_table (timestamp is EARLIER)
|
|
978
|
+
→ 1700000100001_add_column
|
|
979
|
+
```
|
|
980
|
+
|
|
981
|
+
Prod has already recorded `...200000_drop_thing` as executed. On the next deploy
|
|
982
|
+
the `migrate` job sees two pending migrations that sort *before* it, throws
|
|
983
|
+
"Corrupted migrations", and **exits non-zero**. If migrations run as a pre-deploy
|
|
984
|
+
job (common on PaaS like DigitalOcean App Platform), the failed job fails the whole
|
|
985
|
+
deploy and the platform **auto-rolls-back to the previous image** — so prod silently
|
|
986
|
+
stays on stale code and every subsequent deploy fails the same way. A self-reinforcing
|
|
987
|
+
loop that looks like a deploy/token problem but is really a migration-ledger problem.
|
|
988
|
+
|
|
989
|
+
**Prevent it:** before merging a long-lived branch, check whether `main` has merged
|
|
990
|
+
any migration with a *later* timestamp than yours. If so, regenerate your migration's
|
|
991
|
+
timestamp so it sorts last (`migrate:make` again, or rename the file) **before it
|
|
992
|
+
merges** — only safe while the migration has not yet run in any shared DB. Never
|
|
993
|
+
re-stamp a migration that prod has already executed; that forces it to re-run.
|
|
994
|
+
|
|
995
|
+
**Fix it once prod is wedged:** reconcile the ledger so the executed set is a clean
|
|
996
|
+
*prefix* again, then let the normal strict migrate job run. Do **not** reach for
|
|
997
|
+
`allowUnorderedMigrations: true` — it works (kysely-ctl spreads the `migrations`
|
|
998
|
+
config into the `Migrator`), but it permanently weakens the ordering guard to paper
|
|
999
|
+
over one bad state. Instead, surgically remove the prematurely-recorded row from the
|
|
1000
|
+
migration ledger table (default `kysely_migration`):
|
|
1001
|
+
|
|
1002
|
+
```sql
|
|
1003
|
+
-- prod ledger has the later-timestamp migration recorded, blocking the two earlier ones
|
|
1004
|
+
DELETE FROM kysely_migration WHERE name = '1700000200000_drop_thing';
|
|
1005
|
+
```
|
|
1006
|
+
|
|
1007
|
+
Now `add_table → add_column → drop_thing` are all pending in true timestamp order, and
|
|
1008
|
+
the next deploy's strict migrate job applies them cleanly. This only works when the
|
|
1009
|
+
removed migration is **idempotent to re-run** (e.g. a `dropTable`/`dropColumn` written
|
|
1010
|
+
with `ifExists`, so re-applying it after the others is a safe no-op). Verify the
|
|
1011
|
+
ledger is a contiguous prefix after the DELETE, and prefer letting the deploy's own
|
|
1012
|
+
migrate job re-apply rather than running migrations from a laptop against prod.
|
|
1013
|
+
|
|
967
1014
|
## Type Generation
|
|
968
1015
|
|
|
969
1016
|
Use `kysely-codegen` to generate types from your database:
|