hadara 0.3.3 → 0.3.4-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.
@@ -0,0 +1,150 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createHandoffStaleProblemsReport = createHandoffStaleProblemsReport;
7
+ exports.formatHandoffStaleProblemsReport = formatHandoffStaleProblemsReport;
8
+ const node_crypto_1 = __importDefault(require("node:crypto"));
9
+ const node_fs_1 = __importDefault(require("node:fs"));
10
+ const node_path_1 = __importDefault(require("node:path"));
11
+ const markdown_table_1 = require("../services/markdown-table");
12
+ const task_capsule_1 = require("../task/task-capsule");
13
+ const RELEASE_SOURCE_PATHS = ['docs/RELEASE_READINESS.md', 'docs/RELEASE_NOTES.md', 'docs/PROJECT_STATE.md', 'docs/AGENT_HANDOFF.md'];
14
+ const TASK_STALE_REVIEW_LANGUAGE = /\b(not yet|needs closeout|needs publish|needs recycle|blocked|todo|awaiting|unresolved)\b|still needs (closeout|publish|recycle)/i;
15
+ const RELEASE_STALE_REVIEW_LANGUAGE = /\b(pending|not yet|needs publish|needs recycle|blocked|todo|awaiting|unresolved)\b|publish\/recycle still pending|still needs (publish|recycle)/i;
16
+ function createHandoffStaleProblemsReport(projectRoot) {
17
+ const handoffPath = node_path_1.default.join(projectRoot, 'docs', 'AGENT_HANDOFF.md');
18
+ const handoffExists = node_fs_1.default.existsSync(handoffPath);
19
+ const handoffContent = handoffExists ? node_fs_1.default.readFileSync(handoffPath, 'utf8') : '';
20
+ const issues = [];
21
+ if (!handoffExists) {
22
+ issues.push({ severity: 'error', code: 'AGENT_HANDOFF_MISSING', message: 'docs/AGENT_HANDOFF.md is missing.', path: 'docs/AGENT_HANDOFF.md' });
23
+ }
24
+ const rows = handoffExists ? knownProblemRows(handoffContent) : [];
25
+ const completedTasks = readCompletedTasks(projectRoot);
26
+ const releaseSources = readReleaseSources(projectRoot);
27
+ const candidates = rows.flatMap((cells, index) => analyzeKnownProblemRow(cells, index + 1, completedTasks, releaseSources));
28
+ return {
29
+ schemaVersion: 'hadara.handoff.staleProblems.v1',
30
+ command: 'handoff.stale-problems',
31
+ ok: !issues.some((issue) => issue.severity === 'error'),
32
+ readOnly: true,
33
+ generatedAt: new Date().toISOString(),
34
+ target: {
35
+ path: 'docs/AGENT_HANDOFF.md',
36
+ beforeHash: hashContent(handoffContent),
37
+ writeBoundary: 'read-only'
38
+ },
39
+ summary: {
40
+ knownProblemRows: rows.length,
41
+ candidates: candidates.length
42
+ },
43
+ candidates,
44
+ issues
45
+ };
46
+ }
47
+ function formatHandoffStaleProblemsReport(report) {
48
+ const lines = [`[HADARA] handoff stale-problems: ${report.ok ? 'ok' : 'issues'} candidates=${report.summary.candidates}`];
49
+ lines.push(`target=${report.target.path} beforeHash=${report.target.beforeHash}`);
50
+ for (const candidate of report.candidates) {
51
+ lines.push(`${candidate.confidence}\trow ${candidate.rowIndex}\t${candidate.reason}`);
52
+ lines.push(` action: ${candidate.suggestedAction}`);
53
+ }
54
+ for (const issue of report.issues)
55
+ lines.push(`[${issue.severity}] ${issue.code}: ${issue.message}`);
56
+ return lines.join('\n');
57
+ }
58
+ function analyzeKnownProblemRow(cells, rowIndex, completedTasks, releaseSources) {
59
+ const rowText = cells.join(' · ');
60
+ const normalized = rowText.toLowerCase();
61
+ const candidates = [];
62
+ for (const taskId of unique([...rowText.matchAll(/\bT-\d{4}\b/g)].map((match) => match[0]))) {
63
+ const task = completedTasks.find((candidate) => candidate.taskId === taskId);
64
+ if (!task)
65
+ continue;
66
+ if (!TASK_STALE_REVIEW_LANGUAGE.test(rowText))
67
+ continue;
68
+ candidates.push({
69
+ id: `known-problem-${rowIndex}-${taskId.toLowerCase()}`,
70
+ rowIndex,
71
+ cells,
72
+ rowText,
73
+ confidence: 'high',
74
+ reason: `Known-problem row mentions ${taskId}, but that task capsule is marked ${task.status}.`,
75
+ matchedSources: [{ path: task.capsulePath, summary: `${task.taskId} ${task.title} is ${task.status}.` }],
76
+ suggestedAction: `Review this row and remove or rewrite it if ${taskId} resolved the problem.`
77
+ });
78
+ }
79
+ for (const version of unique([...rowText.matchAll(/\b\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?\b/g)].map((match) => match[0]))) {
80
+ const sourceMatches = releaseSources
81
+ .filter((source) => {
82
+ const sourceText = source.content.toLowerCase();
83
+ return source.content.includes(version) && /(published|verified|recycled|installed-package|npm view|dist-tag|latest)/i.test(source.content) && /published|verified|recycled|installed-package|npm view|dist-tag|latest/.test(sourceText);
84
+ })
85
+ .map((source) => ({ path: source.path, summary: `${version} appears in release/publish/recycle state text.` }));
86
+ if (sourceMatches.length === 0)
87
+ continue;
88
+ if (!RELEASE_STALE_REVIEW_LANGUAGE.test(normalized))
89
+ continue;
90
+ candidates.push({
91
+ id: `known-problem-${rowIndex}-version-${version.replace(/[^0-9a-z.-]/gi, '-')}`,
92
+ rowIndex,
93
+ cells,
94
+ rowText,
95
+ confidence: 'high',
96
+ reason: `Known-problem row mentions ${version}, and release state docs contain publish/recycle completion signals for that version.`,
97
+ matchedSources: sourceMatches,
98
+ suggestedAction: `Review this row and remove or rewrite it if ${version} publish/recycle work is complete.`
99
+ });
100
+ }
101
+ return dedupeCandidates(candidates);
102
+ }
103
+ function readCompletedTasks(projectRoot) {
104
+ return (0, task_capsule_1.listTaskCapsules)(projectRoot)
105
+ .map((task) => ({
106
+ taskId: task.id,
107
+ title: task.title,
108
+ status: readTaskStatus(task.dir) ?? 'unknown',
109
+ capsulePath: toPortablePath(node_path_1.default.relative(projectRoot, task.dir))
110
+ }))
111
+ .filter((task) => task.status === 'Done');
112
+ }
113
+ function knownProblemRows(handoffContent) {
114
+ return (0, markdown_table_1.parseMarkdownRowsUnderHeading)(handoffContent, '## Current Known Problems').filter((row) => {
115
+ const normalized = row.map((cell) => cell.toLowerCase());
116
+ return normalized.join('|') !== 'issue|impact|next step';
117
+ });
118
+ }
119
+ function readTaskStatus(taskDir) {
120
+ const taskPath = node_path_1.default.join(taskDir, 'TASK.md');
121
+ if (!node_fs_1.default.existsSync(taskPath))
122
+ return null;
123
+ const content = node_fs_1.default.readFileSync(taskPath, 'utf8');
124
+ return content.match(/^## Status\s*\n+([^\n]+)/m)?.[1]?.trim() ?? null;
125
+ }
126
+ function readReleaseSources(projectRoot) {
127
+ return RELEASE_SOURCE_PATHS.map((relativePath) => {
128
+ const absolutePath = node_path_1.default.join(projectRoot, relativePath);
129
+ return { path: relativePath, content: node_fs_1.default.existsSync(absolutePath) ? node_fs_1.default.readFileSync(absolutePath, 'utf8') : '' };
130
+ });
131
+ }
132
+ function dedupeCandidates(candidates) {
133
+ const seen = new Set();
134
+ return candidates.filter((candidate) => {
135
+ const key = `${candidate.rowIndex}:${candidate.reason}`;
136
+ if (seen.has(key))
137
+ return false;
138
+ seen.add(key);
139
+ return true;
140
+ });
141
+ }
142
+ function unique(values) {
143
+ return [...new Set(values)];
144
+ }
145
+ function hashContent(content) {
146
+ return `sha256:${node_crypto_1.default.createHash('sha256').update(content, 'utf8').digest('hex')}`;
147
+ }
148
+ function toPortablePath(value) {
149
+ return value.split(node_path_1.default.sep).join('/');
150
+ }
@@ -18,6 +18,7 @@
18
18
  "validateWith",
19
19
  "writeBoundaries",
20
20
  "sliceCandidates",
21
+ "agentActions",
21
22
  "knownProblems",
22
23
  "stateProjection",
23
24
  "sourceSummary",
@@ -38,6 +39,7 @@
38
39
  "validateWith": { "type": "array", "items": { "$ref": "#/$defs/validationSuggestion" } },
39
40
  "writeBoundaries": { "type": "array", "items": { "$ref": "#/$defs/writeBoundary" } },
40
41
  "sliceCandidates": { "type": "array", "items": { "$ref": "#/$defs/sliceCandidate" } },
42
+ "agentActions": { "type": "array", "items": { "$ref": "#/$defs/agentAction" } },
41
43
  "knownProblems": { "type": "array", "items": { "$ref": "#/$defs/item" } },
42
44
  "stateProjection": { "$ref": "#/$defs/stateProjection" },
43
45
  "sourceSummary": { "$ref": "#/$defs/sourceSummary" },
@@ -151,6 +153,27 @@
151
153
  }
152
154
  }
153
155
  },
156
+ "agentAction": {
157
+ "type": "object",
158
+ "additionalProperties": true,
159
+ "required": ["id", "kind", "priority", "reason", "command", "writeBoundary"],
160
+ "properties": {
161
+ "id": { "type": "string", "minLength": 1 },
162
+ "kind": { "enum": ["read-first", "slice", "validate"] },
163
+ "priority": { "type": "number" },
164
+ "reason": { "type": "string", "minLength": 1 },
165
+ "command": { "type": "string", "minLength": 1 },
166
+ "commandArgs": {
167
+ "type": "array",
168
+ "minItems": 1,
169
+ "items": { "type": "string", "minLength": 1 }
170
+ },
171
+ "sourceItemId": { "type": "string" },
172
+ "sliceCandidateId": { "type": "string" },
173
+ "path": { "type": "string" },
174
+ "writeBoundary": { "const": "read-only" }
175
+ }
176
+ },
154
177
  "stateProjection": {
155
178
  "type": "object",
156
179
  "additionalProperties": true,
@@ -0,0 +1,73 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "hadara.evidence.summary.v1",
4
+ "x-hadara-schema-id": "hadara.evidence.summary.v1",
5
+ "title": "HADARA Evidence Summary Report",
6
+ "type": "object",
7
+ "additionalProperties": true,
8
+ "required": ["schemaVersion", "command", "ok", "readOnly", "taskId", "summary", "records", "latest", "latestCloseEvidence", "copyHints", "issues"],
9
+ "properties": {
10
+ "schemaVersion": { "const": "hadara.evidence.summary.v1" },
11
+ "command": { "const": "evidence.summary" },
12
+ "ok": { "type": "boolean" },
13
+ "readOnly": { "const": true },
14
+ "taskId": { "type": "string", "pattern": "^T-[0-9]{4}$" },
15
+ "summary": {
16
+ "type": "object",
17
+ "additionalProperties": true,
18
+ "required": ["count", "durableCount", "unstableCount", "privateIncluded", "latestId", "latestCloseEvidenceId"],
19
+ "properties": {
20
+ "count": { "type": "integer", "minimum": 0 },
21
+ "durableCount": { "type": "integer", "minimum": 0 },
22
+ "unstableCount": { "type": "integer", "minimum": 0 },
23
+ "privateIncluded": { "type": "boolean" },
24
+ "latestId": { "type": ["string", "null"] },
25
+ "latestCloseEvidenceId": { "type": ["string", "null"] }
26
+ }
27
+ },
28
+ "records": { "type": "array", "items": { "$ref": "#/$defs/summaryRecord" } },
29
+ "latest": { "oneOf": [{ "$ref": "#/$defs/summaryRecord" }, { "type": "null" }] },
30
+ "latestCloseEvidence": { "oneOf": [{ "$ref": "#/$defs/summaryRecord" }, { "type": "null" }] },
31
+ "copyHints": {
32
+ "type": "object",
33
+ "additionalProperties": true,
34
+ "required": ["latestId", "latestCloseEvidenceId", "durableIds"],
35
+ "properties": {
36
+ "latestId": { "type": ["string", "null"] },
37
+ "latestCloseEvidenceId": { "type": ["string", "null"] },
38
+ "durableIds": { "type": "array", "items": { "type": "string", "minLength": 1 } }
39
+ }
40
+ },
41
+ "issues": { "type": "array", "items": { "$ref": "#/$defs/issue" } }
42
+ },
43
+ "$defs": {
44
+ "summaryRecord": {
45
+ "type": "object",
46
+ "additionalProperties": true,
47
+ "required": ["id", "time", "category", "outcome", "visibility", "summary", "tags", "sourceLine", "idSource", "idStability", "persistedSchemaVersion"],
48
+ "properties": {
49
+ "id": { "type": "string", "minLength": 1 },
50
+ "time": { "type": "string", "minLength": 1 },
51
+ "category": { "type": "string", "enum": ["validation", "implementation", "release", "security", "policy", "operation", "decision", "handoff", "audit", "note", "observation"] },
52
+ "outcome": { "type": "string", "enum": ["passed", "failed", "blocked", "unknown", "recorded", "not-applicable"] },
53
+ "visibility": { "type": "string", "enum": ["public", "private"] },
54
+ "summary": { "type": "string", "minLength": 1 },
55
+ "tags": { "type": "array", "items": { "type": "string" } },
56
+ "sourceLine": { "type": "integer", "minimum": 1 },
57
+ "idSource": { "type": "string", "enum": ["persisted", "line-fallback"] },
58
+ "idStability": { "type": "string", "enum": ["durable", "unstable-on-reorder"] },
59
+ "persistedSchemaVersion": { "type": "string", "enum": ["hadara.evidence.v1", "hadara.evidence.v2"] }
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,64 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "hadara.handoff.staleProblems.v1",
4
+ "x-hadara-schema-id": "hadara.handoff.staleProblems.v1",
5
+ "type": "object",
6
+ "additionalProperties": true,
7
+ "required": ["schemaVersion", "command", "ok", "readOnly", "generatedAt", "target", "summary", "candidates", "issues"],
8
+ "properties": {
9
+ "schemaVersion": { "const": "hadara.handoff.staleProblems.v1" },
10
+ "command": { "const": "handoff.stale-problems" },
11
+ "ok": { "type": "boolean" },
12
+ "readOnly": { "const": true },
13
+ "generatedAt": { "type": "string" },
14
+ "target": {
15
+ "type": "object",
16
+ "additionalProperties": true,
17
+ "required": ["path", "beforeHash", "writeBoundary"],
18
+ "properties": {
19
+ "path": { "const": "docs/AGENT_HANDOFF.md" },
20
+ "beforeHash": { "type": "string", "pattern": "^sha256:[a-f0-9]{64}$" },
21
+ "writeBoundary": { "const": "read-only" }
22
+ }
23
+ },
24
+ "summary": {
25
+ "type": "object",
26
+ "additionalProperties": true,
27
+ "required": ["knownProblemRows", "candidates"],
28
+ "properties": {
29
+ "knownProblemRows": { "type": "integer", "minimum": 0 },
30
+ "candidates": { "type": "integer", "minimum": 0 }
31
+ }
32
+ },
33
+ "candidates": {
34
+ "type": "array",
35
+ "items": {
36
+ "type": "object",
37
+ "additionalProperties": true,
38
+ "required": ["id", "rowIndex", "cells", "rowText", "confidence", "reason", "matchedSources", "suggestedAction"],
39
+ "properties": {
40
+ "id": { "type": "string" },
41
+ "rowIndex": { "type": "integer", "minimum": 1 },
42
+ "cells": { "type": "array", "items": { "type": "string" } },
43
+ "rowText": { "type": "string" },
44
+ "confidence": { "enum": ["medium", "high"] },
45
+ "reason": { "type": "string" },
46
+ "matchedSources": {
47
+ "type": "array",
48
+ "items": {
49
+ "type": "object",
50
+ "additionalProperties": true,
51
+ "required": ["path", "summary"],
52
+ "properties": {
53
+ "path": { "type": "string" },
54
+ "summary": { "type": "string" }
55
+ }
56
+ }
57
+ },
58
+ "suggestedAction": { "type": "string" }
59
+ }
60
+ }
61
+ },
62
+ "issues": { "type": "array", "items": { "type": "object", "additionalProperties": true } }
63
+ }
64
+ }
@@ -0,0 +1,150 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "hadara.packageRecycle.v1",
4
+ "x-hadara-schema-id": "hadara.packageRecycle.v1",
5
+ "title": "HADARA Installed Package Recycle Report",
6
+ "type": "object",
7
+ "additionalProperties": true,
8
+ "required": [
9
+ "schemaVersion",
10
+ "command",
11
+ "ok",
12
+ "mode",
13
+ "readOnly",
14
+ "package",
15
+ "networkPolicy",
16
+ "execution",
17
+ "workspace",
18
+ "steps",
19
+ "artifacts",
20
+ "privacy",
21
+ "issues"
22
+ ],
23
+ "properties": {
24
+ "schemaVersion": { "const": "hadara.packageRecycle.v1" },
25
+ "command": { "const": "package.recycle" },
26
+ "ok": { "type": "boolean" },
27
+ "mode": { "type": "string", "enum": ["dry-run", "execute"] },
28
+ "readOnly": { "type": "boolean" },
29
+ "package": {
30
+ "type": "object",
31
+ "additionalProperties": true,
32
+ "required": ["specifier", "name", "expectedVersion", "observedVersion", "latestVersion", "distTags"],
33
+ "properties": {
34
+ "specifier": { "type": "string", "minLength": 1 },
35
+ "name": { "type": "string", "minLength": 1 },
36
+ "expectedVersion": { "type": ["string", "null"] },
37
+ "observedVersion": { "type": ["string", "null"] },
38
+ "latestVersion": { "type": ["string", "null"] },
39
+ "distTags": {
40
+ "type": "object",
41
+ "additionalProperties": { "type": "string" }
42
+ }
43
+ }
44
+ },
45
+ "networkPolicy": {
46
+ "type": "object",
47
+ "additionalProperties": true,
48
+ "required": ["mode", "enforced", "notes"],
49
+ "properties": {
50
+ "mode": { "const": "environment-inherited" },
51
+ "enforced": { "const": false },
52
+ "notes": { "type": "array", "items": { "type": "string", "minLength": 1 } }
53
+ }
54
+ },
55
+ "execution": {
56
+ "type": "object",
57
+ "additionalProperties": true,
58
+ "required": [
59
+ "npmViewExecuted",
60
+ "npmDistTagExecuted",
61
+ "packageInstallExecuted",
62
+ "installedVersionExecuted",
63
+ "lifecycleHelpExecuted",
64
+ "initExecuted",
65
+ "taskLifecycleExecuted",
66
+ "contextSmokeExecuted",
67
+ "releaseMutationExecuted",
68
+ "publishExecuted"
69
+ ],
70
+ "properties": {
71
+ "npmViewExecuted": { "type": "boolean" },
72
+ "npmDistTagExecuted": { "type": "boolean" },
73
+ "packageInstallExecuted": { "type": "boolean" },
74
+ "installedVersionExecuted": { "type": "boolean" },
75
+ "lifecycleHelpExecuted": { "type": "boolean" },
76
+ "initExecuted": { "type": "boolean" },
77
+ "taskLifecycleExecuted": { "type": "boolean" },
78
+ "contextSmokeExecuted": { "type": "boolean" },
79
+ "releaseMutationExecuted": { "const": false },
80
+ "publishExecuted": { "const": false }
81
+ }
82
+ },
83
+ "workspace": {
84
+ "type": "object",
85
+ "additionalProperties": true,
86
+ "required": ["kind", "displayPath", "pathRedacted", "retention"],
87
+ "properties": {
88
+ "kind": { "const": "disposable" },
89
+ "displayPath": { "type": "string", "minLength": 1 },
90
+ "pathRedacted": { "const": true },
91
+ "retention": { "type": "string", "enum": ["deleted", "kept-temporary"] }
92
+ }
93
+ },
94
+ "steps": { "type": "array", "items": { "$ref": "#/$defs/step" } },
95
+ "artifacts": { "type": "array", "items": { "$ref": "#/$defs/artifact" } },
96
+ "privacy": {
97
+ "type": "object",
98
+ "additionalProperties": true,
99
+ "required": ["rawLogsIncluded", "rawPackageContentsIncluded", "privatePathsIncluded", "environmentSecretsIncluded", "privateStorePathsIncluded"],
100
+ "properties": {
101
+ "rawLogsIncluded": { "const": false },
102
+ "rawPackageContentsIncluded": { "const": false },
103
+ "privatePathsIncluded": { "const": false },
104
+ "environmentSecretsIncluded": { "const": false },
105
+ "privateStorePathsIncluded": { "const": false }
106
+ }
107
+ },
108
+ "issues": { "type": "array", "items": { "$ref": "#/$defs/issue" } }
109
+ },
110
+ "$defs": {
111
+ "step": {
112
+ "type": "object",
113
+ "additionalProperties": true,
114
+ "required": ["id", "label", "status", "summary"],
115
+ "properties": {
116
+ "id": { "type": "string", "minLength": 1 },
117
+ "label": { "type": "string", "minLength": 1 },
118
+ "status": { "type": "string", "enum": ["planned", "passed", "failed", "skipped"] },
119
+ "command": { "type": "string", "minLength": 1 },
120
+ "exitCode": { "type": ["integer", "null"] },
121
+ "elapsedMs": { "type": "integer" },
122
+ "summary": { "type": "string", "minLength": 1 }
123
+ }
124
+ },
125
+ "artifact": {
126
+ "type": "object",
127
+ "additionalProperties": true,
128
+ "required": ["kind", "visibility", "rawContentIncluded"],
129
+ "properties": {
130
+ "kind": { "type": "string", "enum": ["summary", "command-log", "install-tree"] },
131
+ "visibility": { "type": "string", "enum": ["public", "private", "temporary"] },
132
+ "evidencePath": { "type": "string", "pattern": "^tasks/T-[0-9]{4}-.+/artifacts/package-recycle/.+" },
133
+ "relativePath": { "type": "string", "minLength": 1 },
134
+ "pathRedacted": { "const": true },
135
+ "rawContentIncluded": { "const": false }
136
+ }
137
+ },
138
+ "issue": {
139
+ "type": "object",
140
+ "additionalProperties": true,
141
+ "required": ["severity", "code", "message"],
142
+ "properties": {
143
+ "severity": { "type": "string", "enum": ["warning", "error"] },
144
+ "code": { "type": "string", "minLength": 1 },
145
+ "message": { "type": "string", "minLength": 1 },
146
+ "stepId": { "type": "string", "minLength": 1 }
147
+ }
148
+ }
149
+ }
150
+ }
@@ -0,0 +1,39 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "hadara.releaseCloseout.v1",
4
+ "x-hadara-schema-id": "hadara.releaseCloseout.v1",
5
+ "type": "object",
6
+ "additionalProperties": true,
7
+ "required": ["schemaVersion", "command", "ok", "readOnly", "generatedAt", "input", "summary", "surfaces", "suggestedFragments", "issues"],
8
+ "properties": {
9
+ "schemaVersion": { "const": "hadara.releaseCloseout.v1" },
10
+ "command": { "const": "release.closeout" },
11
+ "ok": { "type": "boolean" },
12
+ "readOnly": { "const": true },
13
+ "generatedAt": { "type": "string" },
14
+ "input": {
15
+ "type": "object",
16
+ "additionalProperties": true,
17
+ "required": ["version", "taskId"],
18
+ "properties": {
19
+ "version": { "type": ["string", "null"] },
20
+ "taskId": { "type": ["string", "null"] }
21
+ }
22
+ },
23
+ "summary": {
24
+ "type": "object",
25
+ "additionalProperties": true,
26
+ "required": ["files", "current", "stale", "missing", "suggestedFragments"],
27
+ "properties": {
28
+ "files": { "type": "integer", "minimum": 0 },
29
+ "current": { "type": "integer", "minimum": 0 },
30
+ "stale": { "type": "integer", "minimum": 0 },
31
+ "missing": { "type": "integer", "minimum": 0 },
32
+ "suggestedFragments": { "type": "integer", "minimum": 0 }
33
+ }
34
+ },
35
+ "surfaces": { "type": "array", "items": { "type": "object", "additionalProperties": true } },
36
+ "suggestedFragments": { "type": "array", "items": { "type": "object", "additionalProperties": true } },
37
+ "issues": { "type": "array", "items": { "type": "object", "additionalProperties": true } }
38
+ }
39
+ }
@@ -43,6 +43,13 @@
43
43
  "owner": "services/evidence-list",
44
44
  "notes": "Shared by CLI evidence list and read-only MCP hadara.evidence.list."
45
45
  },
46
+ {
47
+ "id": "hadara.evidence.summary.v1",
48
+ "path": "src/schemas/evidence-summary.schema.json",
49
+ "status": "fixture",
50
+ "owner": "services/evidence-summary",
51
+ "notes": "Compact read-only evidence id summary for agent copy/paste and close-proof discovery."
52
+ },
46
53
  {
47
54
  "id": "hadara.evidence.lint.v1",
48
55
  "path": "src/schemas/evidence-lint.schema.json",
@@ -218,6 +225,13 @@
218
225
  "owner": "handoff/suggestion",
219
226
  "notes": "Documents read-only Agent Handoff section-fragment suggestions with shared-doc before-hash metadata."
220
227
  },
228
+ {
229
+ "id": "hadara.handoff.staleProblems.v1",
230
+ "path": "src/schemas/handoff-stale-problems.schema.json",
231
+ "status": "fixture",
232
+ "owner": "handoff/stale-problems",
233
+ "notes": "Documents read-only Agent Handoff stale known-problem candidate detection."
234
+ },
221
235
  {
222
236
  "id": "hadara.dev.docker_check.v1",
223
237
  "path": "src/schemas/dev-docker-check.schema.json",
@@ -428,6 +442,13 @@
428
442
  "owner": "package-smoke/report",
429
443
  "notes": "Documents reduced package-smoke reports before dry-run or executable package-smoke command implementation."
430
444
  },
445
+ {
446
+ "id": "hadara.packageRecycle.v1",
447
+ "path": "src/schemas/package-recycle.schema.json",
448
+ "status": "fixture",
449
+ "owner": "package-recycle/report",
450
+ "notes": "Documents reduced installed-package recycle reports for npm registry/package consumer smoke validation."
451
+ },
431
452
  {
432
453
  "id": "hadara.plan_context.v1",
433
454
  "path": "src/schemas/plan-context.schema.json",
@@ -470,6 +491,13 @@
470
491
  "owner": "release/dry-run",
471
492
  "notes": "Documents read-only final release dry-run reports that cross-check public evidence artifacts and planned release targets without publish or GitHub Release mutation."
472
493
  },
494
+ {
495
+ "id": "hadara.releaseCloseout.v1",
496
+ "path": "src/schemas/release-closeout.schema.json",
497
+ "status": "fixture",
498
+ "owner": "release/closeout",
499
+ "notes": "Documents read-only release closeout planning across release docs, shared state docs, and active release capsule files."
500
+ },
473
501
  {
474
502
  "id": "hadara.releasePublish.v1",
475
503
  "path": "src/schemas/release-publish.schema.json",
@@ -71,6 +71,10 @@
71
71
  "required": [
72
72
  "mode",
73
73
  "primaryNextAction",
74
+ "primaryAction",
75
+ "whyThisNow",
76
+ "avoidForNow",
77
+ "nextCommandArgs",
74
78
  "reason",
75
79
  "taskRequired",
76
80
  "liveContextPackAvailable",
@@ -79,6 +83,32 @@
79
83
  "properties": {
80
84
  "mode": { "enum": ["live-context-pack", "warm-cache", "bounded-no-live"] },
81
85
  "primaryNextAction": { "enum": ["select-task", "inspect-task"] },
86
+ "primaryAction": {
87
+ "type": "object",
88
+ "additionalProperties": true,
89
+ "required": ["id", "label", "command", "args", "reason", "writeBoundary", "recommendedActorRole"],
90
+ "properties": {
91
+ "id": { "type": "string", "minLength": 1 },
92
+ "label": { "type": "string", "minLength": 1 },
93
+ "command": { "type": "string", "minLength": 1 },
94
+ "args": {
95
+ "type": "array",
96
+ "items": { "type": "string" }
97
+ },
98
+ "reason": { "type": "string", "minLength": 1 },
99
+ "writeBoundary": { "const": "read-only" },
100
+ "recommendedActorRole": { "const": "agent-worker" }
101
+ }
102
+ },
103
+ "whyThisNow": { "type": "string", "minLength": 1 },
104
+ "avoidForNow": {
105
+ "type": "array",
106
+ "items": { "type": "string", "minLength": 1 }
107
+ },
108
+ "nextCommandArgs": {
109
+ "type": "array",
110
+ "items": { "type": "string" }
111
+ },
82
112
  "reason": { "type": "string", "minLength": 1 },
83
113
  "taskRequired": { "type": "boolean" },
84
114
  "liveContextPackAvailable": { "type": "boolean" },
@@ -23,7 +23,7 @@
23
23
  "schemaVersion": { "const": "hadara.smokeEvidenceSummary.v1" },
24
24
  "time": { "type": "string", "minLength": 1 },
25
25
  "taskId": { "type": "string", "pattern": "^T-[0-9]{4}$" },
26
- "category": { "type": "string", "enum": ["package-smoke", "clean-checkout-smoke"] },
26
+ "category": { "type": "string", "enum": ["package-smoke", "package-recycle", "clean-checkout-smoke"] },
27
27
  "sourceReport": {
28
28
  "type": "object",
29
29
  "additionalProperties": true,