hadara 0.1.0-rc.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.
Files changed (121) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +109 -0
  3. package/dist/agent/evidence.js +50 -0
  4. package/dist/agent/loop.js +124 -0
  5. package/dist/cli/args.js +70 -0
  6. package/dist/cli/dashboard.js +185 -0
  7. package/dist/cli/debt.js +41 -0
  8. package/dist/cli/doctor.js +68 -0
  9. package/dist/cli/errors.js +58 -0
  10. package/dist/cli/evidence-json.js +75 -0
  11. package/dist/cli/evidence.js +80 -0
  12. package/dist/cli/handoff.js +16 -0
  13. package/dist/cli/harness.js +57 -0
  14. package/dist/cli/hermes-json.js +31 -0
  15. package/dist/cli/hermes.js +28 -0
  16. package/dist/cli/init.js +142 -0
  17. package/dist/cli/install.js +34 -0
  18. package/dist/cli/main.js +216 -0
  19. package/dist/cli/mcp.js +15 -0
  20. package/dist/cli/package-smoke.js +37 -0
  21. package/dist/cli/policy-json.js +22 -0
  22. package/dist/cli/policy.js +43 -0
  23. package/dist/cli/release-artifact.js +47 -0
  24. package/dist/cli/release-dry-run.js +24 -0
  25. package/dist/cli/release-gate.js +28 -0
  26. package/dist/cli/release-publish.js +41 -0
  27. package/dist/cli/run-scaffold.js +68 -0
  28. package/dist/cli/run-state.js +41 -0
  29. package/dist/cli/run.js +191 -0
  30. package/dist/cli/smoke.js +58 -0
  31. package/dist/cli/status-json.js +6 -0
  32. package/dist/cli/status.js +26 -0
  33. package/dist/cli/task-json.js +8 -0
  34. package/dist/cli/task.js +64 -0
  35. package/dist/cli/tools.js +25 -0
  36. package/dist/cli/tui.js +72 -0
  37. package/dist/cli/write-preflight.js +27 -0
  38. package/dist/core/audit.js +41 -0
  39. package/dist/core/events.js +63 -0
  40. package/dist/core/fs.js +44 -0
  41. package/dist/core/paths.js +59 -0
  42. package/dist/core/redaction.js +178 -0
  43. package/dist/core/schema.js +253 -0
  44. package/dist/core/workspace.js +47 -0
  45. package/dist/evidence/evidence.js +170 -0
  46. package/dist/evidence/private-manifest.js +101 -0
  47. package/dist/handoff/handoff.js +49 -0
  48. package/dist/harness/replay.js +200 -0
  49. package/dist/harness/validate.js +465 -0
  50. package/dist/hermes/context-export.js +104 -0
  51. package/dist/index.js +29 -0
  52. package/dist/mcp/server.js +104 -0
  53. package/dist/mcp/tool-dispatch.js +159 -0
  54. package/dist/mcp/tool-registry.js +150 -0
  55. package/dist/mcp/tool-schemas.js +18 -0
  56. package/dist/policy/command-risk.js +39 -0
  57. package/dist/policy/permission-matrix.js +42 -0
  58. package/dist/policy/policy.js +20 -0
  59. package/dist/policy/preflight.js +47 -0
  60. package/dist/policy/presets.js +24 -0
  61. package/dist/policy/tokenizer.js +53 -0
  62. package/dist/providers/fallback-executor.js +46 -0
  63. package/dist/providers/mock-provider.js +49 -0
  64. package/dist/providers/provider-contract.js +2 -0
  65. package/dist/providers/provider-preparation.js +220 -0
  66. package/dist/providers/scripted-provider.js +69 -0
  67. package/dist/schemas/active-run-projection.schema.json +73 -0
  68. package/dist/schemas/active-run-resume.schema.json +68 -0
  69. package/dist/schemas/clean-checkout-smoke.schema.json +126 -0
  70. package/dist/schemas/context-export.schema.json +35 -0
  71. package/dist/schemas/event.schema.json +17 -0
  72. package/dist/schemas/evidence-list.schema.json +49 -0
  73. package/dist/schemas/feature-smoke.schema.json +67 -0
  74. package/dist/schemas/install-plan.schema.json +93 -0
  75. package/dist/schemas/package-smoke.schema.json +130 -0
  76. package/dist/schemas/private-evidence.schema.json +48 -0
  77. package/dist/schemas/provider-call.schema.json +42 -0
  78. package/dist/schemas/provider-config.schema.json +43 -0
  79. package/dist/schemas/release-artifact-manifest.schema.json +55 -0
  80. package/dist/schemas/release-artifact.schema.json +140 -0
  81. package/dist/schemas/release-dry-run.schema.json +141 -0
  82. package/dist/schemas/release-gate.schema.json +42 -0
  83. package/dist/schemas/release-publish.schema.json +114 -0
  84. package/dist/schemas/schema-index.json +145 -0
  85. package/dist/schemas/smoke-evidence-summary.schema.json +88 -0
  86. package/dist/schemas/tools-list.schema.json +78 -0
  87. package/dist/schemas/write-preflight.schema.json +47 -0
  88. package/dist/services/active-run-state.js +215 -0
  89. package/dist/services/capability-registry.js +540 -0
  90. package/dist/services/clean-checkout-smoke.js +393 -0
  91. package/dist/services/evidence-list.js +136 -0
  92. package/dist/services/feature-smoke.js +155 -0
  93. package/dist/services/harness-service.js +7 -0
  94. package/dist/services/install-plan.js +233 -0
  95. package/dist/services/operational-debt.js +767 -0
  96. package/dist/services/operations-status-service.js +195 -0
  97. package/dist/services/package-smoke.js +676 -0
  98. package/dist/services/policy-service.js +25 -0
  99. package/dist/services/project-read-model.js +101 -0
  100. package/dist/services/release-artifact-evidence.js +77 -0
  101. package/dist/services/release-artifact.js +351 -0
  102. package/dist/services/release-dry-run.js +253 -0
  103. package/dist/services/release-evidence.js +138 -0
  104. package/dist/services/release-publish.js +163 -0
  105. package/dist/services/smoke-evidence.js +104 -0
  106. package/dist/services/task-read-model.js +125 -0
  107. package/dist/services/tools-list.js +26 -0
  108. package/dist/services/write-preflight.js +240 -0
  109. package/dist/task/task-capsule.js +121 -0
  110. package/dist/tools/fake-shell.js +56 -0
  111. package/dist/tui/cache.js +341 -0
  112. package/dist/tui/constants.js +44 -0
  113. package/dist/tui/layout.js +140 -0
  114. package/dist/tui/markdown.js +238 -0
  115. package/dist/tui/read-model-worker.js +24 -0
  116. package/dist/tui/read-model.js +502 -0
  117. package/dist/tui/snapshot.js +434 -0
  118. package/dist/tui/state.js +229 -0
  119. package/dist/tui/terminal.js +475 -0
  120. package/dist/tui/theme.js +86 -0
  121. package/package.json +16 -0
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ProviderFallbackError = void 0;
4
+ exports.chatWithProviderFallback = chatWithProviderFallback;
5
+ class ProviderFallbackError extends Error {
6
+ attempts;
7
+ constructor(attempts) {
8
+ super('All provider fallback attempts failed.');
9
+ this.name = 'ProviderFallbackError';
10
+ this.attempts = attempts;
11
+ }
12
+ }
13
+ exports.ProviderFallbackError = ProviderFallbackError;
14
+ async function chatWithProviderFallback(providers, request) {
15
+ if (providers.length === 0) {
16
+ throw new ProviderFallbackError([]);
17
+ }
18
+ const attempts = [];
19
+ for (const provider of providers) {
20
+ try {
21
+ const response = await provider.chat(request);
22
+ attempts.push({
23
+ provider: provider.id,
24
+ ok: true,
25
+ model: response.model
26
+ });
27
+ return { response, attempts };
28
+ }
29
+ catch (error) {
30
+ attempts.push({
31
+ provider: provider.id,
32
+ ok: false,
33
+ error: normalizeProviderFailure(provider, error)
34
+ });
35
+ }
36
+ }
37
+ throw new ProviderFallbackError(attempts);
38
+ }
39
+ function normalizeProviderFailure(provider, error) {
40
+ if (isProviderError(error))
41
+ return error;
42
+ return provider.normalizeError(error);
43
+ }
44
+ function isProviderError(error) {
45
+ return Boolean(error && typeof error === 'object' && 'provider' in error && 'code' in error && 'retriable' in error);
46
+ }
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MockProvider = void 0;
4
+ class MockProvider {
5
+ id = 'mock';
6
+ displayName = 'MockProvider';
7
+ capabilities = {
8
+ supportsStreaming: true,
9
+ supportsToolCalling: false,
10
+ supportsReasoning: false,
11
+ supportsVision: false,
12
+ maxContextTokens: 8192,
13
+ localOnly: true,
14
+ costProfile: 'free'
15
+ };
16
+ async chat(request) {
17
+ const last = request.messages.at(-1)?.content ?? '';
18
+ return {
19
+ provider: this.id,
20
+ model: request.model ?? 'mock-model',
21
+ content: `Mock response for: ${last}`,
22
+ finishReason: 'stop',
23
+ usage: {
24
+ inputTokens: (await this.countTokens(JSON.stringify(request.messages))).tokens,
25
+ outputTokens: 8
26
+ }
27
+ };
28
+ }
29
+ async *stream(request) {
30
+ yield { type: 'start', provider: this.id, model: request.model ?? 'mock-model' };
31
+ const response = await this.chat(request);
32
+ for (const token of response.content.split(' ')) {
33
+ yield { type: 'delta', text: `${token} ` };
34
+ }
35
+ yield { type: 'finish', finishReason: response.finishReason };
36
+ }
37
+ async countTokens(input) {
38
+ return { tokens: Math.ceil(input.length / 4), approximate: true };
39
+ }
40
+ normalizeError(error) {
41
+ return {
42
+ provider: this.id,
43
+ code: 'MOCK_PROVIDER_ERROR',
44
+ message: error instanceof Error ? error.message : String(error),
45
+ retriable: false
46
+ };
47
+ }
48
+ }
49
+ exports.MockProvider = MockProvider;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,220 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ProviderCallReportError = exports.ProviderConfigError = void 0;
4
+ exports.createProviderConfig = createProviderConfig;
5
+ exports.normalizeProviderConfig = normalizeProviderConfig;
6
+ exports.createProviderCallReport = createProviderCallReport;
7
+ exports.assertProviderConfigSchema = assertProviderConfigSchema;
8
+ exports.assertProviderCallSchema = assertProviderCallSchema;
9
+ const redaction_1 = require("../core/redaction");
10
+ const schema_1 = require("../core/schema");
11
+ class ProviderConfigError extends Error {
12
+ constructor(message) {
13
+ super(message);
14
+ this.name = 'ProviderConfigError';
15
+ }
16
+ }
17
+ exports.ProviderConfigError = ProviderConfigError;
18
+ class ProviderCallReportError extends Error {
19
+ constructor(message) {
20
+ super(message);
21
+ this.name = 'ProviderCallReportError';
22
+ }
23
+ }
24
+ exports.ProviderCallReportError = ProviderCallReportError;
25
+ const SECRET_VALUE_KEYS = new Set(['apiKey', 'apiKeyValue', 'token', 'secret', 'password', 'authorization']);
26
+ const PROVIDER_CONFIG_INPUT_KEYS = new Set(['providers', 'defaultProvider']);
27
+ const PROVIDER_ADAPTER_CONFIG_INPUT_KEYS = new Set([
28
+ 'id',
29
+ 'kind',
30
+ 'enabled',
31
+ 'baseUrlEnv',
32
+ 'apiKeyEnv',
33
+ 'model',
34
+ 'capabilities',
35
+ 'localOnly',
36
+ 'costProfile'
37
+ ]);
38
+ const PROVIDER_CAPABILITY_INPUT_KEYS = new Set(['supportsStreaming', 'supportsToolCalling', 'supportsReasoning', 'supportsVision']);
39
+ const PROVIDER_KIND_VALUES = new Set(['openai-compatible', 'ollama', 'llama-cpp']);
40
+ const COST_PROFILE_VALUES = new Set(['free', 'low', 'medium', 'high', 'unknown']);
41
+ const PROVIDER_ID_PATTERN = /^[A-Za-z0-9_.:-]+$/;
42
+ const ENV_NAME_PATTERN = /^[A-Z_][A-Z0-9_]*$/;
43
+ function createProviderConfig(input) {
44
+ rejectUnknownFields(input, PROVIDER_CONFIG_INPUT_KEYS, 'provider config');
45
+ if (!Array.isArray(input.providers)) {
46
+ throw new ProviderConfigError('provider config providers must be an array.');
47
+ }
48
+ const providers = input.providers.map(normalizeProviderConfig);
49
+ const defaultProvider = input.defaultProvider ?? null;
50
+ if (defaultProvider && !providers.some((provider) => provider.id === defaultProvider)) {
51
+ throw new ProviderConfigError(`Default provider "${defaultProvider}" is not configured.`);
52
+ }
53
+ const config = {
54
+ schemaVersion: 'hadara.provider.config.v1',
55
+ providers,
56
+ defaultProvider
57
+ };
58
+ return assertProviderConfigSchema(config);
59
+ }
60
+ function normalizeProviderConfig(input) {
61
+ rejectUnknownFields(input, PROVIDER_ADAPTER_CONFIG_INPUT_KEYS, 'provider adapter config');
62
+ rejectSecretValueFields(input);
63
+ const id = normalizeProviderId(input.id, 'provider id', ProviderConfigError);
64
+ const kind = normalizeProviderKind(input.kind);
65
+ const model = requireNonEmptyString(input.model, 'provider model', ProviderConfigError);
66
+ const capabilities = normalizeCapabilities(input.capabilities);
67
+ const config = {
68
+ id,
69
+ kind,
70
+ enabled: optionalBoolean(input.enabled, 'enabled') ?? false,
71
+ model,
72
+ capabilities,
73
+ localOnly: optionalBoolean(input.localOnly, 'localOnly') ?? kind !== 'openai-compatible',
74
+ costProfile: normalizeCostProfile(input.costProfile)
75
+ };
76
+ if (input.baseUrlEnv)
77
+ config.baseUrlEnv = normalizeEnvName(input.baseUrlEnv, 'baseUrlEnv');
78
+ if (input.apiKeyEnv)
79
+ config.apiKeyEnv = normalizeEnvName(input.apiKeyEnv, 'apiKeyEnv');
80
+ return config;
81
+ }
82
+ function createProviderCallReport(input) {
83
+ const provider = normalizeProviderId(input.provider, 'provider', ProviderCallReportError);
84
+ const model = input.model ?? input.response?.model;
85
+ const issues = input.error ? [normalizeProviderCallIssue(input.error)] : [];
86
+ const report = {
87
+ schemaVersion: 'hadara.provider.call.v1',
88
+ provider,
89
+ ...(model ? { model } : {}),
90
+ ok: issues.length === 0,
91
+ input: {
92
+ messages: input.request.messages.length,
93
+ approxTokens: approximateTokens(JSON.stringify(input.request.messages))
94
+ },
95
+ ...(input.response
96
+ ? {
97
+ output: {
98
+ finishReason: input.response.finishReason,
99
+ approxTokens: input.response.usage?.outputTokens ?? approximateTokens(input.response.content)
100
+ }
101
+ }
102
+ : {}),
103
+ issues
104
+ };
105
+ return assertProviderCallSchema(report);
106
+ }
107
+ function assertProviderConfigSchema(config) {
108
+ const result = (0, schema_1.validateSchema)('hadara.provider.config.v1', config);
109
+ if (!result.ok) {
110
+ throw new ProviderConfigError(formatSchemaIssues('Provider config', result.issues));
111
+ }
112
+ return config;
113
+ }
114
+ function assertProviderCallSchema(report) {
115
+ const result = (0, schema_1.validateSchema)('hadara.provider.call.v1', report);
116
+ if (!result.ok) {
117
+ throw new ProviderCallReportError(formatSchemaIssues('Provider call report', result.issues));
118
+ }
119
+ return report;
120
+ }
121
+ function normalizeProviderCallIssue(error) {
122
+ if (isProviderError(error)) {
123
+ return {
124
+ severity: 'error',
125
+ code: error.code,
126
+ message: (0, redaction_1.redactSecrets)(error.message),
127
+ retriable: error.retriable
128
+ };
129
+ }
130
+ return {
131
+ severity: 'error',
132
+ code: 'PROVIDER_UNKNOWN',
133
+ message: (0, redaction_1.redactSecrets)(error instanceof Error ? error.message : String(error)),
134
+ retriable: false
135
+ };
136
+ }
137
+ function rejectSecretValueFields(input) {
138
+ const candidate = input;
139
+ for (const key of SECRET_VALUE_KEYS) {
140
+ if (Object.prototype.hasOwnProperty.call(candidate, key)) {
141
+ throw new ProviderConfigError(`Provider config must reference secret environment variable names, not "${key}" values.`);
142
+ }
143
+ }
144
+ }
145
+ function rejectUnknownFields(input, allowedKeys, label) {
146
+ if (!isPlainObject(input)) {
147
+ throw new ProviderConfigError(`${label} must be an object.`);
148
+ }
149
+ const unknownKeys = Object.keys(input).filter((key) => !allowedKeys.has(key));
150
+ if (unknownKeys.length > 0) {
151
+ throw new ProviderConfigError(`${label} contains unsupported field(s): ${unknownKeys.join(', ')}.`);
152
+ }
153
+ }
154
+ function normalizeProviderId(value, label, ErrorClass) {
155
+ const id = requireNonEmptyString(value, label, ErrorClass);
156
+ if (!PROVIDER_ID_PATTERN.test(id)) {
157
+ throw new ErrorClass(`${label} must match ${PROVIDER_ID_PATTERN.source}.`);
158
+ }
159
+ return id;
160
+ }
161
+ function normalizeProviderKind(value) {
162
+ if (!PROVIDER_KIND_VALUES.has(value)) {
163
+ throw new ProviderConfigError(`provider kind must be one of ${Array.from(PROVIDER_KIND_VALUES).join(', ')}.`);
164
+ }
165
+ return value;
166
+ }
167
+ function normalizeCostProfile(value) {
168
+ const costProfile = value ?? 'unknown';
169
+ if (!COST_PROFILE_VALUES.has(costProfile)) {
170
+ throw new ProviderConfigError(`costProfile must be one of ${Array.from(COST_PROFILE_VALUES).join(', ')}.`);
171
+ }
172
+ return costProfile;
173
+ }
174
+ function normalizeCapabilities(input) {
175
+ if (input !== undefined) {
176
+ rejectUnknownFields(input, PROVIDER_CAPABILITY_INPUT_KEYS, 'provider capabilities');
177
+ }
178
+ return {
179
+ streaming: optionalBoolean(input?.supportsStreaming, 'supportsStreaming') ?? false,
180
+ toolCalling: optionalBoolean(input?.supportsToolCalling, 'supportsToolCalling') ?? false,
181
+ reasoning: optionalBoolean(input?.supportsReasoning, 'supportsReasoning') ?? false,
182
+ vision: optionalBoolean(input?.supportsVision, 'supportsVision') ?? false
183
+ };
184
+ }
185
+ function optionalBoolean(value, label) {
186
+ if (value === undefined)
187
+ return undefined;
188
+ if (typeof value !== 'boolean') {
189
+ throw new ProviderConfigError(`${label} must be a boolean.`);
190
+ }
191
+ return value;
192
+ }
193
+ function normalizeEnvName(value, fieldName) {
194
+ const envName = requireNonEmptyString(value, fieldName, ProviderConfigError);
195
+ if (!ENV_NAME_PATTERN.test(envName)) {
196
+ throw new ProviderConfigError(`${fieldName} must be an environment variable name.`);
197
+ }
198
+ return envName;
199
+ }
200
+ function requireNonEmptyString(value, label, ErrorClass) {
201
+ if (typeof value !== 'string' || value.trim().length === 0) {
202
+ throw new ErrorClass(`${label} must be a non-empty string.`);
203
+ }
204
+ return value.trim();
205
+ }
206
+ function approximateTokens(input) {
207
+ return Math.max(1, Math.ceil(input.length / 4));
208
+ }
209
+ function isProviderError(error) {
210
+ return Boolean(error && typeof error === 'object' && 'provider' in error && 'code' in error && 'retriable' in error);
211
+ }
212
+ function isPlainObject(value) {
213
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
214
+ }
215
+ function formatSchemaIssues(label, issues) {
216
+ const firstIssue = issues[0];
217
+ if (!firstIssue)
218
+ return `${label} failed schema validation.`;
219
+ return `${label} failed schema validation: ${firstIssue.path} ${firstIssue.code} ${firstIssue.message}`;
220
+ }
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ScriptedProvider = void 0;
4
+ class ScriptedProvider {
5
+ script;
6
+ id = 'scripted';
7
+ displayName = 'ScriptedProvider';
8
+ capabilities = {
9
+ supportsStreaming: true,
10
+ supportsToolCalling: false,
11
+ supportsReasoning: false,
12
+ supportsVision: false,
13
+ maxContextTokens: 8192,
14
+ localOnly: true,
15
+ costProfile: 'free'
16
+ };
17
+ currentIndex = 0;
18
+ constructor(script) {
19
+ this.script = script;
20
+ }
21
+ async chat(request) {
22
+ const last = request.messages.at(-1)?.content ?? '';
23
+ const step = this.script[this.currentIndex];
24
+ if (!step) {
25
+ throw this.normalizeError(new Error(`ScriptedProvider exhausted after ${this.currentIndex} step(s). Last message: ${last}`));
26
+ }
27
+ if (step.match && !last.includes(step.match)) {
28
+ throw this.normalizeError(new Error(`ScriptedProvider step ${this.currentIndex + 1} expected message containing "${step.match}". Last message: ${last}`));
29
+ }
30
+ this.currentIndex += 1;
31
+ return {
32
+ provider: this.id,
33
+ model: request.model ?? 'scripted-model',
34
+ content: step.response,
35
+ finishReason: step.finishReason ?? 'stop'
36
+ };
37
+ }
38
+ async *stream(request) {
39
+ yield { type: 'start', provider: this.id, model: request.model ?? 'scripted-model' };
40
+ try {
41
+ const response = await this.chat(request);
42
+ for (const token of response.content.split(' ')) {
43
+ yield { type: 'delta', text: `${token} ` };
44
+ }
45
+ yield { type: 'finish', finishReason: response.finishReason };
46
+ }
47
+ catch (error) {
48
+ const normalized = this.normalizeError(error);
49
+ yield { type: 'error', message: normalized.message, retriable: normalized.retriable };
50
+ }
51
+ }
52
+ async countTokens(input) {
53
+ return { tokens: Math.ceil(input.length / 4), approximate: true };
54
+ }
55
+ normalizeError(error) {
56
+ if (isProviderError(error))
57
+ return error;
58
+ return {
59
+ provider: this.id,
60
+ code: 'SCRIPTED_PROVIDER_ERROR',
61
+ message: error instanceof Error ? error.message : String(error),
62
+ retriable: false
63
+ };
64
+ }
65
+ }
66
+ exports.ScriptedProvider = ScriptedProvider;
67
+ function isProviderError(error) {
68
+ return Boolean(error && typeof error === 'object' && 'provider' in error && 'code' in error && 'retriable' in error);
69
+ }
@@ -0,0 +1,73 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "hadara.active_run.projection.v1",
4
+ "x-hadara-schema-id": "hadara.active_run.projection.v1",
5
+ "title": "HADARA Active Run Projection Report",
6
+ "type": "object",
7
+ "additionalProperties": true,
8
+ "required": ["schemaVersion", "command", "ok", "path", "activeRun", "handoff", "resume", "issues"],
9
+ "properties": {
10
+ "schemaVersion": { "const": "hadara.active_run.projection.v1" },
11
+ "command": { "const": "active-run.projection" },
12
+ "ok": { "const": true },
13
+ "path": { "const": ".hadara/local/state/active-run.json" },
14
+ "activeRun": {
15
+ "oneOf": [{ "$ref": "#/$defs/activeRunManifest" }, { "type": "null" }]
16
+ },
17
+ "handoff": {
18
+ "type": "object",
19
+ "additionalProperties": true,
20
+ "required": ["fresh", "staleReason"],
21
+ "properties": {
22
+ "fresh": { "type": "boolean" },
23
+ "staleReason": { "type": ["string", "null"] }
24
+ }
25
+ },
26
+ "resume": {
27
+ "oneOf": [
28
+ {
29
+ "type": "object",
30
+ "additionalProperties": true,
31
+ "required": ["taskId", "capsule", "nextAction"],
32
+ "properties": {
33
+ "taskId": { "type": "string", "pattern": "^T-[0-9]{4}$" },
34
+ "capsule": { "type": "string" },
35
+ "nextAction": { "type": "string", "minLength": 1 }
36
+ }
37
+ },
38
+ { "type": "null" }
39
+ ]
40
+ },
41
+ "issues": {
42
+ "type": "array",
43
+ "items": { "$ref": "#/$defs/issue" }
44
+ }
45
+ },
46
+ "$defs": {
47
+ "activeRunManifest": {
48
+ "type": "object",
49
+ "additionalProperties": true,
50
+ "required": ["schemaVersion", "runId", "taskId", "capsule", "status", "startedAt", "updatedAt", "summary"],
51
+ "properties": {
52
+ "schemaVersion": { "const": "hadara.active_run.v1" },
53
+ "runId": { "type": "string", "minLength": 1 },
54
+ "taskId": { "type": "string", "pattern": "^T-[0-9]{4}$" },
55
+ "capsule": { "type": "string" },
56
+ "status": { "type": "string", "enum": ["active", "paused"] },
57
+ "startedAt": { "type": "string", "minLength": 1 },
58
+ "updatedAt": { "type": "string", "minLength": 1 },
59
+ "summary": { "type": "string" }
60
+ }
61
+ },
62
+ "issue": {
63
+ "type": "object",
64
+ "additionalProperties": true,
65
+ "required": ["severity", "code", "message"],
66
+ "properties": {
67
+ "severity": { "type": "string", "enum": ["warning", "error"] },
68
+ "code": { "type": "string", "minLength": 1 },
69
+ "message": { "type": "string", "minLength": 1 }
70
+ }
71
+ }
72
+ }
73
+ }
@@ -0,0 +1,68 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "hadara.active_run.resume.v1",
4
+ "x-hadara-schema-id": "hadara.active_run.resume.v1",
5
+ "title": "HADARA Active Run Resume Guidance Report",
6
+ "type": "object",
7
+ "additionalProperties": true,
8
+ "required": ["schemaVersion", "command", "ok", "activeRun", "resumePrompt", "issues"],
9
+ "properties": {
10
+ "schemaVersion": { "const": "hadara.active_run.resume.v1" },
11
+ "command": { "const": "active-run.resume" },
12
+ "ok": { "const": true },
13
+ "activeRun": {
14
+ "oneOf": [{ "$ref": "#/$defs/activeRunManifest" }, { "type": "null" }]
15
+ },
16
+ "resumePrompt": {
17
+ "type": "object",
18
+ "additionalProperties": true,
19
+ "required": ["summary", "mustRead", "nextActions", "constraints"],
20
+ "properties": {
21
+ "summary": { "type": "string", "minLength": 1 },
22
+ "mustRead": {
23
+ "type": "array",
24
+ "items": { "type": "string", "minLength": 1 }
25
+ },
26
+ "nextActions": {
27
+ "type": "array",
28
+ "items": { "type": "string", "minLength": 1 }
29
+ },
30
+ "constraints": {
31
+ "type": "array",
32
+ "items": { "type": "string", "minLength": 1 }
33
+ }
34
+ }
35
+ },
36
+ "issues": {
37
+ "type": "array",
38
+ "items": { "$ref": "#/$defs/issue" }
39
+ }
40
+ },
41
+ "$defs": {
42
+ "activeRunManifest": {
43
+ "type": "object",
44
+ "additionalProperties": true,
45
+ "required": ["schemaVersion", "runId", "taskId", "capsule", "status", "startedAt", "updatedAt", "summary"],
46
+ "properties": {
47
+ "schemaVersion": { "const": "hadara.active_run.v1" },
48
+ "runId": { "type": "string", "minLength": 1 },
49
+ "taskId": { "type": "string", "pattern": "^T-[0-9]{4}$" },
50
+ "capsule": { "type": "string" },
51
+ "status": { "type": "string", "enum": ["active", "paused"] },
52
+ "startedAt": { "type": "string", "minLength": 1 },
53
+ "updatedAt": { "type": "string", "minLength": 1 },
54
+ "summary": { "type": "string" }
55
+ }
56
+ },
57
+ "issue": {
58
+ "type": "object",
59
+ "additionalProperties": true,
60
+ "required": ["severity", "code", "message"],
61
+ "properties": {
62
+ "severity": { "type": "string", "enum": ["warning", "error"] },
63
+ "code": { "type": "string", "minLength": 1 },
64
+ "message": { "type": "string", "minLength": 1 }
65
+ }
66
+ }
67
+ }
68
+ }
@@ -0,0 +1,126 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "hadara.cleanCheckoutSmoke.v1",
4
+ "x-hadara-schema-id": "hadara.cleanCheckoutSmoke.v1",
5
+ "title": "HADARA Clean Checkout Smoke Report",
6
+ "type": "object",
7
+ "additionalProperties": true,
8
+ "required": [
9
+ "schemaVersion",
10
+ "command",
11
+ "ok",
12
+ "mode",
13
+ "execution",
14
+ "workspace",
15
+ "source",
16
+ "steps",
17
+ "privacy",
18
+ "issues"
19
+ ],
20
+ "properties": {
21
+ "schemaVersion": { "const": "hadara.cleanCheckoutSmoke.v1" },
22
+ "command": { "const": "smoke.cleanCheckout" },
23
+ "ok": { "type": "boolean" },
24
+ "mode": { "type": "string", "enum": ["execute"] },
25
+ "execution": {
26
+ "type": "object",
27
+ "additionalProperties": true,
28
+ "required": ["sourceCopied", "dependencyInstallExecuted", "buildExecuted", "checkExecuted", "builtCliSmokeExecuted", "packageInstallExecuted", "releaseMutationExecuted", "publishExecuted"],
29
+ "properties": {
30
+ "sourceCopied": { "type": "boolean" },
31
+ "dependencyInstallExecuted": { "type": "boolean" },
32
+ "buildExecuted": { "type": "boolean" },
33
+ "checkExecuted": { "type": "boolean" },
34
+ "builtCliSmokeExecuted": { "type": "boolean" },
35
+ "packageInstallExecuted": { "const": false },
36
+ "releaseMutationExecuted": { "const": false },
37
+ "publishExecuted": { "const": false }
38
+ }
39
+ },
40
+ "workspace": {
41
+ "type": "object",
42
+ "additionalProperties": true,
43
+ "required": ["kind", "displayPath", "pathRedacted", "retention"],
44
+ "properties": {
45
+ "kind": { "const": "disposable-clean-checkout" },
46
+ "displayPath": { "type": "string", "minLength": 1 },
47
+ "relativePath": { "type": "string", "minLength": 1 },
48
+ "pathRedacted": { "const": true },
49
+ "retention": { "type": "string", "enum": ["deleted", "kept-temporary"] }
50
+ }
51
+ },
52
+ "source": {
53
+ "type": "object",
54
+ "additionalProperties": true,
55
+ "required": ["kind", "displayPath", "pathRedacted", "mutated"],
56
+ "properties": {
57
+ "kind": { "const": "source-checkout" },
58
+ "displayPath": { "type": "string", "minLength": 1 },
59
+ "relativePath": { "type": "string", "minLength": 1 },
60
+ "pathRedacted": { "const": true },
61
+ "mutated": { "const": false }
62
+ }
63
+ },
64
+ "steps": {
65
+ "type": "array",
66
+ "items": { "$ref": "#/$defs/step" }
67
+ },
68
+ "artifacts": {
69
+ "type": "array",
70
+ "items": { "$ref": "#/$defs/artifact" }
71
+ },
72
+ "privacy": {
73
+ "type": "object",
74
+ "additionalProperties": true,
75
+ "required": ["rawLogsIncluded", "privatePathsIncluded", "environmentSecretsIncluded", "privateStorePathsIncluded"],
76
+ "properties": {
77
+ "rawLogsIncluded": { "const": false },
78
+ "privatePathsIncluded": { "const": false },
79
+ "environmentSecretsIncluded": { "const": false },
80
+ "privateStorePathsIncluded": { "const": false }
81
+ }
82
+ },
83
+ "issues": {
84
+ "type": "array",
85
+ "items": { "$ref": "#/$defs/issue" }
86
+ }
87
+ },
88
+ "$defs": {
89
+ "step": {
90
+ "type": "object",
91
+ "additionalProperties": true,
92
+ "required": ["id", "label", "command", "status", "summary"],
93
+ "properties": {
94
+ "id": { "type": "string", "minLength": 1 },
95
+ "label": { "type": "string", "minLength": 1 },
96
+ "command": { "type": "string", "minLength": 1 },
97
+ "status": { "type": "string", "enum": ["passed", "failed", "skipped"] },
98
+ "exitCode": { "type": ["integer", "null"] },
99
+ "elapsedMs": { "type": "integer" },
100
+ "summary": { "type": "string", "minLength": 1 }
101
+ }
102
+ },
103
+ "issue": {
104
+ "type": "object",
105
+ "additionalProperties": true,
106
+ "required": ["severity", "code", "message"],
107
+ "properties": {
108
+ "severity": { "type": "string", "enum": ["warning", "error"] },
109
+ "code": { "type": "string", "minLength": 1 },
110
+ "message": { "type": "string", "minLength": 1 },
111
+ "stepId": { "type": "string", "minLength": 1 }
112
+ }
113
+ },
114
+ "artifact": {
115
+ "type": "object",
116
+ "additionalProperties": true,
117
+ "required": ["kind", "visibility", "evidencePath", "rawContentIncluded"],
118
+ "properties": {
119
+ "kind": { "const": "summary" },
120
+ "visibility": { "const": "public" },
121
+ "evidencePath": { "type": "string", "pattern": "^tasks/T-[0-9]{4}-.+/artifacts/clean-checkout-smoke/.+" },
122
+ "rawContentIncluded": { "const": false }
123
+ }
124
+ }
125
+ }
126
+ }