@moreih29/nexus-core 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/conformance/README.md +208 -16
- package/conformance/examples/plan.extension.schema.example.json +25 -0
- package/conformance/lifecycle/README.md +17 -0
- package/conformance/lifecycle/agent-complete.json +44 -0
- package/conformance/lifecycle/agent-resume.json +43 -0
- package/conformance/lifecycle/agent-spawn.json +42 -0
- package/conformance/lifecycle/session-end.json +32 -0
- package/conformance/lifecycle/session-start.json +38 -0
- package/conformance/scenarios/full-plan-cycle.json +17 -2
- package/conformance/scenarios/task-deps-ordering.json +12 -0
- package/conformance/schema/fixture.schema.json +139 -9
- package/conformance/state-schemas/agent-tracker.schema.json +10 -5
- package/conformance/state-schemas/history.schema.json +11 -1
- package/conformance/state-schemas/plan.schema.json +5 -0
- package/conformance/state-schemas/runtime.schema.json +13 -4
- package/conformance/state-schemas/tasks.schema.json +5 -0
- package/conformance/tools/artifact-write.json +97 -0
- package/conformance/tools/context.json +172 -0
- package/conformance/tools/history-search.json +219 -0
- package/conformance/tools/plan-decide.json +72 -3
- package/conformance/tools/plan-start.json +14 -0
- package/conformance/tools/plan-status.json +127 -0
- package/conformance/tools/plan-update.json +341 -0
- package/conformance/tools/task-add.json +89 -6
- package/conformance/tools/task-close.json +67 -4
- package/conformance/tools/task-list.json +20 -0
- package/conformance/tools/task-update.json +28 -0
- package/docs/consumer-implementation-guide.md +1 -1
- package/docs/nexus-outputs-contract.md +287 -0
- package/docs/nexus-tools-contract.md +12 -2
- package/manifest.json +54 -54
- package/package.json +6 -1
- package/scripts/.gitkeep +0 -0
- package/scripts/conformance-coverage.ts +466 -0
- package/scripts/import-from-claude-nexus.ts +403 -0
- package/scripts/lib/frontmatter.ts +71 -0
- package/scripts/lib/lint.ts +216 -0
- package/scripts/lib/structure.ts +159 -0
- package/scripts/lib/validate.ts +668 -0
- package/scripts/validate.ts +90 -0
|
@@ -2,10 +2,36 @@
|
|
|
2
2
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
3
|
"$id": "fixture.schema.json",
|
|
4
4
|
"title": "Nexus Conformance Test Fixture",
|
|
5
|
-
"description": "Declarative test case for Nexus MCP tool behavioral verification",
|
|
5
|
+
"description": "Declarative test case for Nexus MCP tool behavioral verification. Each fixture must declare exactly one of: action (single tool invocation), event (single lifecycle event), or steps (multi-step sequence).",
|
|
6
6
|
"type": "object",
|
|
7
7
|
"additionalProperties": false,
|
|
8
|
-
"required": ["test_id", "description"],
|
|
8
|
+
"required": ["test_id", "description", "covers"],
|
|
9
|
+
"oneOf": [
|
|
10
|
+
{
|
|
11
|
+
"required": ["action"],
|
|
12
|
+
"properties": {
|
|
13
|
+
"action": true,
|
|
14
|
+
"event": false,
|
|
15
|
+
"steps": false
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"required": ["event"],
|
|
20
|
+
"properties": {
|
|
21
|
+
"action": false,
|
|
22
|
+
"event": true,
|
|
23
|
+
"steps": false
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"required": ["steps"],
|
|
28
|
+
"properties": {
|
|
29
|
+
"action": false,
|
|
30
|
+
"event": false,
|
|
31
|
+
"steps": true
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
],
|
|
9
35
|
"properties": {
|
|
10
36
|
"test_id": {
|
|
11
37
|
"type": "string",
|
|
@@ -17,6 +43,68 @@
|
|
|
17
43
|
"minLength": 10,
|
|
18
44
|
"description": "Human-readable description of what behavior this fixture verifies"
|
|
19
45
|
},
|
|
46
|
+
"covers": {
|
|
47
|
+
"type": "object",
|
|
48
|
+
"description": "Declaration of which schema fields and return value paths this fixture verifies. At least one of state_schemas or return_value must be non-empty.",
|
|
49
|
+
"additionalProperties": false,
|
|
50
|
+
"anyOf": [
|
|
51
|
+
{
|
|
52
|
+
"properties": {
|
|
53
|
+
"state_schemas": {
|
|
54
|
+
"minProperties": 1
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
"required": ["state_schemas"]
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"properties": {
|
|
61
|
+
"return_value": {
|
|
62
|
+
"minProperties": 1
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
"required": ["return_value"]
|
|
66
|
+
}
|
|
67
|
+
],
|
|
68
|
+
"properties": {
|
|
69
|
+
"state_schemas": {
|
|
70
|
+
"type": "object",
|
|
71
|
+
"description": "Map of state-schema filename (e.g. 'plan.schema.json') to array of field paths verified by this fixture's postcondition. Field paths use dot-notation with array index notation (e.g. 'issues[].status').",
|
|
72
|
+
"additionalProperties": {
|
|
73
|
+
"type": "array",
|
|
74
|
+
"items": {
|
|
75
|
+
"type": "string",
|
|
76
|
+
"pattern": "^[^ ]+$",
|
|
77
|
+
"description": "Field path within the named schema (e.g. 'id', 'issues[].status', 'issues[].how_agents')"
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
"return_value": {
|
|
82
|
+
"type": "object",
|
|
83
|
+
"description": "Map of abstract tool name (e.g. 'plan_start') to array of return-value field paths verified by this fixture's postcondition.",
|
|
84
|
+
"additionalProperties": {
|
|
85
|
+
"type": "array",
|
|
86
|
+
"items": {
|
|
87
|
+
"type": "string",
|
|
88
|
+
"pattern": "^[^ ]+$",
|
|
89
|
+
"description": "Field path within the tool's return value (e.g. 'created', 'plan_id', 'issueCount')"
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
"description": {
|
|
94
|
+
"type": "string",
|
|
95
|
+
"description": "Optional human-readable explanation of coverage rationale or known gaps"
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
"uncovered_params": {
|
|
100
|
+
"type": "array",
|
|
101
|
+
"description": "Params intentionally excluded from postcondition verification. Validators treat entries here as explicit exceptions rather than coverage gaps, preventing false anti-pattern warnings.",
|
|
102
|
+
"items": {
|
|
103
|
+
"type": "string",
|
|
104
|
+
"pattern": "^[^ ]+$",
|
|
105
|
+
"description": "Parameter name from the action or event params that is deliberately not verified"
|
|
106
|
+
}
|
|
107
|
+
},
|
|
20
108
|
"precondition": {
|
|
21
109
|
"type": "object",
|
|
22
110
|
"description": "State that must be established before the action or steps are executed",
|
|
@@ -24,7 +112,7 @@
|
|
|
24
112
|
"properties": {
|
|
25
113
|
"state_files": {
|
|
26
114
|
"type": "object",
|
|
27
|
-
"description": "Map of file path
|
|
115
|
+
"description": "Map of file path to content object. null = file must not exist; empty object {} = file must exist but content is not inspected (use for non-JSON artifacts like .md, .txt, binary files); non-empty object = precondition content written as-is (typically JSON).",
|
|
28
116
|
"additionalProperties": {
|
|
29
117
|
"oneOf": [
|
|
30
118
|
{ "type": "object" },
|
|
@@ -36,11 +124,15 @@
|
|
|
36
124
|
},
|
|
37
125
|
"action": {
|
|
38
126
|
"$ref": "#/$defs/action",
|
|
39
|
-
"description": "Single tool invocation — use for single-action fixtures;
|
|
127
|
+
"description": "Single tool invocation — use for single-action fixtures; mutually exclusive with event and steps"
|
|
128
|
+
},
|
|
129
|
+
"event": {
|
|
130
|
+
"$ref": "#/$defs/event",
|
|
131
|
+
"description": "Single lifecycle event — use for event-based fixtures that require no tool call; mutually exclusive with action and steps"
|
|
40
132
|
},
|
|
41
133
|
"steps": {
|
|
42
134
|
"type": "array",
|
|
43
|
-
"description": "Ordered sequence of tool invocations with per-step assertions — use for multi-step scenarios",
|
|
135
|
+
"description": "Ordered sequence of tool invocations or lifecycle events with per-step assertions — use for multi-step scenarios; mutually exclusive with action and event",
|
|
44
136
|
"minItems": 1,
|
|
45
137
|
"items": { "$ref": "#/$defs/step" }
|
|
46
138
|
},
|
|
@@ -66,6 +158,28 @@
|
|
|
66
158
|
}
|
|
67
159
|
}
|
|
68
160
|
},
|
|
161
|
+
"event": {
|
|
162
|
+
"type": "object",
|
|
163
|
+
"description": "A lifecycle event that triggers harness-level behavior without a direct tool call. Used for verifying runtime.json and agent-tracker.json state changes.",
|
|
164
|
+
"additionalProperties": false,
|
|
165
|
+
"required": ["type"],
|
|
166
|
+
"properties": {
|
|
167
|
+
"type": {
|
|
168
|
+
"type": "string",
|
|
169
|
+
"enum": ["session_start", "session_end", "agent_spawn", "agent_complete", "agent_resume"],
|
|
170
|
+
"description": "Lifecycle event type. session_start/session_end: harness session lifecycle; agent_spawn/agent_complete/agent_resume: agent instance lifecycle."
|
|
171
|
+
},
|
|
172
|
+
"params": {
|
|
173
|
+
"type": "object",
|
|
174
|
+
"description": "Optional event-specific parameters (e.g. harness_id, agent_name, and agent_id for agent_spawn)",
|
|
175
|
+
"additionalProperties": true
|
|
176
|
+
},
|
|
177
|
+
"description": {
|
|
178
|
+
"type": "string",
|
|
179
|
+
"description": "Optional human-readable explanation of the event and its expected effect"
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
},
|
|
69
183
|
"postcondition": {
|
|
70
184
|
"type": "object",
|
|
71
185
|
"description": "Assertions on the state and return value after the action completes",
|
|
@@ -73,7 +187,7 @@
|
|
|
73
187
|
"properties": {
|
|
74
188
|
"state_files": {
|
|
75
189
|
"type": "object",
|
|
76
|
-
"description": "Map of file path
|
|
190
|
+
"description": "Map of file path to assertion object. null = file must not exist after the action; empty object {} = file must exist but content is not inspected (use for non-JSON artifacts like .md, .txt, binary files); non-empty object = JSONPath assertions on parsed JSON content.",
|
|
77
191
|
"additionalProperties": {
|
|
78
192
|
"oneOf": [
|
|
79
193
|
{
|
|
@@ -155,15 +269,31 @@
|
|
|
155
269
|
},
|
|
156
270
|
"step": {
|
|
157
271
|
"type": "object",
|
|
158
|
-
"description": "One step in a multi-step scenario",
|
|
272
|
+
"description": "One step in a multi-step scenario. Each step must contain exactly one of: action (tool invocation) or event (lifecycle event).",
|
|
159
273
|
"additionalProperties": false,
|
|
160
|
-
"
|
|
274
|
+
"oneOf": [
|
|
275
|
+
{
|
|
276
|
+
"required": ["action"],
|
|
277
|
+
"properties": {
|
|
278
|
+
"action": true,
|
|
279
|
+
"event": false
|
|
280
|
+
}
|
|
281
|
+
},
|
|
282
|
+
{
|
|
283
|
+
"required": ["event"],
|
|
284
|
+
"properties": {
|
|
285
|
+
"action": false,
|
|
286
|
+
"event": true
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
],
|
|
161
290
|
"properties": {
|
|
162
291
|
"description": {
|
|
163
292
|
"type": "string",
|
|
164
293
|
"description": "Optional human-readable label for this step"
|
|
165
294
|
},
|
|
166
295
|
"action": { "$ref": "#/$defs/action" },
|
|
296
|
+
"event": { "$ref": "#/$defs/event" },
|
|
167
297
|
"assert_return": {
|
|
168
298
|
"type": "object",
|
|
169
299
|
"description": "JSONPath assertions on the return value of this step's action",
|
|
@@ -189,7 +319,7 @@
|
|
|
189
319
|
},
|
|
190
320
|
"assert_state": {
|
|
191
321
|
"type": "object",
|
|
192
|
-
"description": "Map of file path
|
|
322
|
+
"description": "Map of file path to assertions on state files after this step completes. null means file must not exist.",
|
|
193
323
|
"additionalProperties": {
|
|
194
324
|
"oneOf": [
|
|
195
325
|
{
|
|
@@ -2,17 +2,22 @@
|
|
|
2
2
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
3
|
"$id": "conformance/state-schemas/agent-tracker.schema.json",
|
|
4
4
|
"title": "Nexus Agent Tracker",
|
|
5
|
-
"description": "Schema for .nexus/state/agent-tracker.json — registry of spawned agent instances tracked across a session",
|
|
5
|
+
"description": "Schema for .nexus/state/agent-tracker.json — registry of spawned agent instances tracked across a session. No schema_version field: this file is session-scoped and deleted on session end — migration anchor not required.",
|
|
6
6
|
"type": "array",
|
|
7
7
|
"items": {
|
|
8
8
|
"type": "object",
|
|
9
9
|
"additionalProperties": false,
|
|
10
|
-
"required": ["
|
|
10
|
+
"required": ["harness_id", "agent_name", "agent_id", "started_at", "resume_count", "status"],
|
|
11
11
|
"properties": {
|
|
12
|
-
"
|
|
12
|
+
"harness_id": {
|
|
13
13
|
"type": "string",
|
|
14
|
-
"
|
|
15
|
-
"description": "
|
|
14
|
+
"pattern": "^[a-z][a-z0-9-]*$",
|
|
15
|
+
"description": "Identifier of the harness that spawned this agent."
|
|
16
|
+
},
|
|
17
|
+
"agent_name": {
|
|
18
|
+
"type": "string",
|
|
19
|
+
"pattern": "^[a-z][a-z0-9-]*$",
|
|
20
|
+
"description": "Neutral agent id as defined in nexus-core agents/{id}/meta.yml (e.g. 'architect', 'engineer')."
|
|
16
21
|
},
|
|
17
22
|
"agent_id": {
|
|
18
23
|
"type": "string",
|
|
@@ -7,14 +7,24 @@
|
|
|
7
7
|
"additionalProperties": false,
|
|
8
8
|
"required": ["cycles"],
|
|
9
9
|
"properties": {
|
|
10
|
+
"schema_version": {
|
|
11
|
+
"type": "string",
|
|
12
|
+
"pattern": "^\\d+\\.\\d+$",
|
|
13
|
+
"description": "nexus-core version that introduced this schema shape (e.g. '0.5'). Optional in v0.5.0 — candidate for required in v1.0.0 (Phase 2 entry)."
|
|
14
|
+
},
|
|
10
15
|
"cycles": {
|
|
11
16
|
"type": "array",
|
|
12
17
|
"description": "Chronologically ordered list of completed execution cycles",
|
|
13
18
|
"items": {
|
|
14
19
|
"type": "object",
|
|
15
20
|
"additionalProperties": false,
|
|
16
|
-
"required": ["completed_at", "branch", "plan", "tasks"],
|
|
21
|
+
"required": ["completed_at", "branch", "plan", "tasks", "schema_version"],
|
|
17
22
|
"properties": {
|
|
23
|
+
"schema_version": {
|
|
24
|
+
"type": "string",
|
|
25
|
+
"pattern": "^\\d+\\.\\d+$",
|
|
26
|
+
"description": "Version tag recorded at the time this cycle was archived. Required for every cycle as history.json accumulates across nexus-core versions."
|
|
27
|
+
},
|
|
18
28
|
"completed_at": {
|
|
19
29
|
"type": "string",
|
|
20
30
|
"format": "date-time",
|
|
@@ -7,6 +7,11 @@
|
|
|
7
7
|
"additionalProperties": false,
|
|
8
8
|
"required": ["id", "topic", "issues", "created_at"],
|
|
9
9
|
"properties": {
|
|
10
|
+
"schema_version": {
|
|
11
|
+
"type": "string",
|
|
12
|
+
"pattern": "^\\d+\\.\\d+$",
|
|
13
|
+
"description": "nexus-core version that introduced this schema shape (e.g. '0.5'). Optional in v0.5.0 — candidate for required in v1.0.0 (Phase 2 entry)."
|
|
14
|
+
},
|
|
10
15
|
"id": {
|
|
11
16
|
"type": "number",
|
|
12
17
|
"minimum": 1,
|
|
@@ -5,8 +5,13 @@
|
|
|
5
5
|
"description": "Schema for .nexus/state/runtime.json — ephemeral runtime configuration written by the harness at session start",
|
|
6
6
|
"type": "object",
|
|
7
7
|
"additionalProperties": false,
|
|
8
|
-
"required": ["teams_enabled", "session_started_at", "
|
|
8
|
+
"required": ["teams_enabled", "session_started_at", "harness_id", "harness_version"],
|
|
9
9
|
"properties": {
|
|
10
|
+
"schema_version": {
|
|
11
|
+
"type": "string",
|
|
12
|
+
"pattern": "^\\d+\\.\\d+$",
|
|
13
|
+
"description": "nexus-core version that introduced this schema shape (e.g. '0.5'). Optional in v0.5.0 — candidate for required in v1.0.0 (Phase 2 entry)."
|
|
14
|
+
},
|
|
10
15
|
"teams_enabled": {
|
|
11
16
|
"type": "boolean",
|
|
12
17
|
"description": "Whether multi-agent team orchestration is active in this session"
|
|
@@ -16,10 +21,14 @@
|
|
|
16
21
|
"format": "date-time",
|
|
17
22
|
"description": "ISO 8601 timestamp when the current harness session was started"
|
|
18
23
|
},
|
|
19
|
-
"
|
|
24
|
+
"harness_id": {
|
|
25
|
+
"type": "string",
|
|
26
|
+
"pattern": "^[a-z][a-z0-9-]*$",
|
|
27
|
+
"description": "Identifier of the harness that owns this runtime state (e.g. 'claude-nexus', 'opencode-nexus'). Free string — nexus-core does not enumerate harnesses."
|
|
28
|
+
},
|
|
29
|
+
"harness_version": {
|
|
20
30
|
"type": "string",
|
|
21
|
-
"
|
|
22
|
-
"description": "Version string of the harness plugin that wrote this file"
|
|
31
|
+
"description": "Semver-like version string of the harness plugin that wrote this file."
|
|
23
32
|
}
|
|
24
33
|
}
|
|
25
34
|
}
|
|
@@ -7,6 +7,11 @@
|
|
|
7
7
|
"additionalProperties": false,
|
|
8
8
|
"required": ["goal", "decisions", "tasks"],
|
|
9
9
|
"properties": {
|
|
10
|
+
"schema_version": {
|
|
11
|
+
"type": "string",
|
|
12
|
+
"pattern": "^\\d+\\.\\d+$",
|
|
13
|
+
"description": "nexus-core version that introduced this schema shape (e.g. '0.5'). Optional in v0.5.0 — candidate for required in v1.0.0 (Phase 2 entry)."
|
|
14
|
+
},
|
|
10
15
|
"goal": {
|
|
11
16
|
"type": "string",
|
|
12
17
|
"minLength": 1,
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"test_id": "artifact_write_first",
|
|
4
|
+
"description": "artifact_write creates the artifacts directory and writes the file when no artifacts directory exists, returning success:true and a path ending in the filename",
|
|
5
|
+
"covers": {
|
|
6
|
+
"return_value": {
|
|
7
|
+
"artifact_write": ["success", "path"]
|
|
8
|
+
}
|
|
9
|
+
},
|
|
10
|
+
"uncovered_params": ["filename", "content"],
|
|
11
|
+
"precondition": {
|
|
12
|
+
"state_files": {
|
|
13
|
+
".nexus/state/artifacts/findings.md": null
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"action": {
|
|
17
|
+
"tool": "artifact_write",
|
|
18
|
+
"params": {
|
|
19
|
+
"filename": "findings.md",
|
|
20
|
+
"content": "# Findings\n\nInitial research findings for the conformance test suite."
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"postcondition": {
|
|
24
|
+
"return_value": {
|
|
25
|
+
"$.success": true,
|
|
26
|
+
"$.path": { "type": "string", "pattern": "findings\\.md$" }
|
|
27
|
+
},
|
|
28
|
+
"state_files": {
|
|
29
|
+
".nexus/state/artifacts/findings.md": {}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"test_id": "artifact_write_overwrite",
|
|
35
|
+
"description": "artifact_write overwrites an existing artifact file and returns success:true without error",
|
|
36
|
+
"covers": {
|
|
37
|
+
"return_value": {
|
|
38
|
+
"artifact_write": ["success", "path"]
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"uncovered_params": ["filename", "content"],
|
|
42
|
+
"precondition": {
|
|
43
|
+
"state_files": {
|
|
44
|
+
".nexus/state/artifacts/existing.md": {
|
|
45
|
+
"content": "old content"
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
"action": {
|
|
50
|
+
"tool": "artifact_write",
|
|
51
|
+
"params": {
|
|
52
|
+
"filename": "existing.md",
|
|
53
|
+
"content": "new content"
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
"postcondition": {
|
|
57
|
+
"return_value": {
|
|
58
|
+
"$.success": true,
|
|
59
|
+
"$.path": { "type": "string", "pattern": "existing\\.md$" }
|
|
60
|
+
},
|
|
61
|
+
"state_files": {
|
|
62
|
+
".nexus/state/artifacts/existing.md": {}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"test_id": "artifact_write_creates_directory",
|
|
68
|
+
"description": "artifact_write auto-creates the .nexus/state/artifacts/ directory when it does not exist and then writes the file successfully",
|
|
69
|
+
"covers": {
|
|
70
|
+
"return_value": {
|
|
71
|
+
"artifact_write": ["success", "path"]
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
"uncovered_params": ["filename", "content"],
|
|
75
|
+
"precondition": {
|
|
76
|
+
"state_files": {
|
|
77
|
+
".nexus/state/artifacts/synthesis.md": null
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
"action": {
|
|
81
|
+
"tool": "artifact_write",
|
|
82
|
+
"params": {
|
|
83
|
+
"filename": "synthesis.md",
|
|
84
|
+
"content": "# Synthesis\n\nCross-cycle pattern analysis."
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
"postcondition": {
|
|
88
|
+
"return_value": {
|
|
89
|
+
"$.success": true,
|
|
90
|
+
"$.path": { "type": "string", "pattern": "synthesis\\.md$" }
|
|
91
|
+
},
|
|
92
|
+
"state_files": {
|
|
93
|
+
".nexus/state/artifacts/synthesis.md": {}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
]
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"test_id": "context_no_tasks",
|
|
4
|
+
"description": "context returns activeMode:null and an empty decisions array with a valid branch string when tasks.json does not exist",
|
|
5
|
+
"covers": {
|
|
6
|
+
"return_value": {
|
|
7
|
+
"context": ["activeMode", "branch", "decisions"]
|
|
8
|
+
}
|
|
9
|
+
},
|
|
10
|
+
"precondition": {
|
|
11
|
+
"state_files": {
|
|
12
|
+
".nexus/state/tasks.json": null
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"action": {
|
|
16
|
+
"tool": "context",
|
|
17
|
+
"params": {}
|
|
18
|
+
},
|
|
19
|
+
"postcondition": {
|
|
20
|
+
"return_value": {
|
|
21
|
+
"$.activeMode": null,
|
|
22
|
+
"$.branch": { "type": "string", "minLength": 1 },
|
|
23
|
+
"$.decisions.length": 0
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"test_id": "context_with_tasks",
|
|
29
|
+
"description": "context returns activeMode:team, the goal, and a tasksSummary with the correct total when tasks.json exists with a goal and 2 tasks",
|
|
30
|
+
"covers": {
|
|
31
|
+
"state_schemas": {
|
|
32
|
+
"tasks.schema.json": ["goal", "tasks[].id", "tasks[].status"]
|
|
33
|
+
},
|
|
34
|
+
"return_value": {
|
|
35
|
+
"context": ["activeMode", "goal", "tasksSummary.total", "tasksSummary.completed", "tasksSummary.pending"]
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
"precondition": {
|
|
39
|
+
"state_files": {
|
|
40
|
+
".nexus/state/tasks.json": {
|
|
41
|
+
"goal": "Deliver conformance fixture suite",
|
|
42
|
+
"decisions": [],
|
|
43
|
+
"tasks": [
|
|
44
|
+
{
|
|
45
|
+
"id": 1,
|
|
46
|
+
"title": "Write fixture schema",
|
|
47
|
+
"context": "Define the JSON Schema",
|
|
48
|
+
"status": "completed",
|
|
49
|
+
"deps": [],
|
|
50
|
+
"created_at": "2026-04-13T00:00:00.000Z"
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"id": 2,
|
|
54
|
+
"title": "Write tool fixtures",
|
|
55
|
+
"context": "Create per-tool fixture files",
|
|
56
|
+
"status": "pending",
|
|
57
|
+
"deps": [1],
|
|
58
|
+
"created_at": "2026-04-13T00:00:00.000Z"
|
|
59
|
+
}
|
|
60
|
+
]
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
"action": {
|
|
65
|
+
"tool": "context",
|
|
66
|
+
"params": {}
|
|
67
|
+
},
|
|
68
|
+
"postcondition": {
|
|
69
|
+
"return_value": {
|
|
70
|
+
"$.activeMode": "team",
|
|
71
|
+
"$.goal": "Deliver conformance fixture suite",
|
|
72
|
+
"$.tasksSummary.total": 2
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"test_id": "context_with_decisions",
|
|
78
|
+
"description": "context returns a decisions array with length 2 when decisions.json contains 2 entries alongside an active tasks.json",
|
|
79
|
+
"covers": {
|
|
80
|
+
"return_value": {
|
|
81
|
+
"context": ["decisions"]
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
"precondition": {
|
|
85
|
+
"state_files": {
|
|
86
|
+
".nexus/state/tasks.json": {
|
|
87
|
+
"goal": "Deliver conformance fixture suite",
|
|
88
|
+
"decisions": [
|
|
89
|
+
"Use declarative JSONPath assertions for harness neutrality.",
|
|
90
|
+
"One tool per fixture file to keep scope bounded."
|
|
91
|
+
],
|
|
92
|
+
"tasks": [
|
|
93
|
+
{
|
|
94
|
+
"id": 1,
|
|
95
|
+
"title": "Write fixture schema",
|
|
96
|
+
"context": "Define the JSON Schema",
|
|
97
|
+
"status": "completed",
|
|
98
|
+
"deps": [],
|
|
99
|
+
"created_at": "2026-04-13T00:00:00.000Z"
|
|
100
|
+
}
|
|
101
|
+
]
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
"action": {
|
|
106
|
+
"tool": "context",
|
|
107
|
+
"params": {}
|
|
108
|
+
},
|
|
109
|
+
"postcondition": {
|
|
110
|
+
"return_value": {
|
|
111
|
+
"$.decisions.length": 2
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
"test_id": "context_tasks_summary_breakdown",
|
|
117
|
+
"description": "context computes tasksSummary correctly when the task list contains 1 completed, 1 pending, and 1 in_progress task",
|
|
118
|
+
"covers": {
|
|
119
|
+
"state_schemas": {
|
|
120
|
+
"tasks.schema.json": ["tasks[].status"]
|
|
121
|
+
},
|
|
122
|
+
"return_value": {
|
|
123
|
+
"context": ["tasksSummary.total", "tasksSummary.completed", "tasksSummary.pending"]
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
"precondition": {
|
|
127
|
+
"state_files": {
|
|
128
|
+
".nexus/state/tasks.json": {
|
|
129
|
+
"goal": "Summary breakdown validation",
|
|
130
|
+
"decisions": [],
|
|
131
|
+
"tasks": [
|
|
132
|
+
{
|
|
133
|
+
"id": 1,
|
|
134
|
+
"title": "Done task",
|
|
135
|
+
"context": "Already finished",
|
|
136
|
+
"status": "completed",
|
|
137
|
+
"deps": [],
|
|
138
|
+
"created_at": "2026-04-13T00:00:00.000Z"
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
"id": 2,
|
|
142
|
+
"title": "Pending task",
|
|
143
|
+
"context": "Not yet started",
|
|
144
|
+
"status": "pending",
|
|
145
|
+
"deps": [],
|
|
146
|
+
"created_at": "2026-04-13T00:00:00.000Z"
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
"id": 3,
|
|
150
|
+
"title": "Active task",
|
|
151
|
+
"context": "Currently being worked on",
|
|
152
|
+
"status": "in_progress",
|
|
153
|
+
"deps": [],
|
|
154
|
+
"created_at": "2026-04-13T00:00:00.000Z"
|
|
155
|
+
}
|
|
156
|
+
]
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
"action": {
|
|
161
|
+
"tool": "context",
|
|
162
|
+
"params": {}
|
|
163
|
+
},
|
|
164
|
+
"postcondition": {
|
|
165
|
+
"return_value": {
|
|
166
|
+
"$.tasksSummary.total": 3,
|
|
167
|
+
"$.tasksSummary.completed": 1,
|
|
168
|
+
"$.tasksSummary.pending": 1
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
]
|