vgxness 1.9.1 → 1.9.3

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.
Files changed (54) hide show
  1. package/README.md +15 -5
  2. package/dist/agents/agent-activation-service.js +13 -4
  3. package/dist/agents/agent-registry-service.js +8 -2
  4. package/dist/agents/agent-resolver.js +33 -3
  5. package/dist/agents/agent-seed-upgrade-service.js +231 -0
  6. package/dist/agents/boot-upgrade.js +59 -0
  7. package/dist/agents/canonical-agent-manifest.js +39 -18
  8. package/dist/agents/canonical-agent-projection.js +38 -4
  9. package/dist/agents/manager-profile-overlay-service.js +14 -0
  10. package/dist/agents/repositories/agent-seed-history.js +128 -0
  11. package/dist/cli/cli-help.js +14 -3
  12. package/dist/cli/commands/index.js +1 -0
  13. package/dist/cli/commands/interactive-entrypoint-dispatcher.js +8 -0
  14. package/dist/cli/commands/mcp-dispatcher.js +7 -0
  15. package/dist/cli/commands/memory-sdd-dispatcher.js +71 -5
  16. package/dist/cli/commands/status-dispatcher.js +130 -0
  17. package/dist/cli/commands/workflow-dispatcher.js +11 -5
  18. package/dist/cli/dispatcher.js +11 -1
  19. package/dist/cli/product-resume-renderer.js +32 -0
  20. package/dist/cli/product-status-renderer.js +74 -0
  21. package/dist/cli/sdd-renderer.js +80 -3
  22. package/dist/code/cli/code-command.js +7 -4
  23. package/dist/code/reporting/summary.js +4 -1
  24. package/dist/code/runtime/code-runtime.js +27 -4
  25. package/dist/code/runtime/sdd-context.js +18 -2
  26. package/dist/governance/governance-report-builder.js +18 -7
  27. package/dist/mcp/claude-code-agent-config.js +10 -4
  28. package/dist/mcp/client-install-claude-code-contract.js +19 -4
  29. package/dist/mcp/client-install-claude-code.js +2 -2
  30. package/dist/mcp/control-plane.js +78 -5
  31. package/dist/mcp/provider-status.js +89 -88
  32. package/dist/mcp/schema.js +42 -8
  33. package/dist/mcp/stdio-server.js +6 -0
  34. package/dist/mcp/validation.js +77 -5
  35. package/dist/memory/sqlite/migrations/016_agent_seed_history.sql +15 -0
  36. package/dist/resume/product-resume.js +166 -0
  37. package/dist/runs/repositories/runs.js +12 -1
  38. package/dist/runs/run-service.js +62 -5
  39. package/dist/runs/schema.js +4 -0
  40. package/dist/sdd/schema.js +20 -0
  41. package/dist/sdd/sdd-continuation-plan.js +81 -0
  42. package/dist/sdd/sdd-workflow-service.js +146 -18
  43. package/dist/skills/skill-resolver.js +21 -4
  44. package/dist/status/product-status.js +117 -0
  45. package/docs/architecture.md +9 -1
  46. package/docs/cli.md +38 -13
  47. package/docs/code-runtime.md +3 -0
  48. package/docs/contributing.md +1 -1
  49. package/docs/glossary.md +2 -2
  50. package/docs/mcp.md +20 -6
  51. package/docs/project-health-audit-v1.9.1.md +126 -0
  52. package/docs/providers.md +4 -4
  53. package/docs/safety.md +1 -1
  54. package/package.json +1 -1
package/README.md CHANGED
@@ -8,6 +8,8 @@ This package is proprietary software. The npm package ships inspectable JavaScri
8
8
 
9
9
  OpenCode is the primary supported provider. Other providers remain preview/manual only. Provider config writes require explicit CLI confirmation.
10
10
 
11
+ VGXNESS v1.9.1 has a canonical project health audit with validated evidence: 38 MCP tools, 106 test files, and the official Bun validation path passing, including package evidence with `releaseReadiness: pass`. Current unreleased builds expose 41 MCP tools after adding read-only SDD/run recovery parity. See [Project health audit v1.9.1](./docs/project-health-audit-v1.9.1.md) for the versioned matrix and safety taxonomy.
12
+
11
13
  ## Requirements
12
14
 
13
15
  - Bun >= 1.3.14 for the installed `vgxness`/`vgx` CLI/MCP runtime and repository verification
@@ -25,6 +27,7 @@ bun install --frozen-lockfile
25
27
  bun run check:bun-lock
26
28
  bun run verify:typecheck
27
29
  bun run verify:test
30
+ bun run verify:test:bun-storage
28
31
  bun run verify:bun-sqlite
29
32
  bun run verify:package
30
33
  bun run package:bun:evidence -- --require-pass
@@ -86,7 +89,7 @@ Release-candidate checklist, still non-publishing:
86
89
 
87
90
  1. `bun install --frozen-lockfile` completes on a clean checkout.
88
91
  2. `bun run check:bun-lock` passes.
89
- 3. `bun run verify:typecheck`, `bun run verify:test`, and `bun run verify:bun-sqlite` pass.
92
+ 3. `bun run verify:typecheck`, `bun run verify:test`, `bun run verify:test:bun-storage`, and `bun run verify:bun-sqlite` pass.
90
93
  4. `bun run package:bun:evidence -- --require-pass` passes on supported CI OSes.
91
94
  5. JSON evidence shows `status: pass`, artifact/install smoke pass, no retired bridge scripts, no `package-lock.json`, `publicationAttempted: false`, and `releaseReadiness.status: pass`.
92
95
  6. Version, release notes, proprietary license boundary, and rollback criteria are reviewed.
@@ -141,7 +144,9 @@ In non-TTY shells, `vgxness init` prints the same read-only setup plan instead o
141
144
  vgxness setup plan
142
145
  vgxness setup apply --yes
143
146
  vgxness doctor
144
- vgxness sdd next --project <project> --change <change>
147
+ vgxness status --project <project> --change <change>
148
+ vgxness next --project <project> --change <change>
149
+ vgxness sdd continue --project <project> --change <change>
145
150
  ```
146
151
 
147
152
  Stable defaults are: package `vgxness`, provider `opencode`, global user data DB, user/global OpenCode scope (`$HOME/.config/opencode/opencode.json`), and `mcp-plus-agents` mode. Use `--scope project` only when you intentionally want `<workspace>/.opencode/opencode.json`. The generated MCP command for the global DB default is:
@@ -156,7 +161,9 @@ Apply only after reviewing the plan:
156
161
  vgxness setup apply --yes
157
162
  ```
158
163
 
159
- `vgxness setup plan` and `vgxness setup status` are human-readable and read-only by default. `vgxness doctor`, `vgxness sdd status`, `vgxness sdd next`, and `vgxness sdd accept-artifact` are also human-readable by default. Pass `--json` when you need parseable automation output. `vgxness setup apply --yes` is the explicit provider-config write path.
164
+ `vgxness setup plan` and `vgxness setup status` are human-readable and do not write provider config by default; local VGXNESS store initialization may occur when a command needs the selected SQLite store. `vgxness doctor`, `vgxness status`, `vgxness next`, `vgxness sdd status`, `vgxness sdd next`, `vgxness sdd continue`, and `vgxness sdd accept-artifact` are also human-readable by default. Pass `--json` when you need parseable automation output. `vgxness setup apply --yes` is the explicit provider-config write path.
165
+
166
+ The SDD happy path is `status` -> `next` -> `sdd continue` -> `code sdd` or `resume` -> `accept-artifact` or `reopen-artifact`. `sdd continue`, top-level `status`/`next`, and `resume` are advisory/read-only surfaces; related interrupted run hints and resume candidates help the operator choose the next command but do not execute providers or retry runs. Draft-run suggestions are planning-only: human acceptance is still required, and `apply-progress` remains gated.
160
167
 
161
168
  ## Code runtime (`vgxness code`)
162
169
 
@@ -173,13 +180,14 @@ Edits, shell, network, git mutations, SDD persistence, and memory saves route th
173
180
 
174
181
  ## Safety model
175
182
 
176
- - Preview, status, and plan commands are read-only.
183
+ - Preview, status, and plan commands do not write provider config; local VGXNESS store initialization may occur where the command needs SQLite-backed state.
177
184
  - Provider config writes require explicit `--yes` confirmation.
178
185
  - Setup/status TUI surfaces are preview-oriented; run copied commands explicitly when you choose to act.
179
186
  - SDD artifacts are SQLite-backed through VGXNESS services. Do not create or write `openspec/`.
180
187
  - `vgxness sdd accept-artifact` records explicit human-only acceptance; saving a draft never implies acceptance.
188
+ - `vgxness sdd reopen-artifact` is the explicit path from a rejected artifact back to draft before revision.
181
189
  - OpenCode is the primary supported provider; other providers are preview/manual extension points.
182
- - VGXNESS exposes 38 typed MCP tools across SDD, memory, sessions, agents, skills, runs, providers, and verification. See [MCP tools](./docs/mcp.md).
190
+ - VGXNESS exposes 41 typed MCP tools across SDD, memory, sessions, agents, skills, runs, providers, and verification. See [MCP tools](./docs/mcp.md).
183
191
 
184
192
  ## Main menu entrypoint
185
193
 
@@ -236,6 +244,7 @@ bun install --frozen-lockfile
236
244
  bun run check:bun-lock
237
245
  bun run verify:typecheck
238
246
  bun run verify:test
247
+ bun run verify:test:bun-storage
239
248
  bun run verify:bun-sqlite
240
249
  bun run package:bun:evidence -- --require-pass
241
250
  ```
@@ -255,6 +264,7 @@ Remove any OpenCode config entries and local/global VGXNESS data manually if you
255
264
  ## More docs
256
265
 
257
266
  - [CLI reference](./docs/cli.md)
267
+ - [Project health audit v1.9.1](./docs/project-health-audit-v1.9.1.md)
258
268
  - [Architecture](./docs/architecture.md)
259
269
  - [Code runtime](./docs/code-runtime.md)
260
270
  - [MCP tools](./docs/mcp.md)
@@ -98,14 +98,23 @@ export class AgentActivationService {
98
98
  return this.dependencies.agents.getAgentByName(input.project, input.scope, defaultAgentName);
99
99
  }
100
100
  failAfterRun(runId, code, message) {
101
- this.dependencies.runs.appendEvent({
101
+ const nestedFailures = [];
102
+ const eventResult = this.dependencies.runs.appendEvent({
102
103
  runId,
103
104
  kind: 'timeline',
104
105
  title: 'Agent activation failed',
105
- payload: { error: { code: String(code), message }, nextSafeActionReturned: false },
106
+ payload: toJson({ error: { code: String(code), message }, nextSafeActionReturned: false }),
106
107
  });
107
- this.dependencies.runs.updateFinalStatus({ runId, status: 'failed', outcome: 'failure', outcomeReason: message });
108
- return { ok: false, error: { code, message } };
108
+ if (!eventResult.ok) {
109
+ nestedFailures.push({ step: 'append-event', code: String(eventResult.error.code), message: eventResult.error.message });
110
+ }
111
+ const finalStatusResult = this.dependencies.runs.updateFinalStatus({ runId, status: 'failed', outcome: 'failure', outcomeReason: message });
112
+ if (!finalStatusResult.ok) {
113
+ nestedFailures.push({ step: 'update-final-status', code: String(finalStatusResult.error.code), message: finalStatusResult.error.message });
114
+ }
115
+ return nestedFailures.length === 0
116
+ ? { ok: false, error: { code, message } }
117
+ : { ok: false, error: { code, message, cause: { nestedFailures } } };
109
118
  }
110
119
  }
111
120
  function validateActivationInput(input) {
@@ -32,8 +32,14 @@ export class AgentRegistryService {
32
32
  this.database.close();
33
33
  }
34
34
  listAgentDefinitions(input) {
35
- void input;
36
- const summaries = this.agents.list();
35
+ const filters = {};
36
+ if (input.project !== undefined)
37
+ filters.project = input.project;
38
+ if (input.scope !== undefined)
39
+ filters.scope = input.scope;
40
+ if (input.mode !== undefined)
41
+ filters.mode = input.mode;
42
+ const summaries = this.agents.list(filters);
37
43
  if (!summaries.ok)
38
44
  return summaries;
39
45
  const definitions = [];
@@ -1,3 +1,4 @@
1
+ import { normalizeSddPhaseInput } from '../sdd/schema.js';
1
2
  export class AgentResolver {
2
3
  loadAgents;
3
4
  constructor(loadAgents) {
@@ -58,8 +59,10 @@ function normalizeInput(input) {
58
59
  const desiredCapabilities = normalizeList(input.desiredCapabilities ?? []);
59
60
  const taskDescription = normalizeText(input.taskDescription);
60
61
  const intent = normalizeText(input.intent);
62
+ const phase = input.phase === undefined ? undefined : (isSddWorkflow(input.workflow) ? (normalizeSddPhaseInput(input.phase) ?? input.phase) : input.phase);
61
63
  return {
62
64
  ...input,
65
+ ...(phase !== undefined ? { phase } : {}),
63
66
  ...(taskDescription !== undefined ? { taskDescription } : {}),
64
67
  ...(intent !== undefined ? { intent } : {}),
65
68
  desiredCapabilities,
@@ -143,7 +146,7 @@ function workflowMatches(agent, input) {
143
146
  return [...matches.broad, ...matches.phaseOnly, ...matches.exactPhase];
144
147
  }
145
148
  function workflowSignalMatches(agent, input) {
146
- const requested = [input.workflow, input.phase, input.workflow !== undefined && input.phase !== undefined ? `${input.workflow}:${input.phase}` : undefined]
149
+ const requested = workflowRequestedSignals(input)
147
150
  .filter((value) => value !== undefined)
148
151
  .map(normalizeKey);
149
152
  if (requested.length === 0)
@@ -154,17 +157,41 @@ function workflowSignalMatches(agent, input) {
154
157
  const matches = { broad: [], phaseOnly: [], exactPhase: [] };
155
158
  for (const agentWorkflow of agent.workflows) {
156
159
  const normalizedWorkflow = normalizeKey(agentWorkflow);
157
- if (!requested.includes(normalizedWorkflow))
160
+ const comparableWorkflow = canonicalSddWorkflowTargetKey(agentWorkflow);
161
+ if (!requested.includes(normalizedWorkflow) && !requested.includes(comparableWorkflow) && !sddApplyAliasMatches(agentWorkflow, input))
158
162
  continue;
159
- if (exact !== undefined && normalizedWorkflow === exact)
163
+ if (exact !== undefined && (normalizedWorkflow === exact || comparableWorkflow === exact))
160
164
  matches.exactPhase.push(agentWorkflow);
161
165
  else if (phase !== undefined && normalizedWorkflow === phase)
162
166
  matches.phaseOnly.push(agentWorkflow);
167
+ else if (sddApplyAliasMatches(agentWorkflow, input))
168
+ matches.exactPhase.push(agentWorkflow);
163
169
  else
164
170
  matches.broad.push(agentWorkflow);
165
171
  }
166
172
  return matches;
167
173
  }
174
+ function canonicalSddWorkflowTargetKey(workflow) {
175
+ const normalized = normalizeKey(workflow);
176
+ const separator = normalized.indexOf(':');
177
+ if (separator <= 0)
178
+ return normalized;
179
+ const workflowName = normalized.slice(0, separator);
180
+ const phase = normalized.slice(separator + 1);
181
+ if (workflowName !== 'sdd')
182
+ return normalized;
183
+ return `${workflowName}:${normalizeSddPhaseInput(phase) ?? phase}`;
184
+ }
185
+ function workflowRequestedSignals(input) {
186
+ return [input.workflow, input.phase, input.workflow !== undefined && input.phase !== undefined ? `${input.workflow}:${input.phase}` : undefined];
187
+ }
188
+ function sddApplyAliasMatches(agentWorkflow, input) {
189
+ if (input.phase === undefined || normalizeKey(input.phase) !== 'apply')
190
+ return false;
191
+ if (input.workflow !== undefined && !isSddWorkflow(input.workflow))
192
+ return false;
193
+ return normalizeKey(agentWorkflow) === 'sdd:apply-progress';
194
+ }
168
195
  function phaseSemanticMatchesFor(agent, input) {
169
196
  const workflow = input.workflow !== undefined ? normalizeKey(input.workflow) : undefined;
170
197
  if (workflow !== undefined && workflow !== 'sdd')
@@ -220,6 +247,9 @@ function normalizeText(value) {
220
247
  function normalizeKey(value) {
221
248
  return value.trim().toLowerCase();
222
249
  }
250
+ function isSddWorkflow(workflow) {
251
+ return workflow?.trim().toLowerCase() === 'sdd';
252
+ }
223
253
  function tokenize(value) {
224
254
  const seen = new Set();
225
255
  return value
@@ -0,0 +1,231 @@
1
+ import { canonicalAgentManifest, canonicalPromptContractVersion, canonicalSddSubagentNames } from './canonical-agent-manifest.js';
2
+ import { projectCanonicalAgentManifestToSeed } from './canonical-agent-projection.js';
3
+ export class AgentSeedUpgradeService {
4
+ agents;
5
+ history;
6
+ database;
7
+ constructor(dependencies) {
8
+ this.agents = dependencies.agents;
9
+ this.history = dependencies.history;
10
+ this.database = dependencies.database;
11
+ }
12
+ upgrade(input) {
13
+ if (!input.project.trim())
14
+ return validationFailure('Agent seed upgrade project is required');
15
+ if (input.scope !== 'project' && input.scope !== 'personal')
16
+ return validationFailure('Agent seed upgrade scope is invalid');
17
+ const seed = projectCanonicalAgentManifestToSeed();
18
+ const canonicalByName = new Map();
19
+ for (const agent of seed.agents)
20
+ canonicalByName.set(agent.name, agent);
21
+ for (const subagent of seed.subagents)
22
+ canonicalByName.set(subagent.name, subagent);
23
+ const source = input.source ?? 'boot-upgrade';
24
+ const summary = {
25
+ created: [],
26
+ upgraded: [],
27
+ noop: [],
28
+ overwritten: [],
29
+ errors: [],
30
+ skipped: false,
31
+ };
32
+ const expected = canonicalPromptContractVersion;
33
+ const transaction = this.database.transaction(() => {
34
+ for (const [name, definition] of canonicalByName) {
35
+ const outcome = this.upgradeOne(input.project, input.scope, name, definition, source, expected);
36
+ if (outcome.ok) {
37
+ switch (outcome.value.outcome) {
38
+ case 'created':
39
+ summary.created.push(name);
40
+ break;
41
+ case 'upgraded':
42
+ summary.upgraded.push(name);
43
+ break;
44
+ case 'overwrote-custom-instructions':
45
+ summary.overwritten.push(name);
46
+ break;
47
+ case 'noop':
48
+ summary.noop.push(name);
49
+ break;
50
+ }
51
+ }
52
+ else {
53
+ const failureOutcome = outcome.error.code === 'validation_failed' ? 'validation_failed' : 'db_error';
54
+ summary.errors.push({ agentName: name, outcome: failureOutcome, reason: outcome.error.message });
55
+ }
56
+ }
57
+ return summary;
58
+ });
59
+ if (!transaction.ok) {
60
+ return { ok: false, error: transaction.error };
61
+ }
62
+ return transaction;
63
+ }
64
+ hasDrift(input) {
65
+ const expected = input.expectedVersion ?? canonicalPromptContractVersion;
66
+ try {
67
+ const canonicalNames = [canonicalAgentManifest.defaultAgentName, ...canonicalSddSubagentNames];
68
+ const placeholders = canonicalNames.map(() => '?').join(', ');
69
+ const row = this.database.connection
70
+ .prepare(`
71
+ SELECT COUNT(*) AS stale_count
72
+ FROM agents
73
+ WHERE project = ? AND scope = ? AND name IN (${placeholders})
74
+ AND json_extract(adapters_json, '$.opencode.config.options.vgxnessPromptContractVersion') <> ?
75
+ `)
76
+ .get(input.project, input.scope, ...canonicalNames, expected);
77
+ return ok((row?.stale_count ?? 0) > 0);
78
+ }
79
+ catch (cause) {
80
+ return fail('Failed to detect agent seed drift', cause);
81
+ }
82
+ }
83
+ upgradeOne(project, scope, name, definition, source, expected) {
84
+ const existing = this.agents.getByName(project, scope, name);
85
+ const fromVersion = existing.ok ? readPromptContractVersion(existing.value) : null;
86
+ if (existing.ok && fromVersion === expected && isByteEqualToCanonical(existing.value, definition)) {
87
+ return ok({ outcome: 'noop', fromVersion: expected });
88
+ }
89
+ const parentAgentId = 'parentAgentName' in definition ? this.resolveParentId(project, scope, definition.parentAgentName) : undefined;
90
+ if ('parentAgentName' in definition && parentAgentId === undefined) {
91
+ return validationFailure(`Unresolved parentAgentName: ${definition.parentAgentName}`);
92
+ }
93
+ const registerInput = toRegisterInput(project, scope, definition, parentAgentId);
94
+ const registered = this.agents.register(registerInput);
95
+ if (!registered.ok) {
96
+ this.appendHistory({
97
+ project,
98
+ scope,
99
+ agentName: name,
100
+ fromVersion,
101
+ toVersion: expected,
102
+ outcome: registered.error.code === 'validation_failed' ? 'validation_failed' : 'db_error',
103
+ reason: registered.error.message,
104
+ source,
105
+ });
106
+ return registered;
107
+ }
108
+ let outcome;
109
+ if (!existing.ok) {
110
+ outcome = 'created';
111
+ }
112
+ else if (fromVersion !== null && fromVersion !== expected) {
113
+ outcome = 'upgraded';
114
+ }
115
+ else {
116
+ outcome = 'overwrote-custom-instructions';
117
+ }
118
+ this.appendHistory({
119
+ project,
120
+ scope,
121
+ agentName: name,
122
+ fromVersion,
123
+ toVersion: expected,
124
+ outcome,
125
+ reason: outcomeReason(outcome, fromVersion, expected, existing.ok),
126
+ source,
127
+ });
128
+ return ok({ outcome, fromVersion });
129
+ }
130
+ resolveParentId(project, scope, parentAgentName) {
131
+ const parent = this.agents.getByName(project, scope, parentAgentName);
132
+ if (!parent.ok || parent.value.mode !== 'agent')
133
+ return undefined;
134
+ return parent.value.id;
135
+ }
136
+ appendHistory(input) {
137
+ this.history.append({
138
+ project: input.project,
139
+ scope: input.scope,
140
+ agentName: input.agentName,
141
+ fromVersion: input.fromVersion,
142
+ toVersion: input.toVersion,
143
+ outcome: input.outcome,
144
+ reason: input.reason,
145
+ source: input.source,
146
+ });
147
+ }
148
+ }
149
+ function toRegisterInput(project, scope, definition, parentAgentId) {
150
+ const input = {
151
+ project,
152
+ scope,
153
+ mode: 'parentAgentName' in definition ? 'subagent' : 'agent',
154
+ name: definition.name,
155
+ description: definition.description,
156
+ instructions: definition.instructions,
157
+ };
158
+ if (definition.capabilities !== undefined)
159
+ input.capabilities = definition.capabilities;
160
+ if (definition.permissions !== undefined)
161
+ input.permissions = definition.permissions;
162
+ if (definition.memory !== undefined)
163
+ input.memory = definition.memory;
164
+ if (definition.workflows !== undefined)
165
+ input.workflows = definition.workflows;
166
+ if (definition.skills !== undefined)
167
+ input.skills = definition.skills;
168
+ if (definition.adapters !== undefined)
169
+ input.adapters = definition.adapters;
170
+ if (parentAgentId !== undefined)
171
+ input.parentAgentId = parentAgentId;
172
+ return input;
173
+ }
174
+ function isByteEqualToCanonical(existing, definition) {
175
+ if (existing.description !== definition.description)
176
+ return false;
177
+ if (existing.instructions.value !== definition.instructions.value)
178
+ return false;
179
+ if (!adaptersEqual(existing.adapters, definition.adapters ?? {}))
180
+ return false;
181
+ if (!arraysEqual(existing.capabilities, definition.capabilities ?? []))
182
+ return false;
183
+ if (!arraysEqual(existing.workflows, definition.workflows ?? []))
184
+ return false;
185
+ if (!arraysEqual(existing.skills, definition.skills ?? []))
186
+ return false;
187
+ return true;
188
+ }
189
+ function adaptersEqual(a, b) {
190
+ return JSON.stringify(a ?? {}) === JSON.stringify(b ?? {});
191
+ }
192
+ function arraysEqual(a, b) {
193
+ if (a.length !== b.length)
194
+ return false;
195
+ for (let i = 0; i < a.length; i += 1) {
196
+ if (a[i] !== b[i])
197
+ return false;
198
+ }
199
+ return true;
200
+ }
201
+ function readPromptContractVersion(agent) {
202
+ const opencode = agent.adapters?.opencode;
203
+ if (opencode === undefined)
204
+ return null;
205
+ const options = opencode.config?.options;
206
+ const value = options?.vgxnessPromptContractVersion;
207
+ if (typeof value !== 'number' || !Number.isInteger(value))
208
+ return null;
209
+ return value;
210
+ }
211
+ function outcomeReason(outcome, fromVersion, toVersion, existed) {
212
+ if (outcome === 'created')
213
+ return `created canonical row at v${toVersion}`;
214
+ if (outcome === 'upgraded')
215
+ return `upgraded v${fromVersion ?? 'unknown'} -> v${toVersion}`;
216
+ if (outcome === 'overwrote-custom-instructions')
217
+ return `overwrote customized row (was v${fromVersion ?? 'unknown'}) with v${toVersion} canonical`;
218
+ return existed ? `noop at v${toVersion}` : `noop at v${toVersion}`;
219
+ }
220
+ function ok(value) {
221
+ return { ok: true, value };
222
+ }
223
+ function validationFailure(message) {
224
+ return { ok: false, error: { code: 'validation_failed', message } };
225
+ }
226
+ function fail(message, cause) {
227
+ const error = { code: 'validation_failed', message };
228
+ if (cause !== undefined)
229
+ error.cause = cause;
230
+ return { ok: false, error };
231
+ }
@@ -0,0 +1,59 @@
1
+ import { AgentSeedUpgradeService } from './agent-seed-upgrade-service.js';
2
+ import { AgentRepository } from './repositories/agents.js';
3
+ import { AgentSeedHistoryRepository } from './repositories/agent-seed-history.js';
4
+ import { canonicalAgentManifest } from './canonical-agent-manifest.js';
5
+ const skipEnvVar = 'VGXNESS_SKIP_AGENT_SEED_AUTO_UPGRADE';
6
+ export function runBootAgentSeedUpgrade(database, env = process.env, project = canonicalAgentManifest.project, scope = canonicalAgentManifest.scope) {
7
+ if (isOptOut(env)) {
8
+ return { ok: true, skipped: true, created: 0, upgraded: 0, overwritten: 0, noop: 0, errors: 0 };
9
+ }
10
+ try {
11
+ const service = new AgentSeedUpgradeService({
12
+ agents: new AgentRepository(database),
13
+ history: new AgentSeedHistoryRepository(database),
14
+ database,
15
+ });
16
+ const result = service.upgrade({ project, scope, source: 'boot-upgrade' });
17
+ if (!result.ok) {
18
+ const message = `boot-upgrade failed: ${result.error.message} (code=${result.error.code})`;
19
+ process.stderr.write(`[vgxness] ${message}\n`);
20
+ return { ok: false, skipped: false, created: 0, upgraded: 0, overwritten: 0, noop: 0, errors: 1, message };
21
+ }
22
+ const value = result.value;
23
+ const touched = value.created.length + value.upgraded.length + value.overwritten.length + value.errors.length;
24
+ if (touched > 0) {
25
+ const parts = [];
26
+ if (value.created.length > 0)
27
+ parts.push(`created ${value.created.length}`);
28
+ if (value.upgraded.length > 0)
29
+ parts.push(`upgraded ${value.upgraded.length}`);
30
+ if (value.overwritten.length > 0)
31
+ parts.push(`overwrote ${value.overwritten.length}`);
32
+ if (value.errors.length > 0)
33
+ parts.push(`errors ${value.errors.length}`);
34
+ process.stderr.write(`[vgxness] boot-upgrade: ${parts.join(', ')}\n`);
35
+ for (const error of value.errors) {
36
+ process.stderr.write(`[vgxness] boot-upgrade: ${error.agentName} ${error.outcome}: ${error.reason}\n`);
37
+ }
38
+ }
39
+ return {
40
+ ok: true,
41
+ skipped: false,
42
+ created: value.created.length,
43
+ upgraded: value.upgraded.length,
44
+ overwritten: value.overwritten.length,
45
+ noop: value.noop.length,
46
+ errors: value.errors.length,
47
+ };
48
+ }
49
+ catch (cause) {
50
+ const detail = cause instanceof Error ? `${cause.name}: ${cause.message}` : String(cause);
51
+ const message = `boot-upgrade threw: ${detail}`;
52
+ process.stderr.write(`[vgxness] ${message}\n`);
53
+ return { ok: false, skipped: false, created: 0, upgraded: 0, overwritten: 0, noop: 0, errors: 1, message };
54
+ }
55
+ }
56
+ function isOptOut(env) {
57
+ const value = env[skipEnvVar];
58
+ return value === '1' || value === 'true';
59
+ }
@@ -1,6 +1,8 @@
1
1
  import { canonicalBehaviorContractVersion } from '../behavior/behavior-contract-manifest.js';
2
2
  export const canonicalDefaultAgentName = 'vgxness-manager';
3
- export const canonicalPromptContractVersion = 7;
3
+ export const canonicalOpenCodeDefaultModel = 'openai/gpt-5.5';
4
+ export const canonicalOpenCodeManagerReasoningEffort = 'high';
5
+ export const canonicalPromptContractVersion = 9;
4
6
  export const canonicalSddSubagentNames = [
5
7
  'vgxness-sdd-explore',
6
8
  'vgxness-sdd-propose',
@@ -76,13 +78,13 @@ function managerDefinition() {
76
78
  builtIn: true,
77
79
  name: canonicalDefaultAgentName,
78
80
  description: 'Coordinates VGXNESS MCP state and SDD sub-agents while routing Tier 0-2 lightweight work, Tier 3 preflight validation, and Tier 4 formal SDD.',
79
- instructions: { kind: 'inline', value: registryManagerInstructions },
81
+ instructions: { kind: 'inline', value: registryManagerInstructionsV9 },
80
82
  capabilities: ['sdd-orchestration', 'agent-routing', 'mcp-coordination', 'project-local-automation'],
81
83
  permissions: { read: 'allow', edit: 'ask', shell: 'ask', git: 'ask', memory: 'allow', 'provider-tool': 'deny', secrets: 'deny' },
82
84
  memory: { scopes: ['project'] },
83
85
  workflows: ['explore', 'quickfix', 'plan', 'build', 'debug', 'sdd', 'agent-seeding', 'opencode-install'],
84
86
  skills: ['vgxness-sdd-manager'],
85
- adapters: { opencode: { model: 'openai/gpt-5.5', config: { options: { reasoningEffort: 'high', vgxnessPromptContractVersion: canonicalPromptContractVersion, vgxnessBehaviorContractVersion: canonicalBehaviorContractVersion }, permission: { task: createCanonicalOpenCodeSddTaskPermissions() } } } },
87
+ adapters: { opencode: { model: canonicalOpenCodeDefaultModel, config: { options: { reasoningEffort: canonicalOpenCodeManagerReasoningEffort, vgxnessPromptContractVersion: canonicalPromptContractVersion, vgxnessBehaviorContractVersion: canonicalBehaviorContractVersion }, permission: { task: createCanonicalOpenCodeSddTaskPermissions() } } } },
86
88
  providerSupport: commonSupport(),
87
89
  };
88
90
  }
@@ -101,7 +103,7 @@ function subagentDefinition(name) {
101
103
  memory: { scopes: ['project'] },
102
104
  workflows: data.workflows,
103
105
  skills: data.skills,
104
- adapters: { opencode: { model: 'openai/gpt-5.5', config: { hidden: true, options: { vgxnessPromptContractVersion: canonicalPromptContractVersion, vgxnessBehaviorContractVersion: canonicalBehaviorContractVersion } } } },
106
+ adapters: { opencode: { model: canonicalOpenCodeDefaultModel, config: { hidden: true, options: { vgxnessPromptContractVersion: canonicalPromptContractVersion, vgxnessBehaviorContractVersion: canonicalBehaviorContractVersion } } } },
105
107
  providerSupport: commonSupport(),
106
108
  };
107
109
  }
@@ -114,12 +116,17 @@ export function createCanonicalOpenCodeSddSubagentPrompt(name) {
114
116
  const contract = subagentData[name].phaseContract;
115
117
  return `${common}\n\nPhase contract: ${contract}\n\nSDD governance v1: SDD artifact acceptance is human-only. Do not mark, describe, or persist generated phase output as accepted unless the user explicitly accepts it or an MCP acceptance record shows a human actor. Before advancing phases, use VGXNESS MCP readiness/status tools so draft, rejected, superseded, or legacy artifacts are not treated as accepted prerequisites. For risky VGX-managed side effects, use VGXNESS run preflight/reporting and include runId, phase, and agent context when available. OpenCode native/provider tools are audit-only and non-hard-blocking in governance v1; do not claim they are hard-blocked by OpenCode config.\n\nProvider-native daily progression: daily SDD progression happens inside OpenCode through conversation, VGXNESS MCP, and hidden SDD subagents. Do not instruct the user to run terminal SDD phase commands for normal daily flow. Return phase output, decisions, changed files, and evidence so the manager can persist artifacts and advance through MCP. Preserve confirmation/preflight requirements for apply, verify, init, archive, edits, shell, git, provider-tool, secrets, destructive, privileged, or ambiguous operations.`;
116
118
  }
119
+ /**
120
+ * Provider runtime prompt for generated provider managers.
121
+ * This feeds the OpenCode default config and Claude generated agent files; it is
122
+ * intentionally separate from registry/seed instructions below.
123
+ */
117
124
  export const canonicalOpenCodeManagerPrompt = `# VGXNESS Manager - compact SDD orchestrator
118
125
 
119
- Bind only to the primary \`vgxness-manager\` agent. Executor agents (for example \`vgxness-sdd-apply\`) use their own prompts.
126
+ Bind only to the primary \`vgxness-manager\` agent. Executor agents use their own prompts.
120
127
 
121
128
  ## Role
122
- Coordinate SDD; keep chat thin, use VGXNESS MCP as durable state, delegate to the smallest exact hidden SDD subagent, then synthesize evidence. Coach while coordinating: teach briefly, explain practical tradeoffs, stay realistic about risk/effort/unknowns, respectfully challenge weak assumptions, keep the user comfortable and in control, and avoid lectures or unnecessary verbosity.
129
+ Coordinate SDD; keep chat thin, use VGXNESS MCP as durable state, delegate to the smallest exact hidden SDD subagent, synthesize evidence. Coach while coordinating: teach briefly, explain practical tradeoffs, stay realistic about risk/effort/unknowns, respectfully challenge weak assumptions, keep the user comfortable and in control, avoid lectures or unnecessary verbosity.
123
130
 
124
131
  ## Non-negotiable governance
125
132
  - SDD artifact acceptance is human-only. Never infer or fabricate acceptance from generated output, subagent/model output, file presence, confidence, or legacy artifacts. Treat draft/rejected/superseded/stale/unaccepted artifacts as not accepted until a human acceptance record exists.
@@ -127,9 +134,8 @@ Coordinate SDD; keep chat thin, use VGXNESS MCP as durable state, delegate to th
127
134
  - Before risky VGX-managed side effects (edit, shell/tests, git, network, provider-tool, secrets, external-directory, destructive, privileged, ambiguous), call \`vgxness_run_preflight\` with runId/workflow/phase/agent context when available. If approval/block is required, stop; do not invent approval.
128
135
  - Direct human acceptance of an exact SDD artifact via \`vgxness_sdd_accept_artifact\` is not a generic SDD write for manager routing: do not call \`vgxness_run_preflight\` solely for that acceptance when the user explicitly accepted the exact project/change/phase artifact, \`acceptedBy.type\` is \`"human"\`, \`acceptedBy.id\` is non-empty, and status/readiness confirms the artifact is eligible. This shortcut applies only to \`vgxness_sdd_accept_artifact\`, not \`vgxness_sdd_save_artifact\`, edits, shell/tests, git, provider config, memory writes, external paths, secrets, destructive/privileged/ambiguous operations.
129
136
  - OpenCode native/provider tools are governance-v1 audit-only/non-hard-blocking. Report warnings; do not say native OpenCode tools are hard-blocked by config.
130
- - Do not mutate provider/global OpenCode config unless explicitly requested. Do not write to \`openspec/\`. Never revert/overwrite unrelated user work. Preserve \`permission.task\` deny-by-default with only exact known SDD subagents allowed.
131
- - Do not publish packages unless explicitly requested.
132
- - Do not change model or reasoning effort.
137
+ - Do not mutate provider/global OpenCode config. Do not write to \`openspec/\`. Do not publish packages unless explicitly requested. Never revert/overwrite unrelated user work. Preserve \`permission.task\` deny-by-default with only exact known SDD subagents allowed.
138
+ - Do not change provider model/reasoning config unless explicitly requested.
133
139
 
134
140
  ## Flexible governance routing
135
141
  Use the lightest safe path: Tier 0-2 direct; Tier 3 preflight/explicit validation; Tier 4 formal SDD for governance, permission model, SDD acceptance, architecture/security, or cross-surface behavior. Provider status/doctor/preview/handoff are read-only audit-only; provider config writes stay gated.
@@ -138,26 +144,41 @@ Use the lightest safe path: Tier 0-2 direct; Tier 3 preflight/explicit validatio
138
144
  Daily SDD happens inside OpenCode through conversation, VGXNESS MCP, and hidden SDD subagents. Do not tell users to run terminal SDD phase commands for normal flow. CLI is an escape hatch for bootstrap, doctor, recovery, setup gaps, or explicit request.
139
145
 
140
146
  ## MCP playbook
141
- - For starting, resuming, or recovering context: prefer \`vgxness_context_cockpit\` with project + workspace; treat \`vgxness_session_restore\` as one signal, not truth. For ending, pausing, handing off, or compacting: \`vgxness_session_close\` with current session id and actor \`manager\`; if no id, do not invent one and summarize.
142
- - SDD artifacts: list/read with \`vgxness_sdd_get_artifact\`/\`vgxness_sdd_list_artifacts\`; use \`payloadMode: "compact"\` by default so the primary context stays clean. Use verbose only when required, preferably inside the delegated phase subagent. Save with \`vgxness_sdd_save_artifact\` only after the appropriate flow. SDD artifacts are not generic memory.
143
- - Acceptance/readiness: check SDD status/readiness for the exact project/change/phase, confirm explicit human acceptance of that exact artifact, call \`vgxness_sdd_accept_artifact\` directly with audit context (\`acceptedBy.type: "human"\`, non-empty \`acceptedBy.id\`, runId, agentId, note/rationale when useful), then re-check status/readiness before reporting state. Do not add \`vgxness_run_preflight\` solely for that exact direct acceptance call. Ambiguous replies count only when tied to an immediate exact acceptance prompt. Use \`vgxness_governance_report\` for readiness, artifact states, preflight posture, and audit warnings before risky/ambiguous transitions and in apply/verify summaries.
147
+ - For starting, resuming, or recovering context: prefer \`vgxness_context_cockpit\`; treat \`vgxness_session_restore\` as one signal, not truth. For ending, pausing, handing off, or compacting: \`vgxness_session_close\` with current session id and actor \`manager\`; if no id, do not invent one and summarize.
148
+ - SDD artifacts: guide state with \`vgxness_sdd_next\`/\`vgxness_sdd_cockpit\`; list/read with \`vgxness_sdd_get_artifact\`/\`vgxness_sdd_list_artifacts\`; prefer \`payloadMode: "compact"\` so the primary context stays clean; use verbose only when required, preferably inside the delegated phase subagent. Save with \`vgxness_sdd_save_artifact\` only after the appropriate flow. Use \`vgxness_sdd_reopen_artifact\` only for rejected artifacts returning to draft, with explicit human actor/audit context. SDD artifacts are not generic memory.
149
+ - Acceptance/readiness: check SDD status/readiness for the exact project/change/phase, confirm explicit human acceptance of that exact artifact, call \`vgxness_sdd_accept_artifact\` directly with audit context (\`acceptedBy.type: "human"\`, non-empty \`acceptedBy.id\`, runId, agentId), then re-check status/readiness before reporting state. Do not add \`vgxness_run_preflight\` solely for that exact direct acceptance call. Ambiguous replies count only when tied to an immediate exact acceptance prompt. Use \`vgxness_governance_report\` for readiness, artifact states, preflight posture, and audit warnings.
144
150
  - Memory: call \`vgxness_memory_search\`/\`vgxness_memory_get\` for prior work or unclear context; call \`vgxness_memory_save\` for durable discoveries, decisions, bug fixes, config, patterns, or preferences; use \`vgxness_memory_update\` only to correct/evolve a known id. Do not duplicate full SDD artifacts as memory.
145
151
  - Agents/profile/payloads: resolve exact phase with \`vgxness_agent_resolve\`. \`vgxness_agent_activate\`, \`vgxness_opencode_manager_payload\`, and \`vgxness_skill_payload\` are preview context only; agent_activate does not execute a provider or write provider config. Use \`vgxness_manager_profile_get\` before behavior changes; \`vgxness_manager_profile_set\` requires explicit human authorization.
146
- - Runs: use \`vgxness_run_start\`/\`vgxness_run_list\`/\`vgxness_run_get\` for significant implementation/verification or multi-step delegated work; checkpoint with \`vgxness_run_checkpoint\`, preflight with \`vgxness_run_preflight\`, and close with \`vgxness_run_finalize\`.
147
- - Provider diagnostics: \`vgxness_provider_status\` and \`vgxness_provider_doctor\` are read-only reports.
152
+ - Runs/recovery: use \`vgxness_run_start\`/\`vgxness_run_list\`/\`vgxness_run_get\` for run work; checkpoint with \`vgxness_run_checkpoint\`, preflight with \`vgxness_run_preflight\`, and close with \`vgxness_run_finalize\`. Unknown runId: \`vgxness_run_resume_candidates\`. For interrupted runs, inspect with \`vgxness_run_resume_inspect\`, then call \`vgxness_run_resume_gate\` with approvalId from pendingApprovals/inspect before advice; never pass runId as approvalId
153
+ - Provider diagnostics: \`vgxness_provider_status\`/\`vgxness_provider_doctor\` are read-only reports.
148
154
 
149
155
  ## Minimum flows
150
156
  - Simple answer: inline; memory only for prior context; no run by default.
151
- - Proposal/spec/design/tasks: status/next -> readiness -> read prerequisites -> resolve exact subagent -> delegate -> persist by governance.
152
- - Apply/verify: require prerequisites -> read artifacts -> resolve exact subagent -> start/recover run -> preflight writes/shell/git/tests -> delegate -> checkpoint -> save output -> finalize when clear.
153
- - Config/provider/prompt change: inspect manager/profile or payload first; persistent changes require explicit human authorization.
157
+ - Proposal/spec/design/tasks: status/next -> readiness -> prerequisites -> exact subagent -> delegate -> persist by governance.
158
+ - Apply/verify: require prerequisites -> artifacts -> exact subagent -> start/recover run -> preflight writes/shell/git/tests -> delegate -> checkpoint -> save -> finalize.
159
+ - Config/provider/prompt change: inspect manager/profile or payload first; persistent changes need explicit human authorization.
160
+ - Recovery: MCP first. Continue: use \`vgxness_sdd_continue\`; read-only/advisory: no provider execution, run creation, artifact mutation, provider config/openspec writes, or acceptance/apply-progress bypass. CLI \`vgxness sdd continue\` is human fallback only. \`vgxness resume --project\` is for candidate runs; \`vgxness code sdd ... --draft-run\` is a planning-only path, never for apply-progress.
154
161
 
155
162
  ## Delegation thresholds
156
163
  Inline only small decisions, 1-3 file reads, status commands, and atomic one-file mechanical edits. Delegate broad exploration, substantial implementation, writes with analysis/new logic, and execution-heavy verification. Never delegate to unknown agents; use exact SDD phase mapping.
157
164
 
158
165
  ## Output
159
166
  Be concise: delegated work, results, files/decisions, evidence/tests, risks, next step.`;
160
- const registryManagerInstructions = 'You are the VGXNESS SDD coordinator, not a monolithic executor. Coach briefly while coordinating: explain useful tradeoffs, be realistic about risks and unknowns, respectfully challenge weak assumptions with better options, keep the user comfortable and in control, and stay concise. Use VGXNESS MCP as the durable control plane: restore session context with vgxness_session_restore before inferring start/resume state from chat, and close/pause/compact with vgxness_session_close using actor manager plus an actionable summary when a current session id exists. Check SDD status/next/ready, read prerequisites with sdd_get_artifact or sdd_list_artifacts, save accepted phase output with sdd_save_artifact, search/get/save/update memory only for reusable knowledge, resolve exact SDD subagents before substantial phase work, use runs/checkpoints/preflight/finalize for significant implementation or verification, and use vgxness_provider_status for configured/phase/next questions plus vgxness_provider_doctor for read-only OpenCode MCP/manager health. Prefer payloadMode=compact for manager-facing status/context reads, SDD artifact reads/lists, and activation handoffs so the primary context stays clean; request payloadMode=verbose only when full artifact contents, provider payloads, or skill context are actually needed, preferably inside delegated phase subagents. CLI is an escape hatch for bootstrap, doctor, rollback, recovery, MCP unavailable/setup missing, or explicit user request; do not tell users to run terminal SDD phase commands for normal daily flow. Delegate real SDD phase work to the smallest exact vgxness-sdd-* subagent allowed by permission.task, synthesize results, and persist artifacts/checkpoints. Do not perform substantial multi-file implementation inline. Do not mutate global/provider OpenCode config, install skills, publish packages, or write openspec/ unless explicitly authorized. Checked-in manager and subagent instructions are self-contained; external sdd-* skill files are optional registry assets, not requirements.';
167
+ /**
168
+ * Registry/seed instructions for the manager agent definition.
169
+ * These feed the canonical manifest, checked-in seed, boot upgrade, registry
170
+ * render baselines, and manager profile overlay baselines; they are
171
+ * intentionally distinct from the provider runtime prompt above.
172
+ */
173
+ const registryManagerInstructionsV9 = [
174
+ 'You are the VGXNESS SDD coordinator, not a monolithic executor. Coach briefly while coordinating: explain useful tradeoffs, be realistic about risks and unknowns, respectfully challenge weak assumptions with better options, keep the user comfortable and in control, and stay concise.',
175
+ 'Use VGXNESS MCP as the durable control plane: restore session context with vgxness_session_restore before inferring start/resume state from chat, and close/pause/compact with vgxness_session_close using actor manager plus an actionable summary when a current session id exists.',
176
+ 'Check SDD status/next/ready/cockpit, read prerequisites with sdd_get_artifact or sdd_list_artifacts, use public sdd_continue/internal vgxness_sdd_continue first for advisory read-only continuation plans, use sdd_reopen_artifact only for rejected artifacts returning to draft with explicit human actor/audit context, save accepted phase output with sdd_save_artifact, search/get/save/update memory only for reusable knowledge, resolve exact SDD subagents before substantial phase work, use runs/checkpoints/preflight/finalize for significant implementation or verification, use run_resume_candidates for unknown runId, inspect interrupted runs by runId with run_resume_inspect, then call run_resume_gate with approvalId from pendingApprovals/inspect; never pass runId as approvalId; use vgxness_provider_status for configured/phase/next questions plus vgxness_provider_doctor for read-only OpenCode MCP/manager health.',
177
+ 'Prefer payloadMode=compact for manager-facing status/context reads, SDD artifact reads/lists, and activation handoffs so the primary context stays clean; request payloadMode=verbose only when full artifact contents, provider payloads, or skill context are actually needed, preferably inside delegated phase subagents.',
178
+ 'MCP sdd_continue must not execute providers, create runs, mutate artifacts, write provider config/openspec, bypass human acceptance, or treat draft-run as apply-progress.',
179
+ 'CLI is an escape hatch for bootstrap, doctor, rollback, recovery, MCP unavailable/setup missing, or explicit user request; do not tell users to run terminal SDD phase commands for normal daily flow. CLI vgxness sdd continue is a human/manual fallback only; vgxness resume --project is for candidate runs, and vgxness code sdd ... --draft-run is planning-only.',
180
+ 'OpenCode native/provider tools are governance-v1 audit-only/non-hard-blocking; report warnings, never say they are hard-blocked by config.',
181
+ ].join(' ');
161
182
  const subagentData = {
162
183
  'vgxness-sdd-explore': { seedDescription: 'Investigates codebase context and identifies options before proposals.', seedInstructions: 'You are the explore phase executor, not the orchestrator. Do not delegate. Explore repository evidence for the requested SDD change. Do not implement code changes. Return concise findings, risks, and recommended next artifacts.', capabilities: ['sdd-exploration', 'codebase-research', 'discovery'], permissions: { read: 'allow', edit: 'deny', shell: 'ask', git: 'deny', memory: 'allow', 'provider-tool': 'deny', secrets: 'deny' }, workflows: ['sdd:explore'], skills: ['vgxness-sdd-explore'], phaseContract: 'Investigate codebase context, constraints, options, and risks. Do not implement code changes. Return findings and recommended next artifacts.' },
163
184
  'vgxness-sdd-propose': { seedDescription: 'Creates focused change proposals from exploration findings.', seedInstructions: 'You are the proposal phase executor, not the orchestrator. Do not delegate. Create a focused SDD proposal from exploration evidence. Do not implement code changes. Identify scope, tradeoffs, non-goals, and acceptance direction.', capabilities: ['sdd-proposal', 'proposal-planning', 'scope-definition'], permissions: { read: 'allow', edit: 'deny', shell: 'deny', git: 'deny', memory: 'allow', 'provider-tool': 'deny', secrets: 'deny' }, workflows: ['sdd:proposal'], skills: ['vgxness-sdd-proposal'], phaseContract: 'Create or refine a focused SDD proposal from exploration evidence. Do not implement code changes. Include scope, tradeoffs, non-goals, and acceptance direction.' },