@moreih29/nexus-core 0.4.0 → 0.6.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 +15 -18
- package/conformance/examples/plan.extension.schema.example.json +25 -0
- package/conformance/lifecycle/README.md +1 -3
- package/conformance/lifecycle/agent-complete.json +2 -1
- package/conformance/lifecycle/agent-resume.json +2 -1
- package/conformance/lifecycle/agent-spawn.json +5 -8
- package/conformance/scenarios/full-plan-cycle.json +3 -3
- package/conformance/schema/fixture.schema.json +6 -6
- 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/tasks.schema.json +5 -0
- package/conformance/tools/plan-decide.json +7 -7
- package/conformance/tools/plan-start.json +1 -1
- package/conformance/tools/task-add.json +1 -1
- package/conformance/tools/task-close.json +2 -0
- package/docs/consumer-implementation-guide.md +7 -11
- package/docs/nexus-layout.md +0 -15
- package/docs/nexus-outputs-contract.md +15 -25
- package/docs/nexus-state-overview.md +0 -19
- package/docs/nexus-tools-contract.md +12 -2
- package/manifest.json +26 -26
- package/package.json +5 -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
- package/conformance/lifecycle/session-end.json +0 -31
- package/conformance/lifecycle/session-start.json +0 -36
- package/conformance/state-schemas/runtime.schema.json +0 -25
package/conformance/README.md
CHANGED
|
@@ -105,18 +105,16 @@ Each fixture must contain exactly one of: `action` (single tool invocation), `ev
|
|
|
105
105
|
|
|
106
106
|
## Event-based (Lifecycle) Fixtures
|
|
107
107
|
|
|
108
|
-
|
|
108
|
+
`agent-tracker.json`은 MCP tool이 아니라 harness의 session hook이 관리한다. 이 파일의 구조적 정확성을 검증하기 위해 `action` 대신 `event` 필드를 사용하는 lifecycle fixture를 사용한다.
|
|
109
109
|
|
|
110
110
|
Event fixture는 "harness가 특정 event를 실행한 후 state 파일의 구조가 올바른가"를 선언적으로 명세한다. Tool invocation 없이 event 트리거만으로 postcondition을 검증한다.
|
|
111
111
|
|
|
112
112
|
### Event types
|
|
113
113
|
|
|
114
|
-
`event.type`은 다음
|
|
114
|
+
`event.type`은 다음 3종 중 하나여야 한다:
|
|
115
115
|
|
|
116
116
|
| Event type | 책임 범위 |
|
|
117
117
|
|---|---|
|
|
118
|
-
| `session_start` | `runtime.json` 초기화, `agent-tracker.json` 빈 배열 생성 |
|
|
119
|
-
| `session_end` | `runtime.json` 삭제, `agent-tracker.json` 삭제 |
|
|
120
118
|
| `agent_spawn` | `agent-tracker.json`에 신규 항목 생성 (running 상태) |
|
|
121
119
|
| `agent_complete` | `agent-tracker.json` 항목을 완료 상태로 전환 |
|
|
122
120
|
| `agent_resume` | `agent-tracker.json` 재개 카운터 증가 및 상태 복귀 |
|
|
@@ -125,20 +123,20 @@ Event fixture는 "harness가 특정 event를 실행한 후 state 파일의 구
|
|
|
125
123
|
|
|
126
124
|
```json
|
|
127
125
|
{
|
|
128
|
-
"test_id": "
|
|
126
|
+
"test_id": "agent_spawn_creates_entry",
|
|
129
127
|
"description": "...",
|
|
130
128
|
"covers": {
|
|
131
129
|
"state_schemas": {
|
|
132
|
-
"
|
|
130
|
+
"agent-tracker.schema.json": ["harness_id", "agent_name", "agent_id", "status"]
|
|
133
131
|
}
|
|
134
132
|
},
|
|
135
133
|
"event": {
|
|
136
|
-
"type": "
|
|
134
|
+
"type": "agent_spawn",
|
|
137
135
|
"params": { ... }
|
|
138
136
|
},
|
|
139
137
|
"postcondition": {
|
|
140
138
|
"state_files": {
|
|
141
|
-
".nexus/state/
|
|
139
|
+
".nexus/state/agent-tracker.json": { "$[0].status": "running" }
|
|
142
140
|
}
|
|
143
141
|
}
|
|
144
142
|
}
|
|
@@ -146,12 +144,10 @@ Event fixture는 "harness가 특정 event를 실행한 후 state 파일의 구
|
|
|
146
144
|
|
|
147
145
|
### Lifecycle fixture 목록
|
|
148
146
|
|
|
149
|
-
`conformance/lifecycle/` 디렉토리에
|
|
147
|
+
`conformance/lifecycle/` 디렉토리에 3개 파일이 존재한다:
|
|
150
148
|
|
|
151
149
|
| 파일 | Event type | 검증 대상 |
|
|
152
150
|
|---|---|---|
|
|
153
|
-
| `session-start.json` | `session_start` | `runtime.json` 초기화, `agent-tracker.json` 빈 배열 |
|
|
154
|
-
| `session-end.json` | `session_end` | `runtime.json` 삭제, `agent-tracker.json` 삭제 |
|
|
155
151
|
| `agent-spawn.json` | `agent_spawn` | `agent-tracker.json` 첫 항목 생성 (running 상태) |
|
|
156
152
|
| `agent-complete.json` | `agent_complete` | `agent-tracker.json` 항목 완료 상태 전환 |
|
|
157
153
|
| `agent-resume.json` | `agent_resume` | `agent-tracker.json` 재개 카운터 및 상태 복귀 |
|
|
@@ -170,6 +166,7 @@ Assertions are key/value objects where keys are JSONPath expressions and values
|
|
|
170
166
|
| `"$.field": { "type": "number", "min": 1 }` | Numeric value >= 1 |
|
|
171
167
|
| `"$.field": { "type": "string", "minLength": 5 }` | String with minimum length |
|
|
172
168
|
| `".nexus/state/plan.json": null` | File must not exist |
|
|
169
|
+
| `".nexus/state/artifacts/findings.md": {}` | File must exist; content not inspected (use for non-JSON artifacts like .md, .txt, binary files) |
|
|
173
170
|
|
|
174
171
|
For `state_files`, a `null` value at the file path key means the file must be absent. A `null` value at a JSONPath key within a file assertion means that field must be `null`.
|
|
175
172
|
|
|
@@ -240,7 +237,10 @@ A conformance test runner does the following for each fixture:
|
|
|
240
237
|
- For multi-step scenarios: iterate `steps` in order, calling each `action` (or triggering each `event`) and evaluating `assert_return` and `assert_state` after each step before proceeding.
|
|
241
238
|
4. **Evaluate postconditions**:
|
|
242
239
|
- Check `postcondition.return_value` assertions against the tool's return value.
|
|
243
|
-
- Check `postcondition.state_files` assertions against the actual file system state.
|
|
240
|
+
- Check `postcondition.state_files` assertions against the actual file system state. For each entry in `state_files`:
|
|
241
|
+
- Value is `null` → assert the file does NOT exist.
|
|
242
|
+
- Value is an empty object `{}` → assert the file EXISTS; do NOT parse content (use for non-JSON artifacts: .md, .txt, binary).
|
|
243
|
+
- Value is a non-empty object `{...}` → parse file as JSON and evaluate each JSONPath assertion against the parsed content.
|
|
244
244
|
- If `postcondition.error` is `true`, the tool call must have produced an error.
|
|
245
245
|
- If `postcondition.error_contains` is set, the error message must contain that substring.
|
|
246
246
|
5. **Report** pass/fail per `test_id`.
|
|
@@ -277,29 +277,26 @@ for (const fixture of fixtures) {
|
|
|
277
277
|
| `context` | Read or write .nexus/context/ knowledge files | `tools/context.json` |
|
|
278
278
|
| `artifact_write` | Write an artifact output file | `tools/artifact-write.json` |
|
|
279
279
|
|
|
280
|
-
### Lifecycle events (
|
|
280
|
+
### Lifecycle events (3/3 커버됨)
|
|
281
281
|
|
|
282
282
|
| Event type | Fixture file |
|
|
283
283
|
|---|---|
|
|
284
|
-
| `session_start` | `lifecycle/session-start.json` |
|
|
285
|
-
| `session_end` | `lifecycle/session-end.json` |
|
|
286
284
|
| `agent_spawn` | `lifecycle/agent-spawn.json` |
|
|
287
285
|
| `agent_complete` | `lifecycle/agent-complete.json` |
|
|
288
286
|
| `agent_resume` | `lifecycle/agent-resume.json` |
|
|
289
287
|
|
|
290
288
|
### State-schema field coverage
|
|
291
289
|
|
|
292
|
-
|
|
290
|
+
4개 state-schema의 모든 필드가 100% 커버된다:
|
|
293
291
|
|
|
294
292
|
| Schema | 검증 도구 |
|
|
295
293
|
|---|---|
|
|
296
294
|
| `plan.schema.json` | `tools/plan-*.json` fixtures |
|
|
297
295
|
| `tasks.schema.json` | `tools/task-*.json` fixtures |
|
|
298
296
|
| `history.schema.json` | `tools/history-search.json`, `tools/task-close.json` |
|
|
299
|
-
| `runtime.schema.json` | `lifecycle/session-*.json` fixtures |
|
|
300
297
|
| `agent-tracker.schema.json` | `lifecycle/agent-*.json` fixtures |
|
|
301
298
|
|
|
302
|
-
|
|
299
|
+
Validator 통과 결과 예시: `✓ All state-schema fields covered: 4 schemas across fixture suite`
|
|
303
300
|
|
|
304
301
|
## Excluded tools
|
|
305
302
|
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "conformance/examples/plan.extension.schema.example.json",
|
|
4
|
+
"title": "Example: Harness-local plan state extension",
|
|
5
|
+
"description": "Non-normative reference example of a harness-local extension schema for plan.json. Harnesses MAY add supplemental fields via {base}.extension.json files in .nexus/state/{harness-id}/. Consumers replace harness_specific_field_example with their own fields. See docs/nexus-outputs-contract.md §Harness-local State Extension for the pattern definition.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"required": ["extends"],
|
|
9
|
+
"properties": {
|
|
10
|
+
"extends": {
|
|
11
|
+
"type": "string",
|
|
12
|
+
"const": "conformance/state-schemas/plan.schema.json",
|
|
13
|
+
"description": "Reference to the parent common-schema this extension supplements"
|
|
14
|
+
},
|
|
15
|
+
"harness_id": {
|
|
16
|
+
"type": "string",
|
|
17
|
+
"pattern": "^[a-z][a-z0-9-]*$",
|
|
18
|
+
"description": "Identifier of the harness that produced this extension file"
|
|
19
|
+
},
|
|
20
|
+
"harness_specific_field_example": {
|
|
21
|
+
"type": "string",
|
|
22
|
+
"description": "Placeholder — replace with your harness's actual extension fields as needed"
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -6,12 +6,10 @@
|
|
|
6
6
|
|
|
7
7
|
| Fixture | Event Type | 검증 대상 |
|
|
8
8
|
|---|---|---|
|
|
9
|
-
| `session-start.json` | `session_start` | `runtime.json` 초기화, `agent-tracker.json` 빈 배열 |
|
|
10
|
-
| `session-end.json` | `session_end` | `runtime.json` 삭제, `agent-tracker.json` 삭제 |
|
|
11
9
|
| `agent-spawn.json` | `agent_spawn` | `agent-tracker.json` 첫 항목 생성 (running 상태) |
|
|
12
10
|
| `agent-complete.json` | `agent_complete` | `agent-tracker.json` 항목 완료 상태 전환 |
|
|
13
11
|
| `agent-resume.json` | `agent_resume` | `agent-tracker.json` 재개 카운터 및 상태 복귀 |
|
|
14
12
|
|
|
15
13
|
## Tool-action 대신 Event 트리거 사용
|
|
16
14
|
|
|
17
|
-
각 fixture는 `action` (tool invocation) 대신 `event` 필드를 사용한다. `
|
|
15
|
+
각 fixture는 `action` (tool invocation) 대신 `event` 필드를 사용한다. `agent-tracker.json`은 harness의 session hook이 관리하며, MCP tool이 직접 쓰지 않는다. Event fixture는 "harness가 event를 실행한 후 state 파일의 구조가 올바른가"를 선언적으로 명세한다.
|
|
@@ -3,18 +3,14 @@
|
|
|
3
3
|
"description": "Verifies that agent_spawn appends a new running agent entry to agent-tracker.json with required fields initialized correctly",
|
|
4
4
|
"precondition": {
|
|
5
5
|
"state_files": {
|
|
6
|
-
".nexus/state/runtime.json": {
|
|
7
|
-
"teams_enabled": true,
|
|
8
|
-
"session_started_at": "2026-04-13T00:00:00.000Z",
|
|
9
|
-
"plugin_version": "0.4.0"
|
|
10
|
-
},
|
|
11
6
|
".nexus/state/agent-tracker.json": []
|
|
12
7
|
}
|
|
13
8
|
},
|
|
14
9
|
"event": {
|
|
15
10
|
"type": "agent_spawn",
|
|
16
11
|
"params": {
|
|
17
|
-
"
|
|
12
|
+
"harness_id": "claude-nexus",
|
|
13
|
+
"agent_name": "architect",
|
|
18
14
|
"agent_id": "uuid-eng01"
|
|
19
15
|
},
|
|
20
16
|
"description": "Harness spawns an agent instance and records its initial state in the agent registry"
|
|
@@ -23,7 +19,8 @@
|
|
|
23
19
|
"state_files": {
|
|
24
20
|
".nexus/state/agent-tracker.json": {
|
|
25
21
|
"$.length": 1,
|
|
26
|
-
"$[0].
|
|
22
|
+
"$[0].harness_id": "claude-nexus",
|
|
23
|
+
"$[0].agent_name": "architect",
|
|
27
24
|
"$[0].agent_id": "uuid-eng01",
|
|
28
25
|
"$[0].started_at": { "type": "iso8601" },
|
|
29
26
|
"$[0].resume_count": 0,
|
|
@@ -33,7 +30,7 @@
|
|
|
33
30
|
},
|
|
34
31
|
"covers": {
|
|
35
32
|
"state_schemas": {
|
|
36
|
-
"agent-tracker.schema.json": ["
|
|
33
|
+
"agent-tracker.schema.json": ["harness_id", "agent_name", "agent_id", "started_at", "resume_count", "status"]
|
|
37
34
|
}
|
|
38
35
|
}
|
|
39
36
|
}
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
},
|
|
16
16
|
"description": "End-to-end lifecycle scenario: plan/task/history state transitions and each tool's return value across 5 sequential invocations."
|
|
17
17
|
},
|
|
18
|
-
"uncovered_params": ["research_summary", "issue_id", "
|
|
18
|
+
"uncovered_params": ["research_summary", "issue_id", "decision", "title", "context", "deps"],
|
|
19
19
|
"precondition": {
|
|
20
20
|
"state_files": {
|
|
21
21
|
".nexus/state/plan.json": null,
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"tool": "plan_decide",
|
|
57
57
|
"params": {
|
|
58
58
|
"issue_id": 1,
|
|
59
|
-
"
|
|
59
|
+
"decision": "Keep .nexus/state/ as the canonical location. Documented in state-schemas README."
|
|
60
60
|
}
|
|
61
61
|
},
|
|
62
62
|
"assert_return": {
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
"tool": "plan_decide",
|
|
79
79
|
"params": {
|
|
80
80
|
"issue_id": 2,
|
|
81
|
-
"
|
|
81
|
+
"decision": "Ship a one-shot migration script as a standalone npm script. Document in RELEASING.md."
|
|
82
82
|
}
|
|
83
83
|
},
|
|
84
84
|
"assert_return": {
|
|
@@ -112,7 +112,7 @@
|
|
|
112
112
|
"properties": {
|
|
113
113
|
"state_files": {
|
|
114
114
|
"type": "object",
|
|
115
|
-
"description": "Map of file path to content object
|
|
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).",
|
|
116
116
|
"additionalProperties": {
|
|
117
117
|
"oneOf": [
|
|
118
118
|
{ "type": "object" },
|
|
@@ -160,18 +160,18 @@
|
|
|
160
160
|
},
|
|
161
161
|
"event": {
|
|
162
162
|
"type": "object",
|
|
163
|
-
"description": "A lifecycle event that triggers harness-level behavior without a direct tool call. Used for verifying
|
|
163
|
+
"description": "A lifecycle event that triggers harness-level behavior without a direct tool call. Used for verifying agent-tracker.json state changes.",
|
|
164
164
|
"additionalProperties": false,
|
|
165
165
|
"required": ["type"],
|
|
166
166
|
"properties": {
|
|
167
167
|
"type": {
|
|
168
168
|
"type": "string",
|
|
169
|
-
"enum": ["
|
|
170
|
-
"description": "Lifecycle event type.
|
|
169
|
+
"enum": ["agent_spawn", "agent_complete", "agent_resume"],
|
|
170
|
+
"description": "Lifecycle event type. agent_spawn/agent_complete/agent_resume: agent instance lifecycle."
|
|
171
171
|
},
|
|
172
172
|
"params": {
|
|
173
173
|
"type": "object",
|
|
174
|
-
"description": "Optional event-specific parameters (e.g.
|
|
174
|
+
"description": "Optional event-specific parameters (e.g. harness_id, agent_name, and agent_id for agent_spawn)",
|
|
175
175
|
"additionalProperties": true
|
|
176
176
|
},
|
|
177
177
|
"description": {
|
|
@@ -187,7 +187,7 @@
|
|
|
187
187
|
"properties": {
|
|
188
188
|
"state_files": {
|
|
189
189
|
"type": "object",
|
|
190
|
-
"description": "Map of file path to assertion object
|
|
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.",
|
|
191
191
|
"additionalProperties": {
|
|
192
192
|
"oneOf": [
|
|
193
193
|
{
|
|
@@ -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,
|
|
@@ -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,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
[
|
|
2
2
|
{
|
|
3
3
|
"test_id": "plan_decide_happy_path",
|
|
4
|
-
"description": "plan_decide marks an issue as decided and records the decision
|
|
4
|
+
"description": "plan_decide marks an issue as decided and records the decision text on the issue object",
|
|
5
5
|
"covers": {
|
|
6
6
|
"state_schemas": {
|
|
7
7
|
"plan.schema.json": ["issues[].status", "issues[].decision"]
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"plan_decide": ["decided", "allComplete", "remaining"]
|
|
11
11
|
}
|
|
12
12
|
},
|
|
13
|
-
"uncovered_params": ["issue_id", "
|
|
13
|
+
"uncovered_params": ["issue_id", "decision"],
|
|
14
14
|
"precondition": {
|
|
15
15
|
"state_files": {
|
|
16
16
|
".nexus/state/plan.json": {
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"tool": "plan_decide",
|
|
38
38
|
"params": {
|
|
39
39
|
"issue_id": 1,
|
|
40
|
-
"
|
|
40
|
+
"decision": "Use declarative JSON with JSONPath assertions. Harness-neutral tool names only."
|
|
41
41
|
}
|
|
42
42
|
},
|
|
43
43
|
"postcondition": {
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
"plan.schema.json": []
|
|
64
64
|
}
|
|
65
65
|
},
|
|
66
|
-
"uncovered_params": ["issue_id", "
|
|
66
|
+
"uncovered_params": ["issue_id", "decision"],
|
|
67
67
|
"precondition": {
|
|
68
68
|
"state_files": {
|
|
69
69
|
".nexus/state/plan.json": null
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
"tool": "plan_decide",
|
|
74
74
|
"params": {
|
|
75
75
|
"issue_id": 1,
|
|
76
|
-
"
|
|
76
|
+
"decision": "Some decision"
|
|
77
77
|
}
|
|
78
78
|
},
|
|
79
79
|
"postcondition": {
|
|
@@ -90,7 +90,7 @@
|
|
|
90
90
|
"plan.schema.json": ["issues[].how_agents", "issues[].how_agents[]", "issues[].how_summary", "issues[].how_agent_ids"]
|
|
91
91
|
}
|
|
92
92
|
},
|
|
93
|
-
"uncovered_params": ["issue_id"],
|
|
93
|
+
"uncovered_params": ["issue_id", "decision"],
|
|
94
94
|
"precondition": {
|
|
95
95
|
"state_files": {
|
|
96
96
|
".nexus/state/plan.json": {
|
|
@@ -112,7 +112,7 @@
|
|
|
112
112
|
"tool": "plan_decide",
|
|
113
113
|
"params": {
|
|
114
114
|
"issue_id": 1,
|
|
115
|
-
"
|
|
115
|
+
"decision": "Declarative JSON with JSONPath assertions, harness-neutral.",
|
|
116
116
|
"how_agents": ["architect", "postdoc"],
|
|
117
117
|
"how_summary": {
|
|
118
118
|
"architect": "JSONPath assertions provide harness-agnostic verifiability.",
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"description": "plan_start creates plan.json with correct structure when given a topic, issues, and research_summary",
|
|
5
5
|
"covers": {
|
|
6
6
|
"state_schemas": {
|
|
7
|
-
"plan.schema.json": ["id", "topic", "issues[].id", "issues[].title", "issues[].status", "research_summary", "created_at"]
|
|
7
|
+
"plan.schema.json": ["schema_version", "id", "topic", "issues[].id", "issues[].title", "issues[].status", "research_summary", "created_at"]
|
|
8
8
|
},
|
|
9
9
|
"return_value": {
|
|
10
10
|
"plan_start": ["created", "plan_id", "topic", "issueCount"]
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"description": "task_add creates tasks.json with the new task when no tasks.json existed, assigning id=1 and status=pending",
|
|
5
5
|
"covers": {
|
|
6
6
|
"state_schemas": {
|
|
7
|
-
"tasks.schema.json": ["tasks[].id", "tasks[].title", "tasks[].status", "tasks[].deps", "tasks[].approach", "tasks[].acceptance", "tasks[].risk", "tasks[].context", "tasks[].created_at"]
|
|
7
|
+
"tasks.schema.json": ["schema_version", "tasks[].id", "tasks[].title", "tasks[].status", "tasks[].deps", "tasks[].approach", "tasks[].acceptance", "tasks[].risk", "tasks[].context", "tasks[].created_at"]
|
|
8
8
|
},
|
|
9
9
|
"return_value": {
|
|
10
10
|
"task_add": ["task"]
|
|
@@ -97,7 +97,7 @@ A complete Nexus consumer comprises nine components. They have hard dependencies
|
|
|
97
97
|
| # | Component | Description |
|
|
98
98
|
|---|-----------|-------------|
|
|
99
99
|
| 1 | `.nexus/` Directory Initialization | Create the required directory tree and `.gitignore` at session start |
|
|
100
|
-
| 2 | State File Management | Read/write plan.json, tasks.json, history.json,
|
|
100
|
+
| 2 | State File Management | Read/write plan.json, tasks.json, history.json, agent-tracker.json |
|
|
101
101
|
| 3 | MCP Tool Implementation | Concrete implementations of the 11 abstract Nexus tools |
|
|
102
102
|
| 4 | Capability Mapping | Local file translating abstract capability IDs to concrete disallowed tools |
|
|
103
103
|
| 5 | Agent Catalog | Load nexus-core agents, apply capability-map, register with harness |
|
|
@@ -159,7 +159,6 @@ Nexus state is split into two categories with different scopes, persistence, and
|
|
|
159
159
|
├── state/ ← session-scoped (not git-tracked)
|
|
160
160
|
│ ├── plan.json
|
|
161
161
|
│ ├── tasks.json
|
|
162
|
-
│ ├── runtime.json
|
|
163
162
|
│ ├── agent-tracker.json
|
|
164
163
|
│ ├── tool-log.jsonl
|
|
165
164
|
│ ├── edit-tracker.json
|
|
@@ -182,9 +181,8 @@ At session start, your harness must:
|
|
|
182
181
|
1. Create `.nexus/` if it does not exist.
|
|
183
182
|
2. Create `.nexus/state/` if it does not exist.
|
|
184
183
|
3. Write `.nexus/.gitignore` with content `state/` if the file does not exist.
|
|
185
|
-
4.
|
|
186
|
-
5.
|
|
187
|
-
6. Check for stale state files from a prior crashed session. If `plan.json` or `tasks.json` exist without a running session, warn the user that a previous session may not have closed cleanly.
|
|
184
|
+
4. Initialize `.nexus/state/agent-tracker.json` as an empty array `[]`.
|
|
185
|
+
5. Check for stale state files from a prior crashed session. If `plan.json` or `tasks.json` exist without a running session, warn the user that a previous session may not have closed cleanly.
|
|
188
186
|
|
|
189
187
|
### Key state files
|
|
190
188
|
|
|
@@ -192,7 +190,6 @@ At session start, your harness must:
|
|
|
192
190
|
|------|-------|------------|------------|------------|
|
|
193
191
|
| `state/plan.json` | Session | No | `plan_start` tool | `task_close` tool |
|
|
194
192
|
| `state/tasks.json` | Session | No | `task_add` tool (first call) | `task_close` tool |
|
|
195
|
-
| `state/runtime.json` | Session | No | session_start hook | session_end hook |
|
|
196
193
|
| `state/agent-tracker.json` | Session | No | session_start hook | session_end hook |
|
|
197
194
|
| `state/tool-log.jsonl` | Session | No | post_tool_use hook | session_end hook |
|
|
198
195
|
| `state/edit-tracker.json` | Session | No | post_tool_use hook (first edit) | task_close / session_end |
|
|
@@ -200,7 +197,7 @@ At session start, your harness must:
|
|
|
200
197
|
|
|
201
198
|
### Schema validation
|
|
202
199
|
|
|
203
|
-
JSON Schema definitions for all state files are available in `conformance/state-schemas/`. The schemas cover `plan.json`, `tasks.json`, `history.json`,
|
|
200
|
+
JSON Schema definitions for all state files are available in `conformance/state-schemas/`. The schemas cover `plan.json`, `tasks.json`, `history.json`, and `agent-tracker.json`. Validate state files against these schemas in your test suite.
|
|
204
201
|
|
|
205
202
|
For full lifecycle and tool access details, see [nexus-state-overview.md](./nexus-state-overview.md) and [nexus-layout.md](./nexus-layout.md).
|
|
206
203
|
|
|
@@ -526,7 +523,6 @@ Identify the equivalent events in your harness's plugin system and implement the
|
|
|
526
523
|
**Expected consumer behavior:**
|
|
527
524
|
- Create `.nexus/` and `.nexus/state/` directories if they do not exist.
|
|
528
525
|
- Write `.nexus/.gitignore` with `state/` if it does not exist.
|
|
529
|
-
- Write `.nexus/state/runtime.json` with session metadata: session ID, harness version, start timestamp, and any environment properties your harness tracks.
|
|
530
526
|
- Initialize `.nexus/state/agent-tracker.json` as `[]`.
|
|
531
527
|
- Check for stale state from a prior crashed session: if `plan.json` or `tasks.json` exist, warn the user that these may be leftover from an unclean shutdown.
|
|
532
528
|
- Load the knowledge index: list files in `.nexus/memory/`, `.nexus/context/`, and `.nexus/rules/` to build the reference index that will be injected into subagent spawns.
|
|
@@ -555,7 +551,7 @@ Identify the equivalent events in your harness's plugin system and implement the
|
|
|
555
551
|
**When it fires:** Lead spawns a subagent to execute a task.
|
|
556
552
|
|
|
557
553
|
**Expected consumer behavior:**
|
|
558
|
-
- Record the new agent entry in `agent-tracker.json`: `{
|
|
554
|
+
- Record the new agent entry in `agent-tracker.json`: `{ harness_id, agent_name, agent_id, task_id, started_at }`.
|
|
559
555
|
- Inject the knowledge index into the subagent's initial context: the list of files in `.nexus/memory/`, `.nexus/context/`, and `.nexus/rules/` so the agent knows what project knowledge is available.
|
|
560
556
|
- Apply capability restrictions: resolve `effective_capabilities` for this agent type and configure the subagent's tool access accordingly (see §6).
|
|
561
557
|
- Apply the resume evaluation: check `owner_reuse_policy` on the task and the agent's `resume_tier` to determine whether to spawn fresh or resume a prior session (see §10).
|
|
@@ -607,7 +603,7 @@ Read-only tools (query tools, status reads) are never blocked by capability gate
|
|
|
607
603
|
**Expected consumer behavior:**
|
|
608
604
|
- Check for pending tasks: if `tasks.json` exists and contains incomplete tasks (status `pending` or `in_progress`), warn the user that the session is ending with unfinished work and suggest calling `task_close` to archive before exiting.
|
|
609
605
|
- Check for an active plan: if `plan.json` exists, warn that the plan session will be lost if not archived.
|
|
610
|
-
- Delete `
|
|
606
|
+
- Delete `agent-tracker.json` (a session-scoped file that has no value beyond the session).
|
|
611
607
|
- Optionally rotate or archive `tool-log.jsonl` if your harness supports log retention.
|
|
612
608
|
- Do not delete `history.json`, `memory/`, `context/`, or `rules/` — these are project-scoped and must persist.
|
|
613
609
|
|
|
@@ -807,7 +803,7 @@ Implement tag detection in your `user_message` hook. When `[plan]` is detected,
|
|
|
807
803
|
|
|
808
804
|
| Event | Minimum required behavior |
|
|
809
805
|
|-------|--------------------------|
|
|
810
|
-
| `session_start` | Create `.nexus/state/` directory;
|
|
806
|
+
| `session_start` | Create `.nexus/state/` directory; initialize `agent-tracker.json` as `[]` |
|
|
811
807
|
| `user_message` | Detect `[plan]` tag; load `skills/nx-plan/body.md`; inject into Lead's context |
|
|
812
808
|
| `session_end` | Check for `tasks.json`; if present with incomplete tasks, warn the user |
|
|
813
809
|
|
package/docs/nexus-layout.md
CHANGED
|
@@ -11,7 +11,6 @@ This document is the canonical reference for the `.nexus/` directory structure u
|
|
|
11
11
|
├── state/ ← session/branch-scoped (ephemeral)
|
|
12
12
|
│ ├── plan.json
|
|
13
13
|
│ ├── tasks.json
|
|
14
|
-
│ ├── runtime.json
|
|
15
14
|
│ ├── agent-tracker.json
|
|
16
15
|
│ ├── tool-log.jsonl
|
|
17
16
|
│ ├── edit-tracker.json
|
|
@@ -73,20 +72,6 @@ This document is the canonical reference for the `.nexus/` directory structure u
|
|
|
73
72
|
|
|
74
73
|
---
|
|
75
74
|
|
|
76
|
-
#### `state/runtime.json`
|
|
77
|
-
|
|
78
|
-
**Purpose.** Harness-internal session state that does not belong in plan or task records (e.g., active agent registrations, session-level flags).
|
|
79
|
-
|
|
80
|
-
**Scope.** Session-scoped.
|
|
81
|
-
|
|
82
|
-
**Git tracking.** Ignored.
|
|
83
|
-
|
|
84
|
-
**Lifecycle.** Created at session start. Discarded at session end.
|
|
85
|
-
|
|
86
|
-
**Owner.** Harness runtime.
|
|
87
|
-
|
|
88
|
-
---
|
|
89
|
-
|
|
90
75
|
#### `state/agent-tracker.json`
|
|
91
76
|
|
|
92
77
|
**Purpose.** Records which subagents have been spawned in the current session, their assigned tasks, and their resume-tier classification.
|