@moreih29/nexus-core 0.12.0 → 0.13.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/README.md +48 -63
- package/assets/agents/architect/body.ko.md +177 -0
- package/{agents → assets/agents}/architect/body.md +16 -0
- package/assets/agents/designer/body.ko.md +125 -0
- package/{agents → assets/agents}/designer/body.md +16 -0
- package/assets/agents/engineer/body.ko.md +106 -0
- package/{agents → assets/agents}/engineer/body.md +14 -0
- package/assets/agents/lead/body.ko.md +70 -0
- package/assets/agents/lead/body.md +70 -0
- package/assets/agents/postdoc/body.ko.md +122 -0
- package/{agents → assets/agents}/postdoc/body.md +16 -0
- package/assets/agents/researcher/body.ko.md +137 -0
- package/{agents → assets/agents}/researcher/body.md +15 -0
- package/assets/agents/reviewer/body.ko.md +138 -0
- package/{agents → assets/agents}/reviewer/body.md +15 -0
- package/assets/agents/strategist/body.ko.md +116 -0
- package/{agents → assets/agents}/strategist/body.md +16 -0
- package/assets/agents/tester/body.ko.md +195 -0
- package/{agents → assets/agents}/tester/body.md +15 -0
- package/assets/agents/writer/body.ko.md +122 -0
- package/{agents → assets/agents}/writer/body.md +14 -0
- package/assets/capability-matrix.yml +198 -0
- package/assets/hooks/agent-bootstrap/handler.test.ts +368 -0
- package/assets/hooks/agent-bootstrap/handler.ts +119 -0
- package/assets/hooks/agent-bootstrap/meta.yml +10 -0
- package/assets/hooks/agent-finalize/handler.test.ts +368 -0
- package/assets/hooks/agent-finalize/handler.ts +76 -0
- package/assets/hooks/agent-finalize/meta.yml +10 -0
- package/assets/hooks/capability-matrix.yml +313 -0
- package/assets/hooks/post-tool-telemetry/handler.test.ts +302 -0
- package/assets/hooks/post-tool-telemetry/handler.ts +49 -0
- package/assets/hooks/post-tool-telemetry/meta.yml +11 -0
- package/assets/hooks/prompt-router/handler.test.ts +801 -0
- package/assets/hooks/prompt-router/handler.ts +261 -0
- package/assets/hooks/prompt-router/meta.yml +11 -0
- package/assets/hooks/session-init/handler.test.ts +274 -0
- package/assets/hooks/session-init/handler.ts +30 -0
- package/assets/hooks/session-init/meta.yml +9 -0
- package/assets/lsp-servers.json +55 -0
- package/assets/schema/lsp-servers.schema.json +67 -0
- package/assets/skills/nx-init/body.ko.md +197 -0
- package/{skills → assets/skills}/nx-init/body.md +11 -0
- package/assets/skills/nx-plan/body.ko.md +361 -0
- package/{skills → assets/skills}/nx-plan/body.md +13 -0
- package/assets/skills/nx-run/body.ko.md +161 -0
- package/{skills → assets/skills}/nx-run/body.md +11 -0
- package/assets/skills/nx-sync/body.ko.md +92 -0
- package/{skills → assets/skills}/nx-sync/body.md +10 -0
- package/assets/tools/tool-name-map.yml +353 -0
- package/dist/hooks/opencode-mount.d.ts +35 -0
- package/dist/hooks/opencode-mount.d.ts.map +1 -0
- package/dist/hooks/opencode-mount.js +332 -0
- package/dist/hooks/opencode-mount.js.map +1 -0
- package/dist/hooks/runtime.d.ts +37 -0
- package/dist/hooks/runtime.d.ts.map +1 -0
- package/dist/hooks/runtime.js +274 -0
- package/dist/hooks/runtime.js.map +1 -0
- package/dist/hooks/types.d.ts +196 -0
- package/dist/hooks/types.d.ts.map +1 -0
- package/dist/hooks/types.js +85 -0
- package/dist/hooks/types.js.map +1 -0
- package/dist/lsp/cache.d.ts +9 -0
- package/dist/lsp/cache.d.ts.map +1 -0
- package/dist/lsp/cache.js +216 -0
- package/dist/lsp/cache.js.map +1 -0
- package/dist/lsp/client.d.ts +24 -0
- package/dist/lsp/client.d.ts.map +1 -0
- package/dist/lsp/client.js +166 -0
- package/dist/lsp/client.js.map +1 -0
- package/dist/lsp/detect.d.ts +77 -0
- package/dist/lsp/detect.d.ts.map +1 -0
- package/dist/lsp/detect.js +116 -0
- package/dist/lsp/detect.js.map +1 -0
- package/dist/mcp/server.d.ts +5 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +34 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools/artifact.d.ts +4 -0
- package/dist/mcp/tools/artifact.d.ts.map +1 -0
- package/dist/mcp/tools/artifact.js +36 -0
- package/dist/mcp/tools/artifact.js.map +1 -0
- package/dist/mcp/tools/history.d.ts +3 -0
- package/dist/mcp/tools/history.d.ts.map +1 -0
- package/dist/mcp/tools/history.js +29 -0
- package/dist/mcp/tools/history.js.map +1 -0
- package/dist/mcp/tools/lsp.d.ts +13 -0
- package/dist/mcp/tools/lsp.d.ts.map +1 -0
- package/dist/mcp/tools/lsp.js +225 -0
- package/dist/mcp/tools/lsp.js.map +1 -0
- package/dist/mcp/tools/plan.d.ts +3 -0
- package/dist/mcp/tools/plan.d.ts.map +1 -0
- package/dist/mcp/tools/plan.js +317 -0
- package/dist/mcp/tools/plan.js.map +1 -0
- package/dist/mcp/tools/task.d.ts +3 -0
- package/dist/mcp/tools/task.d.ts.map +1 -0
- package/dist/mcp/tools/task.js +252 -0
- package/dist/mcp/tools/task.js.map +1 -0
- package/dist/shared/invocations.d.ts +74 -0
- package/dist/shared/invocations.d.ts.map +1 -0
- package/dist/shared/invocations.js +247 -0
- package/dist/shared/invocations.js.map +1 -0
- package/dist/shared/json-store.d.ts +37 -0
- package/dist/shared/json-store.d.ts.map +1 -0
- package/dist/shared/json-store.js +163 -0
- package/dist/shared/json-store.js.map +1 -0
- package/dist/shared/mcp-utils.d.ts +3 -0
- package/dist/shared/mcp-utils.d.ts.map +1 -0
- package/dist/shared/mcp-utils.js +6 -0
- package/dist/shared/mcp-utils.js.map +1 -0
- package/dist/shared/paths.d.ts +21 -0
- package/dist/shared/paths.d.ts.map +1 -0
- package/dist/shared/paths.js +81 -0
- package/dist/shared/paths.js.map +1 -0
- package/dist/shared/tool-log.d.ts +8 -0
- package/dist/shared/tool-log.d.ts.map +1 -0
- package/dist/shared/tool-log.js +22 -0
- package/dist/shared/tool-log.js.map +1 -0
- package/dist/types/state.d.ts +862 -0
- package/dist/types/state.d.ts.map +1 -0
- package/dist/types/state.js +66 -0
- package/dist/types/state.js.map +1 -0
- package/docs/consuming/codex-lead-merge.md +106 -0
- package/docs/plugin-guide.md +360 -0
- package/docs/plugin-template/claude/.github/workflows/build.yml +60 -0
- package/docs/plugin-template/claude/README.md +110 -0
- package/docs/plugin-template/claude/package.json +16 -0
- package/docs/plugin-template/codex/.github/workflows/build.yml +51 -0
- package/docs/plugin-template/codex/README.md +147 -0
- package/docs/plugin-template/codex/package.json +17 -0
- package/docs/plugin-template/opencode/.github/workflows/build.yml +61 -0
- package/docs/plugin-template/opencode/README.md +121 -0
- package/docs/plugin-template/opencode/package.json +25 -0
- package/package.json +21 -21
- package/scripts/build-agents.test.ts +1279 -0
- package/scripts/build-agents.ts +978 -0
- package/scripts/build-hooks.test.ts +1385 -0
- package/scripts/build-hooks.ts +584 -0
- package/scripts/cli.test.ts +367 -0
- package/scripts/cli.ts +547 -0
- package/agents/architect/meta.yml +0 -13
- package/agents/designer/meta.yml +0 -13
- package/agents/engineer/meta.yml +0 -11
- package/agents/postdoc/meta.yml +0 -13
- package/agents/researcher/meta.yml +0 -12
- package/agents/reviewer/meta.yml +0 -12
- package/agents/strategist/meta.yml +0 -13
- package/agents/tester/meta.yml +0 -12
- package/agents/writer/meta.yml +0 -11
- package/conformance/README.md +0 -311
- package/conformance/examples/plan.extension.schema.example.json +0 -25
- package/conformance/lifecycle/README.md +0 -48
- package/conformance/lifecycle/agent-complete.json +0 -44
- package/conformance/lifecycle/agent-resume.json +0 -43
- package/conformance/lifecycle/agent-spawn.json +0 -36
- package/conformance/lifecycle/memory-access-record.json +0 -27
- package/conformance/lifecycle/session-end.json +0 -48
- package/conformance/scenarios/full-plan-cycle.json +0 -147
- package/conformance/scenarios/task-deps-ordering.json +0 -95
- package/conformance/schema/fixture.schema.json +0 -354
- package/conformance/state-schemas/agent-tracker.schema.json +0 -63
- package/conformance/state-schemas/history.schema.json +0 -134
- package/conformance/state-schemas/memory-access.schema.json +0 -36
- package/conformance/state-schemas/plan.schema.json +0 -77
- package/conformance/state-schemas/tasks.schema.json +0 -98
- package/conformance/tools/artifact-write.json +0 -97
- package/conformance/tools/context.json +0 -172
- package/conformance/tools/history-search.json +0 -219
- package/conformance/tools/plan-decide.json +0 -139
- package/conformance/tools/plan-start.json +0 -81
- package/conformance/tools/plan-status.json +0 -127
- package/conformance/tools/plan-update.json +0 -341
- package/conformance/tools/task-add.json +0 -156
- package/conformance/tools/task-close.json +0 -161
- package/conformance/tools/task-list.json +0 -177
- package/conformance/tools/task-update.json +0 -167
- package/docs/behavioral-contracts.md +0 -145
- package/docs/consumer-implementation-guide.md +0 -840
- package/docs/memory-lifecycle-contract.md +0 -119
- package/docs/nexus-layout.md +0 -224
- package/docs/nexus-outputs-contract.md +0 -344
- package/docs/nexus-state-overview.md +0 -170
- package/docs/nexus-tools-contract.md +0 -438
- package/manifest.json +0 -448
- package/schema/README.md +0 -69
- package/schema/agent.schema.json +0 -23
- package/schema/common.schema.json +0 -17
- package/schema/manifest.schema.json +0 -78
- package/schema/memory-policy.schema.json +0 -98
- package/schema/skill.schema.json +0 -54
- package/schema/task-exceptions.schema.json +0 -40
- package/schema/vocabulary.schema.json +0 -167
- package/scripts/.gitkeep +0 -0
- package/scripts/conformance-coverage.ts +0 -466
- package/scripts/import-from-claude-nexus.ts +0 -403
- package/scripts/lib/frontmatter.ts +0 -71
- package/scripts/lib/lint.ts +0 -348
- package/scripts/lib/structure.ts +0 -159
- package/scripts/lib/validate.ts +0 -796
- package/scripts/validate.ts +0 -90
- package/skills/nx-init/meta.yml +0 -8
- package/skills/nx-plan/meta.yml +0 -10
- package/skills/nx-run/meta.yml +0 -8
- package/skills/nx-sync/meta.yml +0 -7
- package/vocabulary/capabilities.yml +0 -65
- package/vocabulary/categories.yml +0 -11
- package/vocabulary/invocations.yml +0 -147
- package/vocabulary/memory_policy.yml +0 -88
- package/vocabulary/resume-tiers.yml +0 -11
- package/vocabulary/tags.yml +0 -60
- package/vocabulary/task-exceptions.yml +0 -29
|
@@ -1,177 +0,0 @@
|
|
|
1
|
-
[
|
|
2
|
-
{
|
|
3
|
-
"test_id": "task_list_no_tasks_file",
|
|
4
|
-
"description": "task_list returns exists:false when tasks.json does not exist",
|
|
5
|
-
"covers": {
|
|
6
|
-
"return_value": {
|
|
7
|
-
"task_list": ["exists"]
|
|
8
|
-
}
|
|
9
|
-
},
|
|
10
|
-
"precondition": {
|
|
11
|
-
"state_files": {
|
|
12
|
-
".nexus/state/tasks.json": null
|
|
13
|
-
}
|
|
14
|
-
},
|
|
15
|
-
"action": {
|
|
16
|
-
"tool": "task_list",
|
|
17
|
-
"params": {}
|
|
18
|
-
},
|
|
19
|
-
"postcondition": {
|
|
20
|
-
"return_value": {
|
|
21
|
-
"$.exists": false
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
},
|
|
25
|
-
{
|
|
26
|
-
"test_id": "task_list_happy_path",
|
|
27
|
-
"description": "task_list returns goal, full task list, and a correct progress summary when tasks.json exists",
|
|
28
|
-
"covers": {
|
|
29
|
-
"return_value": {
|
|
30
|
-
"task_list": ["goal", "tasks", "summary.total", "summary.completed", "summary.pending", "summary.ready"]
|
|
31
|
-
}
|
|
32
|
-
},
|
|
33
|
-
"precondition": {
|
|
34
|
-
"state_files": {
|
|
35
|
-
".nexus/state/tasks.json": {
|
|
36
|
-
"goal": "Ship conformance fixtures for nexus-core",
|
|
37
|
-
"decisions": ["Use declarative JSONPath assertions"],
|
|
38
|
-
"tasks": [
|
|
39
|
-
{
|
|
40
|
-
"id": 1,
|
|
41
|
-
"title": "Create fixture.schema.json",
|
|
42
|
-
"context": "Define the JSON Schema for fixture files",
|
|
43
|
-
"status": "completed",
|
|
44
|
-
"deps": [],
|
|
45
|
-
"created_at": "2026-04-12T00:00:00.000Z"
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
"id": 2,
|
|
49
|
-
"title": "Write plan_start fixture",
|
|
50
|
-
"context": "Happy path and missing-research-summary error case",
|
|
51
|
-
"status": "pending",
|
|
52
|
-
"deps": [1],
|
|
53
|
-
"created_at": "2026-04-12T00:00:00.000Z"
|
|
54
|
-
},
|
|
55
|
-
{
|
|
56
|
-
"id": 3,
|
|
57
|
-
"title": "Write task_add fixture",
|
|
58
|
-
"context": "Happy path and with-goal case",
|
|
59
|
-
"status": "pending",
|
|
60
|
-
"deps": [1],
|
|
61
|
-
"created_at": "2026-04-12T00:00:00.000Z"
|
|
62
|
-
}
|
|
63
|
-
]
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
},
|
|
67
|
-
"action": {
|
|
68
|
-
"tool": "task_list",
|
|
69
|
-
"params": {}
|
|
70
|
-
},
|
|
71
|
-
"postcondition": {
|
|
72
|
-
"return_value": {
|
|
73
|
-
"$.goal": "Ship conformance fixtures for nexus-core",
|
|
74
|
-
"$.tasks.length": 3,
|
|
75
|
-
"$.summary.total": 3,
|
|
76
|
-
"$.summary.completed": 1,
|
|
77
|
-
"$.summary.pending": 2,
|
|
78
|
-
"$.summary.ready.length": 2,
|
|
79
|
-
"$.summary.ready[0]": 2,
|
|
80
|
-
"$.summary.ready[1]": 3
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
},
|
|
84
|
-
{
|
|
85
|
-
"test_id": "task_list_all_pending_no_deps",
|
|
86
|
-
"description": "task_list marks all tasks as ready when they have no dependencies and are all pending",
|
|
87
|
-
"covers": {
|
|
88
|
-
"return_value": {
|
|
89
|
-
"task_list": ["summary.total", "summary.pending", "summary.completed", "summary.ready"]
|
|
90
|
-
}
|
|
91
|
-
},
|
|
92
|
-
"precondition": {
|
|
93
|
-
"state_files": {
|
|
94
|
-
".nexus/state/tasks.json": {
|
|
95
|
-
"goal": "Validate ready computation",
|
|
96
|
-
"decisions": [],
|
|
97
|
-
"tasks": [
|
|
98
|
-
{
|
|
99
|
-
"id": 1,
|
|
100
|
-
"title": "Independent task A",
|
|
101
|
-
"context": "No dependencies",
|
|
102
|
-
"status": "pending",
|
|
103
|
-
"deps": [],
|
|
104
|
-
"created_at": "2026-04-12T00:00:00.000Z"
|
|
105
|
-
},
|
|
106
|
-
{
|
|
107
|
-
"id": 2,
|
|
108
|
-
"title": "Independent task B",
|
|
109
|
-
"context": "No dependencies",
|
|
110
|
-
"status": "pending",
|
|
111
|
-
"deps": [],
|
|
112
|
-
"created_at": "2026-04-12T00:00:00.000Z"
|
|
113
|
-
}
|
|
114
|
-
]
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
},
|
|
118
|
-
"action": {
|
|
119
|
-
"tool": "task_list",
|
|
120
|
-
"params": {}
|
|
121
|
-
},
|
|
122
|
-
"postcondition": {
|
|
123
|
-
"return_value": {
|
|
124
|
-
"$.summary.total": 2,
|
|
125
|
-
"$.summary.pending": 2,
|
|
126
|
-
"$.summary.completed": 0,
|
|
127
|
-
"$.summary.ready.length": 2
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
},
|
|
131
|
-
{
|
|
132
|
-
"test_id": "task_list_blocked_task_not_ready",
|
|
133
|
-
"description": "task_list excludes a task from ready when its dependency is still pending",
|
|
134
|
-
"covers": {
|
|
135
|
-
"return_value": {
|
|
136
|
-
"task_list": ["summary.total", "summary.ready"]
|
|
137
|
-
}
|
|
138
|
-
},
|
|
139
|
-
"precondition": {
|
|
140
|
-
"state_files": {
|
|
141
|
-
".nexus/state/tasks.json": {
|
|
142
|
-
"goal": "Validate blocked task exclusion",
|
|
143
|
-
"decisions": [],
|
|
144
|
-
"tasks": [
|
|
145
|
-
{
|
|
146
|
-
"id": 1,
|
|
147
|
-
"title": "Prerequisite task",
|
|
148
|
-
"context": "Must finish first",
|
|
149
|
-
"status": "pending",
|
|
150
|
-
"deps": [],
|
|
151
|
-
"created_at": "2026-04-12T00:00:00.000Z"
|
|
152
|
-
},
|
|
153
|
-
{
|
|
154
|
-
"id": 2,
|
|
155
|
-
"title": "Dependent task",
|
|
156
|
-
"context": "Cannot start until task 1 is done",
|
|
157
|
-
"status": "pending",
|
|
158
|
-
"deps": [1],
|
|
159
|
-
"created_at": "2026-04-12T00:00:00.000Z"
|
|
160
|
-
}
|
|
161
|
-
]
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
},
|
|
165
|
-
"action": {
|
|
166
|
-
"tool": "task_list",
|
|
167
|
-
"params": {}
|
|
168
|
-
},
|
|
169
|
-
"postcondition": {
|
|
170
|
-
"return_value": {
|
|
171
|
-
"$.summary.total": 2,
|
|
172
|
-
"$.summary.ready.length": 1,
|
|
173
|
-
"$.summary.ready[0]": 1
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
]
|
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
[
|
|
2
|
-
{
|
|
3
|
-
"test_id": "task_update_status_to_in_progress",
|
|
4
|
-
"description": "task_update transitions a pending task to in_progress and returns the updated task object",
|
|
5
|
-
"covers": {
|
|
6
|
-
"state_schemas": {
|
|
7
|
-
"tasks.schema.json": ["tasks[].id", "tasks[].status"]
|
|
8
|
-
},
|
|
9
|
-
"return_value": {
|
|
10
|
-
"task_update": ["task"]
|
|
11
|
-
}
|
|
12
|
-
},
|
|
13
|
-
"precondition": {
|
|
14
|
-
"state_files": {
|
|
15
|
-
".nexus/state/tasks.json": {
|
|
16
|
-
"goal": "Validate task_update behaviour",
|
|
17
|
-
"decisions": [],
|
|
18
|
-
"tasks": [
|
|
19
|
-
{
|
|
20
|
-
"id": 1,
|
|
21
|
-
"title": "Implement core feature",
|
|
22
|
-
"context": "Write the initial implementation",
|
|
23
|
-
"status": "pending",
|
|
24
|
-
"deps": [],
|
|
25
|
-
"created_at": "2026-04-12T00:00:00.000Z"
|
|
26
|
-
}
|
|
27
|
-
]
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
},
|
|
31
|
-
"action": {
|
|
32
|
-
"tool": "task_update",
|
|
33
|
-
"params": {
|
|
34
|
-
"id": 1,
|
|
35
|
-
"status": "in_progress"
|
|
36
|
-
}
|
|
37
|
-
},
|
|
38
|
-
"postcondition": {
|
|
39
|
-
"return_value": {
|
|
40
|
-
"$.task.id": 1,
|
|
41
|
-
"$.task.status": "in_progress",
|
|
42
|
-
"$.task.title": "Implement core feature"
|
|
43
|
-
},
|
|
44
|
-
"state_files": {
|
|
45
|
-
".nexus/state/tasks.json": {
|
|
46
|
-
"$.tasks[0].id": 1,
|
|
47
|
-
"$.tasks[0].status": "in_progress"
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
"test_id": "task_update_status_to_completed",
|
|
54
|
-
"description": "task_update transitions an in_progress task to completed and persists the change in tasks.json",
|
|
55
|
-
"covers": {
|
|
56
|
-
"state_schemas": {
|
|
57
|
-
"tasks.schema.json": ["tasks[].id", "tasks[].status"]
|
|
58
|
-
},
|
|
59
|
-
"return_value": {
|
|
60
|
-
"task_update": ["task"]
|
|
61
|
-
}
|
|
62
|
-
},
|
|
63
|
-
"precondition": {
|
|
64
|
-
"state_files": {
|
|
65
|
-
".nexus/state/tasks.json": {
|
|
66
|
-
"goal": "Validate task_update behaviour",
|
|
67
|
-
"decisions": [],
|
|
68
|
-
"tasks": [
|
|
69
|
-
{
|
|
70
|
-
"id": 1,
|
|
71
|
-
"title": "Implement core feature",
|
|
72
|
-
"context": "Write the initial implementation",
|
|
73
|
-
"status": "in_progress",
|
|
74
|
-
"deps": [],
|
|
75
|
-
"created_at": "2026-04-12T00:00:00.000Z"
|
|
76
|
-
}
|
|
77
|
-
]
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
},
|
|
81
|
-
"action": {
|
|
82
|
-
"tool": "task_update",
|
|
83
|
-
"params": {
|
|
84
|
-
"id": 1,
|
|
85
|
-
"status": "completed"
|
|
86
|
-
}
|
|
87
|
-
},
|
|
88
|
-
"postcondition": {
|
|
89
|
-
"return_value": {
|
|
90
|
-
"$.task.id": 1,
|
|
91
|
-
"$.task.status": "completed",
|
|
92
|
-
"$.task.title": "Implement core feature"
|
|
93
|
-
},
|
|
94
|
-
"state_files": {
|
|
95
|
-
".nexus/state/tasks.json": {
|
|
96
|
-
"$.tasks[0].id": 1,
|
|
97
|
-
"$.tasks[0].status": "completed"
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
},
|
|
102
|
-
{
|
|
103
|
-
"test_id": "task_update_not_found_error",
|
|
104
|
-
"description": "task_update returns an error when the referenced task id does not exist in tasks.json",
|
|
105
|
-
"covers": {
|
|
106
|
-
"state_schemas": {
|
|
107
|
-
"tasks.schema.json": []
|
|
108
|
-
}
|
|
109
|
-
},
|
|
110
|
-
"uncovered_params": ["id", "status"],
|
|
111
|
-
"precondition": {
|
|
112
|
-
"state_files": {
|
|
113
|
-
".nexus/state/tasks.json": {
|
|
114
|
-
"goal": "Validate task_update behaviour",
|
|
115
|
-
"decisions": [],
|
|
116
|
-
"tasks": [
|
|
117
|
-
{
|
|
118
|
-
"id": 1,
|
|
119
|
-
"title": "Only task",
|
|
120
|
-
"context": "The only task in the list",
|
|
121
|
-
"status": "pending",
|
|
122
|
-
"deps": [],
|
|
123
|
-
"created_at": "2026-04-12T00:00:00.000Z"
|
|
124
|
-
}
|
|
125
|
-
]
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
},
|
|
129
|
-
"action": {
|
|
130
|
-
"tool": "task_update",
|
|
131
|
-
"params": {
|
|
132
|
-
"id": 99,
|
|
133
|
-
"status": "completed"
|
|
134
|
-
}
|
|
135
|
-
},
|
|
136
|
-
"postcondition": {
|
|
137
|
-
"error": true,
|
|
138
|
-
"error_contains": "Task id 99 not found"
|
|
139
|
-
}
|
|
140
|
-
},
|
|
141
|
-
{
|
|
142
|
-
"test_id": "task_update_no_tasks_file_error",
|
|
143
|
-
"description": "task_update returns an error when tasks.json does not exist",
|
|
144
|
-
"covers": {
|
|
145
|
-
"state_schemas": {
|
|
146
|
-
"tasks.schema.json": []
|
|
147
|
-
}
|
|
148
|
-
},
|
|
149
|
-
"uncovered_params": ["id", "status"],
|
|
150
|
-
"precondition": {
|
|
151
|
-
"state_files": {
|
|
152
|
-
".nexus/state/tasks.json": null
|
|
153
|
-
}
|
|
154
|
-
},
|
|
155
|
-
"action": {
|
|
156
|
-
"tool": "task_update",
|
|
157
|
-
"params": {
|
|
158
|
-
"id": 1,
|
|
159
|
-
"status": "completed"
|
|
160
|
-
}
|
|
161
|
-
},
|
|
162
|
-
"postcondition": {
|
|
163
|
-
"error": true,
|
|
164
|
-
"error_contains": "tasks.json not found"
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
]
|
|
@@ -1,145 +0,0 @@
|
|
|
1
|
-
# Behavioral Contracts
|
|
2
|
-
|
|
3
|
-
This document formalizes the behavioral contracts that all Nexus harnesses must implement. These contracts define state machines, coordination rules, and semantic boundaries that are harness-neutral — they describe *what* must happen, not *how* any specific harness implements it.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## 1. Task Lifecycle State Machine
|
|
8
|
-
|
|
9
|
-
Tasks transition through the following states:
|
|
10
|
-
|
|
11
|
-
```
|
|
12
|
-
pending → in_progress → completed
|
|
13
|
-
↑ |
|
|
14
|
-
└── (reopen) ──┘
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
**States.**
|
|
18
|
-
|
|
19
|
-
| State | Meaning |
|
|
20
|
-
|---|---|
|
|
21
|
-
| `pending` | Task is waiting to begin. Not yet assigned or all dependencies unresolved. |
|
|
22
|
-
| `in_progress` | Task is actively being worked on by an assigned agent. |
|
|
23
|
-
| `completed` | Task has finished and its output is available. |
|
|
24
|
-
|
|
25
|
-
**Reopen.** A `completed` task may be transitioned back to `pending` via `task_update`. This is used when review or downstream work reveals that the task's output is insufficient and it must be reworked.
|
|
26
|
-
|
|
27
|
-
**No `blocked` state.** There is no explicit `blocked` state. A task that cannot proceed because a dependency has not completed remains in `pending`. Harnesses compute readiness from dependency status rather than relying on an explicit blocked marker.
|
|
28
|
-
|
|
29
|
-
**Readiness computation.** A task is ready to begin when both conditions hold:
|
|
30
|
-
1. Its status is `pending`.
|
|
31
|
-
2. Every task listed in its `deps` field has status `completed`.
|
|
32
|
-
|
|
33
|
-
---
|
|
34
|
-
|
|
35
|
-
## 2. Plan Lifecycle State Machine
|
|
36
|
-
|
|
37
|
-
Plan issues transition through the following states:
|
|
38
|
-
|
|
39
|
-
```
|
|
40
|
-
pending → decided
|
|
41
|
-
↑ |
|
|
42
|
-
└─────────┘ (reopen)
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
**States.**
|
|
46
|
-
|
|
47
|
-
| State | Meaning |
|
|
48
|
-
|---|---|
|
|
49
|
-
| `pending` | Issue is open and no decision has been recorded. |
|
|
50
|
-
| `decided` | A decision has been recorded for this issue. |
|
|
51
|
-
|
|
52
|
-
**Reopen.** A `decided` issue may be transitioned back to `pending` via `plan_update` with `action: reopen`. On reopen, the `decision` field for that issue is deleted. The issue returns to open discussion.
|
|
53
|
-
|
|
54
|
-
**Plan complete signal.** A plan is considered complete when all issues within it have status `decided`. This signals that the plan phase is finished and execution may begin.
|
|
55
|
-
|
|
56
|
-
---
|
|
57
|
-
|
|
58
|
-
## 3. Resume Tier and Owner Reuse Policy Coordination
|
|
59
|
-
|
|
60
|
-
### Resume Tiers
|
|
61
|
-
|
|
62
|
-
Each agent role carries a resume tier that governs whether a prior agent session may be reused for a new task assignment, or whether a fresh spawn is required. The three tiers are defined in `vocabulary/resume-tiers.yml`.
|
|
63
|
-
|
|
64
|
-
**`ephemeral`.** The agent is always spawned fresh. No prior session is carried forward. Used for roles where independence from prior context is essential to correctness (e.g., verification roles).
|
|
65
|
-
|
|
66
|
-
**`bounded`.** The agent may resume a prior session only when all of the following conditions hold: (a) the same owner identity is assigned, (b) the target files or artifacts are the same, and (c) no intervening edits have occurred to those targets since the prior session. If any condition is not met, a fresh spawn is used. Agent instructions for bounded-tier agents must include a directive to re-read the target files at the start of each resumed session to ensure current state is reflected.
|
|
67
|
-
|
|
68
|
-
**`persistent`.** The agent resumes by default within the same run session. Cross-task reuse is allowed. Used for roles where accumulated context is the primary asset (e.g., analysis and design roles).
|
|
69
|
-
|
|
70
|
-
### Owner Reuse Policy Override
|
|
71
|
-
|
|
72
|
-
The `owner_reuse_policy` field in `tasks.json` allows per-task override of the default resume-tier behavior.
|
|
73
|
-
|
|
74
|
-
| Value | Effect |
|
|
75
|
-
|---|---|
|
|
76
|
-
| `fresh` | Force a fresh spawn regardless of resume tier. |
|
|
77
|
-
| `resume_if_same_artifact` | Apply bounded-tier behavior: resume only if same artifact, same owner, no intervening edits. |
|
|
78
|
-
| `resume` | Force resume regardless of resume tier, if a prior session is available. |
|
|
79
|
-
|
|
80
|
-
When `owner_reuse_policy` is absent, the agent's default resume tier governs.
|
|
81
|
-
|
|
82
|
-
### Resume Gating
|
|
83
|
-
|
|
84
|
-
Before attempting to resume a prior agent session, the harness must verify that its resume mechanism is available for the current context. If the mechanism is unavailable, the harness must fall back to a fresh spawn silently, without surfacing an error to the user. Resume gating is a harness-level concern; nexus-core specifies only that fallback must occur.
|
|
85
|
-
|
|
86
|
-
---
|
|
87
|
-
|
|
88
|
-
## 4. Permission Model
|
|
89
|
-
|
|
90
|
-
**Lead.** The Lead agent may invoke all skills, call all tools available to the harness, spawn subagents, and record plan decisions. Lead is the only role that may initiate a new plan or run cycle.
|
|
91
|
-
|
|
92
|
-
**Subagents.** Each subagent role has a defined set of capabilities that restrict which tools it may call. Capabilities are declared in the agent's `meta.yml` using the capability abstraction defined in `vocabulary/capabilities.yml`. A subagent may not call tools outside its declared capability set.
|
|
93
|
-
|
|
94
|
-
**Gate enforcement.** The mechanism by which capability gates are enforced is harness-specific. nexus-core specifies the semantic — which capabilities a role holds — but not the enforcement implementation. Harnesses are responsible for translating capability declarations into their native access-control mechanism.
|
|
95
|
-
|
|
96
|
-
**Capability override rule (additive-only).** A consumer's effective capability set for any agent is computed as:
|
|
97
|
-
|
|
98
|
-
```
|
|
99
|
-
effective_capabilities(agent) = canonical_capabilities(agent) ∪ consumer_additions(agent)
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
`canonical_capabilities` is the `capabilities` array in `agents/{id}/meta.yml` — the nexus-core canonical definition. `consumer_additions` is a harness-local set of additional capabilities the consumer chooses to apply (format and storage are consumer decisions). Consumers may **add** capabilities but **must not remove** canonical ones. Removing a canonical capability (e.g., removing `no_file_edit` from an agent that canonically carries it) would violate the nexus-core design intent and is forbidden. The union is idempotent — if nexus-core later adds a capability that a consumer already applied locally, the overlap is harmless.
|
|
103
|
-
|
|
104
|
-
---
|
|
105
|
-
|
|
106
|
-
## 5. Session Boundary Semantics
|
|
107
|
-
|
|
108
|
-
A **session** begins when the harness launches and ends when the harness closes or the user explicitly terminates it. A session may contain one or more plan/run cycles.
|
|
109
|
-
|
|
110
|
-
A **cycle** consists of exactly one `plan.json` lifecycle and one `tasks.json` lifecycle. A cycle begins when a new plan is created and ends with `task_close`, which archives the cycle's plan and task records into `history.json`.
|
|
111
|
-
|
|
112
|
-
```
|
|
113
|
-
Session
|
|
114
|
-
└── Cycle 1: plan.json + tasks.json → task_close → history.json
|
|
115
|
-
└── Cycle 2: plan.json + tasks.json → task_close → history.json
|
|
116
|
-
└── ...
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
Session state (the `state/` directory) persists across cycles within a single session. When a new cycle begins within the same session, `plan.json` and `tasks.json` are replaced; other session state (e.g., agent registrations) may persist or be reset depending on harness policy.
|
|
120
|
-
|
|
121
|
-
Session end discards all remaining session state that has not been promoted to project-scoped storage.
|
|
122
|
-
|
|
123
|
-
---
|
|
124
|
-
|
|
125
|
-
## 6. `manual_only` Contract
|
|
126
|
-
|
|
127
|
-
A skill declared with `manual_only: true` in its `meta.yml` must not be auto-invoked by the language model as a result of natural-language inference.
|
|
128
|
-
|
|
129
|
-
**Activation constraint.** Only an explicit user-initiated trigger may activate a `manual_only` skill. Valid explicit triggers are: a slash command typed by the user, or a bracket tag typed by the user (e.g., `[plan]`). Inference from conversational context does not qualify as an explicit trigger.
|
|
130
|
-
|
|
131
|
-
**Consumer harness obligation.** Consumer harnesses that implement auto-invocation detection — where the language model may activate skills based on recognized patterns in user messages — must filter `manual_only` skills out of the skill activation list exposed to the language model. A `manual_only` skill must not appear as a candidate for automatic activation under any circumstances.
|
|
132
|
-
|
|
133
|
-
This contract ensures that high-consequence or structurally significant skills are only invoked when the user has expressed deliberate intent.
|
|
134
|
-
|
|
135
|
-
---
|
|
136
|
-
|
|
137
|
-
## 7. Natural-Language Trigger Boundary
|
|
138
|
-
|
|
139
|
-
Natural-language trigger detection is **consumer-owned**. nexus-core does not define, distribute, or maintain natural-language pattern lists for any skill or tag.
|
|
140
|
-
|
|
141
|
-
**Canonical trigger form.** The authoritative trigger for every tag is the explicit bracket form defined in `vocabulary/tags.yml` (e.g., `[plan]`, `[run]`, `[sync]`). This is the form nexus-core specifies. All other activation forms are consumer extensions.
|
|
142
|
-
|
|
143
|
-
**Consumer responsibility.** Each consumer harness independently defines the natural-language patterns it recognizes as equivalent to an explicit trigger, tests those patterns, and maintains them over time. nexus-core provides no shared pattern library and makes no guarantees about pattern compatibility across harnesses.
|
|
144
|
-
|
|
145
|
-
**Divergence is acceptable.** Different consumer harnesses may recognize different natural-language phrasings for the same underlying skill. This divergence is explicitly acceptable. Harnesses must not assume that another harness's pattern set matches their own.
|