diff --git a/docs/QINGLONG_3_0_ARCHITECTURE_RFC.md b/docs/QINGLONG_3_0_ARCHITECTURE_RFC.md index bc7fe349..5a240f85 100644 --- a/docs/QINGLONG_3_0_ARCHITECTURE_RFC.md +++ b/docs/QINGLONG_3_0_ARCHITECTURE_RFC.md @@ -167,8 +167,11 @@ package、生产依赖、daemon 或 Edge import。 Runtime Core `591/591`、Cluster PostgreSQL `361 total / 358 pass / 3 conditional skip / 0 fail`、 - v70 定向门 `74/74` 均为零失败。PostgreSQL 18.6 arm64 HA 再次通过 146 gates、timeline `1→2`, - 最终报告 SHA-256 为 `42ca97de43cfebd4611282b1fd5c0b09030eda89e88144967497902b01d18b3a`; + v70 定向门 `74/74`、CI 同构八角色 PostgreSQL integration `57/57` 均为零失败。Automation Manager + 对 Project 与 immutable plan 只执行普通 SERIALIZABLE `SELECT`,不要求越权的 row-lock 权限; + Task/Trigger 可变 head 与 schedule 仍保持 `FOR UPDATE`。PostgreSQL 18.6 arm64 HA 再次通过 146 gates、 + timeline `1→2`,最终报告 SHA-256 为 + `a7c8a05e08c748d677475a09ce2998b741ed9326e27678613e93d431bc3769aa`; 真实用例覆盖 Trigger 固定 Task r1、Task current r2、原子生成 Task r3/Trigger r2 并重定向 pin, 同时证明 bundle ref-only execution、schedule reset、无流消费 replay 与数据库角色隔离。D-402 关闭 mutation/receipt 边界;direct external custody、promotion 后 receipt replay 和固定低性能 Edge diff --git a/docs/adr/ADR-0497-atomic-cluster-legacy-env-migration-application.md b/docs/adr/ADR-0497-atomic-cluster-legacy-env-migration-application.md index 2a616a42..4b21a054 100644 --- a/docs/adr/ADR-0497-atomic-cluster-legacy-env-migration-application.md +++ b/docs/adr/ADR-0497-atomic-cluster-legacy-env-migration-application.md @@ -103,9 +103,11 @@ batch;Edge/Standalone 默认 import graph 不加载 PostgreSQL authority。 ## 当前验证与后续门禁 runtime-core 完整测试 `591/591`;cluster-postgres package 测试 `361 total / 358 pass / 3 -conditional skip / 0 fail`;v70 migration/schema/readiness 定向门 `74/74`。真实 PostgreSQL 18.6 -arm64 HA 多次通过 146 gates,timeline `1→2`;最终报告 SHA-256 为 -`42ca97de43cfebd4611282b1fd5c0b09030eda89e88144967497902b01d18b3a`。 +conditional skip / 0 fail`;v70 migration/schema/readiness 定向门 `74/74`;CI 同构八角色 +PostgreSQL integration `57/57`。Automation Manager 对 Project 与 immutable plan 只需普通 +SERIALIZABLE `SELECT`,Task/Trigger 可变 head 与 schedule 继续持有 `FOR UPDATE`。真实 PostgreSQL +18.6 arm64 HA 多次通过 146 gates,timeline `1→2`;最终报告 SHA-256 为 +`a7c8a05e08c748d677475a09ce2998b741ed9326e27678613e93d431bc3769aa`。 真实数据库用例证明:带空格的合法 Task/Trigger ID 可迁移;Trigger 固定 Task r1、Task current r2 时会原子生成 Task r3 与 Trigger r2 并让新 Trigger 固定 r3;execution plan 只出现 bundle ref; diff --git a/packages/ql3-cluster-postgres/src/reconciliation/clusterLegacyEnvMigrationApplicationRepository.ts b/packages/ql3-cluster-postgres/src/reconciliation/clusterLegacyEnvMigrationApplicationRepository.ts index d87986ac..2a7212e2 100644 --- a/packages/ql3-cluster-postgres/src/reconciliation/clusterLegacyEnvMigrationApplicationRepository.ts +++ b/packages/ql3-cluster-postgres/src/reconciliation/clusterLegacyEnvMigrationApplicationRepository.ts @@ -319,8 +319,7 @@ async function loadPlan( const result = await client.query( `SELECT plan_json AS "planJson" FROM "ql3"."cluster_legacy_env_migration_plans" - WHERE plan_id = $1 - FOR SHARE`, + WHERE plan_id = $1`, [intent.planId], ); if (result.rows.length !== 1) throw conflict(); @@ -1126,7 +1125,7 @@ export class PostgresClusterLegacyEnvMigrationApplicationRepository ); if (occupied) throw conflict(); const project = await client.query<{ status: unknown }>( - `SELECT status FROM "ql3"."projects" WHERE id = $1 FOR SHARE`, + `SELECT status FROM "ql3"."projects" WHERE id = $1`, [intent.projectId], ); if (project.rows.length !== 1 || project.rows[0]?.status !== 'active') { diff --git a/packages/ql3-cluster-postgres/test/postgres.integration.test.cjs b/packages/ql3-cluster-postgres/test/postgres.integration.test.cjs index 42c1093b..8c055300 100644 --- a/packages/ql3-cluster-postgres/test/postgres.integration.test.cjs +++ b/packages/ql3-cluster-postgres/test/postgres.integration.test.cjs @@ -5019,6 +5019,12 @@ if (!migrationConnectionString) { eventCount: 2, }, ]); + await database.pool.query( + `UPDATE "ql3"."trigger_schedules" + SET next_fire_at_ms = $1 + WHERE project_id = $2 AND trigger_id = $3`, + [forcedDueAtMs + 3_600_000, 'default', triggerId], + ); const takeoverTriggerId = `trigger-takeover-${'x'.repeat(32)}`; await new PostgresTriggerRepository(database.pool).appendTriggerRevision({ @@ -6982,7 +6988,7 @@ if (!migrationConnectionString) { assert.equal(row.taskSpec.config.timeoutMs, 30_000); assert.equal(row.taskName, task.name); assert.equal(row.taskDescription, task.description); - assert.deepEqual(row.taskLabels, task.labels); + assert.deepEqual(row.taskLabels, { ...task.labels }); assert.equal(row.executionPlan.environmentBundleRef, secretRef); assert.equal(row.triggerRevision, 2); assert.equal(row.triggerTaskRevision, 3);