refactor(managed-agent): align shared MySQL schema conventions (#16143)

* docs(managed-agent): document database tables and columns

* refactor(managed-agent): align shared MySQL schema conventions
This commit is contained in:
jinye authored and GitHub committed 2026-11-03 12:00:29 +00:00
1 parent 6fe83a8245
commit b1cd4ac0c6
150 files changed
+2457 -1750

No files matched your search

@@ -0,0 +1,94 @@
# Managed schema conventions
[English](2026-11-02-managed-schema-conventions.md) | [简体中文](2026-11-02-managed-schema-conventions.zh-CN.md)
## Scope
Align the shared pre-release V1 database baseline with the MySQL conventions in
Alibaba's Java Development Manual (Huangshan edition). Server and Broker must
continue to initialize and validate the same catalog on MySQL 8.4 and H2.
Physical deletion and retention policies are outside this change.
Reference: the MySQL chapter, printed pages 32–35, in the
[official Huangshan manual](<https://github.com/alibaba/p3c/blob/6c59c8c36ecd8722c712d5685b8c3822c1c8b030/Java开发手册(黄山版).pdf>).
## Decisions
- Give every table an unsigned auto-increment, unique `id`. Use it as the primary
key except on `ma_session` and `ma_tenant_guard`, which retain their original
business primary keys `(tenant_id, session_id)` and `(tenant_key, guard_domain)`.
These two tables coordinate existing records through upserts. With `id` as
their clustered primary key, native MySQL captured `PRIMARY` supremum locks
blocking unrelated Sessions, tenants and guard domains during acquisition.
Keep their business clustering and a separate unique `id` index to preserve
the existing creation and locking-read protocol. The other 36 tables keep `id`
primary keys and unique business keys. Business identities, tenant scoping,
idempotency, and fencing continue to use the original business keys.
- Keep the existing `gmt_create` and `gmt_modified` names and all
epoch-millisecond timestamp fields. Application clocks, lease deadlines, and
ordered pagination depend on the current timestamp contracts.
Do not add duplicate timestamps. Database row IDs are excluded from domain
projections and CSI evidence.
- Use `is_` names and unsigned tiny integers for boolean columns. Keep nullable
flags nullable and generated flags generated. Update SQL consumers and boolean
row decoding together; serialized API and journal payload names stay intact.
Range checks retain the 0/1 domain on both engines without H2's connection-bound
optimization of constant `IN` lists.
- Use unsigned integer declarations for nonnegative counters, versions,
generations, sizes, and ordinals. Validate signedness for every integer type on
MySQL. H2 ignores unsigned storage ranges, so native MySQL evidence remains
required. Retain the nonnegative CHECK constraints for H2. MySQL and MariaDB
require `STRICT_TRANS_TABLES` or `STRICT_ALL_TABLES` in global and session
`sql_mode` to reject ordinary out-of-range unsigned writes instead of clamping
them; `IGNORE` writes can downgrade these errors to warnings.
- Name ordinary indexes with `idx_` and unique constraints with `uk_`. MySQL
always exposes the primary index as `PRIMARY`; the DDL gives its constraint a
table-specific `pk_` name where supported.
- Remove database foreign keys. Existing application admission, ownership, and
transaction checks continue to govern related writes. Preserve all former
parent and child identity indexes and business uniqueness constraints.
- Store fixed-width SHA-256 strings in `CHAR`. Keep shared receipt and operation
digest columns variable-width when their namespaces store different digest
formats.
- Keep full indexes for short discriminator strings: their complete values are
needed by covering and ordered queries, and shortening them loses information.
Use a bounded prefix for the longer host identity lookup. MySQL executable
comments express its prefix while H2 uses the full-column equivalent.
## Catalog validation
The canonical resource remains V1. Existing development catalogs must be
recreated; no repair, migration, or history rewrite is introduced. Validation
must reject missing row IDs, incorrect primary or business keys, missing
auto-increment behavior, changed integer types or signedness, and changed index
prefixes. It must continue rejecting legacy, partial, and foreign catalogs.
Shared Server/Broker admission and validation refuse non-strict MySQL or MariaDB
before schema writes. The database defaults and every application connection
must retain strict mode during operation; the startup check does not enforce
later administrative or connection-mode changes, and does not change SQL modes.
## Verification and acceptance
- Exercise Broker and Flyway initialization, repeated validation, row ID
generation on fresh H2 and disposable MySQL 8.4 databases.
- Independently verify all 38 generated IDs are unique, both coordination tables
retain their ordered business primary keys, and the other 36 retain `id`
primary keys. Native concurrency checks must preserve same-key exclusion,
independent guard domains/tenants/Sessions, concurrent first creation,
committed migration-fence visibility, SSH overlap arbitration, publication
ordering and bounded lifecycle completion. Existing failures remain unresolved
until the corrected revision passes the required native gates.
- Verify that duplicate business identities still fail, flags retain their
values and nullability, and representative Server/Broker stores still read and
write the renamed columns.
- Check snapshot/projection contracts, schema drift rejection, and relevant
queue, publication, scheduling, Workspace and Runtime consumers.
- Reject non-strict global or session modes before initialization or validation,
and verify ordinary negative unsigned writes fail under both supported strict modes on
MySQL without changing the server's global settings in the test.
- Run focused local Maven checks within the module's shared validation budget;
report full-suite and native-process gaps for CI.
Acceptance remains pending until the checks above and the required CI gates
pass. Changing row layout, removing foreign keys, and updating CSI field names
requires a fresh development installation under the existing pre-release policy.
@@ -0,0 +1,65 @@
# Managed 数据库规约
[English](2026-11-02-managed-schema-conventions.md) | [简体中文](2026-11-02-managed-schema-conventions.zh-CN.md)
## 范围
按照《阿里巴巴 Java 开发手册(黄山版)》的 MySQL 规约整理共享的发布前 V1 数据库基线。
Server 和 Broker 必须继续在 MySQL 8.4 与 H2 上初始化和校验同一套数据库。
物理删除及保留期策略不在本次修改范围内。
参考来源为[官方黄山版手册](<https://github.com/alibaba/p3c/blob/6c59c8c36ecd8722c712d5685b8c3822c1c8b030/Java开发手册(黄山版).pdf>)
中印刷页码 32–35 页的 MySQL 章节。
## 决策
- 每张表增加无符号、自增且唯一的 `id`,除 `ma_session` 和 `ma_tenant_guard` 外均用作主键。
这两张表保留原业务主键 `(tenant_id, session_id)` 和 `(tenant_key, guard_domain)`。
两表通过 upsert 协调已有记录;以 `id` 作为聚簇主键时,原生 MySQL 已捕获取锁过程中的
`PRIMARY` supremum 锁,阻塞了无关 Session、租户及锁域。
保留业务聚簇和单独的 `id` 唯一索引,以保留现有首次创建及加锁读取协议。
其余 36 张表继续使用 `id` 主键和业务唯一键。
业务身份、租户范围、幂等及防止旧执行者写入的检查继续使用原业务键。
- 沿用现有 `gmt_create`、`gmt_modified` 命名及所有毫秒时间字段。
应用时钟、租约截止时间及有序分页依赖现有时间戳约定。不新增重复时间字段。
数据库生成的行 ID 不进入领域投影和 CSI 证据。
- 布尔字段采用 `is_` 命名及无符号微整型。保留可空标志的可空性、派生标志的计算方式。
同步调整 SQL 消费者和行数据的布尔解码;序列化 API 及日志载荷的字段名保持原样。
用范围检查在两种数据库上保留 0/1 值域,避免 H2 对常量 `IN` 列表的优化依赖初始化连接。
- 非负计数、版本、代次、大小及序号使用无符号整数声明。
MySQL 校验覆盖所有整数类型的符号属性。H2 忽略无符号存储范围,因此仍需真实 MySQL 验证。
保留非负 CHECK 约束用于 H2。MySQL 和 MariaDB 的全局及会话 `sql_mode` 必须包含
`STRICT_TRANS_TABLES` 或 `STRICT_ALL_TABLES`,让普通的越界无符号写入被拒绝,而不是被截断;
`IGNORE` 写入仍可能把这类错误降级为警告。
- 普通索引使用 `idx_` 前缀,唯一约束使用 `uk_` 前缀。
MySQL 始终将主键索引显示为 `PRIMARY`;DDL 在支持时为主键约束声明表内唯一的 `pk_` 名称。
- 移除数据库外键。现有应用准入、所有权及事务检查继续控制关联写入。
保留原父子身份索引和业务唯一约束。
- 固定宽度 SHA-256 字符串使用 `CHAR`。多个命名空间存储不同摘要格式的共享回执和操作摘要列,
继续使用变长类型。
- 短判别字符串保留完整索引:覆盖查询和有序查询需要完整值,截短会丢失信息。
较长的主机身份查询使用有界前缀。通过 MySQL 可执行注释声明前缀,H2 使用对应完整列索引。
## 数据库校验
标准资源继续使用 V1。已有开发数据库需要重建,不引入修复、升级迁移或历史改写。
校验必须拒绝缺失的行 ID、错误的主键或业务唯一键、缺少自增行为、错误的整数类型或符号属性,
以及变化的索引前缀。继续拒绝旧版、不完整及包含其他业务对象的数据库。
Server/Broker 共享准入和校验入口,在写入结构前拒绝非严格模式的 MySQL 或 MariaDB。
运行期间数据库默认值及每个应用连接都必须保持严格模式;启动检查不控制之后的管理员或连接模式变更,
也不会修改 SQL 模式。
## 验证与验收
- 在新建 H2 和临时 MySQL 8.4 数据库上验证 Broker、Flyway 初始化、重复校验、行 ID 生成行为。
- 独立验证全部 38 张表生成的 ID 均唯一,两张协调表保留顺序正确的业务主键,其余 36 张表保留 `id` 主键。
原生并发检查须验证同键互斥、不同锁域/租户/Session 互不阻塞、并发首次创建、等待后可见已提交迁移栅栏、
SSH 目录重叠仲裁、发布锁顺序及有界生命周期完成。修复版本通过必需原生门禁前,原失败仍保留为未解决。
- 验证重复业务身份仍被拒绝,标志值及可空性保持一致,代表性的 Server/Broker 存储仍能读写更名后的列。
- 检查快照和投影约定、结构偏移拒绝行为,以及相关队列、发布、调度、Workspace 和 Runtime 消费者。
- 在初始化或校验前拒绝非严格的全局或会话模式;在 MySQL 的两种严格模式下验证普通负数无符号写入被拒绝,
测试不修改服务器全局设置。
- 在模块共享验证预算内运行针对性的本地 Maven 检查;将全量测试及原生进程验证缺口交给 CI 并明确记录。
上述检查及必需 CI 门禁通过前,验收仍待完成。
行结构变化、移除外键及 CSI 字段名调整,遵循现有发布前策略,需要全新安装开发环境。
@@ -0,0 +1,65 @@
/**
* @license
* Copyright 2026 Qwen Team
* SPDX-License-Identifier: Apache-2.0
*/
import { describe, expect, it } from 'vitest';
import { projectEvents } from './hosted-sse-observer.js';
describe.each([
{
surface: 'public',
expected: {
schema_version: 1,
projection_version: 1,
sequence: 7,
event_id: 'event',
session_id: 'session',
turn_id: 'turn',
type: 'turn.completed',
created_at: 1_700_000_000,
data: { status: 'completed' },
},
},
{
surface: 'web',
expected: {
schemaVersion: 1,
projectionVersion: 1,
sequence: 7,
eventId: 'event',
sessionId: 'session',
turnId: 'turn',
type: 'turn.completed',
createdAt: 1_700_000_000_123,
data: { status: 'completed' },
},
},
])('projectEvents ($surface)', ({ surface, expected }) => {
it.each([
[false, false],
[0, false],
[true, true],
[1, true],
])('projects the canonical SQL terminal flag %s', (flag, terminal) => {
const rows = [
{
schema_version: 1,
projection_version: 1,
sequence_id: 7,
event_id: 'event',
session_id: 'session',
turn_id: 'turn',
item_id: null,
content_part_id: null,
event_type: 'turn.completed',
gmt_create: 1_700_000_000_123,
data_json: '{"status":"completed"}',
is_terminal: flag,
},
];
expect(projectEvents(rows, surface)).toEqual([{ ...expected, terminal }]);
});
});
@@ -191,7 +191,7 @@ export function projectEvents(
? Math.floor(Number(row['gmt_create']) / 1000)
: row['gmt_create'],
data: JSON.parse(String(row['data_json'])),
terminal: Boolean(row['terminal']),
terminal: Boolean(row['is_terminal']),
};
return Object.fromEntries(
Object.entries(fields)
+1 -1
View File
@@ -99,7 +99,7 @@
"test:integration:sandbox:docker": "cross-env QWEN_SANDBOX=docker npm run build:sandbox && QWEN_SANDBOX=docker vitest run --root ./integration-tests",
"test:integration:sandbox:podman": "cross-env QWEN_SANDBOX=podman vitest run --root ./integration-tests",
"test:integration:hosted:sandbox:none": "cross-env QWEN_SANDBOX=false vitest run --root ./integration-tests --config ./vitest.hosted.config.ts",
"test:integration:no-ak:sandbox:none": "cross-env QWEN_SANDBOX=false vitest run --root ./integration-tests --poolOptions.forks.maxForks 2 ./fake-openai-server.test.ts ./test-helper.test.ts ./chat-transcript-contract.test.ts ./skill-hooks-invocation-parity.test.ts ./skill-hooks-resume.test.ts ./qwen-live-m4-acp-call.test.ts ./qwen-live-m4-acp-permission.test.ts ./qwen-live-m4-acp-steering.test.ts ./qwen-live-m4-acp-multibackend.test.ts ./qwen-live-m1-call.test.ts ./qwen-live-m2-inject.test.ts ./qwen-live-m2-permission.test.ts ./qwen-live-m2-steering.test.ts ./cli/_prompt-latency-policy.test.ts ./cli/agent-loop-parity.test.ts ./cli/acp-agent-loop-parity.test.ts ./cli/hosted-harness-process.test.ts ./cli/daemon-invocation-context.test.ts ./cli/headless-workflow-skill.test.ts ./cli/workflow-ancestor-discovery.test.ts ./cli/daemon-workflow-ancestor-trust.test.ts ./cli/workflow-intent.test.ts ./cli/workflow-mode.test.ts ./cli/acp-workflow-mode.test.ts ./cli/daemon-workflow-intent.test.ts ./cli/daemon-workflow-mode.test.ts ./cli/list_directory.test.ts ./cli/tool-hook-context.test.ts ./cli/tool-hook-updated-input.test.ts ./cli/qwen-serve-routes.test.ts ./cli/qwen-serve-session-cd.test.ts ./cli/qwen-serve-streaming.test.ts ./cli/qwen-serve-standalone-concurrency.test.ts ./interactive/workflow-completion.test.ts ./interactive/workflow-intent.test.ts ./interactive/workflow-mode.test.ts ./interactive/mods-tool-middleware.test.ts ./interactive/statusline-parity.test.ts ./interactive/tui-editor-parity.test.ts ./interactive/tui-input-ownership.test.ts ./sdk-typescript/abort-and-lifecycle.test.ts ./sdk-typescript/permission-control.test.ts ./sdk-typescript/sdk-mcp-server.test.ts ./sdk-typescript/subagents.test.ts ./sdk-typescript/system-control.test.ts ./sdk-typescript/tool-control.test.ts ./sdk-typescript/workflow-intent.test.ts ./sdk-typescript/workflow-mode.test.ts",
"test:integration:no-ak:sandbox:none": "cross-env QWEN_SANDBOX=false vitest run --root ./integration-tests --poolOptions.forks.maxForks 2 ./fake-openai-server.test.ts ./test-helper.test.ts ./chat-transcript-contract.test.ts ./skill-hooks-invocation-parity.test.ts ./skill-hooks-resume.test.ts ./qwen-live-m4-acp-call.test.ts ./qwen-live-m4-acp-permission.test.ts ./qwen-live-m4-acp-steering.test.ts ./qwen-live-m4-acp-multibackend.test.ts ./qwen-live-m1-call.test.ts ./qwen-live-m2-inject.test.ts ./qwen-live-m2-permission.test.ts ./qwen-live-m2-steering.test.ts ./cli/_prompt-latency-policy.test.ts ./cli/agent-loop-parity.test.ts ./cli/acp-agent-loop-parity.test.ts ./cli/hosted-harness-process.test.ts ./cli/daemon-invocation-context.test.ts ./cli/headless-workflow-skill.test.ts ./cli/workflow-ancestor-discovery.test.ts ./cli/daemon-workflow-ancestor-trust.test.ts ./cli/workflow-intent.test.ts ./cli/workflow-mode.test.ts ./cli/acp-workflow-mode.test.ts ./cli/daemon-workflow-intent.test.ts ./cli/daemon-workflow-mode.test.ts ./cli/list_directory.test.ts ./cli/tool-hook-context.test.ts ./cli/tool-hook-updated-input.test.ts ./cli/qwen-serve-routes.test.ts ./cli/qwen-serve-session-cd.test.ts ./cli/qwen-serve-streaming.test.ts ./cli/qwen-serve-standalone-concurrency.test.ts ./helpers/hosted-sse-observer.test.ts ./interactive/workflow-completion.test.ts ./interactive/workflow-intent.test.ts ./interactive/workflow-mode.test.ts ./interactive/mods-tool-middleware.test.ts ./interactive/statusline-parity.test.ts ./interactive/tui-editor-parity.test.ts ./interactive/tui-input-ownership.test.ts ./sdk-typescript/abort-and-lifecycle.test.ts ./sdk-typescript/permission-control.test.ts ./sdk-typescript/sdk-mcp-server.test.ts ./sdk-typescript/subagents.test.ts ./sdk-typescript/system-control.test.ts ./sdk-typescript/tool-control.test.ts ./sdk-typescript/workflow-intent.test.ts ./sdk-typescript/workflow-mode.test.ts",
"test:integration:sdk:sandbox:none": "cross-env QWEN_SANDBOX=false vitest run --root ./integration-tests --poolOptions.forks.maxForks 2 sdk-typescript",
"test:integration:sdk:sandbox:docker": "cross-env QWEN_SANDBOX=docker npm run build:sandbox && QWEN_SANDBOX=docker vitest run --root ./integration-tests --poolOptions.forks.maxForks 2 sdk-typescript",
"test:sdk:python": "python3 -m pytest -c packages/sdk-python/pyproject.toml packages/sdk-python/tests -q",
+10 -1
View File
@@ -332,7 +332,16 @@ reclaim anything. If the database check fails, capacity remains skipped.
MySQL is the supported database family; full integration CI uses MySQL 8.4.
MariaDB no longer has a CI lane or an ongoing compatibility guarantee.
Existing dialect handling remains in place; this change does not reject
connections that previously worked or introduce a catalog migration.
MariaDB solely by product name or introduce a catalog migration.
MySQL and MariaDB require `STRICT_TRANS_TABLES` or `STRICT_ALL_TABLES` in both
global and session `sql_mode`. Schema admission and validation reject non-strict
connections before schema writes. Strict mode prevents ordinary writes to unsigned
counters from silently clamping negative values to zero; `IGNORE` writes can
downgrade these errors to warnings. Configure the database defaults and
every application connection to retain strict mode throughout operation; a
startup check does not police later administrative or connection-mode changes.
The application does not change the server's SQL mode.
Run the packaged CLI with `qwen serve --profile hosted-harness` as a separate
process (the credentialed launch is spelled out in the Full WebShell
@@ -47,7 +47,7 @@ final class AgentEventJournal {
result.getString("turn_id"),
result.getString("event_type"),
storeRows.readMap(result.getString("data_json")),
result.getBoolean("terminal"),
result.getBoolean("is_terminal"),
result.getString("source_key"),
result.getLong("gmt_create"),
result.getInt("schema_version"),
@@ -58,7 +58,7 @@ final class AgentEventJournal {
static final String INSERT_EVENT = "INSERT INTO ma_public_event"
+ " (tenant_id, session_id, sequence_id, event_id, turn_id,"
+ " event_type, data_json, terminal, source_key, gmt_create,"
+ " event_type, data_json, is_terminal, source_key, gmt_create,"
+ " schema_version, projection_version, item_id, content_part_id)"
+ " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
@@ -678,14 +678,14 @@ final class AgentExecutionOperations {
+ " <= ? AND EXISTS (SELECT 1 FROM ma_session private_scope"
+ " WHERE private_scope.tenant_id = ma_operation.tenant_id AND"
+ " private_scope.session_id = ma_operation.session_id AND"
+ " private_scope.csi_guard = FALSE) ORDER BY available_at"
+ " private_scope.is_csi_guard = FALSE) ORDER BY available_at"
+ " LIMIT ?",
lifecycleOperations.operationTargetMapper,
now,
limit));
if (targets.size() < limit) {
targets.addAll(jdbc.query(
"SELECT tenant_id, session_id, operation_id FROM ma_operation WHERE operation_kind = 'TASK_CANCEL' AND delivery_state = 'LEASED' AND claim_until < " + ManagedSchemaTime.SQL_NOW + " AND EXISTS (SELECT 1 FROM ma_session private_scope WHERE private_scope.tenant_id = ma_operation.tenant_id AND private_scope.session_id = ma_operation.session_id AND private_scope.csi_guard = FALSE) ORDER BY claim_until LIMIT ?",
"SELECT tenant_id, session_id, operation_id FROM ma_operation WHERE operation_kind = 'TASK_CANCEL' AND delivery_state = 'LEASED' AND claim_until < " + ManagedSchemaTime.SQL_NOW + " AND EXISTS (SELECT 1 FROM ma_session private_scope WHERE private_scope.tenant_id = ma_operation.tenant_id AND private_scope.session_id = ma_operation.session_id AND private_scope.is_csi_guard = FALSE) ORDER BY claim_until LIMIT ?",
lifecycleOperations.operationTargetMapper, limit - targets.size()));
}
return List.copyOf(targets);
@@ -700,7 +700,7 @@ final class AgentExecutionOperations {
+ " 'RECOVERY_BLOCKED' AND available_at <= ? AND delivery_state = 'BLOCKED'"
+ " AND EXISTS (SELECT 1 FROM ma_session s WHERE s.tenant_id ="
+ " ma_operation.tenant_id AND s.session_id = ma_operation.session_id AND"
+ " s.csi_guard = FALSE) ORDER BY available_at LIMIT ?",
+ " s.is_csi_guard = FALSE) ORDER BY available_at LIMIT ?",
(result, row) -> new ParkedOperation(result.getString("tenant_id"),
result.getString("session_id"), result.getString("operation_id"),
result.getString("operation_kind")),
@@ -584,7 +584,7 @@ final class AgentLifecycleOperations {
+ " 'BLOCKED') AND available_at <= ? AND EXISTS (SELECT 1 FROM"
+ " ma_session private_scope WHERE private_scope.tenant_id ="
+ " ma_operation.tenant_id AND private_scope.session_id ="
+ " ma_operation.session_id AND private_scope.csi_guard ="
+ " ma_operation.session_id AND private_scope.is_csi_guard ="
+ " FALSE) ORDER BY available_at LIMIT ?",
operationTargetMapper,
now,
@@ -592,7 +592,7 @@ final class AgentLifecycleOperations {
if (targets.size() < limit) {
targets.addAll(
jdbc.query(
"SELECT tenant_id, session_id, operation_id FROM ma_operation WHERE operation_kind IN ('CLOSE', 'ARCHIVE', 'DELETE', 'CWD_CHANGE') AND state = 'RUNNING' AND delivery_state = 'LEASED' AND claim_until < " + ManagedSchemaTime.SQL_NOW + " AND EXISTS (SELECT 1 FROM ma_session private_scope WHERE private_scope.tenant_id = ma_operation.tenant_id AND private_scope.session_id = ma_operation.session_id AND private_scope.csi_guard = FALSE) ORDER BY claim_until LIMIT ?",
"SELECT tenant_id, session_id, operation_id FROM ma_operation WHERE operation_kind IN ('CLOSE', 'ARCHIVE', 'DELETE', 'CWD_CHANGE') AND state = 'RUNNING' AND delivery_state = 'LEASED' AND claim_until < " + ManagedSchemaTime.SQL_NOW + " AND EXISTS (SELECT 1 FROM ma_session private_scope WHERE private_scope.tenant_id = ma_operation.tenant_id AND private_scope.session_id = ma_operation.session_id AND private_scope.is_csi_guard = FALSE) ORDER BY claim_until LIMIT ?",
operationTargetMapper,
limit - targets.size()));
}
@@ -78,7 +78,7 @@ final class AgentMessageProjection {
String cursor, int limit, boolean backward, long afterSequence) {
storeRows.requireSession(tenantId, sessionId);
ManagedLegacySessionGuard.requireLegacyMutation(Boolean.TRUE.equals(jdbc.queryForObject(
"SELECT csi_guard FROM ma_session WHERE tenant_id = ? AND session_id = ?",
"SELECT is_csi_guard FROM ma_session WHERE tenant_id = ? AND session_id = ?",
Boolean.class, tenantId, sessionId)));
if (limit < 1 || limit > 100) {
throw new ManagedAgentException(400, "invalid_limit",
@@ -293,7 +293,7 @@ final class AgentMessageProjection {
+ " AND s.covered_sequence > s.replay_floor_sequence"
+ " AND EXISTS (SELECT 1 FROM ma_session private_scope WHERE"
+ " private_scope.tenant_id = s.tenant_id AND private_scope.session_id = s.session_id"
+ " AND private_scope.csi_guard = FALSE)"
+ " AND private_scope.is_csi_guard = FALSE)"
+ " AND NOT EXISTS (SELECT 1 FROM ma_turn t JOIN ma_public_event e ON"
+ " e.tenant_id = t.tenant_id AND e.session_id = t.session_id AND e.turn_id = t.turn_id"
+ " WHERE t.tenant_id = s.tenant_id AND t.session_id = s.session_id"
@@ -339,7 +339,7 @@ final class AgentMessageProjection {
List<MaterializationTarget> findMaterializationTargets(int limit) {
return jdbc.query(
"SELECT s.tenant_id, s.session_id FROM ma_session s JOIN ma_event_stream p ON p.tenant_id = s.tenant_id AND p.session_id = s.session_id AND p.stream_kind = 'SESSION' AND p.stream_id = X'' WHERE s.session_kind = 'PUBLIC' AND s.csi_guard = FALSE AND s.retired_at IS NULL AND s.status <> 'DELETED' AND p.projection_pending = TRUE ORDER BY p.gmt_modified ASC LIMIT ?",
"SELECT s.tenant_id, s.session_id FROM ma_session s JOIN ma_event_stream p ON p.tenant_id = s.tenant_id AND p.session_id = s.session_id AND p.stream_kind = 'SESSION' AND p.stream_id = X'' WHERE s.session_kind = 'PUBLIC' AND s.is_csi_guard = FALSE AND s.retired_at IS NULL AND s.status <> 'DELETED' AND p.is_projection_pending = TRUE ORDER BY p.gmt_modified ASC LIMIT ?",
(result, row) ->
new MaterializationTarget(
result.getString("tenant_id"), result.getString("session_id")),
@@ -520,7 +520,7 @@ final class AgentSessionAdmissions {
// paused before this call is about to mint the Session anyway.
// The row lock serializes that verdict against this read, so a
// settled record refuses the mint inside its own transaction —
// addressed by the parent's launch row's own primary key, which
// addressed by the parent's launch row's unique business key, which
// is the same key the idempotent admission derives, so the
// locking read never becomes a cross-tenant table scan under
// REPEATABLE READ.
@@ -843,7 +843,7 @@ final class AgentSessionAdmissions {
+ " context_revision, workspace_config_ref,"
+ " workspace_policy_ref, tool_profile,"
+ " creator_actor_key, owner_actor_key, runtime_request_key, approval_mode,"
+ " plan_enabled, selected_approval_mode, approval_revision, model_id, model_revision) VALUES"
+ " is_plan_enabled, selected_approval_mode, approval_revision, model_id, model_revision) VALUES"
+ " (?, ?, ?, ?, ?, ?, 'ACTIVE', ?, ?, ?, ?, ?, ?, ?,"
+ " ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
tenantId, sessionId, agentId, pin.revision(), pin.digest(),
@@ -86,7 +86,7 @@ final class AgentSessionCommands {
// The replay probe must not lock: a FOR UPDATE read that misses
// next-key-locks a gap of the tenant-shared command index, and
// concurrent admissions holding such gap locks deadlock when they
// all try to insert into the same gap. The PRIMARY KEY deduplicates
// all try to insert into the same gap. The unique business key deduplicates
// racing inserts instead, and the service replays on
// DuplicateKeyException.
Optional<CommandRecord> existing = findCommand(tenantId, operation,
@@ -451,15 +451,15 @@ final class AgentSessionCommands {
String unanswered = "(state = 'RUNNING' AND phase = 'SUBMITTED' AND claim_until <= "
+ ManagedSchemaTime.SQL_NOW + ")";
for (Map<String, Object> row : jdbc.queryForList(
"SELECT operation_key, tenant_id, session_id, idempotency_key FROM ma_operation WHERE operation_kind = 'RENAME' AND " + unanswered + " AND EXISTS (SELECT 1 FROM ma_session private_scope WHERE private_scope.tenant_id = ma_operation.tenant_id AND private_scope.session_id = ma_operation.session_id AND private_scope.csi_guard = FALSE) LIMIT 100")) {
"SELECT operation_key, tenant_id, session_id, idempotency_key FROM ma_operation WHERE operation_kind = 'RENAME' AND " + unanswered + " AND EXISTS (SELECT 1 FROM ma_session private_scope WHERE private_scope.tenant_id = ma_operation.tenant_id AND private_scope.session_id = ma_operation.session_id AND private_scope.is_csi_guard = FALSE) LIMIT 100")) {
parkRename(row, unanswered);
}
jdbc.update(
"UPDATE ma_operation SET state = 'PENDING', delivery_state = 'PENDING', phase = 'ADMITTED', available_at = ?, claim_owner = NULL, claim_until = NULL, gmt_modified = ? WHERE operation_kind = 'RENAME' AND state = 'RUNNING' AND phase = 'PREPARING' AND claim_until <= " + ManagedSchemaTime.SQL_NOW + " AND EXISTS (SELECT 1 FROM ma_session private_scope WHERE private_scope.tenant_id = ma_operation.tenant_id AND private_scope.session_id = ma_operation.session_id AND private_scope.csi_guard = FALSE) LIMIT 100",
"UPDATE ma_operation SET state = 'PENDING', delivery_state = 'PENDING', phase = 'ADMITTED', available_at = ?, claim_owner = NULL, claim_until = NULL, gmt_modified = ? WHERE operation_kind = 'RENAME' AND state = 'RUNNING' AND phase = 'PREPARING' AND claim_until <= " + ManagedSchemaTime.SQL_NOW + " AND EXISTS (SELECT 1 FROM ma_session private_scope WHERE private_scope.tenant_id = ma_operation.tenant_id AND private_scope.session_id = ma_operation.session_id AND private_scope.is_csi_guard = FALSE) LIMIT 100",
now,
now);
return jdbc.query(
"SELECT " + ManagedSchemaProjection.OPERATION.columns() + " FROM ma_operation WHERE operation_kind = 'RENAME' AND delivery_state = 'PENDING' AND state = 'PENDING' AND available_at <= ? AND EXISTS (SELECT 1 FROM ma_session private_scope WHERE private_scope.tenant_id = ma_operation.tenant_id AND private_scope.session_id = ma_operation.session_id AND private_scope.csi_guard = FALSE) ORDER BY available_at LIMIT 100",
"SELECT " + ManagedSchemaProjection.OPERATION.columns() + " FROM ma_operation WHERE operation_kind = 'RENAME' AND delivery_state = 'PENDING' AND state = 'PENDING' AND available_at <= ? AND EXISTS (SELECT 1 FROM ma_session private_scope WHERE private_scope.tenant_id = ma_operation.tenant_id AND private_scope.session_id = ma_operation.session_id AND private_scope.is_csi_guard = FALSE) ORDER BY available_at LIMIT 100",
this::renameDelivery,
now);
}
@@ -862,7 +862,7 @@ final class AgentSessionCommands {
// to a (kind, state) index whose range holds every Session's pending
// rows, and two Sessions' settles then deadlock. H2 skips the hint.
for (String operationKey : jdbc.queryForList("SELECT operation_key"
+ " FROM ma_operation /*! FORCE INDEX (uq_ma_operation_identity) */"
+ " FROM ma_operation /*! FORCE INDEX (uk_ma_operation_identity) */"
+ " WHERE scope_key = ? AND"
+ " operation_kind = ? AND target_key = ? AND state ="
+ " 'PENDING' FOR UPDATE",
@@ -929,7 +929,7 @@ final class AgentSessionCommands {
String payloadDigest, long now) {
jdbc.update("INSERT INTO ma_turn (tenant_id, session_id,"
+ " turn_id, prompt_id, input_json, payload_digest,"
+ " status, gmt_create, gmt_modified, model_id, model_revision, approval_mode, approval_revision, plan_enabled, permission_rules_json) SELECT"
+ " status, gmt_create, gmt_modified, model_id, model_revision, approval_mode, approval_revision, is_plan_enabled, permission_rules_json) SELECT"
+ " ?, ?, ?, ?, ?, ?, 'ACCEPTED', ?, ?, model_id,"
+ " CASE WHEN model_id IS NULL THEN NULL ELSE model_revision END,"
+ " CASE WHEN ((agent_id=? AND agent_definition_digest IS NULL)"
@@ -946,7 +946,7 @@ final class AgentSessionCommands {
+ " OR (agent_id<>? AND agent_definition_digest IS NOT NULL))"
+ " AND workspace_id IS NOT NULL AND tool_profile IN ('hosted-workspace-files/1',"
+ " 'hosted-workspace-shell/1','hosted-workspace-files/3')"
+ " THEN plan_enabled ELSE NULL END,"
+ " THEN is_plan_enabled ELSE NULL END,"
+ " CASE WHEN ((agent_id=? AND agent_definition_digest IS NULL)"
+ " OR (agent_id<>? AND agent_definition_digest IS NOT NULL))"
+ " AND workspace_id IS NOT NULL AND tool_profile IN ('hosted-workspace-files/1',"
@@ -302,7 +302,7 @@ final class AgentSessionPolicies {
if (initial.get("operationId").equals(body.path("command").path("operationId").asText())) {
boolean beforeModel = jdbc.queryForObject("SELECT COUNT(*) FROM ma_turn WHERE tenant_id=? AND session_id=?", Integer.class,
tenantId, sessionId) <= 1
&& jdbc.queryForList("SELECT turn_id FROM ma_turn WHERE tenant_id=? AND session_id=? AND submission_attempted=TRUE LIMIT 1 FOR UPDATE",
&& jdbc.queryForList("SELECT turn_id FROM ma_turn WHERE tenant_id=? AND session_id=? AND is_submission_attempted=TRUE LIMIT 1 FOR UPDATE",
tenantId, sessionId).isEmpty();
if (!beforeModel || !isBootstrapRevision(body)
|| !objectMapper.valueToTree(initial).equals(body.path("command"))) {
@@ -324,7 +324,7 @@ final class AgentSessionPolicies {
JsonNode command = childExtensionBootstrapCommand(child, lineage);
boolean onlyInitialTurn = jdbc.queryForObject("SELECT COUNT(*) FROM ma_turn WHERE tenant_id=? AND session_id=?", Integer.class,
child.tenantId(), child.sessionId()) <= 1
&& jdbc.queryForList("SELECT turn_id FROM ma_turn WHERE tenant_id=? AND session_id=? AND submission_attempted=TRUE LIMIT 1 FOR UPDATE",
&& jdbc.queryForList("SELECT turn_id FROM ma_turn WHERE tenant_id=? AND session_id=? AND is_submission_attempted=TRUE LIMIT 1 FOR UPDATE",
child.tenantId(), child.sessionId()).isEmpty();
if (!onlyInitialTurn || !isBootstrapRevision(body) || !command.equals(body.path("command"))) {
throw new ManagedAgentException(409, "child_launch_snapshot_invalid", "Child extension bootstrap conflicts with its launch snapshot");
@@ -365,7 +365,7 @@ final class AgentSessionPolicies {
String sessionId = session.sessionId();
// The journal may already have a consistent-read snapshot; these reads must observe the
// Plan/Turn admission that won the same Session row before this settings commit.
if (Boolean.TRUE.equals(jdbc.queryForObject("SELECT plan_enabled FROM ma_session WHERE tenant_id=? AND session_id=? FOR UPDATE",
if (Boolean.TRUE.equals(jdbc.queryForObject("SELECT is_plan_enabled FROM ma_session WHERE tenant_id=? AND session_id=? FOR UPDATE",
Boolean.class, tenantId, sessionId))) {
throw new ManagedAgentException(409, "unsupported_feature", "Disable Plan mode before managing MCP servers.");
}
@@ -642,7 +642,7 @@ final class AgentSessionPolicies {
throw new ManagedAgentException(409, "unsupported_feature", "Permission rules are unavailable");
}
boolean planMode = requestedPlanMode == null
? Boolean.TRUE.equals(jdbc.queryForObject("SELECT plan_enabled FROM ma_session WHERE tenant_id=? AND session_id=?",
? Boolean.TRUE.equals(jdbc.queryForObject("SELECT is_plan_enabled FROM ma_session WHERE tenant_id=? AND session_id=?",
Boolean.class, tenantId, sessionId)) : requestedPlanMode;
if (planMode && (!planModeSupported || !supportsPlanMode(session))) {
throw new ManagedAgentException(409, "unsupported_feature", "Plan mode is unavailable");
@@ -663,7 +663,7 @@ final class AgentSessionPolicies {
}
long revision = current + 1;
long now = clock.millis();
jdbc.update("UPDATE ma_session SET selected_approval_mode = ?, approval_revision = ?, plan_enabled = ?, permission_rules_json = ?, gmt_modified = ?,"
jdbc.update("UPDATE ma_session SET selected_approval_mode = ?, approval_revision = ?, is_plan_enabled = ?, permission_rules_json = ?, gmt_modified = ?,"
+ " version = version + 1 WHERE tenant_id = ? AND session_id = ? AND approval_revision = ?",
mode, revision, planMode, rules == null ? null : storeRows.writeJson(rules), now, tenantId, sessionId, current);
ManagedReceipts.insert(jdbc, namespace, tenantId, scopeKind, scope, key, digest,
@@ -163,7 +163,7 @@ final class AgentSessionQueries {
row.getString("session_id"),
row.getString("parent_session_id"),
row.getString("workspace_id"),
(Long) row.getObject("workspace_generation"),
row.getObject("workspace_generation", Long.class),
row.getString("workspace_storage_id"),
row.getBoolean("creator_can_execute")),
arguments.toArray());
@@ -426,10 +426,10 @@ final class AgentSessionQueries {
args.addAll(sessionIds);
Map<String, WebShellApprovalSelection> result = new HashMap<>();
jdbc.query("SELECT session_id, COALESCE(selected_approval_mode, approval_mode) AS mode,"
+ " approval_revision, plan_enabled, permission_rules_json FROM ma_session WHERE tenant_id=? AND session_id IN ("
+ " approval_revision, is_plan_enabled, permission_rules_json FROM ma_session WHERE tenant_id=? AND session_id IN ("
+ AgentStoreRows.placeholders(sessionIds.size()) + ") AND session_kind='PUBLIC'",
row -> { result.put(row.getString("session_id"), new WebShellApprovalSelection(
row.getString("mode"), row.getLong("approval_revision"), row.getBoolean("plan_enabled"),
row.getString("mode"), row.getLong("approval_revision"), row.getBoolean("is_plan_enabled"),
storeRows.readPermissionRules(row.getString("permission_rules_json")))); }, args.toArray());
return result;
}
@@ -449,7 +449,7 @@ final class AgentSessionQueries {
WebShellApprovalSelection findTurnApprovalSelection(String tenantId, String sessionId,
String promptId) {
var rows = jdbc.query("SELECT t.approval_mode, t.approval_revision, t.plan_enabled, t.permission_rules_json,"
var rows = jdbc.query("SELECT t.approval_mode, t.approval_revision, t.is_plan_enabled, t.permission_rules_json,"
+ " s.approval_revision AS selected_revision, s.agent_id, s.agent_definition_digest,"
+ " s.workspace_id, s.tool_profile FROM ma_turn t JOIN ma_session s"
+ " ON s.tenant_id=t.tenant_id AND s.session_id=t.session_id"
@@ -468,7 +468,7 @@ final class AgentSessionQueries {
}
// Legacy prompt replays must preserve the original absence of a selection.
return mode == null ? null : new WebShellApprovalSelection(mode, row.getLong("approval_revision"),
row.getBoolean("plan_enabled"), storeRows.readPermissionRules(row.getString("permission_rules_json")));
row.getBoolean("is_plan_enabled"), storeRows.readPermissionRules(row.getString("permission_rules_json")));
}, tenantId, sessionId, promptId);
if (rows.size() != 1) {
throw new ManagedAgentException(409, "turn_not_found", "The Turn was not found");
@@ -63,7 +63,7 @@ final class AgentStoreRows {
readInput(result.getString("input_json")),
result.getString("payload_digest"),
result.getString("status"),
result.getBoolean("submission_attempted"),
result.getBoolean("is_submission_attempted"),
result.getString("harness_event_epoch"),
nullableLong(result, "harness_last_event_id"),
result.getString("dispatch_owner"),
@@ -208,7 +208,7 @@ final class AgentStoreRows {
+ " ? AND ma_session.session_id = ? FOR UPDATE",
(rows, rowNumber) -> {
if (legacyMutation) {
ManagedLegacySessionGuard.requireLegacyMutation(rows.getBoolean("csi_guard"));
ManagedLegacySessionGuard.requireLegacyMutation(rows.getBoolean("is_csi_guard"));
}
// H2 can retain pre-wait outer-join values after locking the Session.
// Read its stream only after acquiring that lock.
@@ -54,7 +54,7 @@ final class AgentTurnExecution {
// Harness park enters only the coordinator's read-only observation
// branch; cancellation still uses the normal dispatch lane.
return jdbc.query(
"SELECT tenant_id, session_id, turn_id FROM ma_turn WHERE status IN ('ACCEPTED', 'RUNNING', 'CANCELLING') AND (dispatch_lease_until IS NULL OR dispatch_lease_until < ?) AND (retry_after IS NULL OR retry_after <= ?) AND (status = 'CANCELLING' OR error_code IS NULL OR error_code NOT IN ('" + AgentStateStore.WORKFLOW_RECOVERY_BLOCKED + "', '" + AgentStateStore.RUNTIME_RECOVERY_BLOCKED + "')) AND (status = 'CANCELLING' OR NOT EXISTS (SELECT 1 FROM ma_session_worktree w WHERE w.tenant_id = ma_turn.tenant_id AND w.session_id = ma_turn.session_id AND w.state <> 'READY')) AND EXISTS (SELECT 1 FROM ma_session private_scope WHERE private_scope.tenant_id = ma_turn.tenant_id AND private_scope.session_id = ma_turn.session_id AND private_scope.csi_guard = FALSE) ORDER BY gmt_modified ASC LIMIT ?",
"SELECT tenant_id, session_id, turn_id FROM ma_turn WHERE status IN ('ACCEPTED', 'RUNNING', 'CANCELLING') AND (dispatch_lease_until IS NULL OR dispatch_lease_until < ?) AND (retry_after IS NULL OR retry_after <= ?) AND (status = 'CANCELLING' OR error_code IS NULL OR error_code NOT IN ('" + AgentStateStore.WORKFLOW_RECOVERY_BLOCKED + "', '" + AgentStateStore.RUNTIME_RECOVERY_BLOCKED + "')) AND (status = 'CANCELLING' OR NOT EXISTS (SELECT 1 FROM ma_session_worktree w WHERE w.tenant_id = ma_turn.tenant_id AND w.session_id = ma_turn.session_id AND w.state <> 'READY')) AND EXISTS (SELECT 1 FROM ma_session private_scope WHERE private_scope.tenant_id = ma_turn.tenant_id AND private_scope.session_id = ma_turn.session_id AND private_scope.is_csi_guard = FALSE) ORDER BY gmt_modified ASC LIMIT ?",
(result, row) -> new DispatchTarget(
result.getString("tenant_id"),
result.getString("session_id"),
@@ -68,7 +68,7 @@ final class AgentTurnExecution {
return jdbc.query(
"SELECT tenant_id, session_id, turn_id FROM ma_turn WHERE status IN ('ACCEPTED', 'RUNNING') AND error_code = '"
+ AgentStateStore.RUNTIME_RECOVERY_BLOCKED
+ "' AND (dispatch_lease_until IS NULL OR dispatch_lease_until < ?) AND (retry_after IS NULL OR retry_after <= ?) AND EXISTS (SELECT 1 FROM ma_session private_scope WHERE private_scope.tenant_id = ma_turn.tenant_id AND private_scope.session_id = ma_turn.session_id AND private_scope.csi_guard = FALSE) ORDER BY retry_after ASC, gmt_modified ASC LIMIT ?",
+ "' AND (dispatch_lease_until IS NULL OR dispatch_lease_until < ?) AND (retry_after IS NULL OR retry_after <= ?) AND EXISTS (SELECT 1 FROM ma_session private_scope WHERE private_scope.tenant_id = ma_turn.tenant_id AND private_scope.session_id = ma_turn.session_id AND private_scope.is_csi_guard = FALSE) ORDER BY retry_after ASC, gmt_modified ASC LIMIT ?",
(result, row) -> new DispatchTarget(
result.getString("tenant_id"),
result.getString("session_id"),
@@ -146,7 +146,7 @@ final class AgentTurnExecution {
return jdbc.update("UPDATE ma_turn SET error_code = ?, error_message = ?,"
+ " gmt_modified = ?, version = version + 1 WHERE tenant_id = ?"
+ " AND session_id = ? AND turn_id = ? AND dispatch_owner = ?"
+ " AND dispatch_lease_until >= ? AND submission_attempted = TRUE"
+ " AND dispatch_lease_until >= ? AND is_submission_attempted = TRUE"
+ " AND status IN ('ACCEPTED', 'RUNNING')",
AgentStateStore.RUNTIME_RECOVERY_BLOCKED, diagnostic, now,
tenantId, sessionId, turnId, owner, now) == 1;
@@ -274,7 +274,7 @@ final class AgentTurnExecution {
storeRows.requireLegacyMutation(tenantId, sessionId);
long now = clock.millis();
int updated = jdbc.update("UPDATE ma_turn SET"
+ " submission_attempted = TRUE, gmt_modified = ?,"
+ " is_submission_attempted = TRUE, gmt_modified = ?,"
+ " version = version + 1 WHERE tenant_id = ? AND"
+ " session_id = ? AND turn_id = ? AND"
+ " dispatch_owner = ? AND dispatch_lease_until"
@@ -298,11 +298,11 @@ final class AgentTurnExecution {
storeRows.requireLegacyMutation(tenantId, sessionId);
long now = clock.millis();
int updated = jdbc.update("UPDATE ma_turn SET"
+ " submission_attempted = FALSE, gmt_modified = ?,"
+ " is_submission_attempted = FALSE, gmt_modified = ?,"
+ " version = version + 1 WHERE tenant_id = ? AND"
+ " session_id = ? AND turn_id = ? AND"
+ " dispatch_owner = ? AND dispatch_lease_until"
+ " >= ? AND submission_attempted = TRUE AND"
+ " >= ? AND is_submission_attempted = TRUE AND"
+ " harness_event_epoch IS NULL AND status IN"
+ " ('ACCEPTED','RUNNING','CANCELLING')",
now, tenantId, sessionId, turnId, owner, now);
@@ -744,7 +744,7 @@ final class AgentTurnExecution {
+ " version + 1 WHERE tenant_id = ? AND"
+ " session_id = ? AND turn_id = ? AND"
+ " dispatch_owner = ? AND dispatch_lease_until >= ?"
+ " AND submission_attempted = FALSE",
+ " AND is_submission_attempted = FALSE",
now, now, tenantId, sessionId, turnId, owner, now);
if (updated != 1) {
return;
@@ -768,12 +768,12 @@ final class AgentTurnExecution {
long now = clock.millis();
String message = "The Session worktree could not be prepared.";
List<String> turns = jdbc.queryForList("SELECT turn_id FROM ma_turn WHERE tenant_id = ? AND session_id = ?"
+ " AND status = 'ACCEPTED' AND submission_attempted = FALSE FOR UPDATE", String.class, tenantId, sessionId);
+ " AND status = 'ACCEPTED' AND is_submission_attempted = FALSE FOR UPDATE", String.class, tenantId, sessionId);
for (String turnId : turns) {
jdbc.update("UPDATE ma_turn SET status = 'FAILED', error_code = ?, error_message = ?, completed_at = ?,"
+ " gmt_modified = ?, dispatch_owner = NULL, dispatch_lease_until = NULL, version = version + 1"
+ " WHERE tenant_id = ? AND session_id = ? AND turn_id = ? AND status = 'ACCEPTED'"
+ " AND submission_attempted = FALSE", code, message, now, now, tenantId, sessionId, turnId);
+ " AND is_submission_attempted = FALSE", code, message, now, now, tenantId, sessionId, turnId);
eventJournal.appendEvent(tenantId, sessionId, turnId, "turn.failed", Map.of("code", code, "message", message), true, null, now);
sessionCommands.settleTurnCommands(tenantId, sessionId, turnId, now);
}
@@ -75,8 +75,8 @@ public class AutomationLedgerStore
result.getString("timezone"),
result.getString("session_mode"),
result.getString("overlap"), result.getString("catch_up"),
(Long) result.getObject("catch_up_limit"),
result.getBoolean("enabled"), result.getString("state"),
result.getObject("catch_up_limit", Long.class),
result.getBoolean("is_enabled"), result.getString("state"),
result.getString("blocked_reason"),
result.getLong("armed_at"),
result.getObject("watermark_slot", Long.class),
@@ -252,7 +252,7 @@ public class AutomationLedgerStore
+ " workspace_id, actor_id, record_revision,"
+ " definition_revision, definition_digest, goal,"
+ " cron, timezone, session_mode, overlap, catch_up,"
+ " catch_up_limit, enabled, state, blocked_reason,"
+ " catch_up_limit, is_enabled, state, blocked_reason,"
+ " armed_at, watermark_slot, lease_owner,"
+ " lease_until, fence, gmt_create, gmt_modified,"
+ " gate)"
@@ -286,7 +286,7 @@ public class AutomationLedgerStore
+ " record_revision = ?, definition_revision = ?,"
+ " definition_digest = ?, goal = ?, cron = ?,"
+ " timezone = ?, session_mode = ?, overlap = ?,"
+ " catch_up = ?, catch_up_limit = ?, enabled = ?,"
+ " catch_up = ?, catch_up_limit = ?, is_enabled = ?,"
+ " state = ?, blocked_reason = NULL, armed_at = ?,"
+ " gmt_modified = ?, gate = ?, gate_last_outcome = ?,"
+ " gate_last_at = ?, gate_quiet_since_delivery = ?,"
@@ -388,7 +388,7 @@ public class AutomationLedgerStore
/** Live, enabled, unblocked definitions whose lease is free or expired. */
public List<ScheduleRow> findArmed(long now, int limit) {
return jdbc.query("SELECT " + ManagedSchemaProjection.SCHEDULE.columns() + " FROM ma_schedule"
+ " WHERE state = ? AND enabled = TRUE"
+ " WHERE state = ? AND is_enabled = TRUE"
+ " AND blocked_reason IS NULL"
+ " AND (lease_until IS NULL OR lease_until < ?)"
+ " ORDER BY gmt_modified, schedule_id LIMIT ?", SCHEDULE,
@@ -479,7 +479,7 @@ public class AutomationLedgerStore
/**
* Records one occurrence decision under the writer's lease unless one exists: the row is
* selected from the definition row the owner holds, so a writer whose lease another claim has
* taken inserts nothing, and the primary key keeps the first decision of a slot. Answers the row
* taken inserts nothing, and the unique business key keeps the first decision of a slot. Answers the row
* now held — the one written, or the earlier decision — or empty when another claim has taken
* the lease and no decision exists.
*/
@@ -730,7 +730,7 @@ public class AutomationLedgerStore
}
/**
* Claims (tenant, key) for one request before any side effect: the primary key arbitrates, so
* Claims (tenant, key) for one request before any side effect: the unique business key arbitrates, so
* only one concurrent or retried caller owns the identity; the row's empty result marks it
* unanswered. A claim whose requester dies mid-flight stays durable, which is what lets a
* different request under the same key conflict instead of repeating the side effect.
@@ -258,7 +258,7 @@ public class ChannelInstanceStore
// The ordering index can scan all completed deliveries before finding a due row.
return jdbc.query("SELECT session_id, record_id, revision,"
+ " delivery_state, record_resource_id"
+ " FROM ma_session_record USE INDEX (ix_ma_record_session_delivery)"
+ " FROM ma_session_record USE INDEX (idx_ma_record_session_delivery)"
+ " WHERE record_kind = 'DOMAIN' AND session_scope_key = ?"
+ " AND domain = 'channel_delivery'"
+ " AND delivery_state IN ('planned', 'partial')"
@@ -139,7 +139,7 @@ public class ChildResultRelayStore
* write would otherwise leave the stale snapshot behind a row the
* correction could not see yet. The parent's consuming revision
* updates that same record row first, so the two commits serialize.
* The lookup names the record's primary key; matching only the
* The lookup names the record's unique business key; matching only the
* session scope would make MySQL lock every row the scan touches. */
private String lockedDeliveryState(String tenantId,
String parentSessionId, String childRunId) {
@@ -626,7 +626,7 @@ public class ChildResultRelayStore
String order) {
List<TurnLine> rows = jdbc.query(
"SELECT turn_id, status, completed_at, error_code,"
+ " submission_attempted, harness_event_epoch"
+ " is_submission_attempted, harness_event_epoch"
+ " FROM ma_turn"
+ " WHERE tenant_id = ? AND session_id = ?"
+ " ORDER BY gmt_create " + order + ", turn_id "
@@ -635,7 +635,7 @@ public class ChildResultRelayStore
result.getString("status"),
result.getObject("completed_at", Long.class),
result.getString("error_code"),
result.getBoolean("submission_attempted"),
result.getBoolean("is_submission_attempted"),
result.getString("harness_event_epoch")),
tenantId, sessionId);
return rows.isEmpty() ? null : rows.getFirst();
@@ -110,9 +110,9 @@ public final class ExternalStorageRegistrationStore implements ExternalStorageRe
* Reads one tenant-bound registration for the external Workspace profile.
*
* <p>Read-only by construction: no lock, no write, no idempotency record. The
* lookup uses the same primary key the write path inserts
* lookup uses the same unique business key the write path inserts
* ({@link JdbcRuntimeBindingRepository#storageAliasKey}), joins the owner row
* on the owner's primary key, and admits only a {@code REGISTERED} row. It
* on the owner's unique business key, and admits only a {@code REGISTERED} row. It
* then enforces exactly these fields: the decoded record's alias id equals the
* requested alias, its identity owner key equals the stored physical key, its
* revision equals the stored {@code registration_revision}, and its mount root
@@ -41,7 +41,7 @@ public class HarnessPlacementStore
public boolean hasUnreleasedOwnership(String instance, String boot) {
return !jdbc.query("SELECT m.session_id FROM ma_session m WHERE m.harness_instance_id = ?"
+ " AND m.harness_owner_boot_id = ? AND m.resource_gc_completed = FALSE"
+ " AND m.harness_owner_boot_id = ? AND m.is_resource_gc_completed = FALSE"
+ " AND m.harness_placement_state <> 'RELEASED'"
+ " AND (m.status NOT IN ('CLOSED', 'ARCHIVED', 'DELETED') OR EXISTS ("
+ " SELECT 1 FROM ma_session_head h WHERE h.tenant_id = m.tenant_id AND h.session_id = m.session_id"
@@ -227,7 +227,7 @@ public class HarnessPlacementStore
case ARCHIVE -> "ARCHIVING";
default -> "CLOSING";
};
var admission = jdbc.query("SELECT status, session_kind, workspace_id, csi_guard FROM ma_session"
var admission = jdbc.query("SELECT status, session_kind, workspace_id, is_csi_guard FROM ma_session"
+ " WHERE tenant_id = ? AND session_id = ? FOR UPDATE", (row, index) ->
pendingStatus.equals(row.getString(1))
&& ("PUBLIC".equals(row.getString(2)) || row.getString(3) != null)
@@ -24,7 +24,7 @@ public class JdbcSessionRecoveryRepository implements SessionRecoveryRepository
@Override
public long nonInitialTurns(String tenantId, String sessionId) {
return jdbc.queryForObject("SELECT COUNT(*) FROM ma_turn WHERE tenant_id = ? AND session_id = ?"
+ " AND (status <> 'CANCELLED' OR submission_attempted = TRUE OR harness_event_epoch IS NOT NULL)",
+ " AND (status <> 'CANCELLED' OR is_submission_attempted = TRUE OR harness_event_epoch IS NOT NULL)",
Long.class, tenantId, sessionId);
}
}
@@ -350,7 +350,7 @@ final class JournalCommit {
continuation, head, request.writerId(), request.writerGeneration(), writerToken);
jdbc.update("UPDATE ma_session_head SET"
+ " journal_revision = ?, committed_sequence = ?,"
+ " wake_pending = wake_pending OR ?,"
+ " is_wake_pending = is_wake_pending OR ?,"
+ " wake_head_revision = CASE WHEN wake_head_revision = ? THEN ? ELSE wake_head_revision END,"
+ " cleanup_head_revision = CASE WHEN cleanup_head_revision = ? THEN ? ELSE cleanup_head_revision END,"
+ " last_commit_digest = ?, activation_epoch = ?,"
@@ -308,9 +308,9 @@ final class JournalFencing {
.isConnectionTransactional(target, jdbc.getDataSource())) {
var privatePins =
jdbc.query(
"SELECT csi_guard FROM ma_session WHERE tenant_id ="
+ " ? AND session_id = ? AND csi_guard = TRUE",
(row, index) -> row.getBoolean("csi_guard"),
"SELECT is_csi_guard FROM ma_session WHERE tenant_id ="
+ " ? AND session_id = ? AND is_csi_guard = TRUE",
(row, index) -> row.getBoolean("is_csi_guard"),
tenantId,
sessionId);
if (!privatePins.isEmpty()) {
@@ -325,7 +325,7 @@ final class JournalFencing {
// range locks: taking them on every writer path
// would couple per-turn traffic of unrelated
// Sessions again (#13800). The root is locked
// first, by primary key once it exists, so its pin
// first, by unique business key once it exists, so its pin
// is read as committed now even under an older
// REPEATABLE READ snapshot, no gap is taken that
// another tenant's first writer inserts into, and
@@ -107,8 +107,8 @@ final class JournalResourceReads {
JournalStoreRows.validateStableId(resourceId, "resourceId");
var guarded =
jdbc.queryForList(
"SELECT csi_guard FROM ma_session"
+ " WHERE tenant_id = ? AND session_id = ? AND csi_guard = TRUE",
"SELECT is_csi_guard FROM ma_session"
+ " WHERE tenant_id = ? AND session_id = ? AND is_csi_guard = TRUE",
tenantId,
sessionId);
if (guarded.isEmpty()) {
@@ -449,7 +449,7 @@ final class JournalStoreRows {
+ " p.publication_id WHERE p.tenant_id = ? AND p.workspace_id = ?"
+ " AND p.session_id = ? AND p.admission_resource_id = ? AND"
+ " p.producer_phase IN ('FINISHED', 'REFERENCED') AND"
+ " p.quarantined = FALSE AND o.slot_key = X'61646d697373696f6e'"
+ " p.is_quarantined = FALSE AND o.slot_key = X'61646d697373696f6e'"
+ " AND o.capture_state = 'VERIFIED' AND o.resource_id = ? AND"
+ " o.capture_object_key = ? AND o.sha256 = ? AND o.byte_length ="
+ " ?",
@@ -488,7 +488,7 @@ final class JournalStoreRows {
if ("managed-tool-outcome".equals(resource.kind())) {
Long quarantined = jdbc.queryForObject("SELECT COUNT(*) FROM ma_output_capture"
+ " WHERE tenant_id = ? AND workspace_id = ? AND session_id = ?"
+ " AND admission_resource_id = ? AND quarantined = TRUE",
+ " AND admission_resource_id = ? AND is_quarantined = TRUE",
Long.class, resource.tenantId(), resource.workspaceId(),
resource.sessionId(), resource.resourceId());
if (quarantined != null && quarantined > 0) {
@@ -11,10 +11,10 @@ import org.springframework.transaction.support.TransactionSynchronizationManager
import java.util.Map;
final class LocalStorageOwners {
static final String SESSION_AUTHORITY_SQL = "SELECT 1 FROM ma_session WHERE tenant_id = ? AND workspace_storage_id = ? AND resource_gc_completed = FALSE LIMIT 1";
static final String SESSION_AUTHORITY_SQL = "SELECT 1 FROM ma_session WHERE tenant_id = ? AND workspace_storage_id = ? AND is_resource_gc_completed = FALSE LIMIT 1";
static final String RUNTIME_AUTHORITY_SQL = "SELECT 1 FROM ma_runtime_binding WHERE storage_alias_key = ?"
+ " AND (binding_state NOT IN ('FAILED', 'RELEASED')"
+ " OR (binding_state = 'FAILED' AND provision_seeded = TRUE)) LIMIT 1";
+ " OR (binding_state = 'FAILED' AND is_provision_seeded = TRUE)) LIMIT 1";
static final String OPERATION_AUTHORITY_SQL = "SELECT 1 FROM ma_operation WHERE storage_key = ?"
+ " AND ((operation_kind IN ('WORKSPACE_RECOVERY', 'WORKSPACE_OPERATOR_RECOVERY', 'STORAGE_MIGRATION')"
+ " AND state IN ('CAPTURING', 'VERIFYING', 'PREPARED', 'ATTESTED', 'RETIRING', 'RETIRED', 'PREPARING', 'INVALIDATED'))"
@@ -23,10 +23,10 @@ final class LocalStorageOwners {
+ String.join("', '", ChildWorkspaceStore.PREPARING, ChildWorkspaceStore.READY, ChildWorkspaceStore.MERGING,
ChildWorkspaceStore.APPLYING, ChildWorkspaceStore.APPLIED, ChildWorkspaceStore.DISCARDING,
ChildWorkspaceStore.CONFLICTED, ChildWorkspaceStore.BLOCKED, ChildWorkspaceStore.FAILED) + "'))) LIMIT 1";
static final String HEAD_AUTHORITY_SQL = "SELECT /*! STRAIGHT_JOIN */ 1 FROM ma_session s USE INDEX (ix_ma_session_storage_scope)"
static final String HEAD_AUTHORITY_SQL = "SELECT /*! STRAIGHT_JOIN */ 1 FROM ma_session s USE INDEX (idx_ma_session_storage_scope)"
+ " JOIN ma_session_head h ON h.tenant_key = s.tenant_key AND h.harness_key = s.session_key"
+ " JOIN ma_workspace w ON w.tenant_id = s.tenant_id AND w.workspace_id = h.workspace_id"
+ " WHERE s.tenant_id = ? AND s.workspace_storage_id IS NULL AND s.resource_gc_completed = FALSE"
+ " WHERE s.tenant_id = ? AND s.workspace_storage_id IS NULL AND s.is_resource_gc_completed = FALSE"
+ " AND h.tenant_key = ? AND h.head_kind = 'MANAGED_SESSION' AND w.tenant_id = ? AND w.storage_id = ? LIMIT 1";
private LocalStorageOwners() {
@@ -311,10 +311,10 @@ public class ManagedActionStore
&& continuation.path("calls").get(0).path("call").path("callId").equals(options.path("functionCallId"))
&& continuation.path("calls").get(0).path("inputRef").equals(options.path("inputRef"))
&& continuation.path("calls").get(0).path("actionId").asText().equals(id));
jdbc.update("UPDATE ma_session SET plan_enabled=FALSE, approval_revision=approval_revision+1,"
+ " version=version+1, gmt_modified=? WHERE tenant_id=? AND session_id=? AND plan_enabled=TRUE"
jdbc.update("UPDATE ma_session SET is_plan_enabled=FALSE, approval_revision=approval_revision+1,"
+ " version=version+1, gmt_modified=? WHERE tenant_id=? AND session_id=? AND is_plan_enabled=TRUE"
+ " AND EXISTS (SELECT 1 FROM ma_turn WHERE tenant_id=? AND session_id=?"
+ " AND prompt_id=? AND plan_enabled=TRUE AND status IN ('ACCEPTED','RUNNING'))",
+ " AND prompt_id=? AND is_plan_enabled=TRUE AND status IN ('ACCEPTED','RUNNING'))",
event.path("occurredAt").asLong(), tenantId, sessionId, tenantId, sessionId,
options.path("turnId").asText());
}
@@ -384,7 +384,7 @@ public class ManagedActionStore
return options.path("v").asInt() == 3 && options.path("toolName").asText().equals("exit_plan_mode")
&& jdbc.queryForObject("SELECT COUNT(*) FROM ma_turn t JOIN ma_session s ON s.tenant_id=t.tenant_id"
+ " AND s.session_id=t.session_id WHERE t.tenant_id=? AND t.session_id=? AND t.prompt_id=?"
+ " AND t.plan_enabled=TRUE AND s.session_kind='PUBLIC' AND s.parent_session_id IS NULL",
+ " AND t.is_plan_enabled=TRUE AND s.session_kind='PUBLIC' AND s.parent_session_id IS NULL",
Integer.class, tenantId, sessionId, options.path("turnId").asText()) == 1;
}
@@ -109,7 +109,7 @@ public final class ManagedExtensionAgentLaunch {
+ " AND s.last_generation=b.runtime_generation WHERE b.binding_id=? AND b.runtime_generation=?"
+ " AND b.tenant_id=? AND b.workspace_id=? AND b.workspace_generation=? AND b.storage_id=?"
+ " AND b.isolation_class='session' AND b.isolation_key=? AND b.binding_state='READY'"
+ " AND b.drain_requested=FALSE AND b.runtime_instance_id IS NOT NULL AND b.runtime_lease_id IS NOT NULL FOR UPDATE",
+ " AND b.is_drain_requested=FALSE AND b.runtime_instance_id IS NOT NULL AND b.runtime_lease_id IS NOT NULL FOR UPDATE",
String.class, runtime.path("bindingId").asText(), selectedGeneration, parent.tenantId(),
parent.workspace().getWorkspaceId(), Long.toString(parent.workspace().getWorkspaceGeneration()),
parent.workspace().getStorageId(), parent.sessionId());
@@ -19,14 +19,14 @@ final class ManagedLegacySessionGuard {
connection.getMetaData().getDatabaseProductName();
String index =
"MySQL".equals(product) || "MariaDB".equals(product)
? " FORCE INDEX (ma_session_csi_guard_idx)"
? " FORCE INDEX (idx_ma_session_csi_guard)"
: "";
try (var statement =
connection.prepareStatement(
"SELECT csi_guard FROM ma_session"
"SELECT is_csi_guard FROM ma_session"
+ index
+ " WHERE tenant_id = ? AND session_id"
+ " = ? AND csi_guard = TRUE FOR"
+ " = ? AND is_csi_guard = TRUE FOR"
+ " UPDATE")) {
statement.setQueryTimeout(10);
statement.setBytes(
@@ -36,7 +36,7 @@ final class ManagedProjectionResourceCollector {
boolean runOnce() {
boolean changed = false;
var candidates = jdbc.queryForList(
"SELECT resource_key, tenant_id, session_id FROM ma_resource WHERE retention_until <= " + ManagedSchemaTime.SQL_NOW + " AND NOT EXISTS (SELECT 1 FROM ma_session s WHERE s.tenant_id = ma_resource.tenant_id AND s.session_id = ma_resource.session_id AND s.csi_guard = TRUE) ORDER BY retention_until, resource_key LIMIT "
"SELECT resource_key, tenant_id, session_id FROM ma_resource WHERE retention_until <= " + ManagedSchemaTime.SQL_NOW + " AND NOT EXISTS (SELECT 1 FROM ma_session s WHERE s.tenant_id = ma_resource.tenant_id AND s.session_id = ma_resource.session_id AND s.is_csi_guard = TRUE) ORDER BY retention_until, resource_key LIMIT "
+ BATCH);
for (var candidate : candidates) {
changed |= Boolean.TRUE.equals(ManagedSessionStore.skipContended(transactions,
@@ -88,7 +88,7 @@ final class ManagedProjectionResourceCollector {
ToolPublicationRetentionStore.hash(tenant), ToolPublicationRetentionStore.hash(session), tenant, session).isEmpty();
protectedBody |= !jdbc.queryForList(
"SELECT session_id FROM ma_session WHERE tenant_id = ? AND"
+ " session_id = ? AND recovery_protected = TRUE",
+ " session_id = ? AND is_recovery_protected = TRUE",
tenant, session).isEmpty();
protectedBody |= !jdbc.queryForList(
"SELECT lease_id FROM ma_read_lease WHERE tenant_key = ? AND"
@@ -37,7 +37,7 @@ final class ManagedReceipts {
List<Receipt> rows =
jdbc.query(
"SELECT tenant_id, scope_id, idempotency_key, request_digest, session_id,"
+ " turn_id, state, session_status_before, actor_id, workspace_bound, gmt_create,"
+ " turn_id, state, session_status_before, actor_id, is_workspace_bound, gmt_create,"
+ " gmt_modified, operation, result_json, result_operation_key FROM ma_request_receipt WHERE receipt_key = ? AND namespace = ?"
+ " AND tenant_key = ? AND scope_key = ?"
+ (lock ? " FOR UPDATE" : ""),
@@ -51,7 +51,7 @@ final class ManagedReceipts {
row.getString("state"),
row.getString("session_status_before"),
row.getBytes("actor_id"),
row.getObject("workspace_bound", Boolean.class),
row.getObject("is_workspace_bound", Boolean.class),
row.getLong("gmt_create"), row.getLong("gmt_modified"),
row.getString("operation"), row.getString("result_json"),
row.getString("result_operation_key")),
@@ -92,7 +92,7 @@ final class ManagedReceipts {
"INSERT INTO ma_request_receipt (receipt_key, namespace, tenant_key, tenant_id,"
+ " scope_kind, scope_key, scope_id, idempotency_key, idempotency_digest,"
+ " request_digest, operation, actor_id, session_id, turn_id, state,"
+ " session_status_before, workspace_bound, gmt_create, gmt_modified) VALUES (?,"
+ " session_status_before, is_workspace_bound, gmt_create, gmt_modified) VALUES (?,"
+ " ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
ManagedSchemaKeys.receiptKey(namespace, tenant, scopeKind, scopeId, key),
namespace.name(),
@@ -26,7 +26,7 @@ public final class ManagedRuntimeRetentionGuard implements JdbcRuntimeRetention.
&& exists(
connection,
"SELECT 1 FROM ma_session WHERE tenant_id = ? AND session_id = ?"
+ " AND csi_guard = TRUE LIMIT 1 FOR UPDATE",
+ " AND is_csi_guard = TRUE LIMIT 1 FOR UPDATE",
identity(request.getScope().getTenantId()),
identity(request.getIsolationKey()))
|| exists(
@@ -210,7 +210,7 @@ final class ManagedSessionRetirementStore {
}
var roots =
jdbc.queryForList(
"SELECT retired_at, retirement_generation, recovery_protected FROM"
"SELECT retired_at, retirement_generation, is_recovery_protected FROM"
+ " ma_session WHERE tenant_id = ? AND session_id = ? FOR UPDATE",
tenant,
session);
@@ -218,7 +218,7 @@ final class ManagedSessionRetirementStore {
|| roots.getFirst().get("retired_at") == null
|| ToolPublicationRetentionStore.number(roots.getFirst(), "retirement_generation")
< 1
|| ToolPublicationRetentionStore.flag(roots.getFirst(), "recovery_protected")) {
|| ToolPublicationRetentionStore.flag(roots.getFirst(), "is_recovery_protected")) {
throw new IllegalStateException("Session retirement is incomplete");
}
var heads =
@@ -276,7 +276,7 @@ final class ManagedSessionRetirementStore {
throw new IllegalStateException("Session collection is not settled");
}
if (jdbc.update(
"UPDATE ma_session SET gmt_modified = " + ManagedSchemaTime.SQL_NOW + ", resource_gc_completed = TRUE WHERE tenant_id = ? AND session_id = ? AND retired_at IS NOT NULL",
"UPDATE ma_session SET gmt_modified = " + ManagedSchemaTime.SQL_NOW + ", is_resource_gc_completed = TRUE WHERE tenant_id = ? AND session_id = ? AND retired_at IS NOT NULL",
tenant,
session)
!= 1) {
@@ -84,8 +84,8 @@ public class ManagedTaskEventStore
public EventPage read(String tenantId, String sessionId, String taskId, long after, int limit) {
List<TaskEvent> events = jdbc.query("SELECT sequence_id AS event_sequence, event_type,"
+ " gmt_create AS occurred_at, schema_version, projection_version, state, runtime_state,"
+ " text, truncated, artifact_id, capture_id, output_stream_id AS stream_id,"
+ " first_ordinal, end_ordinal, archived FROM ma_public_event WHERE tenant_id = ?"
+ " text, is_truncated, artifact_id, capture_id, output_stream_id AS stream_id,"
+ " first_ordinal, end_ordinal, is_archived FROM ma_public_event WHERE tenant_id = ?"
+ " AND session_id = ? AND stream_kind = 'TASK' AND stream_id = ?"
+ " AND sequence_id > ? ORDER BY sequence_id LIMIT ?",
ManagedTaskEventStore::eventRow, tenantId, sessionId, taskId, after, limit + 1);
@@ -139,7 +139,7 @@ public class ManagedTaskEventStore
ranges.toString(), occurredAt, tenantId, sessionId, taskId);
}
jdbc.update("INSERT INTO ma_public_event (tenant_id,session_id,stream_kind,stream_id,sequence_id,"
+ "event_id,event_type,gmt_create,schema_version,projection_version,text,truncated,capture_id,"
+ "event_id,event_type,gmt_create,schema_version,projection_version,text,is_truncated,capture_id,"
+ "output_stream_id,first_ordinal,end_ordinal) VALUES (?,?,'TASK',?,?,?,'output',?,?,?,?,?,?,?,?,?)",
tenantId, sessionId, taskId, sequence, eventId(tenantId, sessionId, taskId, sequence),
occurredAt, SCHEMA_VERSION, PROJECTION_VERSION, text, truncated,
@@ -178,9 +178,9 @@ public class ManagedTaskEventStore
public int markOutputArchived(String tenantId, String sessionId, String taskId, long throughSequence) {
return transaction(() -> {
lockStream(tenantId, sessionId, taskId, 0);
return jdbc.update("UPDATE ma_public_event SET archived = TRUE WHERE tenant_id = ? AND session_id = ?"
return jdbc.update("UPDATE ma_public_event SET is_archived = TRUE WHERE tenant_id = ? AND session_id = ?"
+ " AND stream_kind = 'TASK' AND stream_id = ? AND event_type = 'output'"
+ " AND archived = FALSE AND sequence_id <= ?",
+ " AND is_archived = FALSE AND sequence_id <= ?",
tenantId, sessionId, taskId, throughSequence);
});
}
@@ -243,7 +243,7 @@ public class ManagedTaskEventStore
private Long oldestUnarchived(String tenantId, String sessionId, String taskId) {
return jdbc.queryForObject("SELECT MIN(sequence_id) FROM ma_public_event WHERE tenant_id = ? AND session_id = ?"
+ " AND stream_kind = 'TASK' AND stream_id = ? AND event_type = 'output' AND archived = FALSE",
+ " AND stream_kind = 'TASK' AND stream_id = ? AND event_type = 'output' AND is_archived = FALSE",
Long.class, tenantId, sessionId, taskId);
}
@@ -378,8 +378,8 @@ public class ManagedTaskEventStore
return new TaskEvent(result.getLong("event_sequence"), result.getString("event_type"),
result.getLong("occurred_at"), result.getInt("schema_version"), result.getInt("projection_version"),
result.getString("state"), result.getString("runtime_state"), result.getString("text"),
result.getObject("truncated", Boolean.class), result.getString("artifact_id"),
result.getObject("is_truncated", Boolean.class), result.getString("artifact_id"),
result.getString("capture_id"), result.getString("stream_id"), result.getObject("first_ordinal", Long.class),
result.getObject("end_ordinal", Long.class), result.getBoolean("archived"));
result.getObject("end_ordinal", Long.class), result.getBoolean("is_archived"));
}
}
@@ -119,7 +119,7 @@ public class ManagedToolResultProjector {
private Projection resolve(Source source, ToolPublicationRetentionStore.ReadLease lease, Runnable guard) throws IOException {
guard.run();
store.verifySource(source);
var candidates = jdbc.query("SELECT " + ManagedSchemaProjection.OUTPUT_CAPTURE.columns("p") + ", CASE WHEN quarantined THEN 1 ELSE 0 END AS quarantine_mark FROM ma_output_capture p WHERE scope_key = ? AND tenant_id = ?"
var candidates = jdbc.query("SELECT " + ManagedSchemaProjection.OUTPUT_CAPTURE.columns("p") + ", CASE WHEN is_quarantined THEN 1 ELSE 0 END AS quarantine_mark FROM ma_output_capture p WHERE scope_key = ? AND tenant_id = ?"
+ " AND workspace_id = ? AND session_id = ? AND execution_key = ?",
(schemaRow, schemaIndex) -> com.alibaba.qwen.code.runtimebroker.managedschema.ManagedSchemaRows.read(schemaRow),
ToolPublicationDataStore.scope(source.sessionKey()),
@@ -119,7 +119,7 @@ public class ManagedToolResultStore
+ " (SELECT 1 FROM ma_session s WHERE"
+ " s.tenant_id = ma_operation.tenant_id"
+ " AND s.session_id ="
+ " ma_operation.session_id AND s.csi_guard"
+ " ma_operation.session_id AND s.is_csi_guard"
+ " = TRUE) AND state = ? AND "
+ due
+ " <= "
@@ -472,7 +472,7 @@ public class ManagedToolResultStore
var rows =
jdbc.query(
"SELECT state, producer_phase, binding_digest, admission_resource_id,"
+ " receipt_sequence, receipt_revision, CASE WHEN quarantined THEN 1"
+ " receipt_sequence, receipt_revision, CASE WHEN is_quarantined THEN 1"
+ " ELSE 0 END AS quarantine_mark FROM ma_output_capture WHERE"
+ " scope_key = ? AND tenant_id = ? AND workspace_id = ? AND session_id"
+ " = ? AND publication_id = ? FOR UPDATE",
@@ -102,7 +102,7 @@ public class ManagedUserMessageStore
String input = "edit".equals(command.action()) ? encode(agents.userMessageInput(command.input())) : null;
if (input == null && snapshot(tenant, session).messages().stream()
.anyMatch(message -> message.id().equals(command.messageId()) && "recovery_blocked".equals(message.state()))) {
jdbc.update("UPDATE ma_user_message_queue SET paused = TRUE WHERE tenant_id = ? AND session_id = ?", tenant, session);
jdbc.update("UPDATE ma_user_message_queue SET is_paused = TRUE WHERE tenant_id = ? AND session_id = ?", tenant, session);
}
// Keep a blocked claim's identity so a late durable receipt can still settle it.
int changed = input == null
@@ -126,7 +126,7 @@ public class ManagedUserMessageStore
throw conflict("user_message_recovery_blocked");
}
String turn = latestTurn(tenant, session).get("turnId");
jdbc.update("UPDATE ma_user_message_queue SET paused = FALSE, resumed_turn_id = ? WHERE tenant_id = ? AND session_id = ?",
jdbc.update("UPDATE ma_user_message_queue SET is_paused = FALSE, resumed_turn_id = ? WHERE tenant_id = ? AND session_id = ?",
turn, tenant, session);
}
default -> throw refusal("invalid_request", "Unknown user message action.");
@@ -160,7 +160,7 @@ public class ManagedUserMessageStore
if (mismatches != null && mismatches > 0) {
jdbc.update("UPDATE ma_user_message SET state = 'recovery_blocked' WHERE tenant_id = ? AND session_id = ? AND state = 'queued'",
tenant, session);
jdbc.update("UPDATE ma_user_message_queue SET paused = TRUE WHERE tenant_id = ? AND session_id = ?", tenant, session);
jdbc.update("UPDATE ma_user_message_queue SET is_paused = TRUE WHERE tenant_id = ? AND session_id = ?", tenant, session);
return List.of();
}
jdbc.update("UPDATE ma_user_message SET state = 'claimed', turn_id = ?, prompt_id = ? WHERE tenant_id = ?"
@@ -173,7 +173,7 @@ public class ManagedUserMessageStore
return jdbc.query("SELECT DISTINCT m.tenant_id, m.session_id, q.last_dispatch_at FROM ma_user_message m JOIN ma_session s"
+ " ON s.tenant_id = m.tenant_id AND s.session_id = m.session_id JOIN ma_user_message_queue q"
+ " ON q.tenant_id = m.tenant_id AND q.session_id = m.session_id WHERE s.status = 'ACTIVE'"
+ " AND q.paused = FALSE AND m.state = 'queued' AND NOT EXISTS (SELECT 1 FROM ma_turn t"
+ " AND q.is_paused = FALSE AND m.state = 'queued' AND NOT EXISTS (SELECT 1 FROM ma_turn t"
+ " WHERE t.tenant_id = m.tenant_id AND t.session_id = m.session_id AND t.status IN ('ACCEPTED', 'RUNNING', 'CANCELLING', 'RECOVERY_BLOCKED'))"
+ " AND NOT EXISTS (SELECT 1 FROM ma_user_message blocked WHERE blocked.tenant_id = m.tenant_id"
+ " AND blocked.session_id = m.session_id AND blocked.state IN ('claimed', 'recovery_blocked'))"
@@ -209,7 +209,7 @@ public class ManagedUserMessageStore
+ " AND state = 'queued' AND COALESCE(context_revision, -1) <> COALESCE(?, -1)", Integer.class, tenant, session, context);
if (mismatches != null && mismatches > 0) {
jdbc.update("UPDATE ma_user_message SET state = 'recovery_blocked' WHERE tenant_id = ? AND session_id = ? AND state = 'queued'", tenant, session);
jdbc.update("UPDATE ma_user_message_queue SET paused = TRUE WHERE tenant_id = ? AND session_id = ?", tenant, session);
jdbc.update("UPDATE ma_user_message_queue SET is_paused = TRUE WHERE tenant_id = ? AND session_id = ?", tenant, session);
return;
}
Message first = snapshot.messages().getFirst();
@@ -270,7 +270,7 @@ public class ManagedUserMessageStore
String resumed = jdbc.queryForObject("SELECT resumed_turn_id FROM ma_user_message_queue WHERE tenant_id = ? AND session_id = ?",
String.class, tenant, session);
if (!Objects.equals(resumed, turn.get("turnId"))) {
jdbc.update("UPDATE ma_user_message_queue SET paused = TRUE WHERE tenant_id = ? AND session_id = ?", tenant, session);
jdbc.update("UPDATE ma_user_message_queue SET is_paused = TRUE WHERE tenant_id = ? AND session_id = ?", tenant, session);
}
}
jdbc.update("UPDATE ma_user_message SET state = 'recovery_blocked' WHERE tenant_id = ? AND session_id = ? AND state = 'claimed'"
@@ -279,7 +279,7 @@ public class ManagedUserMessageStore
}
private Snapshot snapshot(String tenant, String session) {
boolean paused = Boolean.TRUE.equals(jdbc.queryForObject("SELECT paused FROM ma_user_message_queue"
boolean paused = Boolean.TRUE.equals(jdbc.queryForObject("SELECT is_paused FROM ma_user_message_queue"
+ " WHERE tenant_id = ? AND session_id = ?", Boolean.class, tenant, session));
List<Message> messages = read(tenant, session, "state IN ('queued', 'claimed', 'recovery_blocked')");
return new Snapshot(paused || messages.stream().anyMatch(message -> "recovery_blocked".equals(message.state())), messages);
@@ -85,7 +85,7 @@ public final class ResidentWorkspaces extends com.alibaba.qwen.code.managedagent
+ " AND b.canonical_cwd = ? AND b.storage_id = ? AND b.capability_digest = ?"
+ " AND b.isolation_class = 'workspace' AND b.isolation_key IS NULL"
+ " AND b.provisioner_kind = 'kubernetes-workspace' AND b.binding_state = 'READY'"
+ " AND b.drain_requested = FALSE AND b.resource_handle_json IS NOT NULL"
+ " AND b.is_drain_requested = FALSE AND b.resource_handle_json IS NOT NULL"
+ " AND b.provision_seed_ciphertext IS NOT NULL AND b.attestation_generation > 0 FOR UPDATE",
(row, index) -> new Original(row.getString(1), row.getLong(2), row.getString(3)), request(binding).requestKey(), tenantId,
binding.getWorkspaceId(), Long.toString(binding.getWorkspaceGeneration()), selected.registration().mountRoot(),
@@ -36,7 +36,7 @@ public final class SessionResourceCollectionCollector {
+ " AND object_version_id IS NULL AND encryption_key_id IS NULL AND"
+ " deletion_operation_key IS NULL AND NOT EXISTS (SELECT 1 FROM ma_resource_ref f"
+ " WHERE f.resource_key = ma_resource.resource_key) THEN 1 ELSE 0 END AS"
+ " collectible FROM ma_resource USE INDEX (ix_ma_resource_scope_page) WHERE"
+ " collectible FROM ma_resource USE INDEX (idx_ma_resource_scope_page) WHERE"
+ " session_scope_key = ? AND resource_key > ? ORDER BY resource_key LIMIT "
+ (PAGE_ROWS + 1);
private final JdbcTemplate jdbc;
@@ -138,7 +138,7 @@ public final class SessionResourceCollectionCollector {
var rows =
jdbc.query(
"SELECT s.tenant_id, s.session_id, s.session_scope_key FROM ma_session s"
+ " WHERE s.csi_guard = FALSE AND s.retired_at <= ? AND NOT EXISTS"
+ " WHERE s.is_csi_guard = FALSE AND s.retired_at <= ? AND NOT EXISTS"
+ " (SELECT 1 FROM ma_operation o WHERE o.operation_kind ="
+ " 'SESSION_RESOURCE_GC' AND o.scope_key = s.session_scope_key AND"
+ " o.target_key = s.session_scope_key LIMIT 1) ORDER BY s.retired_at"
@@ -181,7 +181,7 @@ public final class SessionResourceCollectionCollector {
Claim claim() {
long time = ToolPublicationRetentionStore.now(jdbc);
var candidates = jdbc.query(
"SELECT scope_key, tenant_id, session_id FROM ma_operation WHERE operation_kind = 'SESSION_RESOURCE_GC' AND NOT EXISTS (SELECT 1 FROM ma_session s WHERE s.tenant_id = ma_operation.tenant_id AND s.session_id = ma_operation.session_id AND s.csi_guard = TRUE) AND state <> 'SUCCEEDED' AND available_at >= 0 AND available_at <= ? AND (claim_owner = ? OR claim_until IS NULL OR claim_until <= ?) ORDER BY available_at, operation_key LIMIT 32",
"SELECT scope_key, tenant_id, session_id FROM ma_operation WHERE operation_kind = 'SESSION_RESOURCE_GC' AND NOT EXISTS (SELECT 1 FROM ma_session s WHERE s.tenant_id = ma_operation.tenant_id AND s.session_id = ma_operation.session_id AND s.is_csi_guard = TRUE) AND state <> 'SUCCEEDED' AND available_at >= 0 AND available_at <= ? AND (claim_owner = ? OR claim_until IS NULL OR claim_until <= ?) ORDER BY available_at, operation_key LIMIT 32",
(row, index) -> ManagedSchemaRows.read(row), time, owner, time);
for (var candidate : candidates) {
Claim claim =
@@ -289,7 +289,7 @@ public final class SessionResourceCollectionCollector {
private String blocker(String tenant, String session, long now, java.util.Map<String, Object> head) {
var roots =
jdbc.query(
"SELECT retired_at, recovery_protected FROM ma_session WHERE tenant_key = ?"
"SELECT retired_at, is_recovery_protected FROM ma_session WHERE tenant_key = ?"
+ " AND session_key = ? AND retired_at IS NOT NULL",
(schemaRow, schemaIndex) -> ManagedSchemaRows.read(schemaRow),
ToolPublicationRetentionStore.hash(tenant),
@@ -297,7 +297,7 @@ public final class SessionResourceCollectionCollector {
if (roots.isEmpty()) {
return "session_not_retired";
}
if (ToolPublicationRetentionStore.flag(roots.getFirst(), "recovery_protected")) {
if (ToolPublicationRetentionStore.flag(roots.getFirst(), "is_recovery_protected")) {
return "recovery_protected";
}
if (ToolPublicationRetentionStore.number(roots.getFirst(), "retired_at")
@@ -202,7 +202,7 @@ public class SessionWorktreeStore
public List<String[]> failedInitialSessions() {
return jdbc.query("SELECT DISTINCT w.tenant_id, w.session_id, w.failure_code FROM ma_session_worktree w"
+ " JOIN ma_turn t ON t.tenant_id = w.tenant_id AND t.session_id = w.session_id"
+ " WHERE w.state IN ('FAILED','BLOCKED') AND t.status = 'ACCEPTED' AND t.submission_attempted = FALSE LIMIT 20",
+ " WHERE w.state IN ('FAILED','BLOCKED') AND t.status = 'ACCEPTED' AND t.is_submission_attempted = FALSE LIMIT 20",
(result, index) -> new String[] {result.getString("tenant_id"), result.getString("session_id"), result.getString("failure_code")});
}
@@ -129,11 +129,11 @@ public final class ToolPublicationAdmissionStore {
String suffix = locked ? " FOR UPDATE" : "";
var publication = jdbc.query("SELECT scope_key, publication_id, tenant_id, workspace_id, session_id, producer_phase,"
+ " admission_resource_id, receipt_sequence, receipt_revision,"
+ " CASE WHEN quarantined THEN 1 ELSE 0 END AS quarantined"
+ " CASE WHEN is_quarantined THEN 1 ELSE 0 END AS is_quarantined"
+ " FROM ma_output_capture WHERE scope_key = ? AND publication_id = ?" + suffix, (schemaRow, schemaIndex) -> ManagedSchemaRows.read(schemaRow), scope(key), id).getFirst();
require(scope(key).equals(publication.get("scope_key")) && id.equals(publication.get("publication_id"))
&& "REFERENCED".equals(publication.get("producer_phase"))
&& ((Number) publication.get("quarantined")).intValue() == 0
&& ((Number) publication.get("is_quarantined")).intValue() == 0
&& text(key, "tenantId").equals(publication.get("tenant_id"))
&& text(key, "workspaceId").equals(publication.get("workspace_id"))
&& text(key, "sessionId").equals(publication.get("session_id"))
@@ -374,7 +374,7 @@ public final class ToolPublicationAdmissionStore {
sessions.lockPublicationWriter(text(key, "tenantId"), text(key, "workspaceId"),
text(key, "sessionId"), request.writerId(), request.writerGeneration(), writerToken);
Map<String, Object> publication = jdbc.query("SELECT producer_phase, binding_json, binding_digest,"
+ " CASE WHEN quarantined THEN 1 ELSE 0 END AS quarantined, admission_resource_id,"
+ " CASE WHEN is_quarantined THEN 1 ELSE 0 END AS is_quarantined, admission_resource_id,"
+ " receipt_sequence, receipt_revision, finish_digest, terminal_resource_id"
+ " FROM ma_output_capture WHERE scope_key = ? AND publication_id = ? AND tenant_id = ?"
+ " AND workspace_id = ? AND session_id = ? FOR UPDATE", (schemaRow, schemaIndex) -> ManagedSchemaRows.read(schemaRow), scope, publicationId,
@@ -382,7 +382,7 @@ public final class ToolPublicationAdmissionStore {
ToolPublicationStore.requireLockedBinding(publication, finished.path("binding"));
require(resourceId.equals(publication.get("admission_resource_id"))
&& candidate.get("terminal_resource_id").equals(publication.get("terminal_resource_id"))
&& ((Number) publication.get("quarantined")).intValue() == 0,
&& ((Number) publication.get("is_quarantined")).intValue() == 0,
"Admission root changed");
var object = jdbc.query("SELECT capture_state AS state, sha256, byte_length, capture_object_key AS object_key"
+ " FROM ma_resource WHERE scope_key = ? AND publication_id = ?"
@@ -410,7 +410,7 @@ public final class ToolPublicationAdmissionStore {
}
var receipt = sessions.commit(text(key, "tenantId"), text(key, "sessionId"),
writerToken, request, authority);
jdbc.update("UPDATE ma_output_capture SET gmt_modified = " + ManagedSchemaTime.SQL_NOW + ", producer_phase = 'REFERENCED', admission_held_bytes = admission_used_bytes, receipt_sequence = ?, receipt_revision = ?, accepted_complete = ? WHERE scope_key = ? AND publication_id = ?",
jdbc.update("UPDATE ma_output_capture SET gmt_modified = " + ManagedSchemaTime.SQL_NOW + ", producer_phase = 'REFERENCED', admission_held_bytes = admission_used_bytes, receipt_sequence = ?, receipt_revision = ?, is_accepted_complete = ? WHERE scope_key = ? AND publication_id = ?",
request.lastSequence(), receipt.journalRevision(),
"committed".equals(outcome.path("decision").asText())
&& "complete".equals(outcome.path("envelope").path("capture").path("captureStatus").asText()),
@@ -126,8 +126,8 @@ public final class ToolPublicationCollector {
+ " c.session_id FROM ma_output_capture c WHERE c.retention_state ="
+ " 'RETIRING' AND NOT EXISTS (SELECT 1 FROM ma_session s WHERE"
+ " s.tenant_id = c.tenant_id AND s.session_id = c.session_id AND"
+ " s.csi_guard = TRUE) AND NOT EXISTS (SELECT 1 FROM ma_operation o"
+ " USE INDEX (ix_ma_operation_publication) WHERE o.scope_key ="
+ " s.is_csi_guard = TRUE) AND NOT EXISTS (SELECT 1 FROM ma_operation o"
+ " USE INDEX (idx_ma_operation_publication) WHERE o.scope_key ="
+ " c.scope_key AND o.publication_id = c.publication_id AND"
+ " o.operation_kind = 'CAPTURE_GC' LIMIT 1) LIMIT 32",
(row, index) -> ManagedSchemaRows.read(row));
@@ -206,7 +206,7 @@ public final class ToolPublicationCollector {
long time = ToolPublicationRetentionStore.now(jdbc);
var candidates =
jdbc.query(
"SELECT scope_key, publication_id, tenant_id, session_id FROM ma_operation WHERE operation_kind = 'CAPTURE_GC' AND NOT EXISTS (SELECT 1 FROM ma_session s WHERE s.tenant_id = ma_operation.tenant_id AND s.session_id = ma_operation.session_id AND s.csi_guard = TRUE) AND state <> 'SUCCEEDED' AND available_at >= 0 AND available_at <= ? AND (claim_owner = ? OR claim_until IS NULL OR claim_until <= ?) ORDER BY available_at, operation_key LIMIT 32",
"SELECT scope_key, publication_id, tenant_id, session_id FROM ma_operation WHERE operation_kind = 'CAPTURE_GC' AND NOT EXISTS (SELECT 1 FROM ma_session s WHERE s.tenant_id = ma_operation.tenant_id AND s.session_id = ma_operation.session_id AND s.is_csi_guard = TRUE) AND state <> 'SUCCEEDED' AND available_at >= 0 AND available_at <= ? AND (claim_owner = ? OR claim_until IS NULL OR claim_until <= ?) ORDER BY available_at, operation_key LIMIT 32",
(row, index) -> ManagedSchemaRows.read(row),
time,
owner,
@@ -333,7 +333,7 @@ public final class ToolPublicationCollector {
private boolean sessionCollectionPending(String tenant, String session) {
return !Boolean.TRUE.equals(jdbc.queryForObject(
"SELECT resource_gc_completed FROM ma_session WHERE tenant_id = ? AND session_id"
"SELECT is_resource_gc_completed FROM ma_session WHERE tenant_id = ? AND session_id"
+ " = ?", Boolean.class, tenant, session));
}
@@ -163,10 +163,10 @@ public final class ToolPublicationDataStore {
capture.set(field, manifest.path(field));
}
var publication = jdbc.query("SELECT producer_phase, admission_resource_id,"
+ " CASE WHEN quarantined THEN 1 ELSE 0 END AS quarantined FROM ma_output_capture"
+ " CASE WHEN is_quarantined THEN 1 ELSE 0 END AS is_quarantined FROM ma_output_capture"
+ " WHERE scope_key = ? AND publication_id = ?", (schemaRow, schemaIndex) -> ManagedSchemaRows.read(schemaRow), scope(key), publicationId).getFirst();
require("REFERENCED".equals(publication.get("producer_phase"))
&& ((Number) publication.get("quarantined")).intValue() == 0,
&& ((Number) publication.get("is_quarantined")).intValue() == 0,
"Original publication receipt is unavailable");
String admissionId = (String) publication.get("admission_resource_id");
byte[] bytes = readResource(key, publicationId, admissionId);
@@ -355,7 +355,7 @@ public final class ToolPublicationDataStore {
+ " AND publication_id = ? AND slot_key = ? AND operation_id = ? AND capture_state = 'CANDIDATE'",
bytes, scope, publicationId, slot, operationId);
}
jdbc.update("UPDATE ma_operation SET gmt_modified = " + ManagedSchemaTime.SQL_NOW + ", verification_ready = TRUE, verification_next_at = ?, claim_owner = NULL, claim_until = NULL WHERE operation_kind IN ('OUTPUT_UPLOAD', 'OUTPUT_VERIFY', 'OUTPUT_FINISH') AND scope_key = ? AND publication_id = ? AND operation_id = ?",
jdbc.update("UPDATE ma_operation SET gmt_modified = " + ManagedSchemaTime.SQL_NOW + ", is_verification_ready = TRUE, verification_next_at = ?, claim_owner = NULL, claim_until = NULL WHERE operation_kind IN ('OUTPUT_UPLOAD', 'OUTPUT_VERIFY', 'OUTPUT_FINISH') AND scope_key = ? AND publication_id = ? AND operation_id = ?",
now(), scope, publicationId, operationId);
});
verificationWakeup.run();
@@ -367,7 +367,7 @@ public final class ToolPublicationDataStore {
}
boolean verifyNextOperation() {
var candidates = jdbc.query("SELECT scope_key, publication_id, operation_id, claim_generation, verification_request_json FROM ma_operation WHERE operation_kind IN ('OUTPUT_UPLOAD', 'OUTPUT_VERIFY', 'OUTPUT_FINISH') AND execution_mode = 'ASYNC' AND state = 'PENDING' AND verification_ready = TRUE AND verification_next_at <= " + ManagedSchemaTime.SQL_NOW + " ORDER BY verification_next_at, scope_key, publication_id, operation_id LIMIT 32", (schemaRow, schemaIndex) -> ManagedSchemaRows.read(schemaRow));
var candidates = jdbc.query("SELECT scope_key, publication_id, operation_id, claim_generation, verification_request_json FROM ma_operation WHERE operation_kind IN ('OUTPUT_UPLOAD', 'OUTPUT_VERIFY', 'OUTPUT_FINISH') AND execution_mode = 'ASYNC' AND state = 'PENDING' AND is_verification_ready = TRUE AND verification_next_at <= " + ManagedSchemaTime.SQL_NOW + " ORDER BY verification_next_at, scope_key, publication_id, operation_id LIMIT 32", (schemaRow, schemaIndex) -> ManagedSchemaRows.read(schemaRow));
boolean processed = false;
for (var candidate : candidates) {
String scope = (String) candidate.get("scope_key");
@@ -841,7 +841,7 @@ public final class ToolPublicationDataStore {
require(operationId != null && operationId.matches("[a-z0-9_-]{1,128}"),
"Invalid publication operation ID");
String scope = scope(key);
var rows = jdbc.query("SELECT o.state, o.result_json, o.failure_status, o.failure_code, CASE WHEN o.execution_mode = 'ASYNC' AND o.verification_ready THEN 1 ELSE 0 END AS ready, COALESCE(o.recovery_deadline, o.deadline) AS deadline, CASE WHEN o.claim_owner IS NULL OR o.claim_until < " + ManagedSchemaTime.SQL_NOW + " THEN 1 ELSE 0 END AS retryable, p.tenant_id, p.token_hash, p.workspace_id, p.session_id FROM ma_operation o JOIN ma_output_capture p ON p.scope_key = o.scope_key AND p.publication_id = o.publication_id WHERE o.operation_kind IN ('OUTPUT_UPLOAD', 'OUTPUT_VERIFY', 'OUTPUT_FINISH') AND o.scope_key = ? AND o.publication_id = ? AND o.operation_id = ?",
var rows = jdbc.query("SELECT o.state, o.result_json, o.failure_status, o.failure_code, CASE WHEN o.execution_mode = 'ASYNC' AND o.is_verification_ready THEN 1 ELSE 0 END AS ready, COALESCE(o.recovery_deadline, o.deadline) AS deadline, CASE WHEN o.claim_owner IS NULL OR o.claim_until < " + ManagedSchemaTime.SQL_NOW + " THEN 1 ELSE 0 END AS retryable, p.tenant_id, p.token_hash, p.workspace_id, p.session_id FROM ma_operation o JOIN ma_output_capture p ON p.scope_key = o.scope_key AND p.publication_id = o.publication_id WHERE o.operation_kind IN ('OUTPUT_UPLOAD', 'OUTPUT_VERIFY', 'OUTPUT_FINISH') AND o.scope_key = ? AND o.publication_id = ? AND o.operation_id = ?",
(r, n) -> {
Map<String, Object> row = new HashMap<>();
for (String field : List.of("state", "tenant_id", "workspace_id", "session_id", "token_hash",
@@ -892,10 +892,10 @@ public final class ToolPublicationDataStore {
transactions.executeWithoutResult(status -> {
var authorization = authorizeClaim(key, scope, publicationId, token);
var publication = jdbc.query("SELECT producer_phase, finish_operation_id,"
+ " finish_predecessor_id, CASE WHEN quarantined THEN 1 ELSE 0 END AS quarantined"
+ " finish_predecessor_id, CASE WHEN is_quarantined THEN 1 ELSE 0 END AS is_quarantined"
+ " FROM ma_output_capture WHERE scope_key = ? AND publication_id = ?", (schemaRow, schemaIndex) -> ManagedSchemaRows.read(schemaRow),
scope, publicationId).getFirst();
require(((Number) publication.get("quarantined")).intValue() == 0,
require(((Number) publication.get("is_quarantined")).intValue() == 0,
"Publication is quarantined");
List<Operation> rows = operation(scope, publicationId, operationId, true);
require(rows.size() == 1, "Publication operation is missing");
@@ -1063,7 +1063,7 @@ public final class ToolPublicationDataStore {
private JsonNode finishedInternal(JsonNode key, String publicationId) {
String scope = scope(key);
var publications = jdbc.query("SELECT producer_phase,"
+ " CASE WHEN quarantined THEN 1 ELSE 0 END AS quarantined, binding_json,"
+ " CASE WHEN is_quarantined THEN 1 ELSE 0 END AS is_quarantined, binding_json,"
+ " terminal_resource_id, finish_operation_id FROM ma_output_capture"
+ " WHERE scope_key = ? AND publication_id = ? AND tenant_id = ?"
+ " AND workspace_id = ? AND session_id = ?", (schemaRow, schemaIndex) -> ManagedSchemaRows.read(schemaRow), scope, publicationId,
@@ -1074,7 +1074,7 @@ public final class ToolPublicationDataStore {
require("FINISHED".equals(publication.get("producer_phase"))
|| "REFERENCED".equals(publication.get("producer_phase")),
"Publication has no finished result");
require(((Number) publication.get("quarantined")).intValue() == 0,
require(((Number) publication.get("is_quarantined")).intValue() == 0,
"Finished publication is quarantined");
String resourceId = (String) publication.get("terminal_resource_id");
Resource terminal = catalogResource(key, publicationId, resourceId);
@@ -1121,7 +1121,7 @@ public final class ToolPublicationDataStore {
sessions.lockPublicationWriter(text(key, "tenantId"), text(key, "workspaceId"),
text(key, "sessionId"), writerId, writerGeneration, writerToken);
var publication = jdbc.query("SELECT producer_phase, binding_json, binding_digest,"
+ " CASE WHEN quarantined THEN 1 ELSE 0 END AS quarantined,"
+ " CASE WHEN is_quarantined THEN 1 ELSE 0 END AS is_quarantined,"
+ " admission_bytes, admission_used_bytes,"
+ " admission_resource_id, terminal_resource_id FROM ma_output_capture"
+ " WHERE scope_key = ? AND publication_id = ? AND tenant_id = ?"
@@ -1131,7 +1131,7 @@ public final class ToolPublicationDataStore {
require("FINISHED".equals(publication.get("producer_phase"))
|| "REFERENCED".equals(publication.get("producer_phase")),
"Publication is not finished");
require(((Number) publication.get("quarantined")).intValue() == 0,
require(((Number) publication.get("is_quarantined")).intValue() == 0,
"Publication is quarantined");
require(original.path("terminal").path("resourceId").asText()
.equals(publication.get("terminal_resource_id")),
@@ -1181,13 +1181,13 @@ public final class ToolPublicationDataStore {
sessions.lockPublicationWriter(text(key, "tenantId"), text(key, "workspaceId"),
text(key, "sessionId"), writerId, writerGeneration, writerToken);
var publication = jdbc.query("SELECT producer_phase, terminal_resource_id, binding_json, binding_digest,"
+ " CASE WHEN quarantined THEN 1 ELSE 0 END AS quarantined"
+ " CASE WHEN is_quarantined THEN 1 ELSE 0 END AS is_quarantined"
+ " FROM ma_output_capture WHERE scope_key = ? AND publication_id = ? AND tenant_id = ?"
+ " AND workspace_id = ? AND session_id = ? FOR UPDATE", (schemaRow, schemaIndex) -> ManagedSchemaRows.read(schemaRow), scope, publicationId,
text(key, "tenantId"), text(key, "workspaceId"), text(key, "sessionId")).getFirst();
ToolPublicationStore.requireLockedBinding(publication, original.path("binding"));
require("FINISHED".equals(publication.get("producer_phase"))
&& ((Number) publication.get("quarantined")).intValue() == 0
&& ((Number) publication.get("is_quarantined")).intValue() == 0
&& original.path("terminal").path("resourceId").asText()
.equals(publication.get("terminal_resource_id")), "Admission publication changed");
Stored row = stored(scope, publicationId, "admission", true).get(0);
@@ -1285,11 +1285,11 @@ public final class ToolPublicationDataStore {
return new FinishClaim(0, null, terminal.objectKey(), terminal.resourceId(), binding, receipt);
}
Map<String, Object> row = jdbc.query("SELECT producer_phase, active_operation_id,"
+ " CASE WHEN quarantined THEN 1 ELSE 0 END AS quarantined,"
+ " CASE WHEN is_quarantined THEN 1 ELSE 0 END AS is_quarantined,"
+ " finish_operation_id, finish_predecessor_id, finish_digest, producer_bytes,"
+ " producer_used_bytes FROM ma_output_capture WHERE scope_key = ?"
+ " AND publication_id = ?", (schemaRow, schemaIndex) -> ManagedSchemaRows.read(schemaRow), scope, publicationId).getFirst();
require(((Number) row.get("quarantined")).intValue() == 0,
require(((Number) row.get("is_quarantined")).intValue() == 0,
"Publication is quarantined");
String phase = (String) row.get("producer_phase");
require("OPEN".equals(phase) || "FINISHING".equals(phase) || "FINISHED".equals(phase),
@@ -1367,7 +1367,7 @@ public final class ToolPublicationDataStore {
List<Operation> current = operation(scope, publicationId, operationId, true);
requireOperationClaim(current, claim.epoch(), now());
Map<String, Object> publication = jdbc.query("SELECT producer_phase,"
+ " CASE WHEN quarantined THEN 1 ELSE 0 END AS quarantined, finish_operation_id,"
+ " CASE WHEN is_quarantined THEN 1 ELSE 0 END AS is_quarantined, finish_operation_id,"
+ " finish_predecessor_id, finish_digest, active_operation_id, capture_used_bytes,"
+ " producer_used_bytes FROM ma_output_capture WHERE scope_key = ?"
+ " AND publication_id = ?", (schemaRow, schemaIndex) -> ManagedSchemaRows.read(schemaRow), scope, publicationId).getFirst();
@@ -1375,7 +1375,7 @@ public final class ToolPublicationDataStore {
&& operationId.equals(publication.get("finish_operation_id"))
&& digest.equals(publication.get("finish_digest"))
&& publication.get("active_operation_id") == null
&& ((Number) publication.get("quarantined")).intValue() == 0,
&& ((Number) publication.get("is_quarantined")).intValue() == 0,
"Finish barrier changed");
if (claim.predecessor() != null) {
List<Operation> previous = operation(scope, publicationId, claim.predecessor(), true);
@@ -1502,10 +1502,10 @@ public final class ToolPublicationDataStore {
return new ScanClaim(0, exactSucceededReplay(scope, publicationId, operationId, slot, requestDigest));
}
var phase = jdbc.query("SELECT producer_phase, finish_predecessor_id,"
+ " CASE WHEN quarantined THEN 1 ELSE 0 END AS quarantined"
+ " CASE WHEN is_quarantined THEN 1 ELSE 0 END AS is_quarantined"
+ " FROM ma_output_capture WHERE scope_key = ? AND publication_id = ?", (schemaRow, schemaIndex) -> ManagedSchemaRows.read(schemaRow),
scope, publicationId).getFirst();
require(((Number) phase.get("quarantined")).intValue() == 0,
require(((Number) phase.get("is_quarantined")).intValue() == 0,
"Publication is quarantined");
require("OPEN".equals(phase.get("producer_phase"))
|| "FINISHING".equals(phase.get("producer_phase"))
@@ -1677,7 +1677,7 @@ public final class ToolPublicationDataStore {
requireOperationClaim(rows, epoch, current);
long until = Math.min(rows.get(0).deadline().getTime(),
current.getTime() + claimTimeout.toMillis());
jdbc.update("UPDATE ma_operation SET gmt_modified = " + ManagedSchemaTime.SQL_NOW + ", claim_until = ?, verification_next_at = CASE WHEN execution_mode = 'ASYNC' AND verification_ready THEN ? ELSE verification_next_at END WHERE operation_kind IN ('OUTPUT_UPLOAD', 'OUTPUT_VERIFY', 'OUTPUT_FINISH') AND scope_key = ? AND publication_id = ? AND operation_id = ?",
jdbc.update("UPDATE ma_operation SET gmt_modified = " + ManagedSchemaTime.SQL_NOW + ", claim_until = ?, verification_next_at = CASE WHEN execution_mode = 'ASYNC' AND is_verification_ready THEN ? ELSE verification_next_at END WHERE operation_kind IN ('OUTPUT_UPLOAD', 'OUTPUT_VERIFY', 'OUTPUT_FINISH') AND scope_key = ? AND publication_id = ? AND operation_id = ?",
new Timestamp(until), new Timestamp(until), scope, publicationId, operationId);
});
next = System.nanoTime() + interval;
@@ -1707,7 +1707,7 @@ public final class ToolPublicationDataStore {
transactions.executeWithoutResult(status -> {
retention.lockRetainedPublication(scope, publicationId);
requireVerificationClaim(scope, publicationId);
jdbc.update("UPDATE ma_output_capture SET gmt_modified = " + ManagedSchemaTime.SQL_NOW + ", quarantined = TRUE WHERE scope_key = ? AND publication_id = ?", scope, publicationId);
jdbc.update("UPDATE ma_output_capture SET gmt_modified = " + ManagedSchemaTime.SQL_NOW + ", is_quarantined = TRUE WHERE scope_key = ? AND publication_id = ?", scope, publicationId);
jdbc.update("UPDATE ma_resource SET capture_state = 'QUARANTINED'"
+ " WHERE scope_key = ? AND publication_id = ?"
+ " AND slot_key = ? AND capture_state = 'VERIFIED'", scope, publicationId, slot);
@@ -1798,10 +1798,10 @@ public final class ToolPublicationDataStore {
return new Candidate(saved.objectKey(), saved.resourceId(), 0, replay);
}
var phase = jdbc.query("SELECT producer_phase, finish_predecessor_id,"
+ " CASE WHEN quarantined THEN 1 ELSE 0 END AS quarantined"
+ " CASE WHEN is_quarantined THEN 1 ELSE 0 END AS is_quarantined"
+ " FROM ma_output_capture WHERE scope_key = ? AND publication_id = ?", (schemaRow, schemaIndex) -> ManagedSchemaRows.read(schemaRow),
scope, publicationId).getFirst();
require(((Number) phase.get("quarantined")).intValue() == 0,
require(((Number) phase.get("is_quarantined")).intValue() == 0,
"Publication is quarantined");
require("OPEN".equals(phase.get("producer_phase"))
|| "FINISHING".equals(phase.get("producer_phase"))
@@ -1954,12 +1954,12 @@ public final class ToolPublicationDataStore {
private JsonNode exactSucceededReplay(String scope, String publicationId, String operationId,
String slot, String requestDigest) {
var publication = jdbc.query("SELECT producer_phase, finish_operation_id,"
+ " terminal_resource_id, CASE WHEN quarantined THEN 1 ELSE 0 END AS quarantined"
+ " terminal_resource_id, CASE WHEN is_quarantined THEN 1 ELSE 0 END AS is_quarantined"
+ " FROM ma_output_capture WHERE scope_key = ? AND publication_id = ?", (schemaRow, schemaIndex) -> ManagedSchemaRows.read(schemaRow),
scope, publicationId).getFirst();
require(("FINISHED".equals(publication.get("producer_phase"))
|| "REFERENCED".equals(publication.get("producer_phase")))
&& ((Number) publication.get("quarantined")).intValue() == 0,
&& ((Number) publication.get("is_quarantined")).intValue() == 0,
"Original publication is not finished");
List<Operation> prior = operation(scope, publicationId, operationId, true);
require(prior.size() == 1 && "SUCCEEDED".equals(prior.get(0).state())
@@ -2131,14 +2131,14 @@ public final class ToolPublicationDataStore {
private List<Operation> operation(String scope, String publicationId, String operationId, boolean locked) {
return jdbc.query("SELECT request_digest, slot_key, state, claim_generation, claim_until, execution_mode,"
+ " verification_ready,"
+ " is_verification_ready,"
+ " COALESCE(recovery_deadline, deadline) AS deadline"
+ " FROM ma_operation WHERE operation_kind IN ('OUTPUT_UPLOAD', 'OUTPUT_VERIFY', 'OUTPUT_FINISH') AND scope_key = ? AND publication_id = ?"
+ " AND operation_id = ?" + (locked ? " FOR UPDATE" : ""),
(r, n) -> new Operation(r.getString("request_digest"), r.getString("slot_key"),
r.getString("state"), r.getLong("claim_generation"), ManagedSchemaTime.timestamp(r, "claim_until"),
ManagedSchemaTime.timestamp(r, "deadline"), "ASYNC".equals(r.getString("execution_mode")),
r.getBoolean("verification_ready")), scope, publicationId, operationId);
r.getBoolean("is_verification_ready")), scope, publicationId, operationId);
}
private void verify(String scope, String publicationId, String objectKey, long length, String digest) {
@@ -2292,7 +2292,7 @@ public final class ToolPublicationDataStore {
arguments.add(ToolPublicationRetentionStore.hash(text(key, "sessionId")));
arguments.addAll(ids);
var rows = jdbc.query("SELECT publication_id, producer_phase, admission_resource_id,"
+ " receipt_revision, receipt_sequence, CASE WHEN quarantined THEN 1 ELSE 0 END AS quarantined"
+ " receipt_revision, receipt_sequence, CASE WHEN is_quarantined THEN 1 ELSE 0 END AS is_quarantined"
+ " FROM ma_output_capture WHERE scope_key = ?"
+ " AND tenant_id = ? AND workspace_id = ? AND session_id = ?"
+ " AND NOT EXISTS (SELECT 1 FROM ma_session r"
@@ -2306,7 +2306,7 @@ public final class ToolPublicationDataStore {
static boolean referenced(Map<String, Object> row, JsonNode outcomeRef, long revision, long sequence) {
return row != null && "REFERENCED".equals(row.get("producer_phase"))
&& row.get("quarantined") instanceof Number mark && mark.intValue() == 0
&& row.get("is_quarantined") instanceof Number mark && mark.intValue() == 0
&& outcomeRef != null && outcomeRef.path("resourceId").isTextual()
&& outcomeRef.path("resourceId").asText().equals(row.get("admission_resource_id"))
&& row.get("receipt_revision") instanceof Number r && r.longValue() == revision
@@ -2318,7 +2318,7 @@ public final class ToolPublicationDataStore {
guard.run();
String scope = scope(key);
var publications = jdbc.query("SELECT binding_json, producer_phase,"
+ " CASE WHEN quarantined THEN 1 ELSE 0 END AS quarantined FROM ma_output_capture"
+ " CASE WHEN is_quarantined THEN 1 ELSE 0 END AS is_quarantined FROM ma_output_capture"
+ " WHERE scope_key = ? AND publication_id = ? AND tenant_id = ?"
+ " AND workspace_id = ? AND session_id = ?", (schemaRow, schemaIndex) -> ManagedSchemaRows.read(schemaRow), scope, publicationId,
text(key, "tenantId"), text(key, "workspaceId"), text(key, "sessionId"));
@@ -2328,7 +2328,7 @@ public final class ToolPublicationDataStore {
require(!requireFinished || "FINISHED".equals(publication.get("producer_phase"))
|| "REFERENCED".equals(publication.get("producer_phase")),
"Publication is not finished");
require(((Number) publication.get("quarantined")).intValue() == 0,
require(((Number) publication.get("is_quarantined")).intValue() == 0,
"Publication is quarantined");
JsonNode binding = ToolPublicationContract.readJson(
((String) publication.get("binding_json")).getBytes(StandardCharsets.UTF_8));
@@ -115,11 +115,11 @@ public final class ToolPublicationRetentionStore implements com.alibaba.qwen.cod
boundedParameters(jdbc, timeoutSeconds, tenant, session, hash(tenant), hash(session),
com.alibaba.qwen.code.managedagent.repository.ManagedSessionStore.sessionScopeKey(tenant, session), time, time));
return jdbc.query(
"SELECT tenant_id, session_id, csi_guard FROM ma_session WHERE tenant_id = ? AND"
"SELECT tenant_id, session_id, is_csi_guard FROM ma_session WHERE tenant_id = ? AND"
+ " session_id = ? FOR UPDATE",
boundedParameters(jdbc, timeoutSeconds, tenant, session),
(row, index) -> {
boolean guarded = row.getBoolean("csi_guard");
boolean guarded = row.getBoolean("is_csi_guard");
if (legacyMutation) {
ManagedLegacySessionGuard.requireLegacyMutation(guarded);
}
@@ -225,7 +225,7 @@ public final class ToolPublicationRetentionStore implements com.alibaba.qwen.cod
}
jdbc.update(
"UPDATE ma_session SET gmt_modified = " + ManagedSchemaTime.SQL_NOW + ", retirement_operation_id = ?, retirement_generation ="
+ " retirement_generation + 1, retired_at = ?, recovery_protected = ? WHERE"
+ " retirement_generation + 1, retired_at = ?, is_recovery_protected = ? WHERE"
+ " tenant_key = ? AND session_key = ? AND retired_at IS NULL",
operation,
time,
@@ -292,7 +292,7 @@ public final class ToolPublicationRetentionStore implements com.alibaba.qwen.cod
String publication = (String) row.get("publication_id");
lockRetainedPublication(scope, publication);
jdbc.update(
"UPDATE ma_output_capture SET gmt_modified = " + ManagedSchemaTime.SQL_NOW + ", quarantined = TRUE WHERE scope_key = ?"
"UPDATE ma_output_capture SET gmt_modified = " + ManagedSchemaTime.SQL_NOW + ", is_quarantined = TRUE WHERE scope_key = ?"
+ " AND publication_id = ?",
scope,
publication);
@@ -668,7 +668,7 @@ public final class ToolPublicationRetentionStore implements com.alibaba.qwen.cod
.query(
"SELECT scope_key, publication_id, tenant_id, session_id,"
+ " capture_used_bytes, producer_used_bytes, admission_used_bytes,"
+ " write_evidence, quarantined, accepted_complete, producer_phase FROM"
+ " is_write_evidence, is_quarantined, is_accepted_complete, producer_phase FROM"
+ " ma_output_capture WHERE retention_state = 'RETIRING' ORDER BY"
+ " scope_key, publication_id LIMIT 100",
(schemaRow, schemaIndex) -> ManagedSchemaRows.read(schemaRow))
@@ -686,7 +686,7 @@ public final class ToolPublicationRetentionStore implements com.alibaba.qwen.cod
+ number(row, "admission_used_bytes");
var roots =
jdbc.query(
"SELECT retired_at, recovery_protected FROM ma_session WHERE tenant_key = ?"
"SELECT retired_at, is_recovery_protected FROM ma_session WHERE tenant_key = ?"
+ " AND session_key = ? AND retired_at IS NOT NULL",
(schemaRow, schemaIndex) -> ManagedSchemaRows.read(schemaRow),
hash(tenant),
@@ -694,16 +694,16 @@ public final class ToolPublicationRetentionStore implements com.alibaba.qwen.cod
String blocker;
if (roots.isEmpty()) {
blocker = "session_not_retired";
} else if (flag(roots.getFirst(), "recovery_protected")) {
} else if (flag(roots.getFirst(), "is_recovery_protected")) {
blocker = "recovery_protected";
} else if (number(roots.getFirst(), "retired_at") > now(jdbc) - grace.toMillis()) {
blocker = "grace_period";
} else if (!flag(row, "write_evidence")) {
} else if (!flag(row, "is_write_evidence")) {
blocker = "legacy_write_evidence_missing";
} else if (flag(row, "quarantined")) {
} else if (flag(row, "is_quarantined")) {
blocker = "quarantined";
} else if (!"REFERENCED".equals(row.get("producer_phase"))
|| !flag(row, "accepted_complete")) {
|| !flag(row, "is_accepted_complete")) {
blocker = "not_accepted_complete";
} else if (count(
"SELECT COUNT(*) FROM ma_read_lease WHERE tenant_key = ? AND session_key ="
@@ -242,12 +242,12 @@ public final class ToolPublicationStore {
var current = jdbc.query(
"SELECT token_hash, state, expires_at, binding_digest,"
+ " binding_json, tenant_id, workspace_id, session_id, CASE"
+ " WHEN quarantined THEN 1 ELSE 0 END AS quarantined FROM"
+ " WHEN is_quarantined THEN 1 ELSE 0 END AS is_quarantined FROM"
+ " ma_output_capture WHERE scope_key = ? AND publication_id ="
+ " ? FOR UPDATE", (schemaRow, schemaIndex) -> ManagedSchemaRows.read(schemaRow),
scope, publicationId).getFirst();
long nowEpoch = ToolPublicationRetentionStore.now(jdbc);
require(((Number) current.get("quarantined")).intValue() == 0, "Publication is quarantined");
require(((Number) current.get("is_quarantined")).intValue() == 0, "Publication is quarantined");
if (access != Access.SETTLE) {
require(equalHash(suppliedHash, (String) current.get("token_hash"))
&& "OPEN".equals(current.get("state")) && current.get("expires_at") != null,
@@ -411,7 +411,7 @@ public final class ToolPublicationStore {
+ " session_id, publication_id, execution_key, capture_id, binding_json,"
+ " binding_digest, token_hash, state, expires_at, capture_bytes,"
+ " producer_bytes, admission_bytes, capture_held_bytes,"
+ " producer_held_bytes, admission_held_bytes, write_evidence) VALUES (?,"
+ " producer_held_bytes, admission_held_bytes, is_write_evidence) VALUES (?,"
+ " ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'OPEN', ?, ?, ?, ?, ?, ?, ?, TRUE)",
scope, tenantKey, tenant, workspace, session, id, hash(text(candidate, "executionCallId")),
text(candidate, "captureId"), candidate.toString(), digest, tokenHash, expires, bytes,
@@ -878,13 +878,13 @@ public final class ToolPublicationStore {
require(sameResult, "Original settled Broker result conflicts with terminal result");
JsonNode terminal = finished.path("terminal");
var publication = jdbc.query("SELECT producer_phase, finish_operation_id, finish_digest,"
+ " terminal_resource_id, CASE WHEN quarantined THEN 1 ELSE 0"
+ " END AS quarantined FROM ma_output_capture WHERE scope_key ="
+ " terminal_resource_id, CASE WHEN is_quarantined THEN 1 ELSE 0"
+ " END AS is_quarantined FROM ma_output_capture WHERE scope_key ="
+ " ? AND publication_id = ? FOR UPDATE", (schemaRow, schemaIndex) -> ManagedSchemaRows.read(schemaRow),
scope, publicationId).getFirst();
require(("FINISHED".equals(publication.get("producer_phase"))
|| "REFERENCED".equals(publication.get("producer_phase")))
&& ((Number) publication.get("quarantined")).intValue() == 0
&& ((Number) publication.get("is_quarantined")).intValue() == 0
&& text(finished, "finishOperationId").equals(publication.get("finish_operation_id"))
&& text(terminal, "resourceId").equals(publication.get("terminal_resource_id"))
&& text(terminal, "digest").equals(publication.get("finish_digest")),
@@ -66,11 +66,11 @@ public class WakeRecoveryStore
+ " h.committed_sequence, h.compacted_through_revision, s.parent_session_id,"
+ " s.parent_child_run_id FROM ma_session_head h JOIN ma_session s ON"
+ " s.tenant_id = h.tenant_id AND s.session_id = h.session_id WHERE"
+ " h.head_kind = 'MANAGED_SESSION' AND h.wake_scan_pending = TRUE"
+ " h.head_kind = 'MANAGED_SESSION' AND h.is_wake_scan_pending = TRUE"
+ " AND h.compacted_through_revision = 0"
+ " AND h.wake_pending = ? AND h.wake_retry_at <= " + ManagedSchemaTime.SQL_NOW + " AND" + UNOWNED
+ " AND h.is_wake_pending = ? AND h.wake_retry_at <= " + ManagedSchemaTime.SQL_NOW + " AND" + UNOWNED
+ " AND s.session_kind = 'PUBLIC' AND s.status = 'ACTIVE'"
+ " AND s.retired_at IS NULL AND s.csi_guard = FALSE"
+ " AND s.retired_at IS NULL AND s.is_csi_guard = FALSE"
+ " AND h.workspace_id = COALESCE(s.workspace_id, ?)"
+ " ORDER BY h.wake_retry_at, h.tenant_key, h.harness_key LIMIT ?",
(row, index) -> new Candidate(row.getString("tenant_id"), row.getString("workspace_id"),
@@ -87,7 +87,7 @@ public class WakeRecoveryStore
// subquery would first lock the head, then wait for a shared Session lock.
var session = jdbc.queryForList("SELECT session_id FROM ma_session WHERE tenant_id = ?"
+ " AND session_id = ? AND session_kind = 'PUBLIC' AND status = 'ACTIVE'"
+ " AND retired_at IS NULL AND csi_guard = FALSE"
+ " AND retired_at IS NULL AND is_csi_guard = FALSE"
+ " AND (workspace_id IS NULL OR workspace_id = ?) FOR UPDATE",
String.class, candidate.tenantId(), candidate.sessionId(), candidate.workspaceId());
if (session.isEmpty() || ManagedConfigStore.blocked(jdbc, candidate.tenantId(), candidate.sessionId())) {
@@ -98,7 +98,7 @@ public class WakeRecoveryStore
+ " AND h.session_id = ? AND h.workspace_id = ?"
+ " AND h.head_kind = 'MANAGED_SESSION' AND h.journal_revision = ?"
+ " AND h.compacted_through_revision = 0"
+ " AND h.wake_scan_pending = TRUE AND h.wake_retry_at <= " + ManagedSchemaTime.SQL_NOW + " AND" + UNOWNED,
+ " AND h.is_wake_scan_pending = TRUE AND h.wake_retry_at <= " + ManagedSchemaTime.SQL_NOW + " AND" + UNOWNED,
ManagedSchemaKeys.key(candidate.tenantId()),
ManagedSchemaKeys.key(candidate.sessionId()), candidate.tenantId(), candidate.sessionId(),
candidate.workspaceId(), candidate.journalRevision()) == 1;
@@ -231,9 +231,9 @@ public class WakeRecoveryStore
+ " WHERE h.tenant_key = ? AND h.harness_key = ? AND h.tenant_id = ?"
+ " AND h.session_id = ? AND h.workspace_id = ? AND h.head_kind = 'MANAGED_SESSION'"
+ " AND h.journal_revision = ? AND h.committed_sequence = ?"
+ " AND h.compacted_through_revision = 0 AND h.wake_scan_pending = TRUE AND" + UNOWNED
+ " AND h.compacted_through_revision = 0 AND h.is_wake_scan_pending = TRUE AND" + UNOWNED
+ " AND s.session_kind = 'PUBLIC' AND s.status = 'ACTIVE'"
+ " AND s.retired_at IS NULL AND s.csi_guard = FALSE"
+ " AND s.retired_at IS NULL AND s.is_csi_guard = FALSE"
+ " AND (s.workspace_id IS NULL OR s.workspace_id = ?)",
Long.class, ManagedSchemaKeys.key(candidate.tenantId()), ManagedSchemaKeys.key(candidate.sessionId()),
candidate.tenantId(), candidate.sessionId(), candidate.workspaceId(), candidate.journalRevision(),
@@ -242,7 +242,7 @@ public class WakeRecoveryStore
/** Only a full prefix at this exact revision may clear the hint. */
public boolean recordPending(Candidate candidate, boolean pending) {
return jdbc.update("UPDATE ma_session_head SET wake_pending = ?, wake_head_revision = ?"
return jdbc.update("UPDATE ma_session_head SET is_wake_pending = ?, wake_head_revision = ?"
+ " WHERE tenant_key = ? AND harness_key = ? AND tenant_id = ?"
+ " AND session_id = ? AND workspace_id = ? AND journal_revision = ?"
+ " AND compacted_through_revision = 0",
@@ -78,7 +78,7 @@ final class WorkspaceCsiApplicationImage {
put(headDelta, "wake_head_revision", revision);
wakeRevision = revision;
}
put(headDelta, "wake_scan_pending", Boolean.TRUE.equals(head.bool("wake_pending"))
put(headDelta, "is_wake_scan_pending", Boolean.TRUE.equals(head.bool("is_wake_pending"))
|| wakeRevision == null || wakeRevision != revision);
put(headDelta, "committed_sequence", request.path("lastSequence").longValue());
put(headDelta, "last_commit_digest", text(request, "commitDigest"));
@@ -69,7 +69,7 @@ final class WorkspaceCsiApplicationInventory {
.enable(DeserializationFeature.FAIL_ON_TRAILING_TOKENS);
private static final List<Declaration> CATALOGUE = List.of(
declaration("ma_agent_definition", "tenant_id,agent_id,revision",
"tenant_id:VARBINARY,agent_id:VARBINARY,revision:BIGINT,digest:VARCHAR,definition_json:LONGTEXT,"
"tenant_id:VARBINARY,agent_id:VARBINARY,revision:BIGINT,digest:CHAR,definition_json:LONGTEXT,"
+ "gmt_create:BIGINT"),
declaration("ma_artifact", "artifact_id",
"artifact_id:VARBINARY,result_id:VARBINARY,scope_key:CHAR,descriptor_json:MEDIUMTEXT,"
@@ -95,7 +95,7 @@ final class WorkspaceCsiApplicationInventory {
"tenant_id:VARBINARY,session_id:VARBINARY,stream_kind:VARCHAR,stream_id:VARBINARY,last_sequence:BIGINT,"
+ "replay_floor_sequence:BIGINT,covered_sequence:BIGINT,wake_covered_sequence:BIGINT,"
+ "projection_version:INT,"
+ "artifact_refs_resource_key:CHAR,output_ranges_json:LONGTEXT,projection_pending:BOOLEAN,"
+ "artifact_refs_resource_key:CHAR,output_ranges_json:LONGTEXT,is_projection_pending:BOOLEAN,"
+ "gmt_modified:BIGINT"),
declaration("ma_extension_operation", "operation_key",
"operation_key:CHAR,scope_key:CHAR,tenant_id:VARBINARY,workspace_id:VARBINARY,actor_key:CHAR,"
@@ -125,7 +125,7 @@ final class WorkspaceCsiApplicationInventory {
+ "session_status_before:VARCHAR,receipt_id:VARBINARY,claim_owner:VARBINARY,claim_generation:BIGINT,"
+ "claim_until:BIGINT,available_at:BIGINT,attempt_count:INT,budget_exempt_attempt:INT,deadline:BIGINT,"
+ "recovery_deadline:BIGINT,execution_mode:VARCHAR,verification_request_json:LONGTEXT,"
+ "verification_ready:BOOLEAN,verification_next_at:BIGINT,publication_id:VARBINARY,"
+ "is_verification_ready:BOOLEAN,verification_next_at:BIGINT,publication_id:VARBINARY,"
+ "publication_command_id:VARBINARY,slot_key:VARBINARY,execution_key:CHAR,item_id:VARBINARY,"
+ "policy_version:VARBINARY,failure_status:INT,failure_code:VARCHAR,gmt_create:BIGINT,gmt_modified:BIGINT,"
+ "completed_at:BIGINT,progress_format:VARCHAR,progress_version:BIGINT,progress_stage:VARCHAR,"
@@ -141,28 +141,28 @@ final class WorkspaceCsiApplicationInventory {
"scope_key:CHAR,tenant_key:CHAR,tenant_id:VARBINARY,workspace_id:VARBINARY,session_id:VARBINARY,"
+ "publication_id:VARBINARY,execution_key:CHAR,capture_id:VARBINARY,binding_json:MEDIUMTEXT,"
+ "binding_digest:CHAR,token_hash:CHAR,state:VARCHAR,expires_at:BIGINT,capture_bytes:BIGINT,"
+ "producer_bytes:BIGINT,admission_bytes:BIGINT,producer_phase:VARCHAR,quarantined:BOOLEAN,"
+ "producer_bytes:BIGINT,admission_bytes:BIGINT,producer_phase:VARCHAR,is_quarantined:BOOLEAN,"
+ "active_operation_id:VARBINARY,finish_operation_id:VARBINARY,finish_predecessor_id:VARBINARY,"
+ "finish_digest:CHAR,terminal_resource_id:VARBINARY,admission_resource_id:VARBINARY,"
+ "receipt_sequence:BIGINT,receipt_revision:BIGINT,capture_held_bytes:BIGINT,producer_held_bytes:BIGINT,"
+ "admission_held_bytes:BIGINT,capture_used_bytes:BIGINT,producer_used_bytes:BIGINT,"
+ "admission_used_bytes:BIGINT,retention_state:VARCHAR,write_evidence:BOOLEAN,accepted_complete:BOOLEAN,"
+ "admission_used_bytes:BIGINT,retention_state:VARCHAR,is_write_evidence:BOOLEAN,is_accepted_complete:BOOLEAN,"
+ "collected_at:BIGINT,collected_bytes:BIGINT,released_held_bytes:BIGINT,manifest_resource_key:CHAR,"
+ "manifest_sha256:CHAR,seal_manifest_resource_key:CHAR,seal_manifest_sha256:CHAR,gmt_create:BIGINT,"
+ "gmt_modified:BIGINT"),
declaration("ma_public_event", "tenant_id,session_id,stream_kind,stream_id,sequence_id",
"tenant_id:VARBINARY,session_id:VARBINARY,sequence_id:BIGINT,event_id:VARBINARY,turn_id:VARBINARY,"
+ "event_type:VARCHAR,data_json:LONGTEXT,terminal:BOOLEAN,source_key:VARBINARY,gmt_create:BIGINT,"
+ "event_type:VARCHAR,data_json:LONGTEXT,is_terminal:BOOLEAN,source_key:VARBINARY,gmt_create:BIGINT,"
+ "schema_version:INT,projection_version:INT,item_id:VARBINARY,content_part_id:VARBINARY,"
+ "stream_kind:VARCHAR,stream_id:VARBINARY,state:VARCHAR,runtime_state:VARCHAR,text:LONGTEXT,"
+ "truncated:BOOLEAN,artifact_id:VARBINARY,capture_id:VARBINARY,output_stream_id:VARBINARY,"
+ "first_ordinal:BIGINT,end_ordinal:BIGINT,archived:BOOLEAN"),
+ "is_truncated:BOOLEAN,artifact_id:VARBINARY,capture_id:VARBINARY,output_stream_id:VARBINARY,"
+ "first_ordinal:BIGINT,end_ordinal:BIGINT,is_archived:BOOLEAN"),
declaration("ma_read_lease", "lease_id",
"lease_id:VARBINARY,tenant_key:CHAR,session_key:CHAR,retirement_generation:BIGINT,expires_at:BIGINT"),
declaration("ma_request_receipt", "receipt_key",
"receipt_key:CHAR,namespace:VARCHAR,tenant_key:CHAR,tenant_id:VARBINARY,scope_kind:VARCHAR,"
+ "scope_key:CHAR,scope_id:VARBINARY,idempotency_key:VARBINARY,idempotency_digest:CHAR,"
+ "request_digest:VARCHAR,actor_id:VARBINARY,operation:VARCHAR,state:VARCHAR,workspace_bound:BOOLEAN,"
+ "request_digest:VARCHAR,actor_id:VARBINARY,operation:VARCHAR,state:VARCHAR,is_workspace_bound:BOOLEAN,"
+ "session_id:VARBINARY,turn_id:VARBINARY,agent_id:VARBINARY,agent_revision:BIGINT,schedule_id:VARBINARY,"
+ "channel_id:VARBINARY,account_generation:BIGINT,semantic_revision:BIGINT,action_id:VARBINARY,"
+ "action_version:BIGINT,decision_scope_key:CHAR,mutation_attempt_sequence:BIGINT,"
@@ -185,11 +185,11 @@ final class WorkspaceCsiApplicationInventory {
+ "workspace_generation:VARBINARY,canonical_cwd:VARCHAR,capability_digest:VARBINARY,"
+ "isolation_class:VARCHAR,isolation_key:VARBINARY,provisioner_kind:VARCHAR,storage_id:VARBINARY,"
+ "storage_alias_key:CHAR,runtime_generation:BIGINT,binding_state:VARCHAR,provision_request_id:VARBINARY,"
+ "provision_seed_ciphertext:LONGTEXT,provision_seeded:BOOLEAN,credential_key_id:VARBINARY,"
+ "provision_seed_ciphertext:LONGTEXT,is_provision_seeded:BOOLEAN,credential_key_id:VARBINARY,"
+ "resource_handle_version:INT,resource_handle_json:LONGTEXT,loss_evidence_json:LONGTEXT,"
+ "stop_evidence_json:LONGTEXT,runtime_instance_id:VARBINARY,runtime_endpoint:VARCHAR,"
+ "runtime_lease_id:VARBINARY,runtime_epoch:BIGINT,runtime_credential_ciphertext:LONGTEXT,"
+ "runtime_credential_key_id:VARBINARY,attestation_generation:BIGINT,drain_requested:BOOLEAN,"
+ "runtime_credential_key_id:VARBINARY,attestation_generation:BIGINT,is_drain_requested:BOOLEAN,"
+ "operation_owner:VARBINARY,operation_lease_until:BIGINT,operation_generation:BIGINT,"
+ "record_version:BIGINT,last_health_at:BIGINT,last_reconciled_at:BIGINT,last_active_at:BIGINT,"
+ "drain_receipt_json:LONGTEXT,first_activation_journal_revision:BIGINT"),
@@ -198,7 +198,7 @@ final class WorkspaceCsiApplicationInventory {
+ "workspace_generation:VARBINARY,canonical_cwd:VARCHAR,capability_digest:VARBINARY,"
+ "isolation_class:VARCHAR,harness_session_id:VARBINARY,turn_kind:VARCHAR,binding_id:VARBINARY,"
+ "runtime_generation:BIGINT,session_state:VARCHAR,record_version:BIGINT,last_active_at:BIGINT,"
+ "execution_storage_key:CHAR,execution_exclusive:BOOLEAN"),
+ "execution_storage_key:CHAR,is_execution_exclusive:BOOLEAN"),
declaration("ma_runtime_slot", "request_key",
"request_key:CHAR,tenant_id:VARBINARY,workspace_id:VARBINARY,workspace_generation:VARBINARY,"
+ "canonical_cwd:VARCHAR,capability_digest:VARBINARY,isolation_class:VARCHAR,isolation_key:VARBINARY,"
@@ -207,7 +207,7 @@ final class WorkspaceCsiApplicationInventory {
"tenant_id:VARBINARY,schedule_id:VARBINARY,session_id:VARBINARY,workspace_id:VARBINARY,"
+ "actor_id:VARBINARY,record_revision:BIGINT,definition_revision:BIGINT,definition_digest:CHAR,"
+ "goal:VARCHAR,cron:VARCHAR,timezone:VARCHAR,session_mode:VARCHAR,overlap:VARCHAR,catch_up:VARCHAR,"
+ "catch_up_limit:BIGINT,enabled:BOOLEAN,state:VARCHAR,blocked_reason:VARCHAR,armed_at:BIGINT,"
+ "catch_up_limit:BIGINT,is_enabled:BOOLEAN,state:VARCHAR,blocked_reason:VARCHAR,armed_at:BIGINT,"
+ "watermark_slot:BIGINT,lease_owner:VARBINARY,lease_until:BIGINT,fence:BIGINT,gmt_create:BIGINT,"
+ "gmt_modified:BIGINT,gate:VARCHAR,gate_last_outcome:VARCHAR,gate_last_at:BIGINT,"
+ "gate_quiet_since_delivery:INT,gate_failures:INT,gate_last_error:VARCHAR"),
@@ -226,14 +226,14 @@ final class WorkspaceCsiApplicationInventory {
+ "approval_mode:VARCHAR,tool_profile:VARCHAR,"
+ "creator_actor_key:VARBINARY,owner_actor_key:VARBINARY,parent_session_id:VARBINARY,"
+ "root_session_id:VARBINARY,parent_child_run_id:VARBINARY,child_depth:INT,"
+ "agent_definition_digest:VARCHAR,session_kind:VARCHAR,tenant_key:CHAR,session_key:CHAR,"
+ "agent_definition_digest:CHAR,session_kind:VARCHAR,tenant_key:CHAR,session_key:CHAR,"
+ "session_scope_key:CHAR,title_revision:BIGINT,retirement_operation_id:VARBINARY,"
+ "retirement_generation:BIGINT,retired_at:BIGINT,recovery_protected:BOOLEAN,"
+ "resource_gc_completed:BOOLEAN,runtime_request_key:CHAR,csi_guard:BOOLEAN,"
+ "retirement_generation:BIGINT,retired_at:BIGINT,is_recovery_protected:BOOLEAN,"
+ "is_resource_gc_completed:BOOLEAN,runtime_request_key:CHAR,is_csi_guard:BOOLEAN,"
+ "model_id:VARBINARY,model_revision:BIGINT,"
+ "model_config_digest:VARCHAR,model_config_key_id:VARCHAR,model_config_ciphertext:LONGTEXT,"
+ "selected_approval_mode:VARCHAR,approval_revision:BIGINT,"
+ "plan_enabled:BOOLEAN,permission_rules_json:LONGTEXT,public_child_agents_version:INT,harness_instance_id:VARBINARY,harness_owner_boot_id:VARBINARY,"
+ "is_plan_enabled:BOOLEAN,permission_rules_json:LONGTEXT,public_child_agents_version:INT,harness_instance_id:VARBINARY,harness_owner_boot_id:VARBINARY,"
+ "harness_placement_epoch:BIGINT,harness_placement_state:VARCHAR"),
declaration("ma_session_head", "tenant_key,harness_key",
"tenant_id:VARBINARY,workspace_id:VARBINARY,session_id:VARBINARY,storage_version:INT,state:VARCHAR,"
@@ -244,8 +244,8 @@ final class WorkspaceCsiApplicationInventory {
+ "activation_id:VARBINARY,activation_phase:VARCHAR,activation_event_epoch:BIGINT,"
+ "activation_expires_at:BIGINT,activation_head_revision:BIGINT,tenant_key:CHAR,harness_key:CHAR,"
+ "harness_session_id:VARBINARY,head_kind:VARCHAR,phase:VARCHAR,operation_id:VARBINARY,"
+ "claim_generation:BIGINT,claim_lease_until:BIGINT,wake_pending:BOOLEAN,wake_head_revision:BIGINT,"
+ "wake_retry_at:BIGINT,wake_scan_pending:BOOLEAN,cleanup_head_revision:BIGINT"),
+ "claim_generation:BIGINT,claim_lease_until:BIGINT,is_wake_pending:BOOLEAN,wake_head_revision:BIGINT,"
+ "wake_retry_at:BIGINT,is_wake_scan_pending:BOOLEAN,cleanup_head_revision:BIGINT"),
declaration("ma_session_journal_tx", "tenant_id,session_id,journal_revision",
"tenant_id:VARBINARY,workspace_id:VARBINARY,session_id:VARBINARY,journal_revision:BIGINT,"
+ "command_key_hash:CHAR,transaction_id:VARBINARY,operation:LONGTEXT,command_id:VARBINARY,"
@@ -289,27 +289,27 @@ final class WorkspaceCsiApplicationInventory {
+ "idempotency_key:VARBINARY,binding_id:VARBINARY,runtime_generation:BIGINT,harness_session_id:VARBINARY,"
+ "runtime_session_id:VARBINARY,runtime_session_key:CHAR,turn_id:VARBINARY,tool_call_id:VARBINARY,"
+ "request_digest:VARCHAR,reference_json:LONGTEXT,execution_state:VARCHAR,execution_status:VARCHAR,"
+ "result_json:LONGTEXT,last_sequence:BIGINT,cancel_requested:BOOLEAN,dispatch_owner:VARBINARY,"
+ "result_json:LONGTEXT,last_sequence:BIGINT,is_cancel_requested:BOOLEAN,dispatch_owner:VARBINARY,"
+ "dispatch_lease_until:BIGINT,dispatch_generation:BIGINT,record_version:BIGINT,settled_at:BIGINT,"
+ "abandoned_at:BIGINT,loss_evidence_id:VARBINARY,authorized_dispatch_generation:BIGINT,"
+ "authorized_binding_version:BIGINT,native_authorization_json:LONGTEXT"),
declaration("ma_turn", "tenant_id,session_id,turn_id",
"tenant_id:VARBINARY,session_id:VARBINARY,turn_id:VARBINARY,prompt_id:VARBINARY,input_json:LONGTEXT,"
+ "payload_digest:VARCHAR,status:VARCHAR,submission_attempted:BOOLEAN,harness_event_epoch:VARBINARY,"
+ "payload_digest:CHAR,status:VARCHAR,is_submission_attempted:BOOLEAN,harness_event_epoch:VARBINARY,"
+ "harness_last_event_id:BIGINT,dispatch_owner:VARBINARY,dispatch_lease_until:BIGINT,error_code:VARCHAR,"
+ "error_message:VARCHAR,gmt_create:BIGINT,gmt_modified:BIGINT,completed_at:BIGINT,version:BIGINT,"
+ "retry_count:INT,consecutive_failures:INT,budget_exempt_failures:INT,retry_after:BIGINT,"
+ "model_id:VARBINARY,model_revision:BIGINT,approval_mode:VARCHAR,approval_revision:BIGINT,"
+ "plan_enabled:BOOLEAN,permission_rules_json:LONGTEXT"),
+ "is_plan_enabled:BOOLEAN,permission_rules_json:LONGTEXT"),
declaration("ma_user_message", "tenant_id,session_id,message_id",
"tenant_id:VARBINARY,session_id:VARBINARY,message_id:VARBINARY,sequence_number:BIGINT,"
+ "revision:BIGINT,actor_id:VARBINARY,input_json:LONGTEXT,state:VARCHAR,context_revision:BIGINT,"
+ "turn_id:VARBINARY,prompt_id:VARBINARY,consumed_sequence:BIGINT"),
declaration("ma_user_message_command", "tenant_id,session_id,command_key",
"tenant_id:VARBINARY,session_id:VARBINARY,command_key:CHAR,actor_id:VARBINARY,"
+ "request_digest:VARCHAR,result_json:LONGTEXT"),
+ "request_digest:CHAR,result_json:LONGTEXT"),
declaration("ma_user_message_queue", "tenant_id,session_id",
"tenant_id:VARBINARY,session_id:VARBINARY,paused:BOOLEAN,resumed_turn_id:VARBINARY,"
"tenant_id:VARBINARY,session_id:VARBINARY,is_paused:BOOLEAN,resumed_turn_id:VARBINARY,"
+ "next_sequence:BIGINT,last_dispatch_at:BIGINT"),
declaration("ma_workspace", "tenant_id,workspace_id",
"tenant_id:VARBINARY,workspace_id:VARBINARY,workspace_generation:BIGINT,storage_id:VARBINARY,"
@@ -941,7 +941,7 @@ final class WorkspaceCsiApplicationInventory {
&& hash(utf8(initial.toString())).equals(row.text("request_digest"))
&& Objects.equals(read.number("started_at"), row.number("gmt_create"))
&& row.number("gmt_modified") != null && row.number("gmt_modified") >= read.number("started_at"));
for (String field : List.of("actor_id", "workspace_bound", "turn_id", "agent_id", "agent_revision", "schedule_id",
for (String field : List.of("actor_id", "is_workspace_bound", "turn_id", "agent_id", "agent_revision", "schedule_id",
"channel_id", "account_generation", "semantic_revision", "action_id", "action_version", "decision_scope_key",
"mutation_attempt_sequence", "session_status_before", "result_operation_key")) {
requireEncoded(row.cell(field).isNull());
@@ -1984,7 +1984,11 @@ final class WorkspaceCsiApplicationInventory {
}
private static boolean schema(ResultSetMetaData metadata, Declaration declaration) throws SQLException {
if (metadata.getColumnCount() != declaration.columns().size()) {
int identity = declaration.columns().size() + 1;
if (metadata.getColumnCount() != identity
|| !"id".equalsIgnoreCase(metadata.getColumnName(identity))
|| metadata.getColumnType(identity) != Types.BIGINT
|| !metadata.isAutoIncrement(identity)) {
return false;
}
for (int index = 0; index < declaration.columns().size(); index++) {
@@ -2379,7 +2383,7 @@ final class WorkspaceCsiApplicationInventory {
return false;
}
if (namespace == com.alibaba.qwen.code.runtimebroker.schema.ManagedSchemaContract.ReceiptNamespace.SESSION_CREATE_MODE) {
Boolean bound = row.bool("workspace_bound");
Boolean bound = row.bool("is_workspace_bound");
return scopeKind == com.alibaba.qwen.code.runtimebroker.schema.ManagedSchemaContract.ReceiptScope.TENANT
&& ownerTenant.equals(scopeId) && bound != null && "RESERVED".equals(row.text("state"))
&& row.cell("session_id").isNull() && row.cell("turn_id").isNull() && row.cell("actor_id").isNull()
@@ -2387,7 +2391,7 @@ final class WorkspaceCsiApplicationInventory {
}
if (namespace != com.alibaba.qwen.code.runtimebroker.schema.ManagedSchemaContract.ReceiptNamespace.SESSION_CREATE_ACTOR
|| scopeKind != com.alibaba.qwen.code.runtimebroker.schema.ManagedSchemaContract.ReceiptScope.ACTOR
|| !Boolean.TRUE.equals(row.bool("workspace_bound")) || !"COMPLETED".equals(row.text("state"))
|| !Boolean.TRUE.equals(row.bool("is_workspace_bound")) || !"COMPLETED".equals(row.text("state"))
|| row.binary("actor_id") == null || !ManagedReceipts.actorScope(row.binary("actor_id")).equals(scopeId)
|| !otherSession(ownerTenant, null, row.text("session_id"))) {
return false;
@@ -2411,7 +2415,7 @@ final class WorkspaceCsiApplicationInventory {
|| !row.text("idempotency_key").matches("[\\x21-\\x7e]{1,128}")) {
return false;
}
for (String field : List.of("workspace_bound", "session_id", "turn_id", "agent_id", "agent_revision",
for (String field : List.of("is_workspace_bound", "session_id", "turn_id", "agent_id", "agent_revision",
"schedule_id", "channel_id", "account_generation", "semantic_revision", "action_id", "action_version",
"decision_scope_key", "mutation_attempt_sequence", "session_status_before", "result_operation_key")) {
if (!row.cell(field).isNull()) {
@@ -2849,7 +2853,7 @@ final class WorkspaceCsiApplicationInventory {
&& row.cell("model_config_digest").isNull() && row.cell("model_config_key_id").isNull()
&& row.cell("model_config_ciphertext").isNull()
&& row.cell("selected_approval_mode").isNull() && Objects.equals(0L, row.number("approval_revision"))
&& Boolean.FALSE.equals(row.bool("plan_enabled")) && row.cell("permission_rules_json").isNull()
&& Boolean.FALSE.equals(row.bool("is_plan_enabled")) && row.cell("permission_rules_json").isNull()
&& Objects.equals(0L, row.number("public_child_agents_version"))
&& row.cell("harness_instance_id").isNull() && row.cell("harness_owner_boot_id").isNull()
&& Objects.equals(0L, row.number("harness_placement_epoch"))
@@ -2862,7 +2866,7 @@ final class WorkspaceCsiApplicationInventory {
&& CsiFilesRetirementProfile.CONFIG_REF.equals(row.text("workspace_config_ref"))
&& CsiFilesRetirementProfile.POLICY_REF.equals(row.text("workspace_policy_ref"))
&& row.number("context_revision") != null && row.number("context_revision") > 0
&& "qwen-code".equals(row.text("agent_id")) && Boolean.TRUE.equals(row.bool("csi_guard"))
&& "qwen-code".equals(row.text("agent_id")) && Boolean.TRUE.equals(row.bool("is_csi_guard"))
&& row.cell("parent_session_id").isNull() && row.cell("root_session_id").isNull()
&& row.cell("parent_child_run_id").isNull() && row.cell("child_depth").isNull()
&& row.binary("creator_actor_key") != null
@@ -2872,7 +2876,7 @@ final class WorkspaceCsiApplicationInventory {
&& "PUBLIC".equals(row.text("session_kind"))
&& Objects.equals(0L, row.number("retirement_generation"))
&& row.cell("retired_at").isNull() && row.cell("retirement_operation_id").isNull()
&& Boolean.FALSE.equals(row.bool("recovery_protected")) && Boolean.FALSE.equals(row.bool("resource_gc_completed"))
&& Boolean.FALSE.equals(row.bool("is_recovery_protected")) && Boolean.FALSE.equals(row.bool("is_resource_gc_completed"))
&& Objects.equals(0L, row.number("harness_last_event_id"))
&& row.cell("harness_boot_id").isNull() && row.cell("harness_event_epoch").isNull()
&& Objects.equals(row.number("gmt_create"), row.number("gmt_modified")));
@@ -2885,7 +2889,7 @@ final class WorkspaceCsiApplicationInventory {
JsonNode data = parse(row.text("data_json"));
Row parent = originalRow("ma_session");
expect(table, row, rawSession(row) && "SESSION".equals(row.text("stream_kind")) && "".equals(row.text("stream_id")) && "session.created".equals(row.text("event_type"))
&& row.cell("turn_id").isNull() && row.cell("source_key").isNull() && Boolean.FALSE.equals(row.bool("terminal"))
&& row.cell("turn_id").isNull() && row.cell("source_key").isNull() && Boolean.FALSE.equals(row.bool("is_terminal"))
&& Objects.equals(1L, row.number("sequence_id")) && data != null && data.isObject()
&& data.size() == 1 && session.equals(data.path("sessionId").textValue())
&& parent != null && Objects.equals(parent.number("gmt_create"), row.number("gmt_create"))
@@ -2952,14 +2956,14 @@ final class WorkspaceCsiApplicationInventory {
case "ma_runtime_binding" -> expect(table, row, request(row)
&& original.bindingId().equals(row.text("binding_id")) && has("Bscope", row.text("scope_key"))
&& Objects.equals(original.generation(), row.number("runtime_generation"))
&& "DRAINING".equals(row.text("binding_state")) && Boolean.TRUE.equals(row.bool("drain_requested"))
&& "DRAINING".equals(row.text("binding_state")) && Boolean.TRUE.equals(row.bool("is_drain_requested"))
&& intent.runtimeInstanceId().equals(row.text("runtime_instance_id"))
&& intent.leaseId().equals(row.text("runtime_lease_id")) && Objects.equals(intent.epoch(), row.number("runtime_epoch"))
&& matches(parse(row.text("resource_handle_json")), parse(intent.resourceHandleJson()))
&& Objects.equals(intent.resourceHandleVersion().longValue(), row.number("resource_handle_version"))
&& Objects.equals(intent.attestationGeneration(), row.number("attestation_generation")));
case "ma_runtime_session" -> expect(table, row, scope(row)
&& row.cell("execution_storage_key").isNull() && Boolean.FALSE.equals(row.bool("execution_exclusive"))
&& row.cell("execution_storage_key").isNull() && Boolean.FALSE.equals(row.bool("is_execution_exclusive"))
&& original.bindingId().equals(row.text("binding_id")) && session.equals(row.text("runtime_session_id"))
&& session.equals(row.text("harness_session_id")) && "bootstrap".equals(row.text("turn_kind"))
&& Objects.equals(original.generation(), row.number("runtime_generation"))
@@ -3019,7 +3023,7 @@ final class WorkspaceCsiApplicationInventory {
&& Objects.equals(0L, row.number("covered_sequence")) && Objects.equals(0L, row.number("replay_floor_sequence"))
&& row.cell("wake_covered_sequence").isNull() && row.cell("artifact_refs_resource_key").isNull()
&& row.cell("output_ranges_json").isNull() && Objects.equals(1L, row.number("projection_version"))
&& Boolean.TRUE.equals(row.bool("projection_pending")) && parent != null
&& Boolean.TRUE.equals(row.bool("is_projection_pending")) && parent != null
&& Objects.equals(parent.number("gmt_create"), row.number("gmt_modified")));
}
case "ma_request_receipt" -> {
@@ -3044,7 +3048,7 @@ final class WorkspaceCsiApplicationInventory {
&& ManagedReceipts.scope(tenant, scopeId).equals(row.text("scope_key"))
&& com.alibaba.qwen.code.runtimebroker.schema.ManagedSchemaKeys.key(idempotency).equals(row.text("idempotency_digest"))
&& row.cell("turn_id").isNull() && row.cell("operation").isNull() && row.cell("session_status_before").isNull()
&& Boolean.TRUE.equals(row.bool("workspace_bound")) && row.text("request_digest") != null);
&& Boolean.TRUE.equals(row.bool("is_workspace_bound")) && row.text("request_digest") != null);
if (namespace == com.alibaba.qwen.code.runtimebroker.schema.ManagedSchemaContract.ReceiptNamespace.SESSION_CREATE_MODE) {
expect(table, row, scopeKind == com.alibaba.qwen.code.runtimebroker.schema.ManagedSchemaContract.ReceiptScope.TENANT
&& tenant.equals(scopeId) && has("creation", idempotency) && row.cell("session_id").isNull()
@@ -121,7 +121,7 @@ public final class WorkspaceCsiCheckpointSnapshotStore {
"SELECT " + ManagedSchemaProjection.OUTPUT_CAPTURE.columns() + " FROM ma_output_capture WHERE scope_key = ? AND publication_id = ?",
publicationScope, publicationId);
scope(publication, key);
require("REFERENCED".equals(publication.get("producer_phase")) && !flag(publication, "quarantined"));
require("REFERENCED".equals(publication.get("producer_phase")) && !flag(publication, "is_quarantined"));
JsonNode binding = ToolPublicationContract.parseBytes("binding",
text(publication, "binding_json").getBytes(StandardCharsets.UTF_8));
require(binding.path("sessionKey").equals(key) && publicationId.equals(binding.path("publicationId").asText())
@@ -339,7 +339,7 @@ public final class WorkspaceCsiCheckpointSnapshotStore {
"SELECT " + ManagedSchemaProjection.RUNTIME_SESSION.columns() + " FROM ma_runtime_session WHERE scope_key = ? AND runtime_session_id = ?",
scopeHash(runtime.getRequest().getScope()), ref.path("sessionId").asText());
require(runtime.getRequest().getScope().equals(scope(session))
&& session.get("execution_storage_key") == null && Boolean.FALSE.equals(session.get("execution_exclusive"))
&& session.get("execution_storage_key") == null && !flag(session, "is_execution_exclusive")
&& runtime.getBindingId().equals(session.get("binding_id"))
&& runtime.getGeneration() == rawNumber(session, "runtime_generation")
&& binding.path("sessionKey").path("sessionId").asText().equals(session.get("harness_session_id")));
@@ -82,10 +82,10 @@ public class WorkspaceExecutionStore
+ " JOIN ma_runtime_slot slot ON slot.active_binding_id = b.binding_id AND slot.request_key = b.request_key"
+ " JOIN ma_storage_owner o ON o.binding_id = b.binding_id AND o.runtime_generation = b.runtime_generation"
+ " WHERE rs.binding_id = ? AND rs.runtime_generation = ? AND rs.runtime_session_id = ?"
+ " AND rs.execution_storage_key IS NULL AND rs.execution_exclusive = FALSE"
+ " AND rs.execution_storage_key IS NULL AND rs.is_execution_exclusive = FALSE"
+ " AND rs.harness_session_id = ? AND rs.session_state IN (" + (releasing
? "'ACQUIRING', 'READY', 'RELEASING', 'RELEASED'" : "'ACQUIRING', 'READY'") + ")"
+ " AND b.request_key = ? AND b.binding_state = 'READY' AND b.drain_requested = FALSE"
+ " AND b.request_key = ? AND b.binding_state = 'READY' AND b.is_drain_requested = FALSE"
+ " AND o.storage_key = ? AND o.storage_kind = 'CSI' AND o.csi_phase = 'RESERVED'"
+ " AND o.csi_registration_key = ? AND o.csi_registration_revision = ?"
+ " AND o.csi_provision_request_id = b.provision_request_id AND o.holder_key IS NULL"
@@ -172,7 +172,7 @@ public class WorkspaceExecutionStore
if (turnId == null || dispatchOwner == null
|| jdbc.queryForObject("SELECT COUNT(*) FROM ma_turn WHERE tenant_id = ?"
+ " AND session_id = ? AND turn_id = ? AND status = 'RUNNING'"
+ " AND submission_attempted = TRUE AND harness_event_epoch IS NOT NULL"
+ " AND is_submission_attempted = TRUE AND harness_event_epoch IS NOT NULL"
+ " AND dispatch_owner = ? AND dispatch_lease_until >= " + ManagedSchemaTime.SQL_NOW,
Long.class, session.tenantId(), session.sessionId(), turnId, dispatchOwner) != 1) {
throw com.alibaba.qwen.code.managedagent.repository.WorkspaceExecutionStore.unavailable();
@@ -261,7 +261,7 @@ public class WorkspaceExecutionStore
+ (cancellation
? " JOIN ma_turn t ON t.tenant_id = s.tenant_id"
+ " AND t.session_id = s.session_id AND t.status = 'CANCELLING'"
+ " AND (t.submission_attempted = TRUE OR t.harness_event_epoch IS NOT NULL)"
+ " AND (t.is_submission_attempted = TRUE OR t.harness_event_epoch IS NOT NULL)"
: committedStop ? ""
: " JOIN ma_workspace r ON r.tenant_id = s.tenant_id"
+ " AND r.workspace_id = s.workspace_id"
@@ -387,12 +387,12 @@ public class WorkspaceExecutionStore
WorkspaceStorageKindGuard.requireExecutionAlias(jdbc, binding.getTenantId(), binding.getStorageId());
String key = storageKey(binding);
WorkspaceMigrationAdmission.requireOpen(jdbc, binding.getTenantId(), binding.getStorageId());
List<Boolean> live = jdbc.query("SELECT binding_id, runtime_generation, binding_state, drain_requested,"
List<Boolean> live = jdbc.query("SELECT binding_id, runtime_generation, binding_state, is_drain_requested,"
+ " tenant_id, workspace_id, workspace_generation, storage_id FROM ma_runtime_binding"
+ " WHERE binding_id = ? FOR UPDATE", (row, index) ->
session.getBindingId().equals(row.getString("binding_id"))
&& session.getRuntimeGeneration() == row.getLong("runtime_generation")
&& "READY".equals(row.getString("binding_state")) && !row.getBoolean("drain_requested")
&& "READY".equals(row.getString("binding_state")) && !row.getBoolean("is_drain_requested")
&& binding.getTenantId().equals(row.getString("tenant_id"))
&& binding.getWorkspaceId().equals(row.getString("workspace_id"))
&& Long.toString(binding.getWorkspaceGeneration()).equals(row.getString("workspace_generation"))
@@ -430,10 +430,10 @@ public class WorkspaceExecutionStore
throw busy();
}
var members = WorkspaceOperations.rows(jdbc, "SELECT runtime_session_id,"
+ " binding_id, runtime_generation, execution_exclusive FROM ma_runtime_session"
+ " binding_id, runtime_generation, is_execution_exclusive FROM ma_runtime_session"
+ " WHERE execution_storage_key = ? FOR UPDATE", key);
for (var member : members) {
if (Boolean.TRUE.equals(member.get("execution_exclusive")) && !sameMember(member, session)) {
if (Boolean.TRUE.equals(member.get("is_execution_exclusive")) && !sameMember(member, session)) {
throw busy();
}
}
@@ -470,9 +470,9 @@ public class WorkspaceExecutionStore
throw com.alibaba.qwen.code.managedagent.repository.WorkspaceExecutionStore.unavailable();
}
var members = WorkspaceOperations.rows(jdbc, "SELECT binding_id, runtime_generation, runtime_session_id,"
+ " execution_exclusive FROM ma_runtime_session WHERE execution_storage_key = ? FOR UPDATE", key);
+ " is_execution_exclusive FROM ma_runtime_session WHERE execution_storage_key = ? FOR UPDATE", key);
for (var member : members) {
if (sameMember(member, session) && Boolean.TRUE.equals(member.get("execution_exclusive"))) {
if (sameMember(member, session) && Boolean.TRUE.equals(member.get("is_execution_exclusive"))) {
throw new RuntimeBrokerException(409, "workspace_rewind_recovery_required",
"An earlier Workspace rewind has an unconfirmed outcome.", false);
}
@@ -480,7 +480,7 @@ public class WorkspaceExecutionStore
if (members.stream().anyMatch(member -> !sameMember(member, session))) {
return false;
}
return jdbc.update("UPDATE ma_runtime_session SET execution_exclusive = TRUE WHERE binding_id = ?"
return jdbc.update("UPDATE ma_runtime_session SET is_execution_exclusive = TRUE WHERE binding_id = ?"
+ " AND runtime_generation = ? AND runtime_session_id = ? AND execution_storage_key = ?",
session.getBindingId(), session.getRuntimeGeneration(), session.getRuntimeSessionId(), key) == 1;
}));
@@ -490,7 +490,7 @@ public class WorkspaceExecutionStore
transaction.executeWithoutResult(status -> {
WorkspaceStorageKindGuard.lockDomain(jdbc, binding.getTenantId());
String key = storageKey(binding);
jdbc.update("UPDATE ma_runtime_session SET execution_exclusive = FALSE WHERE binding_id = ?"
jdbc.update("UPDATE ma_runtime_session SET is_execution_exclusive = FALSE WHERE binding_id = ?"
+ " AND runtime_generation = ? AND runtime_session_id = ? AND execution_storage_key = ?",
session.getBindingId(), session.getRuntimeGeneration(), session.getRuntimeSessionId(), key);
});
@@ -499,7 +499,7 @@ public class WorkspaceExecutionStore
public boolean hasExclusiveClaim(RuntimeSessionRecord session) {
return !jdbc.queryForList("SELECT runtime_session_id FROM ma_runtime_session WHERE binding_id = ?"
+ " AND runtime_generation = ? AND runtime_session_id = ? AND execution_storage_key IS NOT NULL"
+ " AND execution_exclusive = TRUE", String.class, session.getBindingId(), session.getRuntimeGeneration(),
+ " AND is_execution_exclusive = TRUE", String.class, session.getBindingId(), session.getRuntimeGeneration(),
session.getRuntimeSessionId()).isEmpty();
}
@@ -564,7 +564,7 @@ public class WorkspaceExecutionStore
if (live.size() != 1 || !live.getFirst()) {
throw com.alibaba.qwen.code.managedagent.repository.WorkspaceExecutionStore.unavailable();
}
jdbc.update("UPDATE ma_runtime_session SET execution_storage_key = NULL, execution_exclusive = FALSE"
jdbc.update("UPDATE ma_runtime_session SET execution_storage_key = NULL, is_execution_exclusive = FALSE"
+ " WHERE execution_storage_key = ? AND binding_id = ? AND runtime_generation = ?"
+ " AND runtime_session_id = ? AND harness_session_id = ?", key, session.getBindingId(),
session.getRuntimeGeneration(), session.getRuntimeSessionId(), session.getSession().getHarnessSessionId());
@@ -660,11 +660,11 @@ public class WorkspaceExecutionStore
|| HarnessOwnership.sharesRuntimeSessions(saved.getRequest()))) {
return false;
}
var claims = jdbc.query("SELECT binding_state, drain_requested, operation_owner, operation_generation,"
var claims = jdbc.query("SELECT binding_state, is_drain_requested, operation_owner, operation_generation,"
+ " operation_lease_until, tenant_id, storage_id, UNIX_TIMESTAMP() AS db_seconds,"
+ " EXTRACT(MICROSECOND FROM CURRENT_TIMESTAMP(6)) AS db_micros FROM ma_runtime_binding"
+ " WHERE binding_id = ? AND runtime_generation = ?", (row, index) ->
saved.getState().name().equals(row.getString("binding_state")) && row.getBoolean("drain_requested")
saved.getState().name().equals(row.getString("binding_state")) && row.getBoolean("is_drain_requested")
&& saved.getOperationOwner().equals(row.getString("operation_owner"))
&& saved.getOperationGeneration() == row.getLong("operation_generation")
&& ManagedSchemaTime.timestamp(row, "operation_lease_until") != null
@@ -744,7 +744,7 @@ public class WorkspaceExecutionStore
saved.getGeneration(), saved.getOperationOwner(), saved.getOperationGeneration()) != 1) {
throw com.alibaba.qwen.code.managedagent.repository.WorkspaceExecutionStore.unavailable();
}
jdbc.update("UPDATE ma_runtime_session SET execution_storage_key = NULL, execution_exclusive = FALSE"
jdbc.update("UPDATE ma_runtime_session SET execution_storage_key = NULL, is_execution_exclusive = FALSE"
+ " WHERE binding_id = ? AND runtime_generation = ? AND execution_storage_key = ?",
saved.getBindingId(), saved.getGeneration(), key);
});
@@ -132,7 +132,7 @@ public final class WorkspaceOperatorRecoveryStore {
"blocked_execution_call_id", blockedCapture.callId(), "operator_id", operator,
"reason", reason, "prepared_at", Instant.now().toString()));
if (jdbc.update("UPDATE ma_runtime_binding SET binding_state = ?,"
+ " drain_requested = TRUE, operation_owner = NULL, operation_lease_until = NULL,"
+ " is_drain_requested = TRUE, operation_owner = NULL, operation_lease_until = NULL,"
+ " operation_generation = operation_generation + 1, record_version = record_version + 1"
+ " WHERE binding_id = ? AND runtime_generation = ? AND record_version = ?",
saved.getState() == RuntimeBindingRecord.State.LOST ? "LOST" : "OPERATOR_RECOVERY",
@@ -160,11 +160,11 @@ public class WorkspaceProfileLifecycleVerifier {
verifyNotStartedPublication(operation, execution);
} else {
var rows = jdbc.queryForList("SELECT producer_phase, admission_resource_id, receipt_sequence, receipt_revision,"
+ " CASE WHEN quarantined THEN 1 ELSE 0 END AS quarantined FROM ma_output_capture"
+ " CASE WHEN is_quarantined THEN 1 ELSE 0 END AS is_quarantined FROM ma_output_capture"
+ " WHERE tenant_id = ? AND session_id = ? AND publication_id = ? FOR UPDATE",
operation.tenantId(), operation.sessionId(), execution.getReference().get("publicationId"));
if (rows.size() != 1 || !"REFERENCED".equals(rows.getFirst().get("producer_phase"))
|| ((Number) rows.getFirst().get("quarantined")).intValue() != 0
|| ((Number) rows.getFirst().get("is_quarantined")).intValue() != 0
|| !source.outcomeRef().path("resourceId").asText().equals(rows.getFirst().get("admission_resource_id"))
|| source.receiptSequence() != ((Number) rows.getFirst().get("receipt_sequence")).longValue()
|| source.journalRevision() != ((Number) rows.getFirst().get("receipt_revision")).longValue()) {
@@ -313,12 +313,12 @@ public class WorkspaceProfileLifecycleVerifier {
private void verifyNotStartedPublication(OperationRecord operation, ToolExecutionRecord execution) {
var rows = jdbc.queryForList("SELECT state, producer_phase, terminal_resource_id, binding_json, binding_digest,"
+ " CASE WHEN quarantined THEN 1 ELSE 0 END AS quarantined"
+ " CASE WHEN is_quarantined THEN 1 ELSE 0 END AS is_quarantined"
+ " FROM ma_output_capture WHERE tenant_id = ? AND session_id = ? AND publication_id = ? FOR UPDATE",
operation.tenantId(), operation.sessionId(), execution.getReference().get("publicationId"));
if (rows.size() != 1 || !"NOT_STARTED".equals(rows.getFirst().get("state"))
|| !"OPEN".equals(rows.getFirst().get("producer_phase"))
|| ((Number) rows.getFirst().get("quarantined")).intValue() != 0
|| ((Number) rows.getFirst().get("is_quarantined")).intValue() != 0
|| rows.getFirst().get("terminal_resource_id") != null) {
unsettled();
}
@@ -100,7 +100,7 @@ final class WorkspaceRecoveryReader {
&& row.get("object_version_id") == null && row.get("encryption_key_id") == null,
"resource_layout_unsupported");
bytes = (byte[]) row.get("inline_bytes");
var references = jdbc.queryForList("SELECT resource_key FROM ma_resource_ref USE INDEX (ix_ma_ref_resource)"
var references = jdbc.queryForList("SELECT resource_key FROM ma_resource_ref USE INDEX (idx_ma_ref_resource)"
+ " WHERE resource_key = ? AND session_scope_key = ? AND owner_kind IN ('JOURNAL','SESSION_RECORD')"
+ " AND tenant_id = ? AND workspace_id = ? AND session_id = ? AND resource_id = ?"
+ " AND journal_revision <= ? LIMIT 1", String.class, resourceKey, sessionScope,
@@ -298,7 +298,7 @@ final class WorkspaceRecoveryReader {
check(rows.size() == 1, "publication_scope_conflict");
var row = rows.getFirst();
check(!"DELETING".equals(row.get("retention_state")), "source_drift");
check("REFERENCED".equals(row.get("producer_phase")) && Boolean.FALSE.equals(row.get("quarantined"))
check("REFERENCED".equals(row.get("producer_phase")) && Boolean.FALSE.equals(row.get("is_quarantined"))
&& row.get("receipt_revision") instanceof Number && row.get("receipt_sequence") instanceof Number
&& number(row, "receipt_revision") > 0 && number(row, "receipt_revision") <= head.path("journalRevision").asLong()
&& number(row, "receipt_sequence") > 0 && number(row, "receipt_sequence") <= head.path("committedSequence").asLong(),
@@ -641,7 +641,7 @@ public final class WorkspaceRecoveryStore implements com.alibaba.qwen.code.manag
+ " AND retention_state = 'DELETING' LIMIT 1" + currentRead, String.class, captureScope).isEmpty(), "source_drift");
}
var retirements = WorkspaceOperations.rows(jdbc, "SELECT tenant_id, session_id, retirement_operation_id AS operation_id,"
+ " retirement_generation AS generation, retired_at, recovery_protected FROM ma_session"
+ " retirement_generation AS generation, retired_at, is_recovery_protected FROM ma_session"
+ " WHERE tenant_id = ? AND session_id = ? AND retirement_generation > 0", tenant, session);
check(retirements.size() <= 1, "source_drift");
source.putNull("retirement");
@@ -652,7 +652,7 @@ public final class WorkspaceRecoveryStore implements com.alibaba.qwen.code.manag
&& ((Number) row.get("deleted_at")).longValue() > 0
&& ((Number) retirement.get("generation")).longValue() == 1
&& ((Number) retirement.get("retired_at")).longValue() > 0
&& !ToolPublicationRetentionStore.flag(retirement, "recovery_protected"), "source_drift");
&& !ToolPublicationRetentionStore.flag(retirement, "is_recovery_protected"), "source_drift");
JsonNode retiredHead = source.path("head");
check(retiredHead.isNull() || "DELETED".equals(retiredHead.path("state").asText())
&& retiredHead.path("latestCheckpointResourceId").isNull()
@@ -22,16 +22,16 @@ final class ManagedSchemaCatalog {
private static final Pattern COLUMN =
Pattern.compile(
"(?m)^ ([a-z0-9_]+)"
+ " (VARBINARY|VARCHAR|CHAR|BIGINT|INT|BOOLEAN|DATETIME|LONGTEXT|MEDIUMTEXT|MEDIUMBLOB|LONGBLOB)(?:\\((\\d+)\\))?([^\\n"
+ " (VARBINARY|VARCHAR|CHAR|BIGINT|INT|TINYINT|BOOLEAN|DATETIME|LONGTEXT|MEDIUMTEXT|MEDIUMBLOB|LONGBLOB)(?:\\((\\d+)\\))?([^\\n"
+ "]*)");
private static final Pattern PRIMARY = Pattern.compile("PRIMARY KEY \\(([^)]+)\\)");
private static final Pattern UNIQUE = Pattern.compile("UNIQUE(?: KEY [a-z_]+)? \\(([^)]+)\\)");
private static final Pattern CHECK = Pattern.compile("CONSTRAINT ([a-z_]+) CHECK");
private static final Pattern INDEX =
Pattern.compile("CREATE (UNIQUE )?INDEX ([a-z_]+) ON (ma_[a-z_]+) \\(([^)]+)\\)");
Pattern.compile("CREATE (UNIQUE )?INDEX ([a-z_]+) ON (ma_[a-z_]+) \\(([^;]+)\\);");
private static final Pattern INLINE_INDEX = Pattern.compile("INDEX ([a-z_]+)\\s*\\(([^)]+)\\)");
private static final Pattern FOREIGN =
Pattern.compile("FOREIGN KEY \\(([^)]+)\\)\\s*REFERENCES (ma_[a-z_]+) \\(([^)]+)\\)");
private static final Pattern INDEX_PREFIX =
Pattern.compile(" /\\*!50000 \\((\\d+)\\) \\*/");
private ManagedSchemaCatalog() {}
@@ -45,6 +45,14 @@ final class ManagedSchemaCatalog {
throw new SQLException("Managed schema requires a dedicated application catalog;"
+ " system or missing catalog refused before DDL: " + name);
}
try (var statement = connection.prepareStatement("SELECT @@GLOBAL.sql_mode, @@SESSION.sql_mode");
var result = statement.executeQuery()) {
if (!result.next() || !strictSqlMode(result.getString(1)) || !strictSqlMode(result.getString(2))) {
throw new SQLException("Managed schema requires strict SQL mode"
+ " (STRICT_TRANS_TABLES or STRICT_ALL_TABLES) globally and for the current session;"
+ " refused before DDL");
}
}
if (isMariaDb(connection)) {
try (var statement = connection.prepareStatement(
"SELECT @@GLOBAL.check_constraint_checks, @@SESSION.check_constraint_checks");
@@ -58,6 +66,16 @@ final class ManagedSchemaCatalog {
}
}
private static boolean strictSqlMode(String modes) {
for (String mode : modes.split(",")) {
if ("STRICT_TRANS_TABLES".equalsIgnoreCase(mode.trim())
|| "STRICT_ALL_TABLES".equalsIgnoreCase(mode.trim())) {
return true;
}
}
return false;
}
private static boolean isMariaDb(Connection connection) throws SQLException {
var metadata = connection.getMetaData();
String version = metadata.getDatabaseProductVersion();
@@ -137,7 +155,7 @@ final class ManagedSchemaCatalog {
validateGeneratedColumns(connection, name, body);
validateKeys(connection, name, body, ddl);
validateChecks(connection, name, body);
validateForeignKeys(connection, name, body, ddl);
validateForeignKeys(connection, name);
}
if (!declared.equals(ManagedSchemaContract.TABLES)) {
throw new SQLException(
@@ -152,6 +170,7 @@ final class ManagedSchemaCatalog {
Map<String, Boolean> unsigned = new HashMap<>();
Map<String, String> names = new HashMap<>();
Map<String, Boolean> required = new HashMap<>();
Map<String, Boolean> automatic = new HashMap<>();
try (var result =
connection
.getMetaData()
@@ -167,6 +186,8 @@ final class ManagedSchemaCatalog {
required.put(
lower(result.getString("COLUMN_NAME")),
result.getInt("NULLABLE") == DatabaseMetaData.columnNoNulls);
automatic.put(lower(result.getString("COLUMN_NAME")),
"YES".equals(result.getString("IS_AUTOINCREMENT")));
}
}
boolean nativeDatabase = "MySQL".equals(connection.getMetaData().getDatabaseProductName())
@@ -203,10 +224,13 @@ final class ManagedSchemaCatalog {
if (!compatibleType(column.group(2), types.get(key))) {
throw new SQLException("Managed schema column type differs: " + name + "." + key);
}
if (nativeDatabase && "BIGINT".equals(column.group(2))
if (nativeDatabase && Set.of("BIGINT", "INT", "TINYINT").contains(column.group(2))
&& column.group(4).contains("UNSIGNED") != Boolean.TRUE.equals(unsigned.get(key))) {
throw new SQLException("Managed schema integer signedness differs: " + name + "." + key);
}
if (column.group(4).contains("AUTO_INCREMENT") != automatic.get(key)) {
throw new SQLException("Managed schema identity generation differs: " + name + "." + key);
}
if (Set.of("LONGTEXT", "MEDIUMTEXT", "MEDIUMBLOB", "LONGBLOB").contains(column.group(2))
&& actual.get(key) < 1_048_576) {
throw new SQLException("Managed schema body capacity differs: " + name + "." + key);
@@ -315,6 +339,7 @@ final class ManagedSchemaCatalog {
|| index.group(1) != null && !uniqueIndexes.contains(index.group(2))) {
throw new SQLException("Managed schema index differs: " + index.group(2));
}
validateIndexPrefix(connection, name, index.group(2), index.group(4));
}
}
var inline = INLINE_INDEX.matcher(body);
@@ -327,44 +352,36 @@ final class ManagedSchemaCatalog {
}
}
private static void validateForeignKeys(
Connection connection, String name, String body, String ddl) throws SQLException {
Map<String, Map<Integer, String>> actual = new HashMap<>();
try (var result =
connection
.getMetaData()
.getImportedKeys(
connection.getCatalog(),
connection.getSchema(),
storedName(connection, name))) {
while (result.next()) {
String key = lower(result.getString("FK_NAME"));
actual.computeIfAbsent(key, ignored -> new java.util.TreeMap<>())
.put(
result.getInt("KEY_SEQ"),
lower(result.getString("FKCOLUMN_NAME"))
+ ":"
+ lower(result.getString("PKTABLE_NAME"))
+ ":"
+ lower(result.getString("PKCOLUMN_NAME")));
private static void validateIndexPrefix(Connection connection, String table,
String index, String declaration) throws SQLException {
if (!"MySQL".equals(connection.getMetaData().getDatabaseProductName())
&& !isMariaDb(connection)) {
return;
}
String[] fields = declaration.split(",");
try (var statement = connection.prepareStatement(
"SELECT SEQ_IN_INDEX, SUB_PART FROM INFORMATION_SCHEMA.STATISTICS"
+ " WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ? AND INDEX_NAME = ?")) {
statement.setString(1, schema(connection));
statement.setString(2, table);
statement.setString(3, index);
try (var rows = statement.executeQuery()) {
while (rows.next()) {
var prefix = INDEX_PREFIX.matcher(fields[rows.getInt(1) - 1]);
Integer expected = prefix.find() ? Integer.valueOf(prefix.group(1)) : null;
if (!java.util.Objects.equals(expected, rows.getObject(2, Integer.class))) {
throw new SQLException("Managed schema index prefix differs: " + index);
}
}
}
}
var alters = Pattern.compile("ALTER TABLE " + name + " ([^;]+);").matcher(ddl);
String declarations = body;
while (alters.find()) {
declarations += "\n" + alters.group(1);
}
var foreign = FOREIGN.matcher(declarations);
while (foreign.find()) {
List<String> local = columns(foreign.group(1));
List<String> remote = columns(foreign.group(3));
List<String> expected = new ArrayList<>();
for (int index = 0; index < local.size(); index++) {
expected.add(local.get(index) + ":" + foreign.group(2) + ":" + remote.get(index));
}
if (actual.values().stream()
.noneMatch(key -> new ArrayList<>(key.values()).equals(expected))) {
throw new SQLException("Managed schema foreign key is missing: " + name + local);
}
private static void validateForeignKeys(Connection connection, String name) throws SQLException {
try (var keys = connection.getMetaData().getImportedKeys(
connection.getCatalog(), connection.getSchema(), storedName(connection, name))) {
if (keys.next()) {
throw new SQLException("Managed schema must not contain foreign keys: " + name);
}
}
}
@@ -376,6 +393,7 @@ final class ManagedSchemaCatalog {
case "CHAR" -> type == java.sql.Types.CHAR;
case "BIGINT" -> type == java.sql.Types.BIGINT;
case "INT" -> type == java.sql.Types.INTEGER;
case "TINYINT" -> type == java.sql.Types.TINYINT;
case "BOOLEAN" ->
type == java.sql.Types.BOOLEAN
|| type == java.sql.Types.BIT
@@ -594,7 +612,7 @@ final class ManagedSchemaCatalog {
}
private static List<String> columns(String value) {
return java.util.Arrays.stream(value.split(","))
return java.util.Arrays.stream(INDEX_PREFIX.matcher(value).replaceAll("").split(","))
.map(String::trim)
.map(ManagedSchemaCatalog::lower)
.toList();
@@ -23,7 +23,7 @@ public enum ManagedSchemaProjection {
"tenant_id, session_id, stream_kind, stream_id, last_sequence, "
+ "replay_floor_sequence, covered_sequence, wake_covered_sequence, projection_version, "
+ "artifact_refs_resource_key, "
+ "output_ranges_json, projection_pending, gmt_modified"),
+ "output_ranges_json, is_projection_pending, gmt_modified"),
MESSAGE(
"tenant_id, session_id, item_id, turn_id, item_type, item_role, item_status, "
+ "attributes_json, first_sequence, last_sequence, gmt_create, gmt_modified, revision, "
@@ -38,7 +38,7 @@ public enum ManagedSchemaProjection {
+ "payload_version, request_json, result_json, state, phase, admission_stage, "
+ "delivery_state, session_status_before, receipt_id, claim_owner, claim_generation, "
+ "claim_until, available_at, attempt_count, budget_exempt_attempt, deadline, "
+ "recovery_deadline, execution_mode, verification_request_json, verification_ready, "
+ "recovery_deadline, execution_mode, verification_request_json, is_verification_ready, "
+ "verification_next_at, publication_id, publication_command_id, slot_key, "
+ "execution_key, item_id, policy_version, failure_status, failure_code, gmt_create, "
+ "gmt_modified, completed_at, progress_format, progress_version, progress_stage, "
@@ -52,22 +52,22 @@ public enum ManagedSchemaProjection {
"scope_key, tenant_key, tenant_id, workspace_id, session_id, publication_id, "
+ "execution_key, capture_id, binding_json, binding_digest, token_hash, state, "
+ "expires_at, capture_bytes, producer_bytes, admission_bytes, producer_phase, "
+ "quarantined, active_operation_id, finish_operation_id, finish_predecessor_id, "
+ "is_quarantined, active_operation_id, finish_operation_id, finish_predecessor_id, "
+ "finish_digest, terminal_resource_id, admission_resource_id, receipt_sequence, "
+ "receipt_revision, capture_held_bytes, producer_held_bytes, admission_held_bytes, "
+ "capture_used_bytes, producer_used_bytes, admission_used_bytes, retention_state, "
+ "write_evidence, accepted_complete, collected_at, collected_bytes, "
+ "is_write_evidence, is_accepted_complete, collected_at, collected_bytes, "
+ "released_held_bytes, manifest_resource_key, manifest_sha256, "
+ "seal_manifest_resource_key, seal_manifest_sha256, gmt_create, gmt_modified"),
PUBLIC_EVENT(
"tenant_id, session_id, sequence_id, event_id, turn_id, event_type, data_json, "
+ "terminal, source_key, gmt_create, schema_version, projection_version, item_id, "
+ "content_part_id, stream_kind, stream_id, state, runtime_state, text, truncated, "
+ "artifact_id, capture_id, output_stream_id, first_ordinal, end_ordinal, archived"),
+ "is_terminal, source_key, gmt_create, schema_version, projection_version, item_id, "
+ "content_part_id, stream_kind, stream_id, state, runtime_state, text, is_truncated, "
+ "artifact_id, capture_id, output_stream_id, first_ordinal, end_ordinal, is_archived"),
REQUEST_RECEIPT(
"receipt_key, namespace, tenant_key, tenant_id, scope_kind, scope_key, scope_id, "
+ "idempotency_key, idempotency_digest, request_digest, actor_id, operation, state, "
+ "workspace_bound, session_id, turn_id, agent_id, agent_revision, schedule_id, "
+ "is_workspace_bound, session_id, turn_id, agent_id, agent_revision, schedule_id, "
+ "channel_id, account_generation, semantic_revision, action_id, action_version, "
+ "decision_scope_key, mutation_attempt_sequence, session_status_before, "
+ "result_operation_key, result_json, gmt_create, gmt_modified"),
@@ -85,11 +85,11 @@ public enum ManagedSchemaProjection {
"binding_id, request_key, scope_key, tenant_id, workspace_id, workspace_generation, "
+ "canonical_cwd, capability_digest, isolation_class, isolation_key, provisioner_kind, "
+ "storage_id, storage_alias_key, runtime_generation, binding_state, "
+ "provision_request_id, provision_seed_ciphertext, provision_seeded, "
+ "provision_request_id, provision_seed_ciphertext, is_provision_seeded, "
+ "credential_key_id, resource_handle_version, resource_handle_json, "
+ "loss_evidence_json, stop_evidence_json, runtime_instance_id, runtime_endpoint, "
+ "runtime_lease_id, runtime_epoch, runtime_credential_ciphertext, "
+ "runtime_credential_key_id, attestation_generation, drain_requested, "
+ "runtime_credential_key_id, attestation_generation, is_drain_requested, "
+ "operation_owner, operation_lease_until, operation_generation, record_version, "
+ "last_health_at, last_reconciled_at, last_active_at, drain_receipt_json, "
+ "first_activation_journal_revision"),
@@ -97,7 +97,7 @@ public enum ManagedSchemaProjection {
"scope_key, runtime_session_id, tenant_id, workspace_id, workspace_generation, "
+ "canonical_cwd, capability_digest, isolation_class, harness_session_id, turn_kind, "
+ "binding_id, runtime_generation, session_state, record_version, last_active_at, "
+ "execution_storage_key, execution_exclusive"),
+ "execution_storage_key, is_execution_exclusive"),
RUNTIME_SLOT(
"request_key, tenant_id, workspace_id, workspace_generation, canonical_cwd, "
+ "capability_digest, isolation_class, isolation_key, provisioner_kind, storage_id, "
@@ -105,7 +105,7 @@ public enum ManagedSchemaProjection {
SCHEDULE(
"tenant_id, schedule_id, session_id, workspace_id, actor_id, record_revision, "
+ "definition_revision, definition_digest, goal, cron, timezone, session_mode, "
+ "overlap, catch_up, catch_up_limit, enabled, state, blocked_reason, armed_at, "
+ "overlap, catch_up, catch_up_limit, is_enabled, state, blocked_reason, armed_at, "
+ "watermark_slot, lease_owner, lease_until, fence, gmt_create, gmt_modified, "
+ "gate, gate_last_outcome, gate_last_at, gate_quiet_since_delivery, "
+ "gate_failures, gate_last_error"),
@@ -122,10 +122,10 @@ public enum ManagedSchemaProjection {
+ "tool_profile, creator_actor_key, owner_actor_key, parent_session_id, "
+ "root_session_id, parent_child_run_id, child_depth, agent_definition_digest, "
+ "session_kind, tenant_key, session_key, session_scope_key, title_revision, "
+ "retirement_operation_id, retirement_generation, retired_at, recovery_protected, "
+ "resource_gc_completed, runtime_request_key, csi_guard, model_id, model_revision, "
+ "retirement_operation_id, retirement_generation, retired_at, is_recovery_protected, "
+ "is_resource_gc_completed, runtime_request_key, is_csi_guard, model_id, model_revision, "
+ "model_config_digest, model_config_key_id, model_config_ciphertext, "
+ "selected_approval_mode, approval_revision, plan_enabled, permission_rules_json, public_child_agents_version, harness_instance_id, "
+ "selected_approval_mode, approval_revision, is_plan_enabled, permission_rules_json, public_child_agents_version, harness_instance_id, "
+ "harness_owner_boot_id, harness_placement_epoch, harness_placement_state"),
SESSION_HEAD(
"tenant_id, workspace_id, session_id, storage_version, state, writer_generation, "
@@ -135,8 +135,8 @@ public enum ManagedSchemaProjection {
+ "recovery_detail_code, gmt_create, gmt_modified, activation_id, "
+ "activation_phase, activation_event_epoch, activation_expires_at, "
+ "activation_head_revision, tenant_key, harness_key, harness_session_id, head_kind, "
+ "phase, operation_id, claim_generation, claim_lease_until, wake_pending, "
+ "wake_head_revision, wake_retry_at, wake_scan_pending, cleanup_head_revision"),
+ "phase, operation_id, claim_generation, claim_lease_until, is_wake_pending, "
+ "wake_head_revision, wake_retry_at, is_wake_scan_pending, cleanup_head_revision"),
SESSION_JOURNAL_TX(
"tenant_id, workspace_id, session_id, journal_revision, command_key_hash, "
+ "transaction_id, operation, command_id, content_digest, first_sequence, "
@@ -168,17 +168,17 @@ public enum ManagedSchemaProjection {
"execution_call_id_hash, execution_call_id, idempotency_key_hash, idempotency_key, "
+ "binding_id, runtime_generation, harness_session_id, runtime_session_id, "
+ "runtime_session_key, turn_id, tool_call_id, request_digest, reference_json, "
+ "execution_state, execution_status, result_json, last_sequence, cancel_requested, "
+ "execution_state, execution_status, result_json, last_sequence, is_cancel_requested, "
+ "dispatch_owner, dispatch_lease_until, dispatch_generation, record_version, "
+ "settled_at, abandoned_at, loss_evidence_id, authorized_dispatch_generation, "
+ "authorized_binding_version, native_authorization_json"),
TURN(
"tenant_id, session_id, turn_id, prompt_id, input_json, payload_digest, status, "
+ "submission_attempted, harness_event_epoch, harness_last_event_id, dispatch_owner, "
+ "is_submission_attempted, harness_event_epoch, harness_last_event_id, dispatch_owner, "
+ "dispatch_lease_until, error_code, error_message, gmt_create, gmt_modified, "
+ "completed_at, version, retry_count, consecutive_failures, "
+ "budget_exempt_failures, retry_after, model_id, model_revision, "
+ "approval_mode, approval_revision, plan_enabled, permission_rules_json");
+ "approval_mode, approval_revision, is_plan_enabled, permission_rules_json");
private final String columns;
@@ -15,12 +15,29 @@ import java.util.Set;
/** Reads raw SQL rows while decoding only declared UTF-8 identity columns. */
public final class ManagedSchemaRows {
private static final Set<String> BOOLEANS = Set.of(
"recovery_protected", "resource_gc_completed", "submission_attempted",
"projection_pending", "terminal", "truncated",
"archived", "quarantined", "write_evidence", "accepted_complete",
"workspace_bound", "verification_ready", "is_default", "provision_seeded",
"drain_requested", "cancel_requested", "enabled", "csi_guard",
"execution_exclusive");
"is_accepted_complete",
"is_archived",
"is_cancel_requested",
"is_csi_guard",
"is_default",
"is_drain_requested",
"is_enabled",
"is_execution_exclusive",
"is_paused",
"is_plan_enabled",
"is_projection_pending",
"is_provision_seeded",
"is_quarantined",
"is_recovery_protected",
"is_resource_gc_completed",
"is_submission_attempted",
"is_terminal",
"is_truncated",
"is_verification_ready",
"is_wake_pending",
"is_wake_scan_pending",
"is_workspace_bound",
"is_write_evidence");
private static final Set<String> IDENTITIES =
Set.of(
"tenant_id",
@@ -144,7 +161,7 @@ public final class ManagedSchemaRows {
} else if (value instanceof java.time.LocalDateTime timestamp) {
value = java.sql.Timestamp.valueOf(timestamp);
}
if ("csi_guard".equals(label) && value instanceof Number number) {
if ("is_csi_guard".equals(label) && value instanceof Number number) {
value = number.longValue() != 0;
}
row.put(label, value);
@@ -61,7 +61,7 @@ public final class JdbcCsiFilesRetirementGuard {
throw unavailable();
}
var original = new Original(request(row), com.alibaba.qwen.code.runtimebroker.managedschema.ManagedSchemaRows.identity(row, "binding_id"), row.getLong("runtime_generation"),
RuntimeBindingRecord.State.valueOf(row.getString("binding_state")), row.getBoolean("drain_requested"),
RuntimeBindingRecord.State.valueOf(row.getString("binding_state")), row.getBoolean("is_drain_requested"),
row.getLong("record_version"), row.getObject("first_activation_journal_revision", Long.class));
if (!binding.getBindingId().equals(original.bindingId()) || !binding.getRequest().equals(original.request())
|| binding.getGeneration() != original.generation() || binding.getState() != original.state()
@@ -339,7 +339,7 @@ public final class JdbcCsiFilesRetirementGuard {
.identity(rows, "binding_id"),
rows.getLong("runtime_generation"),
RuntimeBindingRecord.State.valueOf(rows.getString("binding_state")),
rows.getBoolean("drain_requested"), rows.getLong("record_version"),
rows.getBoolean("is_drain_requested"), rows.getLong("record_version"),
rows.getObject("first_activation_journal_revision", Long.class));
if (bindings.size() < 2 || isProfile(original.request().getScope())
&& bindings.stream().noneMatch(binding ->
@@ -421,12 +421,12 @@ public final class JdbcCsiFilesRetirementGuard {
}
private static Pin readPin(Connection connection, String tenantId, String sessionId) throws SQLException {
// By primary key: on an existing root this locks that record alone.
// Through ma_session_csi_guard_idx, an unpinned root left a gap lock
// By unique business key: on an existing root this locks that record alone.
// Through idx_ma_session_csi_guard, an unpinned root left a gap lock
// that spans other tenants' keys, so their first writers could not
// insert their own roots (#13996).
try (PreparedStatement statement = statement(connection,
"SELECT csi_guard FROM ma_session WHERE tenant_id = ? AND session_id = ? FOR"
"SELECT is_csi_guard FROM ma_session WHERE tenant_id = ? AND session_id = ? FOR"
+ " UPDATE")) {
JdbcRepositorySupport.setIdentity(statement, 1, tenantId);
JdbcRepositorySupport.setIdentity(statement, 2, sessionId);
@@ -78,7 +78,7 @@ public final class JdbcRuntimeBindingRepository
"runtime_credential_ciphertext",
"runtime_credential_key_id",
"attestation_generation",
"drain_requested",
"is_drain_requested",
"operation_owner",
"operation_lease_until",
"operation_generation",
@@ -202,7 +202,7 @@ public final class JdbcRuntimeBindingRepository
}
}
try (var clear = connection.prepareStatement("UPDATE ma_runtime_session SET execution_storage_key = NULL,"
+ " execution_exclusive = FALSE WHERE execution_storage_key = ? AND binding_id = ?"
+ " is_execution_exclusive = FALSE WHERE execution_storage_key = ? AND binding_id = ?"
+ " AND runtime_generation = ? AND runtime_session_id = ?")) {
clear.setString(1, key);
JdbcRepositorySupport.setIdentity(clear, 2, session.getBindingId());
@@ -2334,7 +2334,7 @@ public final class JdbcRuntimeBindingRepository
"UPDATE ma_runtime_binding SET binding_state = ?, resource_handle_version = ?,"
+ " resource_handle_json = ?, runtime_instance_id = ?, runtime_endpoint = ?,"
+ " runtime_lease_id = ?, runtime_epoch = ?, runtime_credential_ciphertext = ?,"
+ " runtime_credential_key_id = ?, attestation_generation = ?, drain_requested"
+ " runtime_credential_key_id = ?, attestation_generation = ?, is_drain_requested"
+ " = ?, operation_owner = ?, operation_lease_until = ?, operation_generation ="
+ " ?, record_version = ?, last_health_at = ?, last_reconciled_at = ?,"
+ " last_active_at = ?, loss_evidence_json = ?, stop_evidence_json = ?,"
@@ -2496,7 +2496,7 @@ public final class JdbcRuntimeBindingRepository
RuntimeBindingRecord.State.valueOf(
result.getString("binding_state")),
lease, handle, result.getLong("attestation_generation"),
result.getBoolean("drain_requested"),
result.getBoolean("is_drain_requested"),
result.getString("operation_owner"),
JdbcRepositorySupport.getInstant(result,
"operation_lease_until"),
@@ -72,7 +72,7 @@ public final class JdbcRuntimeSessionRepository
JdbcRepositorySupport.setIdentity(statement, 1, original.request().getScope().getTenantId());
JdbcRepositorySupport.setIdentity(statement, 2, original.request().getIsolationKey());
try (var row = statement.executeQuery()) {
if (!row.next() || !row.getBoolean("csi_guard")) {
if (!row.next() || !row.getBoolean("is_csi_guard")) {
throw new IllegalArgumentException("Original managed Session is required");
}
context = new com.alibaba.qwen.code.runtimebroker.managedworkspace.ContextBinding(com.alibaba.qwen.code.runtimebroker.managedschema.ManagedSchemaRows.identity(row, "tenant_id"),
@@ -37,7 +37,7 @@ public final class JdbcToolExecutionRepository
"runtime_session_id", "runtime_session_key", "turn_id",
"tool_call_id", "request_digest", "reference_json",
"execution_state", "execution_status", "result_json",
"last_sequence", "cancel_requested", "dispatch_owner",
"last_sequence", "is_cancel_requested", "dispatch_owner",
"dispatch_lease_until", "dispatch_generation", "record_version",
"settled_at", "abandoned_at", "loss_evidence_id",
"authorized_dispatch_generation", "authorized_binding_version");
@@ -1082,7 +1082,7 @@ public final class JdbcToolExecutionRepository
ToolExecutionRecord record) throws SQLException {
String sql = "UPDATE ma_tool_execution SET execution_state = ?, "
+ "execution_status = ?, result_json = ?, "
+ "last_sequence = ?, cancel_requested = ?, "
+ "last_sequence = ?, is_cancel_requested = ?, "
+ "dispatch_owner = ?, dispatch_lease_until = ?, "
+ "dispatch_generation = ?, record_version = ?, "
+ "settled_at = ?, abandoned_at = ?, loss_evidence_id = ?, "
@@ -1183,7 +1183,7 @@ public final class JdbcToolExecutionRepository
result.getString("execution_status"),
fromJson(result.getString("result_json")),
result.getLong("last_sequence"),
result.getBoolean("cancel_requested"),
result.getBoolean("is_cancel_requested"),
result.getString("dispatch_owner"),
JdbcRepositorySupport.getInstant(result,
"dispatch_lease_until"),
@@ -688,7 +688,7 @@ class ChildResultRelayStoreTest {
TENANT, session);
jdbc.update("INSERT INTO ma_turn (tenant_id, session_id,"
+ " turn_id, prompt_id, input_json, payload_digest,"
+ " status, submission_attempted, gmt_create,"
+ " status, is_submission_attempted, gmt_create,"
+ " gmt_modified, completed_at, version)"
+ " VALUES (?, ?, 'turn-1', 'prompt-1', '[]', 'd',"
+ " 'COMPLETED', TRUE, 1, 2, 2, 1)", TENANT, session);
@@ -702,7 +702,7 @@ class ChildResultRelayStoreTest {
// never dispatch proof (R23's cascade producer).
jdbc.update("INSERT INTO ma_turn (tenant_id, session_id,"
+ " turn_id, prompt_id, input_json, payload_digest,"
+ " status, submission_attempted, gmt_create,"
+ " status, is_submission_attempted, gmt_create,"
+ " gmt_modified, completed_at, version)"
+ " VALUES (?, ?, 'turn-pre', 'prompt-2', '[]', 'd',"
+ " 'FAILED', FALSE, 3, 4, 4, 1)",
@@ -958,7 +958,7 @@ class EventTransportBrokerGate {
private EventRecord storedPublicEvent(String session, long sequence,
String type) {
EventRecord event = publicEvent(session, sequence, type);
jdbc.update("INSERT INTO ma_public_event (tenant_id, session_id, sequence_id, event_id, turn_id, event_type, data_json, terminal, source_key, gmt_create) VALUES (?, ?, ?, ?, ?, ?, '{}', FALSE, NULL, ?)", TENANT, session, sequence,
jdbc.update("INSERT INTO ma_public_event (tenant_id, session_id, sequence_id, event_id, turn_id, event_type, data_json, is_terminal, source_key, gmt_create) VALUES (?, ?, ?, ?, ?, ?, '{}', FALSE, NULL, ?)", TENANT, session, sequence,
event.eventId(), event.turnId(), type, event.createdAt());
jdbc.update("UPDATE ma_event_stream SET last_sequence = ? WHERE"
+ " tenant_id = ? AND session_id = ? AND stream_kind ="
@@ -498,7 +498,7 @@ class HostedHookMessageDisplayReloadIT {
+ destination.toAbsolutePath());
json.writeValue(destination.resolve("events.json").toFile(),
jdbc.queryForList("SELECT session_id, turn_id,"
+ " event_type, terminal FROM ma_public_event"
+ " event_type, is_terminal FROM ma_public_event"
+ " WHERE tenant_id = ? ORDER BY sequence_id",
tenant));
json.writeValue(destination.resolve("model-requests.json")
@@ -517,7 +517,7 @@ class HostedHookStreamGapIT {
+ " CAST(turn_id AS CHAR) AS turn_id,"
+ " CAST(item_id AS CHAR) AS item_id,"
+ " CAST(content_part_id AS CHAR) AS content_part_id,"
+ " event_type, gmt_create, data_json, terminal"
+ " event_type, gmt_create, data_json, is_terminal"
+ " FROM ma_public_event WHERE tenant_id = ? AND"
+ " session_id = ? AND stream_kind = 'SESSION' AND"
+ " stream_id = X'' ORDER BY sequence_id", tenant, session);
@@ -543,7 +543,7 @@ class HostedHookStreamGapIT {
fields.put("type", row.get("event_type"));
fields.put("created_at", web ? millis : millis / 1000);
fields.put("data", json.readTree(row.get("data_json").toString()));
Object terminal = row.get("terminal");
Object terminal = row.get("is_terminal");
fields.put("terminal", terminal instanceof Boolean flag ? flag
: ((Number) terminal).intValue() != 0);
ObjectNode node = json.createObjectNode();
@@ -799,7 +799,7 @@ class HostedHookStreamGapIT {
.toList());
json.writeValue(destination.resolve("events.json").toFile(),
jdbc.queryForList("SELECT session_id, turn_id,"
+ " event_type, terminal FROM ma_public_event"
+ " event_type, is_terminal FROM ma_public_event"
+ " WHERE tenant_id = ? ORDER BY sequence_id",
tenant));
json.writeValue(destination.resolve("model-requests.json")
@@ -657,7 +657,7 @@ class HostedMcpStreamGapIT {
+ " CAST(turn_id AS CHAR) AS turn_id,"
+ " CAST(item_id AS CHAR) AS item_id,"
+ " CAST(content_part_id AS CHAR) AS content_part_id,"
+ " event_type, gmt_create, data_json, terminal"
+ " event_type, gmt_create, data_json, is_terminal"
+ " FROM ma_public_event WHERE tenant_id = ? AND"
+ " session_id = ? AND stream_kind = 'SESSION' AND"
+ " stream_id = X'' ORDER BY sequence_id", tenant, session);
@@ -683,7 +683,7 @@ class HostedMcpStreamGapIT {
fields.put("type", row.get("event_type"));
fields.put("created_at", web ? millis : millis / 1000);
fields.put("data", json.readTree(row.get("data_json").toString()));
Object terminal = row.get("terminal");
Object terminal = row.get("is_terminal");
fields.put("terminal", terminal instanceof Boolean flag ? flag
: ((Number) terminal).intValue() != 0);
ObjectNode node = json.createObjectNode();
@@ -922,7 +922,7 @@ class HostedMcpStreamGapIT {
.toList());
json.writeValue(destination.resolve("events.json").toFile(),
jdbc.queryForList("SELECT session_id, turn_id,"
+ " event_type, terminal FROM ma_public_event"
+ " event_type, is_terminal FROM ma_public_event"
+ " WHERE tenant_id = ? ORDER BY sequence_id",
tenant));
json.writeValue(destination.resolve("model-requests.json")
@@ -198,7 +198,7 @@ final class HostedMonitorRunProbe implements AutoCloseable {
+ " binding_state, runtime_generation,"
+ " loss_evidence_json IS NOT NULL AS loss_evidence,"
+ " stop_evidence_json IS NOT NULL AS stop_evidence,"
+ " drain_requested FROM ma_runtime_binding WHERE"
+ " is_drain_requested FROM ma_runtime_binding WHERE"
+ " tenant_id = ? AND isolation_key = ? ORDER BY"
+ " runtime_generation", tenant, sessionId);
var slots = new java.util.ArrayList<Map<String, Object>>();
@@ -11,6 +11,7 @@ import org.junit.jupiter.params.provider.ValueSource;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
@@ -86,12 +87,20 @@ class HostedMySqlIsolationExtensionTest {
throws Throwable {
var connection = mock(Connection.class);
var metadata = mock(DatabaseMetaData.class);
var modeQuery = mock(PreparedStatement.class);
var modes = mock(ResultSet.class);
var tables = mock(Statement.class);
var cleanup = mock(Statement.class);
var rows = mock(ResultSet.class);
when(connection.getMetaData()).thenReturn(metadata);
when(metadata.getDatabaseProductName()).thenReturn("MySQL");
when(connection.getCatalog()).thenReturn("hosted_isolation_test");
when(connection.prepareStatement("SELECT @@GLOBAL.sql_mode, @@SESSION.sql_mode"))
.thenReturn(modeQuery);
when(modeQuery.executeQuery()).thenReturn(modes);
when(modes.next()).thenReturn(true, false);
when(modes.getString(1)).thenReturn("STRICT_TRANS_TABLES");
when(modes.getString(2)).thenReturn("STRICT_TRANS_TABLES");
when(connection.createStatement()).thenReturn(tables, cleanup);
when(tables.executeQuery(anyString())).thenReturn(rows);
when(rows.next()).thenReturn(true, true, false);
@@ -130,7 +139,9 @@ class HostedMySqlIsolationExtensionTest {
}
});
var order = inOrder(rows, tables, cleanup, connection);
var order = inOrder(modes, modeQuery, rows, tables, cleanup, connection);
order.verify(modes).close();
order.verify(modeQuery).close();
order.verify(rows).close();
order.verify(tables).close();
order.verify(cleanup).execute("SET FOREIGN_KEY_CHECKS = 0");
@@ -673,7 +673,7 @@ class HostedProcessCrashIT {
.containsEntry("runtime_session_id", execution.get("runtime_session_id"))
.containsEntry("binding_id", execution.get("binding_id"))
.containsEntry("runtime_generation", execution.get("runtime_generation"))
.containsEntry("session_state", "READY").containsEntry("execution_exclusive", false);
.containsEntry("session_state", "READY").containsEntry("is_execution_exclusive", false);
assertThat(((Number) member.get("runtime_generation")).longValue()).isEqualTo(1);
assertThat(jdbc.queryForObject("SELECT COUNT(*) FROM ma_runtime_binding b"
+ " JOIN ma_runtime_session rs ON rs.binding_id=b.binding_id AND rs.runtime_generation=b.runtime_generation"
@@ -682,7 +682,7 @@ class HostedProcessCrashIT {
+ " WHERE rs.scope_key=? AND rs.runtime_session_id=? AND b.scope_key=rs.scope_key"
+ " AND b.tenant_id=rs.tenant_id AND b.workspace_id=rs.workspace_id AND b.workspace_generation=rs.workspace_generation"
+ " AND b.canonical_cwd=rs.canonical_cwd AND b.capability_digest=rs.capability_digest AND b.isolation_class=rs.isolation_class"
+ " AND b.provisioner_kind='local-process' AND b.binding_state='READY' AND b.drain_requested=FALSE"
+ " AND b.provisioner_kind='local-process' AND b.binding_state='READY' AND b.is_drain_requested=FALSE"
+ " AND s.workspace_id=b.workspace_id AND s.workspace_generation=b.workspace_generation AND s.workspace_storage_id=b.storage_id"
+ " AND st.physical_key=rs.execution_storage_key AND st.registration_state='REGISTERED' AND st.storage_kind='LOCAL'"
+ " AND st.registration_revision>0 AND s.workspace_config_ref=? AND s.workspace_policy_ref=? AND s.context_config_ref=?",
@@ -246,7 +246,7 @@ final class HostedProviderMediaProbe implements AutoCloseable {
tenant, storageId);
assertThat(physical).isNotBlank();
var member = jdbc.queryForMap("SELECT binding_id, runtime_generation, session_state,"
+ " execution_storage_key, execution_exclusive FROM ma_runtime_session"
+ " execution_storage_key, is_execution_exclusive FROM ma_runtime_session"
+ " WHERE tenant_id = ? AND harness_session_id = ? AND runtime_session_id = ?",
tenant, harness, runtimeId);
boolean released = phase.equals("released") || phase.equals("restarted");
@@ -254,7 +254,7 @@ final class HostedProviderMediaProbe implements AutoCloseable {
assertThat(member.get("runtime_generation")).as("original runtime generation").isEqualTo(row.get("runtime_generation"));
assertThat(member.get("execution_storage_key")).as("physical execution membership")
.isEqualTo(released ? null : physical);
assertThat(member.get("execution_exclusive")).as("shared execution membership").isEqualTo(false);
assertThat(member.get("is_execution_exclusive")).as("shared execution membership").isEqualTo(false);
assertThat(member.get("session_state")).isEqualTo(released ? "RELEASED" : "READY");
if (phase.equals("restarted")) {
assertThat(restarted).isNotNull();
@@ -131,7 +131,7 @@ class HostedProviderMediaProbeTest {
jdbc.update("INSERT INTO ma_tool_execution (execution_call_id_hash, execution_call_id,"
+ " idempotency_key_hash, idempotency_key, binding_id, runtime_generation, harness_session_id,"
+ " runtime_session_id, runtime_session_key, turn_id, tool_call_id, request_digest,"
+ " reference_json, execution_state, last_sequence, cancel_requested, dispatch_generation,"
+ " reference_json, execution_state, last_sequence, is_cancel_requested, dispatch_generation,"
+ " record_version) VALUES (?, 'execute', ?, 'key', 'binding', 1, 'harness', 'runtime', ?,"
+ " 'turn', 'call', 'digest', ?, 'PREPARED', 0, FALSE, 0, 1)",
"b".repeat(64), "c".repeat(64), "d".repeat(64), reference.toString());
@@ -170,10 +170,10 @@ class HostedProviderMediaProbeTest {
jdbc.update("UPDATE ma_runtime_session SET binding_id='binding', runtime_generation=2");
assertThatThrownBy(() -> ReflectionTestUtils.invokeMethod(probe, "check", session, "prepared", fields))
.isInstanceOf(AssertionError.class).hasMessageContaining("original runtime generation");
jdbc.update("UPDATE ma_runtime_session SET runtime_generation=1, execution_exclusive=TRUE");
jdbc.update("UPDATE ma_runtime_session SET runtime_generation=1, is_execution_exclusive=TRUE");
assertThatThrownBy(() -> ReflectionTestUtils.invokeMethod(probe, "check", session, "prepared", fields))
.isInstanceOf(AssertionError.class).hasMessageContaining("shared execution membership");
jdbc.update("UPDATE ma_runtime_session SET execution_exclusive=FALSE");
jdbc.update("UPDATE ma_runtime_session SET is_execution_exclusive=FALSE");
jdbc.update("UPDATE ma_tool_execution SET execution_state='SETTLED', execution_status='success',"
+ " dispatch_generation=1, result_json='{}'");
ReflectionTestUtils.setField(probe, "dispatches", Map.of("runtime", 1));
@@ -1202,7 +1202,7 @@ class HostedPublicWorkspaceIT {
JsonNode events = request("GET", "/v1/agents/sessions/" + session + "/events", null, null, "actor", 200);
assertThat(events.toString()).contains("G0_DONE");
assertThat(jdbc.queryForObject("SELECT COUNT(*) FROM ma_public_event"
+ " WHERE tenant_id = ? AND session_id = ? AND terminal = TRUE", Integer.class, tenant, session))
+ " WHERE tenant_id = ? AND session_id = ? AND is_terminal = TRUE", Integer.class, tenant, session))
.isEqualTo(1);
int requests = modelRequests.size();
long executions = jdbc.queryForObject("SELECT COUNT(*) FROM ma_tool_execution WHERE harness_session_id = ?",
@@ -1491,7 +1491,7 @@ class HostedSessionRelayFaultGatesIT {
+ " CAST(turn_id AS CHAR) AS turn_id,"
+ " CAST(item_id AS CHAR) AS item_id,"
+ " CAST(content_part_id AS CHAR) AS content_part_id,"
+ " event_type, gmt_create, data_json, terminal"
+ " event_type, gmt_create, data_json, is_terminal"
+ " FROM ma_public_event WHERE tenant_id = ? AND"
+ " session_id = ? AND stream_kind = 'SESSION' AND"
+ " stream_id = X'' ORDER BY sequence_id",
@@ -1517,7 +1517,7 @@ class HostedSessionRelayFaultGatesIT {
fields.put("type", row.get("event_type"));
fields.put("created_at", web ? created : created / 1000);
fields.put("data", json.readTree(row.get("data_json").toString()));
Object terminal = row.get("terminal");
Object terminal = row.get("is_terminal");
fields.put("terminal", terminal instanceof Boolean flag ? flag
: ((Number) terminal).intValue() != 0);
ObjectNode node = json.createObjectNode();
@@ -1536,7 +1536,7 @@ class HostedSessionRelayFaultGatesIT {
"SELECT COUNT(*) FROM ma_public_event"
+ " WHERE tenant_id = ? AND"
+ " session_id = ? AND turn_id = ?"
+ " AND terminal",
+ " AND is_terminal",
Integer.class, tenant, session, turn))
.isEqualTo(1));
}
@@ -442,14 +442,14 @@ class HostedShellLifecycleRecoveryIT {
/** The durable blocker the collectors persisted; survives a lost Spring log. */
private Map<String, Object> collectionState() {
var state = new LinkedHashMap<String, Object>();
state.put("capture", jdbc.queryForList("SELECT retention_state, collected_at, write_evidence,"
+ " accepted_complete, quarantined, producer_phase FROM ma_output_capture"
state.put("capture", jdbc.queryForList("SELECT retention_state, collected_at, is_write_evidence,"
+ " is_accepted_complete, is_quarantined, producer_phase FROM ma_output_capture"
+ " WHERE tenant_id = ? AND session_id = ?", tenant, session));
state.put("operations", jdbc.queryForList("SELECT operation_kind, state, phase, failure_code,"
+ " available_at FROM ma_operation WHERE operation_kind IN ('CAPTURE_GC',"
+ " 'SESSION_RESOURCE_GC') AND tenant_id = ? AND session_id = ?", tenant, session));
state.put("retirement", jdbc.queryForList("SELECT retired_at, recovery_protected,"
+ " resource_gc_completed FROM ma_session WHERE tenant_id = ? AND session_id = ?",
state.put("retirement", jdbc.queryForList("SELECT retired_at, is_recovery_protected,"
+ " is_resource_gc_completed FROM ma_session WHERE tenant_id = ? AND session_id = ?",
tenant, session));
state.put("liveReadLeases", jdbc.queryForObject("SELECT COUNT(*) FROM ma_read_lease"
+ " WHERE tenant_key = ? AND session_key = ? AND expires_at > ?", Long.class,
@@ -136,7 +136,7 @@ final class HostedSseGapProbe implements AutoCloseable {
}
assertThat(execution.get("execution_call_id")).isEqualTo(executionId);
String storage = "storage-0";
var member = jdbc.queryForMap("SELECT m.execution_storage_key, m.execution_exclusive, s.physical_key"
var member = jdbc.queryForMap("SELECT m.execution_storage_key, m.is_execution_exclusive, s.physical_key"
+ " FROM ma_runtime_session m JOIN ma_storage s ON s.tenant_id = m.tenant_id"
+ " WHERE s.alias_key = ? AND s.tenant_id = ? AND s.storage_id = ?"
+ " AND m.harness_session_id = ? AND m.binding_id = ?"
@@ -145,7 +145,7 @@ final class HostedSseGapProbe implements AutoCloseable {
tenant, storage, session, execution.get("binding_id"), execution.get("runtime_generation"), promptId);
assertThat(member.get("physical_key")).isNotNull();
assertThat(member.get("execution_storage_key")).isEqualTo(finished ? null : member.get("physical_key"));
assertThat(member.get("execution_exclusive")).isEqualTo(false);
assertThat(member.get("is_execution_exclusive")).isEqualTo(false);
assertThat(execution.get("turn_id")).isEqualTo(promptId);
assertThat(execution.get("runtime_session_id")).isEqualTo(promptId);
assertThat(execution.get("execution_state")).isEqualTo(finished ? "SETTLED" : "EXECUTING");
@@ -1127,7 +1127,7 @@ class HostedWorkflowRelayFaultGatesIT {
+ " CAST(turn_id AS CHAR) AS turn_id,"
+ " CAST(item_id AS CHAR) AS item_id,"
+ " CAST(content_part_id AS CHAR) AS content_part_id,"
+ " event_type, gmt_create, data_json, terminal"
+ " event_type, gmt_create, data_json, is_terminal"
+ " FROM ma_public_event WHERE tenant_id = ? AND"
+ " session_id = ? AND stream_kind = 'SESSION' AND"
+ " stream_id = X'' ORDER BY sequence_id",
@@ -1153,7 +1153,7 @@ class HostedWorkflowRelayFaultGatesIT {
fields.put("type", row.get("event_type"));
fields.put("created_at", web ? created : created / 1000);
fields.put("data", json.readTree(row.get("data_json").toString()));
Object terminal = row.get("terminal");
Object terminal = row.get("is_terminal");
fields.put("terminal", terminal instanceof Boolean flag ? flag
: ((Number) terminal).intValue() != 0);
ObjectNode node = json.createObjectNode();
@@ -1172,7 +1172,7 @@ class HostedWorkflowRelayFaultGatesIT {
"SELECT COUNT(*) FROM ma_public_event"
+ " WHERE tenant_id = ? AND"
+ " session_id = ? AND turn_id = ?"
+ " AND terminal",
+ " AND is_terminal",
Integer.class, tenant, session, turn))
.isEqualTo(1));
}
@@ -525,7 +525,7 @@ class HostedWorkspaceToolTurnIT {
.isEqualTo("中文😀é\\ud800");
for (String sessionId : List.of(sessions.get(index).get("sessionId").toString(), secondarySessionId)) {
var publications = jdbc.queryForList("SELECT state, producer_phase,"
+ " CASE WHEN accepted_complete THEN 1 ELSE 0 END AS complete"
+ " CASE WHEN is_accepted_complete THEN 1 ELSE 0 END AS complete"
+ " FROM ma_output_capture WHERE tenant_id = ? AND session_id = ?", tenant, sessionId);
if (cases.contains("o2")) {
assertThat(publications).hasSize(1);
@@ -684,7 +684,7 @@ class HostedWorkspaceToolTurnIT {
tenant, storageId);
assertThat(physical).isNotBlank();
Map<String, Object> member = jdbc.queryForMap("SELECT binding_id, runtime_generation, runtime_session_id,"
+ " session_state, execution_storage_key, execution_exclusive FROM ma_runtime_session"
+ " session_state, execution_storage_key, is_execution_exclusive FROM ma_runtime_session"
+ " WHERE tenant_id = ? AND harness_session_id = ? AND runtime_session_id = ?",
tenant, session.get("sessionId"), report.path("promptId").asText());
boolean released = storeFaults ? fault.equals("turn-reply") : List.of("prepare", "start", "release").contains(fault);
@@ -698,7 +698,7 @@ class HostedWorkspaceToolTurnIT {
boolean retained = !storeFaults && fault.equals("prepare-twice");
assertThat(member.get("execution_storage_key")).as(fault + " execution membership")
.isEqualTo(retained ? physical : null);
assertThat(member.get("execution_exclusive")).isEqualTo(false);
assertThat(member.get("is_execution_exclusive")).isEqualTo(false);
if (retained) {
assertThat(member.get("binding_id")).isEqualTo(executions.getFirst().get("binding_id"));
assertThat(member.get("runtime_generation")).isEqualTo(executions.getFirst().get("runtime_generation"));
@@ -111,11 +111,11 @@ class ManagedAgentDefinitionAdmissionTest {
assertThatThrownBy(() -> transactions.execute(status -> selected.requireMcpManagement(tenant, "stranger", id, null)))
.isInstanceOfSatisfying(ManagedAgentException.class,
error -> assertThat(error.getCode()).isEqualTo("session_not_found"));
jdbc.update("UPDATE ma_session SET plan_enabled=TRUE, selected_approval_mode='default', approval_revision=1 WHERE tenant_id=? AND session_id=?", tenant, id);
jdbc.update("UPDATE ma_session SET is_plan_enabled=TRUE, selected_approval_mode='default', approval_revision=1 WHERE tenant_id=? AND session_id=?", tenant, id);
assertThatThrownBy(() -> transactions.execute(status -> selected.requireMcpManagement(tenant, "actor", id, "operation")))
.isInstanceOfSatisfying(ManagedAgentException.class,
error -> assertThat(error.getCode()).isEqualTo("unsupported_feature"));
jdbc.update("UPDATE ma_session SET plan_enabled=FALSE WHERE tenant_id=? AND session_id=?", tenant, id);
jdbc.update("UPDATE ma_session SET is_plan_enabled=FALSE WHERE tenant_id=? AND session_id=?", tenant, id);
jdbc.update("INSERT INTO ma_turn (tenant_id, session_id, turn_id, prompt_id, input_json, payload_digest, status, gmt_create, gmt_modified)"
+ " VALUES (?, ?, 'turn', 'prompt', '[]', 'digest', 'RUNNING', 1, 1)", tenant, id);
var readable = transactions.execute(status -> selected.requireMcpManagement(tenant, "actor", id, null));
@@ -1087,7 +1087,7 @@ class ManagedAgentMySqlIT {
scopeKey,
sha256("command-7")))
.extracting(row -> row.get("key"))
.containsExactly("ix_ma_record_operation");
.containsExactly("idx_ma_record_operation");
}
@Test
@@ -1932,19 +1932,19 @@ class ManagedAgentMySqlIT {
for (Object[] lookup :
List.of(
new Object[] {
"uq_ma_hook_once", "hook_once_key_hash = ?", sha256("once-7")
"uk_ma_hook_once", "hook_once_key_hash = ?", sha256("once-7")
},
new Object[] {
"uq_ma_hook_occurrence",
"uk_ma_hook_occurrence",
"hook_occurrence_hash = ? AND hook_ordinal = ?",
sha256("occurrence-7"),
1
},
new Object[] {
"uq_ma_hook_occurrence", "hook_occurrence_hash = ?", sha256("occurrence-7")
"uk_ma_hook_occurrence", "hook_occurrence_hash = ?", sha256("occurrence-7")
},
new Object[] {
"ix_ma_hook_definition",
"idx_ma_hook_definition",
"hook_definition_hash = ?",
sha256("catalog-1\u00001")
})) {
@@ -483,10 +483,10 @@ class ManagedApprovalChangeTest {
var created = transaction().execute(status -> service.createWorkspaceSession(tenant, "actor", "legacy-create",
definition.agentId(), null, null, null, input, new WorkspaceSelection("ws", ".")));
session = created.sessionId();
jdbc.update("UPDATE ma_turn SET status='COMPLETED',approval_mode=NULL,approval_revision=NULL,plan_enabled=NULL WHERE tenant_id=? AND session_id=?",
jdbc.update("UPDATE ma_turn SET status='COMPLETED',approval_mode=NULL,approval_revision=NULL,is_plan_enabled=NULL WHERE tenant_id=? AND session_id=?",
tenant, session);
var submitted = transaction().execute(status -> service.submitTurn(tenant, "actor", "legacy-submit", session, input));
jdbc.update("UPDATE ma_turn SET status='COMPLETED',approval_mode=NULL,approval_revision=NULL,plan_enabled=NULL WHERE tenant_id=? AND session_id=?",
jdbc.update("UPDATE ma_turn SET status='COMPLETED',approval_mode=NULL,approval_revision=NULL,is_plan_enabled=NULL WHERE tenant_id=? AND session_id=?",
tenant, session);
change("actor", "new-policy", "yolo", 0);
assertThat(transaction().execute(status -> service.createWorkspaceSession(tenant, "actor", "legacy-create",
@@ -508,7 +508,7 @@ class ManagedApprovalChangeTest {
var admitted = transaction().execute(status -> store.insertTurnCommand(tenant, "SUBMIT_TURN", "legacy", "legacy-digest",
session, input, SubmitHarnessTurn.computePayloadDigest(input)));
var turn = store.findTurn(tenant, session, admitted.turnId()).orElseThrow();
jdbc.update("UPDATE ma_turn SET approval_mode=NULL, approval_revision=NULL, plan_enabled=NULL, status='COMPLETED'"
jdbc.update("UPDATE ma_turn SET approval_mode=NULL, approval_revision=NULL, is_plan_enabled=NULL, status='COMPLETED'"
+ " WHERE tenant_id=? AND turn_id=?", tenant, admitted.turnId());
assertThat(store.findTurnApprovalSelection(tenant, session, turn.promptId()))
.isNull();
@@ -674,13 +674,13 @@ class ManagedArtifactApiIntegrationTest {
.andExpect(jsonPath("$.access.can_read_content").value(false));
mvc.perform(asReader(get(ROOT + "/artifacts"))).andExpect(status().isOk()).andExpect(header().string("Cache-Control", "private, no-store"))
.andExpect(jsonPath("$.data").isEmpty());
assertThat(fixture.jdbc().queryForObject("SELECT quarantined FROM ma_output_capture", Boolean.class))
assertThat(fixture.jdbc().queryForObject("SELECT is_quarantined FROM ma_output_capture", Boolean.class))
.isTrue();
}
@Test
void deletionAndQuarantineHideContentWithoutChangingExecutionFacts() throws Exception {
fixture.jdbc().update("UPDATE ma_output_capture SET quarantined = TRUE WHERE publication_id = X'7075622d31'");
fixture.jdbc().update("UPDATE ma_output_capture SET is_quarantined = TRUE WHERE publication_id = X'7075622d31'");
mvc.perform(asReader(get(ROOT + "/artifacts/" + stdout.path("id").asText())))
.andExpect(status().isOk()).andExpect(jsonPath("$.artifact.availability").value("unavailable"))
.andExpect(jsonPath("$.access.can_read_content").value(false));
@@ -214,7 +214,7 @@ class ManagedHookAdmissionIndexTest {
event -> {
assertThat(event.getLevel()).isEqualTo(Level.WARN);
assertThat(event.getThrowableProxy().getMessage())
.containsIgnoringCase("uq_ma_hook_once");
.containsIgnoringCase("uk_ma_hook_once");
});
assertThat(
jdbc.queryForObject(
@@ -121,7 +121,7 @@ class ManagedMcpSettingsStoreTest {
new TransactionTemplate(transactionManager).executeWithoutResult(status -> {
jdbc.queryForObject("SELECT session_id FROM ma_session WHERE tenant_id=? AND session_id=? FOR UPDATE",
String.class, "tenant", id);
jdbc.update("UPDATE ma_session SET plan_enabled=TRUE, selected_approval_mode='default', approval_revision=1"
jdbc.update("UPDATE ma_session SET is_plan_enabled=TRUE, selected_approval_mode='default', approval_revision=1"
+ " WHERE tenant_id=? AND session_id=?", "tenant", id);
pending.set(executor.submit(() -> {
started.countDown();
@@ -149,12 +149,12 @@ class ManagedMcpSettingsStoreTest {
ObjectNode first = settings(1, "enabled", null);
var request = journal.requestOrdinary(first.path("operationId").asText(), "config_install", first,
event -> {}, records -> records, 0);
jdbc.update("UPDATE ma_session SET plan_enabled=TRUE, selected_approval_mode='default', approval_revision=1"
jdbc.update("UPDATE ma_session SET is_plan_enabled=TRUE, selected_approval_mode='default', approval_revision=1"
+ " WHERE tenant_id=? AND session_id=?", "tenant", id);
assertThatThrownBy(() -> journal.commit(request)).isInstanceOfSatisfying(ManagedAgentException.class,
error -> assertThat(error.getCode()).isEqualTo("unsupported_feature"));
assertThat(ManagedMcpSettings.find(jdbc, "tenant", id)).isNull();
jdbc.update("UPDATE ma_session SET plan_enabled=FALSE WHERE tenant_id=? AND session_id=?", "tenant", id);
jdbc.update("UPDATE ma_session SET is_plan_enabled=FALSE WHERE tenant_id=? AND session_id=?", "tenant", id);
jdbc.update("INSERT INTO ma_turn (tenant_id, session_id, turn_id, prompt_id, input_json, payload_digest, status, gmt_create, gmt_modified)"
+ " VALUES (?, ?, 'turn', ?, '[]', 'digest', 'ACCEPTED', 1, 1)", "tenant", id, UUID.randomUUID().toString());
assertThatThrownBy(() -> journal.commit(request)).isInstanceOfSatisfying(ManagedAgentException.class,
@@ -126,7 +126,7 @@ class ManagedRuntimeRetentionRaceTest {
fixture.retire();
fixture.jdbc.update("UPDATE ma_storage_owner SET holder_key = NULL, binding_id = NULL,"
+ " runtime_generation = NULL, runtime_session_id = NULL");
fixture.jdbc.update("UPDATE ma_runtime_session SET execution_storage_key = NULL, execution_exclusive = FALSE");
fixture.jdbc.update("UPDATE ma_runtime_session SET execution_storage_key = NULL, is_execution_exclusive = FALSE");
var locked = new CountDownLatch(1);
var release = new CountDownLatch(1);
var first = new AtomicBoolean(true);
@@ -272,7 +272,7 @@ class ManagedRuntimeRetentionRaceTest {
"handleKind", binding.getResourceHandle().getKind(), "handleVersion", binding.getResourceHandle().getVersion(),
"handle", JSON.valueToTree(binding.getResourceHandle().getValue()).toString(), "stoppedAt", OLD.toString())).toString() : null;
// Age a completed lifecycle; production writers above still perform every reference admission check.
jdbc.update("UPDATE ma_runtime_binding SET binding_state = 'RELEASED', last_active_at = ?, drain_requested = TRUE,"
jdbc.update("UPDATE ma_runtime_binding SET binding_state = 'RELEASED', last_active_at = ?, is_drain_requested = TRUE,"
+ " drain_receipt_json = ?, operation_owner = NULL, operation_lease_until = NULL", Timestamp.from(OLD), receipt);
jdbc.update("UPDATE ma_runtime_slot SET active_binding_id = NULL");
jdbc.update("UPDATE ma_runtime_session SET session_state = 'RELEASED', last_active_at = ?", Timestamp.from(OLD));
@@ -281,7 +281,7 @@ class ManagedRuntimeRetentionRaceTest {
if (reference == Reference.OPERATOR || reference == Reference.CSI_RETIREMENT) {
jdbc.update("UPDATE ma_storage_owner SET holder_key = NULL, binding_id = NULL,"
+ " runtime_generation = NULL, runtime_session_id = NULL");
jdbc.update("UPDATE ma_runtime_session SET execution_storage_key = NULL, execution_exclusive = FALSE");
jdbc.update("UPDATE ma_runtime_session SET execution_storage_key = NULL, is_execution_exclusive = FALSE");
}
}
@@ -136,8 +136,8 @@ class ManagedSchemaJournalAtomicityTest {
@ValueSource(booleans = {false, true})
void wakeHintCommitsAndRollsBackWithItsAcceptedInput(boolean knownPrefix) throws Exception {
assertThat(jdbc.queryForObject("SELECT wake_head_revision FROM ma_session_head", Long.class)).isEqualTo(1);
assertThat(jdbc.queryForObject("SELECT wake_scan_pending FROM ma_session_head", Boolean.class)).isFalse();
jdbc.update("UPDATE ma_session_head SET wake_pending = FALSE, wake_head_revision = ?", knownPrefix ? 1L : null);
assertThat(jdbc.queryForObject("SELECT is_wake_scan_pending FROM ma_session_head", Boolean.class)).isFalse();
jdbc.update("UPDATE ma_session_head SET is_wake_pending = FALSE, wake_head_revision = ?", knownPrefix ? 1L : null);
var monitor = ManagedExtensionProjectionContractTest.fixtures()
.required("monitorChainCases").get(0).required("revisions").get(0).required("monitorRun");
var prepared = journal.request("wake-admit", monitor, 1_000);
@@ -150,45 +150,45 @@ class ManagedSchemaJournalAtomicityTest {
var request = journal.requestDomainWithInput("wake-admit", "monitor_run", monitor, closure, "wake-turn", input);
assertThatThrownBy(() -> transactions.executeWithoutResult(status -> {
journal.commit(request);
assertThat(jdbc.queryForObject("SELECT wake_pending FROM ma_session_head", Boolean.class)).isTrue();
assertThat(jdbc.queryForObject("SELECT is_wake_pending FROM ma_session_head", Boolean.class)).isTrue();
assertThat(jdbc.queryForObject("SELECT wake_head_revision FROM ma_session_head", Long.class))
.isEqualTo(knownPrefix ? 2L : null);
assertThat(jdbc.queryForObject("SELECT wake_scan_pending FROM ma_session_head", Boolean.class)).isTrue();
assertThat(jdbc.queryForObject("SELECT is_wake_scan_pending FROM ma_session_head", Boolean.class)).isTrue();
throw new SimulatedCrash();
})).isInstanceOf(SimulatedCrash.class);
assertThat(jdbc.queryForObject("SELECT wake_pending FROM ma_session_head", Boolean.class)).isFalse();
assertThat(jdbc.queryForObject("SELECT is_wake_pending FROM ma_session_head", Boolean.class)).isFalse();
assertThat(jdbc.queryForObject("SELECT wake_head_revision FROM ma_session_head", Long.class))
.isEqualTo(knownPrefix ? 1L : null);
transactions.executeWithoutResult(status -> journal.commit(request));
assertThat(jdbc.queryForObject("SELECT wake_pending FROM ma_session_head", Boolean.class)).isTrue();
assertThat(jdbc.queryForObject("SELECT is_wake_pending FROM ma_session_head", Boolean.class)).isTrue();
assertThat(jdbc.queryForObject("SELECT wake_head_revision FROM ma_session_head", Long.class))
.isEqualTo(knownPrefix ? 2L : null);
journal.committed(request);
// A legacy admission did not maintain the hint; an unrelated modern
// commit must not mark that unexamined prefix as current.
jdbc.update("UPDATE ma_session_head SET wake_pending = FALSE, wake_head_revision = 1");
jdbc.update("UPDATE ma_session_head SET is_wake_pending = FALSE, wake_head_revision = 1");
var next = ManagedExtensionProjectionContractTest.fixtures()
.required("monitorChainCases").get(0).required("revisions").get(1);
var ordinary = journal.request("ordinary-update", next.required("monitorRun"),
next.required("occurredAt").longValue());
transactions.executeWithoutResult(status -> journal.commit(ordinary));
assertThat(jdbc.queryForObject("SELECT journal_revision FROM ma_session_head", Long.class)).isEqualTo(3);
assertThat(jdbc.queryForObject("SELECT wake_pending FROM ma_session_head", Boolean.class)).isFalse();
assertThat(jdbc.queryForObject("SELECT is_wake_pending FROM ma_session_head", Boolean.class)).isFalse();
assertThat(jdbc.queryForObject("SELECT wake_head_revision FROM ma_session_head", Long.class)).isEqualTo(1);
assertThat(jdbc.queryForObject("SELECT wake_scan_pending FROM ma_session_head", Boolean.class)).isTrue();
assertThat(jdbc.queryForObject("SELECT is_wake_scan_pending FROM ma_session_head", Boolean.class)).isTrue();
}
@Test
void anOrdinaryCommitPreservesAnAlreadyPendingWake() throws Exception {
jdbc.update("UPDATE ma_session_head SET wake_pending = TRUE, wake_head_revision = 1");
jdbc.update("UPDATE ma_session_head SET is_wake_pending = TRUE, wake_head_revision = 1");
var monitor = ManagedExtensionProjectionContractTest.fixtures()
.required("monitorChainCases").get(0).required("revisions").get(0).required("monitorRun");
var ordinary = journal.request("ordinary-update", monitor, 1_000);
transactions.executeWithoutResult(status -> journal.commit(ordinary));
assertThat(jdbc.queryForObject("SELECT wake_pending FROM ma_session_head", Boolean.class)).isTrue();
assertThat(jdbc.queryForObject("SELECT is_wake_pending FROM ma_session_head", Boolean.class)).isTrue();
assertThat(jdbc.queryForObject("SELECT wake_head_revision FROM ma_session_head", Long.class)).isEqualTo(2);
assertThat(jdbc.queryForObject("SELECT wake_scan_pending FROM ma_session_head", Boolean.class)).isTrue();
assertThat(jdbc.queryForObject("SELECT is_wake_scan_pending FROM ma_session_head", Boolean.class)).isTrue();
}
@Test
@@ -1,5 +1,6 @@
package com.alibaba.qwen.code.managedagent;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
/** InnoDB lock-wait and deadlock observations shared by the MySQL witnesses (#13800). */
@@ -21,6 +22,37 @@ public final class MySqlLockProbe {
return waits == null ? 0 : waits;
}
/** Capture before releasing test holders so a failed witness retains its lock graph. */
public static String describeLockWaits(JdbcTemplate jdbc, String schema) {
try {
return "InnoDB lock waits for " + schema + ": " + jdbc.queryForList(
"SELECT requested.ENGINE_TRANSACTION_ID AS waiting_transaction,"
+ " waiting_trx.trx_query AS waiting_sql,"
+ " held.ENGINE_TRANSACTION_ID AS blocking_transaction,"
+ " blocking_trx.trx_query AS blocking_sql,"
+ " requested.OBJECT_NAME AS table_name,"
+ " requested.INDEX_NAME AS requested_index,"
+ " requested.LOCK_TYPE AS requested_type,"
+ " requested.LOCK_MODE AS requested_mode,"
+ " requested.LOCK_DATA AS requested_data,"
+ " held.INDEX_NAME AS blocking_index, held.LOCK_TYPE AS blocking_type,"
+ " held.LOCK_MODE AS blocking_mode, held.LOCK_DATA AS blocking_data"
+ " FROM performance_schema.data_lock_waits waits"
+ " JOIN performance_schema.data_locks requested ON requested.ENGINE = waits.ENGINE"
+ " AND requested.ENGINE_LOCK_ID = waits.REQUESTING_ENGINE_LOCK_ID"
+ " JOIN performance_schema.data_locks held ON held.ENGINE = waits.ENGINE"
+ " AND held.ENGINE_LOCK_ID = waits.BLOCKING_ENGINE_LOCK_ID"
+ " LEFT JOIN information_schema.INNODB_TRX waiting_trx"
+ " ON waiting_trx.trx_id = waits.REQUESTING_ENGINE_TRANSACTION_ID"
+ " LEFT JOIN information_schema.INNODB_TRX blocking_trx"
+ " ON blocking_trx.trx_id = waits.BLOCKING_ENGINE_TRANSACTION_ID"
+ " WHERE requested.OBJECT_SCHEMA = ? AND held.OBJECT_SCHEMA = ?",
schema, schema);
} catch (DataAccessException error) {
return "InnoDB lock snapshot unavailable for " + schema + ": " + error;
}
}
/** Waits up to ~9 s until at least {@code expected} transactions of {@code schema} queue. */
public static void awaitLockWaits(JdbcTemplate jdbc, String schema, int expected, String what)
throws InterruptedException {
@@ -1421,7 +1421,7 @@ public class SurfaceAdmissionAcceptanceTest {
+ " schedule_id, session_id, workspace_id, actor_id,"
+ " record_revision, definition_revision, definition_digest,"
+ " goal, cron, timezone, session_mode, overlap, catch_up,"
+ " catch_up_limit, enabled, state, blocked_reason, armed_at,"
+ " catch_up_limit, is_enabled, state, blocked_reason, armed_at,"
+ " watermark_slot, lease_owner, lease_until, fence,"
+ " gmt_create, gmt_modified) VALUES (?, ?, ?, 'ws', ?, 1, 1, ?,"
+ " 'probe', '0 2 * * *', 'UTC', 'persistent', 'skip', 'none',"
@@ -506,7 +506,8 @@ class ToolPublicationLockOrderMySqlIT {
}
assertThat(waiting).as("Publication waits for the placement owner").isPositive();
assertThat(source.subjectPlacementLocks.get())
.as("Placement precedes retention in the contending transaction")
.as(() -> "Placement precedes retention in the contending transaction; "
+ MySqlLockProbe.describeLockWaits(admin, schema))
.containsExactly("placement");
source.releaseOwner.countDown();
owner.get(30, TimeUnit.SECONDS);
@@ -1019,7 +1019,7 @@ class ToolPublicationStoreTest {
objects.get(objectKey)[0] = 'z';
assertThatThrownBy(() -> sessions.readResource("tenant-1", "workspace-1", "session-1",
admission.path("resourceId").asText(), WRITER_TOKEN)).hasMessageContaining("verification");
assertThat(jdbc.queryForObject("SELECT quarantined FROM ma_output_capture"
assertThat(jdbc.queryForObject("SELECT is_quarantined FROM ma_output_capture"
+ " WHERE publication_id = X'7075622d31'", Boolean.class)).isTrue();
assertThatThrownBy(() -> sessions.readResource("tenant-1", "workspace-1", "session-1",
admission.path("resourceId").asText(), WRITER_TOKEN)).hasMessageContaining("verification");
@@ -1272,7 +1272,7 @@ class ToolPublicationStoreTest {
if (!large) {
if (quarantineBeforeProjection) {
jdbc.update(
"UPDATE ma_output_capture SET quarantined = TRUE WHERE publication_id ="
"UPDATE ma_output_capture SET is_quarantined = TRUE WHERE publication_id ="
+ " X'7075622d31'");
}
JsonNode projected = projectPublicReceipt(data);
@@ -1354,7 +1354,7 @@ class ToolPublicationStoreTest {
try (var stream = apiReader.open(artifact)) {
assertThat(stream.readNBytes(2)).isEqualTo("ab".getBytes(StandardCharsets.UTF_8));
jdbc.update(
"UPDATE ma_output_capture SET quarantined = TRUE WHERE publication_id ="
"UPDATE ma_output_capture SET is_quarantined = TRUE WHERE publication_id ="
+ " X'7075622d31'");
byte[] target = new byte[] {'?'};
assertThatThrownBy(() -> stream.read(target)).hasMessageContaining("receipt is unavailable");
@@ -1440,7 +1440,7 @@ class ToolPublicationStoreTest {
.hasMessageContaining("digest changed");
assertThat(jdbc.queryForObject("SELECT capture_state FROM ma_resource"
+ " WHERE slot_key = X'7365676d656e743a7374646f75743a31'", String.class)).isEqualTo("QUARANTINED");
assertThat(jdbc.queryForObject("SELECT quarantined FROM ma_output_capture"
assertThat(jdbc.queryForObject("SELECT is_quarantined FROM ma_output_capture"
+ " WHERE publication_id = X'7075622d31'", Boolean.class)).isFalse();
assertThat(data.prefix(key, "pub-1", PUBLICATION_TOKEN, "good-prefix", "stdout")
.path("byteLength").asLong()).isEqualTo(3);
@@ -2535,10 +2535,10 @@ class ToolPublicationStoreTest {
jdbc.update("INSERT INTO ma_output_capture (scope_key, tenant_key, tenant_id, workspace_id, session_id,"
+ " publication_id, execution_key, capture_id, binding_json, binding_digest, token_hash, state,"
+ " expires_at, capture_bytes, producer_bytes, admission_bytes, capture_held_bytes,"
+ " producer_held_bytes, admission_held_bytes, write_evidence) SELECT scope_key, tenant_key,"
+ " producer_held_bytes, admission_held_bytes, is_write_evidence) SELECT scope_key, tenant_key,"
+ " tenant_id, workspace_id, session_id, ?, ?, ?, binding_json, binding_digest, token_hash, state,"
+ " expires_at, capture_bytes, producer_bytes, admission_bytes, capture_held_bytes,"
+ " producer_held_bytes, admission_held_bytes, write_evidence FROM ma_output_capture"
+ " producer_held_bytes, admission_held_bytes, is_write_evidence FROM ma_output_capture"
+ " WHERE publication_id = ?", to.getBytes(StandardCharsets.UTF_8), digest(to),
to.getBytes(StandardCharsets.UTF_8), from.getBytes(StandardCharsets.UTF_8));
}
@@ -3081,12 +3081,12 @@ class ToolPublicationStoreTest {
void acceptedProducerEvidenceFeedsRetirementEligibility() {
var fixture = apiFixture();
assertThat(fixture.jdbc().queryForObject(
"SELECT write_evidence AND accepted_complete FROM"
"SELECT is_write_evidence AND is_accepted_complete FROM"
+ " ma_output_capture",
Boolean.class)).isTrue();
fixture.jdbc().update(
"UPDATE ma_session SET retirement_operation_id = X'64656c6574652d31',"
+ " retirement_generation = 1, retired_at = 1, recovery_protected ="
+ " retirement_generation = 1, retired_at = 1, is_recovery_protected ="
+ " FALSE WHERE tenant_id = X'74656e616e742d31' AND session_id ="
+ " X'73657373696f6e2d31'");
fixture.jdbc().update("UPDATE ma_output_capture SET retention_state = 'RETIRING'");
@@ -3247,7 +3247,7 @@ class ToolPublicationStoreTest {
var claim = fixture.results().claim().orElseThrow();
fixture.jdbc().update(
"UPDATE ma_session SET retirement_operation_id = X'64656c6574652d31',"
+ " retirement_generation = 1, retired_at = 1, recovery_protected ="
+ " retirement_generation = 1, retired_at = 1, is_recovery_protected ="
+ " FALSE WHERE tenant_id = X'74656e616e742d31' AND session_id ="
+ " X'73657373696f6e2d31'");
var projection = new ManagedToolResultStore.Projection(JSON.createObjectNode(), "pub-1",
@@ -3346,7 +3346,7 @@ class ToolPublicationStoreTest {
var calls = new java.util.concurrent.atomic.AtomicInteger();
org.mockito.Mockito.doAnswer(call -> {
if (calls.incrementAndGet() == 2) {
fixture.jdbc().update("UPDATE ma_output_capture SET quarantined=TRUE");
fixture.jdbc().update("UPDATE ma_output_capture SET is_quarantined=TRUE");
}
return fixture.policy().version();
}).when(policy).version();
@@ -194,7 +194,7 @@ class WorkspaceSessionRetentionMySqlIT {
var claimed = deleteClaim(store, tenant, session);
jdbc.update("DELETE FROM ma_workspace_access");
assertThat(transaction(() -> store.completeOperation(tenant, session, claimed.operationId(), "delete-worker", claimed.claimGeneration(), false))).isTrue();
assertThat(jdbc.queryForObject("SELECT recovery_protected FROM ma_session WHERE retirement_generation > 0", Boolean.class)).isTrue();
assertThat(jdbc.queryForObject("SELECT is_recovery_protected FROM ma_session WHERE retirement_generation > 0", Boolean.class)).isTrue();
var retention = new ToolPublicationRetentionStore(jdbc, new DataSourceTransactionManager(source));
assertThat(retention.observe(Duration.ZERO)).singleElement().extracting(ToolPublicationRetentionStore.Candidate::blocker).isEqualTo("recovery_protected");
assertThatThrownBy(() -> transaction(() -> com.alibaba.qwen.code.managedagent.VerificationFixtures.managedSessionStore(jdbc).acquireWriter(tenant, session, TOKEN,
@@ -495,7 +495,7 @@ class WorkspaceSessionRetentionMySqlIT {
String key = "b".repeat(64);
jdbc.update("INSERT INTO ma_output_capture (scope_key, tenant_key, tenant_id, workspace_id, session_id,"
+ " publication_id, execution_key, capture_id, binding_json, binding_digest, token_hash, state,"
+ " capture_bytes, producer_bytes, admission_bytes, producer_phase, write_evidence, accepted_complete,"
+ " capture_bytes, producer_bytes, admission_bytes, producer_phase, is_write_evidence, is_accepted_complete,"
+ " capture_held_bytes, producer_held_bytes, admission_held_bytes, capture_used_bytes)"
+ " VALUES (?, ?, ?, 'workspace', ?, 'pub-1', ?, 'capture-1', '{}', ?, ?, 'FENCED',"
+ " 1000, 1000, 1000, 'REFERENCED', TRUE, TRUE, 1000, 1000, 1000, 123)",
@@ -67,7 +67,7 @@ class AutomationScannerConcurrencyMySqlIT {
+ " session_id, workspace_id, actor_id,"
+ " record_revision, definition_revision,"
+ " definition_digest, goal, cron, timezone,"
+ " session_mode, overlap, catch_up, enabled, state,"
+ " session_mode, overlap, catch_up, is_enabled, state,"
+ " armed_at, gmt_create, gmt_modified)"
+ " VALUES (?, ?, ?, 'workspace', 'actor', 1, 1,"
+ " 'digest', 'Goal', '* * * * *', 'UTC', 'default',"
@@ -45,7 +45,7 @@ class ManagedSchemaConfigurationTest {
assertThat(sessionListColumns(source)).containsExactly("tenant_id", "gmt_create", "session_id");
assertThat(jdbc.queryForMap("SELECT " + ManagedSchemaProjection.SESSION.columns() + " FROM ma_session"))
.isEqualTo(session)
.containsEntry("csi_guard", false)
.containsEntry("is_csi_guard", false)
.containsEntry("runtime_request_key", null)
.containsEntry("model_id", null)
.containsEntry("model_revision", 0L)
@@ -103,7 +103,7 @@ class ManagedSchemaConfigurationTest {
.getIndexInfo(null, null, "ma_session", false, false)) {
var columns = new ArrayList<String>();
while (rows.next()) {
if ("ix_ma_session_list".equalsIgnoreCase(rows.getString("INDEX_NAME"))) {
if ("idx_ma_session_list".equalsIgnoreCase(rows.getString("INDEX_NAME"))) {
columns.add(rows.getString("COLUMN_NAME").toLowerCase(java.util.Locale.ROOT));
}
}
@@ -132,7 +132,7 @@ public class EventTransportConsumerSqlTest {
"SELECT " + ManagedSchemaProjection.SESSION_HEAD.columns() + " FROM ma_session_head WHERE tenant_id = ? AND session_id = ?",
TENANT,
session);
assertThat(sessionBefore.get("csi_guard")).isEqualTo(true);
assertThat(sessionBefore.get("is_csi_guard")).isEqualTo(true);
deliver(wake(session, WORKSPACE, 3));
assertThat(wakeWatermark(session)).isNull();
@@ -436,7 +436,7 @@ public class EventTransportConsumerSqlTest {
private void event(String session, long sequence, String type) {
jdbc.update("INSERT INTO ma_public_event (tenant_id, session_id,"
+ " sequence_id, event_id, turn_id, event_type, data_json,"
+ " terminal, source_key, gmt_create) VALUES (?, ?, ?, ?,"
+ " is_terminal, source_key, gmt_create) VALUES (?, ?, ?, ?,"
+ " NULL, ?, '{}', FALSE, NULL, ?)",
TENANT, session, sequence, "evt-" + UUID.randomUUID(), type,
1_760_000_000_000L + sequence);
@@ -460,7 +460,7 @@ class WorkspaceCsiSessionMainTest {
void retainedRequestPinStillRefusesAfterAConflictingProfileChange() {
var original = create(request("retained-pin"));
jdbc.update("UPDATE ma_session SET tool_profile = 'hosted-workspace-files/1'");
assertThat(jdbc.queryForObject("SELECT csi_guard FROM ma_session", Boolean.class)).isTrue();
assertThat(jdbc.queryForObject("SELECT is_csi_guard FROM ma_session", Boolean.class)).isTrue();
var before = allTables();
assertPrivateRefusal(() -> new TransactionTemplate(manager).executeWithoutResult(status ->
store().appendPublicEventIfAbsent("tenant", original.sessionId(), null, "session.environment",
@@ -516,7 +516,7 @@ class WorkspaceCsiSessionMainTest {
var privateTurn = new java.util.LinkedHashMap<>(ordinaryTurn);
privateTurn.put("session_id", jdbc.queryForObject(
"SELECT session_id FROM ma_session"
+ " WHERE csi_guard = TRUE ORDER BY session_id LIMIT 1", String.class));
+ " WHERE is_csi_guard = TRUE ORDER BY session_id LIMIT 1", String.class));
privateTurn.put("turn_id", "private-legacy-turn");
privateTurn.put("prompt_id", UUID.randomUUID().toString());
privateTurn.put("gmt_modified", 0L);
@@ -58,7 +58,7 @@ class AgentLockContractTest extends RecoverySettlementStoreTest {
trace.assertSessionBeforeTurn(TENANT, sessionId);
trace.assertOneTransaction(TENANT, sessionId);
var locks = trace.successful(TENANT, sessionId).stream()
.filter(event -> event.sql().contains("for update") && !event.sql().contains("csi_guard = true"))
.filter(event -> event.sql().contains("for update") && !event.sql().contains("is_csi_guard = true"))
.map(event -> event.root() ? "root" : event.turn() ? "turn" : "stream").toList();
assertThat(locks.subList(0, 3)).containsExactly("root", "stream", "turn");
assertThat(trace.events()).anyMatch(event -> event.phase() == StoreLockTrace.Phase.COMMIT);
@@ -53,7 +53,7 @@ class ConsolidatedTaskEventStoreTest {
jdbc.update("INSERT INTO ma_event_stream (tenant_id,session_id,stream_kind,stream_id,last_sequence,gmt_modified)"
+ " VALUES ('tenant','session','SESSION','',1,0)");
jdbc.update("INSERT INTO ma_public_event (tenant_id,session_id,stream_kind,stream_id,sequence_id,event_id,"
+ "event_type,data_json,terminal,gmt_create) VALUES ('tenant','session','SESSION','',1,'session-event',"
+ "event_type,data_json,is_terminal,gmt_create) VALUES ('tenant','session','SESSION','',1,'session-event',"
+ "'session.updated','{}',FALSE,1)");
assertThat(events.expireThrough("tenant", "session", "task", 2)).isEqualTo(2);
assertThat(events.read("tenant", "session", "task", 0, 100).events()).isEmpty();
@@ -66,7 +66,7 @@ final class ExecutedQueryPlan {
counts.add(0d);
JsonNode pages = node.path("r_engine_stats").path("pages_accessed");
if ("const".equals(node.path("access_type").asText())
&& "PRIMARY".equals(node.path("key").asText())
&& node.path("key").isTextual() && !node.path("key").asText().isBlank()
&& pages.isIntegralNumber() && pages.canConvertToLong() && pages.asLong() > 0) {
preExecutionPages.add(pages.asLong());
}
@@ -70,16 +70,16 @@ class ExecutedQueryPlanTest {
}
@Test
void requiresActualPrimaryConstPageEvidence() {
void requiresActualConstIndexPageEvidence() {
for (String access : new String[] {"ref", "const"}) {
for (String key : new String[] {"another", "PRIMARY"}) {
for (String key : new String[] {"", "uk_ma_resource_business_key", "PRIMARY"}) {
for (String pages : new String[] {"null", "0", "\"2\"", "2"}) {
var plan = ExecutedQueryPlan.mariaDb("{\"table\":{\"table_name\":\"r\","
+ "\"access_type\":\"" + access + "\",\"key\":\"" + key + "\","
+ "\"r_rows\":null,\"r_loops\":0,\"r_engine_stats\":{\"pages_accessed\":" + pages + "}}}");
assertThat(plan.scannedRows()).isZero();
assertThat(plan.preExecutionPageReads()).isEqualTo(
access.equals("const") && key.equals("PRIMARY") && pages.equals("2") ? 2 : 0);
access.equals("const") && !key.isBlank() && pages.equals("2") ? 2 : 0);
}
}
}
Loaded 100 of 150 files, more files were not shown because too many files have changed in this diff. Show more