-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathschema_definitions_agent_runtime.test.ts
More file actions
168 lines (151 loc) · 6.92 KB
/
Copy pathschema_definitions_agent_runtime.test.ts
File metadata and controls
168 lines (151 loc) · 6.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/**
* Registration + shape tests for the fleet-general agent runtime
* schema family (v0.1) — fleet-general write integrity layer,
* item-2-fleet-schemas.
*
* These tests exist to:
* 1. Lock the six entity_types (agent_task, agent_attempt,
* agent_outcome, agent_artifact, agent_sensor_signal,
* agent_cycle_summary) so a later rename / accidental delete is
* caught immediately.
* 2. Enforce the cross-cutting LCD contract: singular names, schema
* version pinned at `0.1.0`, category `agent_runtime`, required
* identity fields present, and canonical_name_fields declared.
* 3. Assert the sensor schema locks its `observation_source_priority`
* override so sensor emissions keep beating LLM summaries for this
* entity type even if the registry default is relaxed later.
*/
import { describe, expect, it } from "vitest";
import {
getSchemaDefinition,
getRegisteredEntityTypes,
} from "../../src/services/schema_definitions.js";
const AGENT_RUNTIME_TYPES = [
"agent_task",
"agent_attempt",
"agent_outcome",
"agent_artifact",
"agent_sensor_signal",
"agent_cycle_summary",
] as const;
const REQUIRED_IDENTITY_FIELD: Record<(typeof AGENT_RUNTIME_TYPES)[number], string> = {
agent_task: "task_id",
agent_attempt: "attempt_id",
agent_outcome: "outcome_id",
agent_artifact: "artifact_id",
agent_sensor_signal: "sensor_id",
agent_cycle_summary: "cycle_id",
};
describe("fleet-general agent_* schemas v0.1", () => {
it("registers all six entity types", () => {
const registered = getRegisteredEntityTypes();
for (const entityType of AGENT_RUNTIME_TYPES) {
expect(registered, `expected ${entityType} to be registered`).toContain(entityType);
}
});
it.each(AGENT_RUNTIME_TYPES)(
"%s follows the fleet-general v0.1 contract (singular name, schema_version 0.1.0, category agent_runtime, identity field present, canonical_name_fields declared)",
(entityType) => {
const schema = getSchemaDefinition(entityType);
expect(schema, `${entityType} schema missing`).not.toBeNull();
expect(schema!.entity_type).toBe(entityType);
expect(entityType.endsWith("s")).toBe(false);
expect(schema!.schema_version).toBe("0.1.0");
expect(schema!.metadata?.category).toBe("agent_runtime");
const identityField = REQUIRED_IDENTITY_FIELD[entityType];
const fieldDef = schema!.schema_definition.fields[identityField];
expect(
fieldDef,
`${entityType} is missing required identity field ${identityField}`
).toBeDefined();
expect(fieldDef!.required).toBe(true);
expect(
schema!.schema_definition.canonical_name_fields,
`${entityType} must declare canonical_name_fields`
).toBeDefined();
}
);
it("agent_attempt.task_id and agent_outcome.attempt_id are declared as required link fields", () => {
const attempt = getSchemaDefinition("agent_attempt")!;
expect(attempt.schema_definition.fields.task_id?.required).toBe(true);
const outcome = getSchemaDefinition("agent_outcome")!;
expect(outcome.schema_definition.fields.attempt_id?.required).toBe(true);
const artifact = getSchemaDefinition("agent_artifact")!;
expect(artifact.schema_definition.fields.outcome_id?.required).toBe(true);
});
it("agent_sensor_signal locks observation_source_priority so sensor emissions outrank LLM summaries", () => {
const sensor = getSchemaDefinition("agent_sensor_signal")!;
expect(sensor.reducer_config.observation_source_priority).toEqual([
"sensor",
"workflow_state",
"llm_summary",
"human",
"import",
]);
});
it("does NOT declare agent_sub / agent_id as a schema field (identity lives in provenance via AAuth)", () => {
for (const entityType of AGENT_RUNTIME_TYPES) {
const schema = getSchemaDefinition(entityType)!;
const fields = schema.schema_definition.fields;
expect(Object.keys(fields)).not.toContain("agent_id");
expect(Object.keys(fields)).not.toContain("agent_sub");
}
});
});
describe("agent_session + session_transcript schemas v0.1", () => {
it("registers agent_session and session_transcript", () => {
const registered = getRegisteredEntityTypes();
expect(registered).toContain("agent_session");
expect(registered).toContain("session_transcript");
});
it("agent_session uses joint identity on harness + native_session_id with reject collision policy", () => {
const s = getSchemaDefinition("agent_session");
expect(s, "agent_session schema missing").not.toBeNull();
expect(s!.entity_type).toBe("agent_session");
expect(s!.schema_version).toBe("0.1.0");
expect(s!.metadata?.category).toBe("agent_runtime");
expect(s!.schema_definition.fields.harness?.required).toBe(true);
expect(s!.schema_definition.fields.native_session_id?.required).toBe(true);
expect(s!.schema_definition.canonical_name_fields).toEqual(["harness", "native_session_id"]);
expect(s!.schema_definition.name_collision_policy).toBe("reject");
});
it("session_transcript is content-addressed (identity on content_hash)", () => {
const s = getSchemaDefinition("session_transcript");
expect(s, "session_transcript schema missing").not.toBeNull();
expect(s!.entity_type).toBe("session_transcript");
expect(s!.schema_version).toBe("0.1.0");
expect(s!.metadata?.category).toBe("agent_runtime");
expect(s!.schema_definition.fields.content_hash?.required).toBe(true);
expect(s!.schema_definition.canonical_name_fields).toEqual(["content_hash"]);
});
it("agent_session DOES carry denormalized aauth_sub + trigger provenance, unlike the fleet LCD types", () => {
// The fleet types (agent_task/attempt/outcome) keep agent identity in
// provenance via AAuth and forbid an agent_sub field. agent_session is a
// session-level record where aauth_sub is a denormalized *content* field
// (which agent produced the session) used for discovery/filtering; the
// authoritative provenance still lives in the linked harness_event /
// participation_record / agent_attempt entities.
const fields = getSchemaDefinition("agent_session")!.schema_definition.fields;
expect(Object.keys(fields)).toContain("aauth_sub");
expect(Object.keys(fields)).toContain("trigger_kind");
expect(Object.keys(fields)).toContain("kind");
});
it("declares reference_fields for parent_session_id and session_transcript.agent_session_id", () => {
const session = getSchemaDefinition("agent_session")!;
const transcript = getSchemaDefinition("session_transcript")!;
expect(session.schema_definition.reference_fields).toEqual([
{
field: "parent_session_id",
target_entity_type: "agent_session",
relationship_type: "PART_OF",
},
]);
expect(transcript.schema_definition.reference_fields).toEqual([
{
field: "agent_session_id",
target_entity_type: "agent_session",
relationship_type: "PART_OF",
},
]);
});
});