@jstn-sdk/ma 0.1.13 → 0.14.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/plugins/marketplace.json +0 -0
- package/.codex/agents/Architect.toml +1 -0
- package/.codex/agents/Auditor.toml +1 -0
- package/.codex/agents/Builder.toml +1 -0
- package/.codex/agents/Flow.toml +1 -0
- package/.codex/agents/Sage.toml +1 -0
- package/.codex/agents/Vibe.toml +1 -0
- package/.codex/hooks.json +12 -2
- package/.codex/prompts/enforcement.md +0 -0
- package/.codex/prompts/onboarding.md +6 -1
- package/.codex/prompts/release-rules.md +0 -0
- package/.codex/prompts/skill-contract.md +0 -0
- package/COVERAGE.md +9 -9
- package/DEMO.md +15 -6
- package/LICENSE +0 -0
- package/README.md +127 -784
- package/bin/ma.js +591 -105
- package/data/clone-data.ledger.json +0 -0
- package/data/clone-data.proof.json +0 -0
- package/data/clone-data.rvf +0 -0
- package/docs/README.md +8 -2
- package/docs/assets/banner.png +0 -0
- package/docs/autonomous-tasks.md +46 -0
- package/docs/codex-integration.md +16 -0
- package/docs/getting-started.md +32 -8
- package/docs/installed-sdk.md +0 -0
- package/docs/mcp-setup.md +30 -1
- package/docs/qa/{release-issue-gates-0.1.13.json → release-issue-gates-0.14.1.json} +77 -77
- package/docs/qa/release-readiness-0.1.5.md +0 -0
- package/docs/qa/{release-readiness-0.1.13.md → release-readiness-0.14.1.md} +12 -12
- package/docs/quality.md +24 -0
- package/docs/reference/native-engineering-patterns.md +0 -0
- package/docs/reference/native-security-playbooks.md +0 -0
- package/docs/reference/native-source-selection.md +0 -0
- package/docs/reference/native-style-and-deslop.md +0 -0
- package/docs/release-spec.md +27 -14
- package/docs/skills.md +1 -1
- package/docs/vendor-plugin-publishing.md +49 -0
- package/index.js +73 -0
- package/mcp/collections.json +0 -0
- package/mcp/fallback.json +0 -0
- package/mcp/local/code-intel.js +185 -41
- package/mcp/local/context.js +180 -0
- package/mcp/local/memory.js +17 -6
- package/mcp/local/playbooks.js +0 -0
- package/mcp/local/quality.js +39 -0
- package/mcp/local/state.js +7 -3
- package/mcp/local/team-run.js +8 -3
- package/mcp/local/trace.js +0 -0
- package/mcp/local-capabilities.json +9 -0
- package/mcp/native-playbooks.json +0 -0
- package/mcp/servers.json +0 -0
- package/package.json +37 -6
- package/plugins/meta-architect/.app.json +1 -1
- package/plugins/meta-architect/.claude-plugin/plugin.json +12 -0
- package/plugins/meta-architect/.codex-plugin/plugin.json +1 -1
- package/plugins/meta-architect/.mcp.json +1 -1
- package/plugins/meta-architect/README.md +14 -2
- package/plugins/meta-architect/obsidian/main.js +137 -4
- package/plugins/meta-architect/obsidian/manifest.json +1 -1
- package/plugins/meta-architect/obsidian/styles.css +0 -0
- package/plugins/meta-architect/skills/align/SKILL.md +0 -0
- package/plugins/meta-architect/skills/align/agents/openai.yaml +0 -0
- package/plugins/meta-architect/skills/align/references/shared-language.md +0 -0
- package/plugins/meta-architect/skills/arch/SKILL.md +0 -0
- package/plugins/meta-architect/skills/arch/agents/openai.yaml +0 -0
- package/plugins/meta-architect/skills/build/SKILL.md +0 -0
- package/plugins/meta-architect/skills/build/agents/openai.yaml +0 -0
- package/plugins/meta-architect/skills/cleanup/SKILL.md +0 -0
- package/plugins/meta-architect/skills/cleanup/agents/openai.yaml +0 -0
- package/plugins/meta-architect/skills/cleanup/references/style-and-deslop.md +0 -0
- package/plugins/meta-architect/skills/diagnose/SKILL.md +0 -0
- package/plugins/meta-architect/skills/diagnose/agents/openai.yaml +0 -0
- package/plugins/meta-architect/skills/flow/SKILL.md +0 -0
- package/plugins/meta-architect/skills/flow/agents/openai.yaml +0 -0
- package/plugins/meta-architect/skills/maestro/SKILL.md +17 -1
- package/plugins/meta-architect/skills/maestro/agents/openai.yaml +0 -0
- package/plugins/meta-architect/skills/maestro/references/core-release-rules.md +2 -2
- package/plugins/meta-architect/skills/maestro/references/native-ingest-map.md +0 -0
- package/plugins/meta-architect/skills/sage/SKILL.md +0 -0
- package/plugins/meta-architect/skills/sage/agents/openai.yaml +0 -0
- package/plugins/meta-architect/skills/sage/references/source-selection.md +0 -0
- package/plugins/meta-architect/skills/tdd/SKILL.md +0 -0
- package/plugins/meta-architect/skills/tdd/agents/openai.yaml +0 -0
- package/plugins/meta-architect/skills/vet/SKILL.md +0 -0
- package/plugins/meta-architect/skills/vet/agents/openai.yaml +0 -0
- package/plugins/meta-architect/skills/vet/references/security-playbooks.md +0 -0
- package/plugins/meta-architect/skills/vibe/SKILL.md +0 -0
- package/plugins/meta-architect/skills/vibe/agents/openai.yaml +0 -0
- package/schemas/autonomous-task-queue.schema.json +58 -0
- package/schemas/handoff-packet.schema.json +36 -0
- package/schemas/setup-receipt.schema.json +28 -0
- package/schemas/skill-frontmatter.schema.json +20 -0
- package/schemas/support-bundle.schema.json +37 -0
- package/schemas/task-contract.schema.json +31 -0
- package/scripts/active-autonomy-hook.mjs +141 -11
- package/scripts/biome-staged.js +0 -0
- package/scripts/build-linux-packages.mjs +7 -3
- package/scripts/cleanup-test-fixtures.sh +55 -0
- package/scripts/context-hydration-hook.mjs +89 -0
- package/scripts/demo-smoke.js +285 -0
- package/scripts/doctor.js +10 -8
- package/scripts/install.sh +33 -4
- package/scripts/install.sh.sha256 +1 -0
- package/scripts/linux-package-lib.mjs +0 -0
- package/scripts/linux-package-smoke.mjs +2 -2
- package/scripts/package-size-check.mjs +26 -0
- package/scripts/plugin-build.js +314 -0
- package/scripts/plugin-publish.js +77 -0
- package/scripts/plugin-sync.js +83 -17
- package/scripts/prepack.js +9 -0
- package/scripts/ralph/prompt.md +0 -0
- package/scripts/release-metadata.js +0 -0
- package/scripts/release-sync.js +83 -7
- package/scripts/release-verify.js +131 -7
- package/scripts/setup-npmrc.js +48 -23
- package/scripts/skills-install.js +9 -2
- package/scripts/skills-manifest.js +2 -21
- package/scripts/skills-pack.js +2 -2
- package/scripts/skills-validate.js +5 -55
- package/skills/align/SKILL.md +0 -0
- package/skills/align/agents/openai.yaml +0 -0
- package/skills/align/references/shared-language.md +0 -0
- package/skills/arch/SKILL.md +0 -0
- package/skills/arch/agents/openai.yaml +0 -0
- package/skills/build/SKILL.md +0 -0
- package/skills/build/agents/openai.yaml +0 -0
- package/skills/cleanup/SKILL.md +0 -0
- package/skills/cleanup/agents/openai.yaml +0 -0
- package/skills/cleanup/references/style-and-deslop.md +0 -0
- package/skills/diagnose/SKILL.md +0 -0
- package/skills/diagnose/agents/openai.yaml +0 -0
- package/skills/flow/SKILL.md +0 -0
- package/skills/flow/agents/openai.yaml +0 -0
- package/skills/index.json +0 -0
- package/skills/maestro/SKILL.md +17 -1
- package/skills/maestro/agents/openai.yaml +0 -0
- package/skills/maestro/references/core-release-rules.md +2 -2
- package/skills/maestro/references/native-ingest-map.md +0 -0
- package/skills/sage/SKILL.md +0 -0
- package/skills/sage/agents/openai.yaml +0 -0
- package/skills/sage/references/source-selection.md +0 -0
- package/skills/tdd/SKILL.md +0 -0
- package/skills/tdd/agents/openai.yaml +0 -0
- package/skills/vet/SKILL.md +0 -0
- package/skills/vet/agents/openai.yaml +0 -0
- package/skills/vet/references/security-playbooks.md +0 -0
- package/skills/vibe/SKILL.md +0 -0
- package/skills/vibe/agents/openai.yaml +0 -0
- package/sprint/00-idea.md +0 -0
- package/sprint/01-architecture.md +0 -0
- package/sprint/02-oss-evidence.md +0 -0
- package/sprint/03-logic.md +0 -0
- package/sprint/04-security.md +0 -0
- package/sprint/05-dx-ux.md +0 -0
- package/sprint/06-build-plan.md +0 -0
- package/sprint/07-release.md +2 -2
- package/src/agents.js +281 -0
- package/src/bootstrap.js +272 -65
- package/src/build-gate.js +0 -0
- package/src/codex-app-server.js +291 -0
- package/src/decision-log.js +0 -0
- package/src/fs-utils.js +175 -4
- package/src/launcher.js +26 -23
- package/src/mcp-config.js +9 -1
- package/src/mcp-live-client.js +141 -8
- package/src/paths.js +6 -1
- package/src/policy.js +2 -2
- package/src/prelaunch.js +223 -0
- package/src/process-utils.js +62 -0
- package/src/quality/ai-quality-orchestrator.js +328 -0
- package/src/release-issue-gates.js +62 -0
- package/src/release-operations.js +72 -0
- package/src/release-state.js +0 -0
- package/src/runtime/active-autonomy-core.js +0 -0
- package/src/runtime/agent-compat.js +31 -0
- package/src/runtime/alignment-sentinel.js +0 -0
- package/src/runtime/architect-review.js +249 -11
- package/src/runtime/autonomous-tasks.js +585 -0
- package/src/runtime/build-readiness.js +0 -0
- package/src/runtime/code-graph-rehearse.js +0 -0
- package/src/runtime/codeburn-core.js +118 -0
- package/src/runtime/context-authority.js +40 -0
- package/src/runtime/context-economy-core.js +40 -0
- package/src/runtime/continuity-graph.js +201 -0
- package/src/runtime/continuity-notes.js +71 -26
- package/src/runtime/core-source-ingest.js +2 -2
- package/src/runtime/detached-provider.js +90 -13
- package/src/runtime/doctor-report.js +18 -0
- package/src/runtime/environment-awareness-core.js +0 -0
- package/src/runtime/exposure-catalog.js +0 -0
- package/src/runtime/graphify-core.js +167 -0
- package/src/runtime/guidance-stack.js +9 -2
- package/src/runtime/handoff-packets.js +92 -0
- package/src/runtime/headroom-core.js +104 -0
- package/src/runtime/helper-orchestration-core.js +0 -0
- package/src/runtime/hook-profiles.js +20 -0
- package/src/runtime/learning-loop-core.js +110 -4
- package/src/runtime/live-agent-verification.js +122 -0
- package/src/runtime/maestro-events.js +0 -0
- package/src/runtime/maestro-manager.js +0 -0
- package/src/runtime/maestro-output.js +58 -0
- package/src/runtime/maestro-state.js +0 -0
- package/src/runtime/managed-markdown.js +29 -0
- package/src/runtime/mcp-authority.js +147 -0
- package/src/runtime/mcp-policy.js +0 -0
- package/src/runtime/obsidian-integration-core.js +255 -17
- package/src/runtime/obsidian-plugin-bridge.js +344 -38
- package/src/runtime/orchestrator.js +0 -0
- package/src/runtime/pi-maestro-core.js +89 -0
- package/src/runtime/preferences.js +79 -0
- package/src/runtime/project-context.js +636 -0
- package/src/runtime/prompt-strategy-core.js +0 -0
- package/src/runtime/quorum-review.js +0 -0
- package/src/runtime/ralph-execution-core.js +0 -0
- package/src/runtime/redaction-gateway.js +218 -19
- package/src/runtime/runtime-state.js +94 -2
- package/src/runtime/schema-migrations.js +162 -0
- package/src/runtime/semantic-recording-core.js +0 -0
- package/src/runtime/signal-hooks.js +13 -0
- package/src/runtime/skills-registry-export.js +96 -8
- package/src/runtime/startup-path.js +0 -0
- package/src/runtime/task-contracts.js +83 -0
- package/src/runtime/universal-plugin-broker-core.js +373 -50
- package/src/runtime/workspace-intelligence-runtime.js +0 -0
- package/src/runtime/workspace-virtualizer.js +0 -0
- package/src/runtime/workspaces.js +0 -0
- package/src/runtime-artifacts.js +0 -0
- package/src/setup-lifecycle.js +359 -0
- package/src/skill-frontmatter.js +78 -0
- package/src/skill-installer.js +226 -71
- package/src/skills.js +309 -31
- package/src/state-sync.js +0 -0
- package/src/test-fixtures.js +543 -0
- package/src/tui/grid.js +67 -0
- package/src/tui/status-grid.js +23 -0
- package/support-bundle.json +114 -0
- package/templates/AGENTS.md +6 -2
- package/templates/catalog-manifest.json +0 -0
- package/templates/model-instructions/core.md +0 -0
- package/templates/model-instructions/release.md +0 -0
- package/templates/model-instructions/security.md +0 -0
- package/templates/quality/ai-quality-rules.yml +37 -0
- package/docs/assets/image/Screenshot(1).png +0 -0
- package/docs/assets/image/Screenshot(2).png +0 -0
- package/docs/assets/image/Screenshot(3).png +0 -0
- package/docs/assets/image/Screenshot(4).png +0 -0
- package/docs/assets/image/Screenshot(5).png +0 -0
- package/docs/assets/image/Screenshot(6).png +0 -0
- package/docs/assets/image/Screenshot(7).png +0 -0
- package/docs/assets/image/Screenshot(8).png +0 -0
- package/docs/assets/image/Screenshot(9).png +0 -0
- package/docs/assets/meta-architect-logo.png +0 -0
- package/docs/assets/meta-architect-logo.svg +0 -8
- package/docs/onboarding.md +0 -81
- package/docs/prompt-guidance-contract.md +0 -17
- package/docs/prompt-guidance-fragments/active-autonomy-core.md +0 -7
- package/docs/skills-publishing.md +0 -255
- package/scripts/postinstall.js +0 -23
|
@@ -6,6 +6,8 @@ import {
|
|
|
6
6
|
createDefaultActiveAutonomyCore,
|
|
7
7
|
detectPassivePermissionHandoff,
|
|
8
8
|
} from "../src/runtime/active-autonomy-core.js";
|
|
9
|
+
import { resolveHookProfile } from "../src/runtime/hook-profiles.js";
|
|
10
|
+
import { maskSensitiveText } from "../src/runtime/redaction-gateway.js";
|
|
9
11
|
|
|
10
12
|
const DEFAULT_RESPONSE =
|
|
11
13
|
"AUTO-CONTINUE: continue the current safe branch, execute the next reversible step, then verify before reporting.";
|
|
@@ -57,20 +59,106 @@ function extractAssistantText(payload) {
|
|
|
57
59
|
return "";
|
|
58
60
|
}
|
|
59
61
|
|
|
62
|
+
function extractUserText(payload) {
|
|
63
|
+
const candidates = [
|
|
64
|
+
payload.last_user_message,
|
|
65
|
+
payload["last-user-message"],
|
|
66
|
+
payload.user_message,
|
|
67
|
+
payload.prompt,
|
|
68
|
+
];
|
|
69
|
+
|
|
70
|
+
for (const candidate of candidates) {
|
|
71
|
+
if (typeof candidate === "string" && candidate.trim()) return candidate;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (Array.isArray(payload.messages)) {
|
|
75
|
+
const user = [...payload.messages]
|
|
76
|
+
.reverse()
|
|
77
|
+
.find((message) => message?.role === "user" && typeof message.content === "string");
|
|
78
|
+
return user?.content ?? "";
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return "";
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function redactAuditPreview(value) {
|
|
85
|
+
if (typeof value !== "string" || !value) return { value: value ?? "", redactions: [] };
|
|
86
|
+
const redacted = maskSensitiveText(value.slice(0, 200));
|
|
87
|
+
return {
|
|
88
|
+
value: redacted.sanitizedText,
|
|
89
|
+
redactions: redacted.replacements.map(({ placeholder, placeholderBase }) => ({
|
|
90
|
+
placeholder,
|
|
91
|
+
placeholderBase,
|
|
92
|
+
})),
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
60
96
|
async function appendAudit(cwd, entry) {
|
|
61
97
|
const auditDir = path.join(cwd, ".ma", "hooks");
|
|
62
98
|
await fs.mkdir(auditDir, { recursive: true });
|
|
99
|
+
const assistantPreview = redactAuditPreview(entry.assistantPreview);
|
|
100
|
+
const userPreview = redactAuditPreview(entry.userPreview);
|
|
101
|
+
const safeEntry = {
|
|
102
|
+
...entry,
|
|
103
|
+
...(entry.assistantPreview !== undefined ? { assistantPreview: assistantPreview.value } : {}),
|
|
104
|
+
...(entry.userPreview !== undefined ? { userPreview: userPreview.value } : {}),
|
|
105
|
+
previewRedactions: {
|
|
106
|
+
assistant: assistantPreview.redactions,
|
|
107
|
+
user: userPreview.redactions,
|
|
108
|
+
},
|
|
109
|
+
};
|
|
63
110
|
await fs.appendFile(
|
|
64
111
|
path.join(auditDir, "audit.log"),
|
|
65
|
-
`${JSON.stringify({ timestamp: new Date().toISOString(), ...
|
|
112
|
+
`${JSON.stringify({ timestamp: new Date().toISOString(), ...safeEntry })}\n`,
|
|
66
113
|
"utf8",
|
|
67
114
|
);
|
|
68
115
|
}
|
|
69
116
|
|
|
117
|
+
function classifyFinding(file) {
|
|
118
|
+
const value = String(file ?? "").toLowerCase();
|
|
119
|
+
if (/(node_modules|site-packages|vendor)/.test(value)) return "dependency";
|
|
120
|
+
if (/(dist|build|\.next|coverage|cache)/.test(value)) return "generated";
|
|
121
|
+
if (/(compat|legacy|history)/.test(value)) return "compatibility";
|
|
122
|
+
return "source";
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
async function writeBlockingReceipt(cwd, receipt) {
|
|
126
|
+
const receiptDir = path.join(cwd, ".ma", "hooks", "receipts");
|
|
127
|
+
await fs.mkdir(receiptDir, { recursive: true });
|
|
128
|
+
const receiptPath = path.join(receiptDir, `active-autonomy-${Date.now()}.json`);
|
|
129
|
+
await fs.writeFile(receiptPath, `${JSON.stringify(receipt, null, 2)}\n`, "utf8");
|
|
130
|
+
return path.relative(cwd, receiptPath);
|
|
131
|
+
}
|
|
132
|
+
|
|
70
133
|
const payload = await readStdinJson();
|
|
71
|
-
const
|
|
134
|
+
const profile = resolveHookProfile(payload.profile);
|
|
135
|
+
const cwd = path.resolve(
|
|
136
|
+
payload.project_root ||
|
|
137
|
+
payload.cwd ||
|
|
138
|
+
payload.working_directory ||
|
|
139
|
+
process.env.MA_ROOT ||
|
|
140
|
+
process.cwd(),
|
|
141
|
+
);
|
|
142
|
+
const broadScan =
|
|
143
|
+
profile.scanScope === "broad" ||
|
|
144
|
+
payload.broad_scan === true ||
|
|
145
|
+
process.env.MA_HOOK_BROAD_SCAN === "1";
|
|
146
|
+
const ignoredArtifactClasses = [
|
|
147
|
+
"node_modules",
|
|
148
|
+
".next",
|
|
149
|
+
"dist",
|
|
150
|
+
"build",
|
|
151
|
+
"coverage",
|
|
152
|
+
"cache",
|
|
153
|
+
"venv",
|
|
154
|
+
".venv",
|
|
155
|
+
"site-packages",
|
|
156
|
+
"vendored bundles",
|
|
157
|
+
];
|
|
72
158
|
const assistantText = extractAssistantText(payload);
|
|
73
|
-
const
|
|
159
|
+
const userText = extractUserText(payload);
|
|
160
|
+
const blocked =
|
|
161
|
+
profile.block && detectPassivePermissionHandoff(assistantText, createDefaultActiveAutonomyCore());
|
|
74
162
|
|
|
75
163
|
const result = blocked
|
|
76
164
|
? {
|
|
@@ -85,12 +173,54 @@ const result = blocked
|
|
|
85
173
|
reason: "active_autonomy_no_passive_handoff_detected",
|
|
86
174
|
};
|
|
87
175
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
176
|
+
const matchedFiles = Array.isArray(payload.files) ? payload.files : [];
|
|
177
|
+
const receiptPath = blocked
|
|
178
|
+
? await writeBlockingReceipt(cwd, {
|
|
179
|
+
schemaVersion: "0.1.0",
|
|
180
|
+
record_type: "hook_receipt",
|
|
181
|
+
hook: "active-autonomy",
|
|
182
|
+
ruleId: "active_autonomy_passive_handoff",
|
|
183
|
+
scanRoot: cwd,
|
|
184
|
+
include: broadScan ? ["all"] : ["active-project"],
|
|
185
|
+
exclude: broadScan ? [] : ignoredArtifactClasses,
|
|
186
|
+
matchedFiles: matchedFiles.map((file) => ({
|
|
187
|
+
path: String(file.path ?? file),
|
|
188
|
+
line: Number.isInteger(file.line) ? file.line : null,
|
|
189
|
+
classification: classifyFinding(file.path ?? file),
|
|
190
|
+
})),
|
|
191
|
+
classification: matchedFiles.some((file) => classifyFinding(file.path ?? file) === "source")
|
|
192
|
+
? "source"
|
|
193
|
+
: "false_positive_candidate",
|
|
194
|
+
blocked: true,
|
|
195
|
+
reason: result.reason,
|
|
196
|
+
recommendedAction: "Rewrite the response to continue the safe branch and verify it.",
|
|
197
|
+
suppressionPolicy: "No suppression without an explicit rationale.",
|
|
198
|
+
createdAt: new Date().toISOString(),
|
|
199
|
+
profile: profile.id,
|
|
200
|
+
})
|
|
201
|
+
: null;
|
|
202
|
+
|
|
203
|
+
if (!profile.readOnly)
|
|
204
|
+
await appendAudit(cwd, {
|
|
205
|
+
hook: "active-autonomy",
|
|
206
|
+
scanRoot: cwd,
|
|
207
|
+
scope: broadScan ? "broad-opt-in" : "active-project",
|
|
208
|
+
ignoredArtifactClasses: broadScan ? [] : ignoredArtifactClasses,
|
|
209
|
+
event: payload.type || payload.event || "unknown",
|
|
210
|
+
decision: result.decision,
|
|
211
|
+
stopReason: result.stopReason,
|
|
212
|
+
assistantPreview: assistantText,
|
|
213
|
+
userPreview: userText,
|
|
214
|
+
});
|
|
95
215
|
|
|
96
|
-
process.stdout.write(
|
|
216
|
+
process.stdout.write(
|
|
217
|
+
`${JSON.stringify({
|
|
218
|
+
...result,
|
|
219
|
+
scanRoot: cwd,
|
|
220
|
+
scope: broadScan ? "broad-opt-in" : "active-project",
|
|
221
|
+
ignoredArtifactClasses: broadScan ? [] : ignoredArtifactClasses,
|
|
222
|
+
profile: profile.id,
|
|
223
|
+
readOnly: profile.readOnly,
|
|
224
|
+
...(receiptPath ? { receiptPath } : {}),
|
|
225
|
+
})}\n`,
|
|
226
|
+
);
|
package/scripts/biome-staged.js
CHANGED
|
File without changes
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
import { spawnSync } from "node:child_process";
|
|
4
4
|
import fsp from "node:fs/promises";
|
|
5
|
-
import os from "node:os";
|
|
6
5
|
import path from "node:path";
|
|
7
6
|
import process from "node:process";
|
|
7
|
+
import { createTestNamespace } from "../src/test-fixtures.js";
|
|
8
8
|
import {
|
|
9
9
|
getDebArtifactPath,
|
|
10
10
|
getLinuxPackageManifestPath,
|
|
@@ -87,6 +87,10 @@ async function createCommonRoot(root, packArtifactPath) {
|
|
|
87
87
|
run("tar", ["-xzf", packArtifactPath, "-C", libRoot, "--strip-components=1", "package"], {
|
|
88
88
|
cwd: repoRoot,
|
|
89
89
|
});
|
|
90
|
+
const agentCompatSource = path.join(repoRoot, "node_modules", "@jstn-sdk", "agents");
|
|
91
|
+
const agentCompatTarget = path.join(libRoot, "node_modules", "@jstn-sdk", "agents");
|
|
92
|
+
await fsp.access(agentCompatSource);
|
|
93
|
+
await copyDir(agentCompatSource, agentCompatTarget);
|
|
90
94
|
|
|
91
95
|
const wrapper = `#!/bin/sh
|
|
92
96
|
PREFIX="\${META_ARCHITECT_PREFIX:-}"
|
|
@@ -267,6 +271,7 @@ async function main() {
|
|
|
267
271
|
|
|
268
272
|
await fsp.mkdir(distRoot, { recursive: true });
|
|
269
273
|
const packArtifactPath = getPackArtifactPath(distRoot, packageName, version);
|
|
274
|
+
const workRoot = createTestNamespace("meta-architect-linux-packages");
|
|
270
275
|
await fsp.rm(packArtifactPath, { force: true });
|
|
271
276
|
run(
|
|
272
277
|
"npm",
|
|
@@ -275,14 +280,13 @@ async function main() {
|
|
|
275
280
|
".",
|
|
276
281
|
"--ignore-scripts",
|
|
277
282
|
"--cache",
|
|
278
|
-
path.join(
|
|
283
|
+
path.join(workRoot, "npm-cache"),
|
|
279
284
|
"--pack-destination",
|
|
280
285
|
distRoot,
|
|
281
286
|
],
|
|
282
287
|
{ cwd: repoRoot },
|
|
283
288
|
);
|
|
284
289
|
|
|
285
|
-
const workRoot = await fsp.mkdtemp(path.join(os.tmpdir(), "meta-architect-linux-packages-"));
|
|
286
290
|
const commonRoot = path.join(workRoot, "root");
|
|
287
291
|
await createCommonRoot(commonRoot, packArtifactPath);
|
|
288
292
|
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
REQUESTED_TMP_DIR="${MA_TEST_ROOT:-/tmp/ma-tests}"
|
|
5
|
+
MAX_SIZE_BYTES=$((2 * 1024 * 1024 * 1024))
|
|
6
|
+
|
|
7
|
+
case "$REQUESTED_TMP_DIR" in
|
|
8
|
+
/tmp/ma-tests|/tmp/ma-tests/*) ;;
|
|
9
|
+
*) echo "Refusing to clean unexpected path: $REQUESTED_TMP_DIR" >&2; exit 2 ;;
|
|
10
|
+
esac
|
|
11
|
+
|
|
12
|
+
TMP_DIR=$(node -e 'const path = require("node:path"); process.stdout.write(path.resolve(process.argv[1]));' "$REQUESTED_TMP_DIR")
|
|
13
|
+
case "$TMP_DIR" in
|
|
14
|
+
/tmp/ma-tests|/tmp/ma-tests/*) ;;
|
|
15
|
+
*) echo "Refusing to clean resolved path: $TMP_DIR" >&2; exit 2 ;;
|
|
16
|
+
esac
|
|
17
|
+
|
|
18
|
+
if [ ! -d "$TMP_DIR" ]; then
|
|
19
|
+
echo "Test fixture root does not exist: $TMP_DIR"
|
|
20
|
+
exit 0
|
|
21
|
+
fi
|
|
22
|
+
|
|
23
|
+
find "$TMP_DIR" -type f \( -name '*.tar.zst' -o -name '*.tar.gz' \) -mtime +7 -delete
|
|
24
|
+
find "$TMP_DIR" -type f -name '*.log' -mtime +3 -delete
|
|
25
|
+
namespace_is_active() {
|
|
26
|
+
local namespace="$1"
|
|
27
|
+
local pid
|
|
28
|
+
if [ ! -f "$namespace/.active" ]; then return 1; fi
|
|
29
|
+
pid=$(cat "$namespace/.active" 2>/dev/null || true)
|
|
30
|
+
[[ "$pid" =~ ^[0-9]+$ ]] && kill -0 "$pid" 2>/dev/null
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
prune_namespaces_older_than() {
|
|
34
|
+
local age_minutes="$1"
|
|
35
|
+
local namespace
|
|
36
|
+
shopt -s nullglob
|
|
37
|
+
for namespace in "$TMP_DIR"/*; do
|
|
38
|
+
[ -d "$namespace" ] || continue
|
|
39
|
+
[ "$(basename "$namespace")" = retained ] && continue
|
|
40
|
+
namespace_is_active "$namespace" && continue
|
|
41
|
+
find "$namespace" -maxdepth 0 -type d -mmin +"$age_minutes" -exec rm -rf -- {} +
|
|
42
|
+
done
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
# Retained archives have their own seven-day policy and are not namespaces.
|
|
46
|
+
prune_namespaces_older_than 1440
|
|
47
|
+
|
|
48
|
+
CURRENT_KIB=$(du -sk "$TMP_DIR" 2>/dev/null | cut -f1 || echo 0)
|
|
49
|
+
CURRENT_BYTES=$((CURRENT_KIB * 1024))
|
|
50
|
+
echo "Current $TMP_DIR usage: $CURRENT_BYTES bytes"
|
|
51
|
+
|
|
52
|
+
if [ "$CURRENT_BYTES" -gt "$MAX_SIZE_BYTES" ]; then
|
|
53
|
+
echo "::warning::$TMP_DIR exceeded 2GB; removing expired namespaces"
|
|
54
|
+
prune_namespaces_older_than 60
|
|
55
|
+
fi
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import fs from "node:fs/promises";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { createBudgetedContext } from "../src/runtime/context-economy-core.js";
|
|
6
|
+
import { maskSensitiveText } from "../src/runtime/redaction-gateway.js";
|
|
7
|
+
|
|
8
|
+
const root = path.resolve(process.env.MA_ROOT || process.cwd());
|
|
9
|
+
const contextRoot = path.join(root, ".ma", "context");
|
|
10
|
+
|
|
11
|
+
async function read(relative, fallback = null) {
|
|
12
|
+
try {
|
|
13
|
+
return await fs.readFile(path.join(contextRoot, relative), "utf8");
|
|
14
|
+
} catch {
|
|
15
|
+
return fallback;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const [project, brief, commands, learning] = await Promise.all([
|
|
20
|
+
read("project-index.json"),
|
|
21
|
+
read("agent-brief.md", ""),
|
|
22
|
+
read("commands.json"),
|
|
23
|
+
fs.readFile(path.join(root, ".ma", "learning", "records.jsonl"), "utf8").catch(() => ""),
|
|
24
|
+
]);
|
|
25
|
+
const preferences = await fs
|
|
26
|
+
.readFile(path.join(root, ".ma", "memory", "preferences.json"), "utf8")
|
|
27
|
+
.catch(() => "{}");
|
|
28
|
+
const records = learning
|
|
29
|
+
.split("\n")
|
|
30
|
+
.filter(Boolean)
|
|
31
|
+
.slice(-3)
|
|
32
|
+
.map((line) => {
|
|
33
|
+
try {
|
|
34
|
+
const value = JSON.parse(line);
|
|
35
|
+
return { claim: value.claim, status: value.status, authority: "learning_memory" };
|
|
36
|
+
} catch {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
})
|
|
40
|
+
.filter(Boolean);
|
|
41
|
+
|
|
42
|
+
const result = {
|
|
43
|
+
record_type: "context_hydration",
|
|
44
|
+
root,
|
|
45
|
+
loaded: {
|
|
46
|
+
projectIndex: Boolean(project),
|
|
47
|
+
agentBrief: Boolean(brief),
|
|
48
|
+
commands: Boolean(commands),
|
|
49
|
+
learningRecords: records.length,
|
|
50
|
+
preferences: preferences !== "{}",
|
|
51
|
+
},
|
|
52
|
+
skipped: ["repository-wide source scan", "full Obsidian vault"],
|
|
53
|
+
stale: project
|
|
54
|
+
? (() => {
|
|
55
|
+
try {
|
|
56
|
+
return JSON.parse(project).freshness?.status === "stale";
|
|
57
|
+
} catch {
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
})()
|
|
61
|
+
: true,
|
|
62
|
+
authority: "generated_context",
|
|
63
|
+
context: {
|
|
64
|
+
project: project ? maskSensitiveText(project).sanitizedText : null,
|
|
65
|
+
brief: maskSensitiveText(brief).sanitizedText,
|
|
66
|
+
commands: commands ? maskSensitiveText(commands).sanitizedText : null,
|
|
67
|
+
learning: records,
|
|
68
|
+
preferences: (() => {
|
|
69
|
+
try {
|
|
70
|
+
return JSON.parse(preferences).preferences ?? {};
|
|
71
|
+
} catch {
|
|
72
|
+
return {};
|
|
73
|
+
}
|
|
74
|
+
})(),
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
const budgeted = createBudgetedContext({
|
|
78
|
+
budgetChars: Number(process.env.MA_CONTEXT_BUDGET_CHARS || 12000),
|
|
79
|
+
topic: process.env.MA_CONTEXT_TOPIC,
|
|
80
|
+
items: [
|
|
81
|
+
{ id: "agent-brief", tier: 1, topic: "brief", text: brief },
|
|
82
|
+
{ id: "commands", tier: 3, topic: "commands", text: commands ?? "" },
|
|
83
|
+
{ id: "learning", tier: 4, topic: "learning", text: JSON.stringify(records) },
|
|
84
|
+
{ id: "preferences", tier: 4, topic: "preferences", text: preferences },
|
|
85
|
+
{ id: "project-index", tier: 5, topic: "project", text: project ?? "" },
|
|
86
|
+
],
|
|
87
|
+
});
|
|
88
|
+
result.budget = budgeted;
|
|
89
|
+
process.stdout.write(`${JSON.stringify(result)}\n`);
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import assert from "node:assert/strict";
|
|
4
|
+
import fs from "node:fs/promises";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import {
|
|
7
|
+
createContextEconomyView,
|
|
8
|
+
createDefaultLearningLoopCore,
|
|
9
|
+
createDefaultPromptStrategyCore,
|
|
10
|
+
createDiscoveredEnvironmentAwarenessCore,
|
|
11
|
+
createObsidianNote,
|
|
12
|
+
createRalphPrdContract,
|
|
13
|
+
evaluateLearningLoopReadiness,
|
|
14
|
+
indexObsidianVault,
|
|
15
|
+
readObsidianNote,
|
|
16
|
+
runIdea,
|
|
17
|
+
runInit,
|
|
18
|
+
updateObsidianNote,
|
|
19
|
+
validatePromptStrategyCore,
|
|
20
|
+
validateRalphPrdContract,
|
|
21
|
+
writeObsidianVaultIndex,
|
|
22
|
+
} from "../index.js";
|
|
23
|
+
import { loadRuntimeSnapshot } from "../src/runtime/runtime-state.js";
|
|
24
|
+
import { runMaestro } from "../src/skills.js";
|
|
25
|
+
import { createTestNamespace } from "../src/test-fixtures.js";
|
|
26
|
+
|
|
27
|
+
const demoIdea =
|
|
28
|
+
"Northstar Logistics wants to harden an existing dispatch analytics workspace for a production release. MA must inspect current runtime context, use Obsidian vault notes as brain context, route through relevant roles, preserve security gates, and produce a release-safe next action instead of asking for permission.";
|
|
29
|
+
|
|
30
|
+
async function writeFile(file, content) {
|
|
31
|
+
await fs.mkdir(path.dirname(file), { recursive: true });
|
|
32
|
+
await fs.writeFile(file, content, "utf8");
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async function seedWorkspace(root) {
|
|
36
|
+
await writeFile(
|
|
37
|
+
path.join(root, "package.json"),
|
|
38
|
+
`${JSON.stringify(
|
|
39
|
+
{
|
|
40
|
+
name: "northstar-dispatch-analytics",
|
|
41
|
+
version: "2.4.0",
|
|
42
|
+
type: "module",
|
|
43
|
+
scripts: {
|
|
44
|
+
test: "node --test",
|
|
45
|
+
check: "node --check src/index.js",
|
|
46
|
+
release: "node scripts/release-check.js",
|
|
47
|
+
},
|
|
48
|
+
dependencies: {
|
|
49
|
+
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
null,
|
|
53
|
+
2,
|
|
54
|
+
)}\n`,
|
|
55
|
+
);
|
|
56
|
+
await writeFile(
|
|
57
|
+
path.join(root, "src", "index.js"),
|
|
58
|
+
"export const serviceName = 'northstar-dispatch-analytics';\n",
|
|
59
|
+
);
|
|
60
|
+
await writeFile(
|
|
61
|
+
path.join(root, "mcp", "servers.json"),
|
|
62
|
+
`${JSON.stringify(
|
|
63
|
+
{
|
|
64
|
+
mcpServers: {
|
|
65
|
+
"obsidian-api Docs": {
|
|
66
|
+
url: "https://gitmcp.io/obsidianmd/obsidian-api",
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
null,
|
|
71
|
+
2,
|
|
72
|
+
)}\n`,
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
async function seedVault(vaultPath) {
|
|
77
|
+
await writeFile(
|
|
78
|
+
path.join(vaultPath, "Northstar", "Dispatch Release Objective.md"),
|
|
79
|
+
`---
|
|
80
|
+
ma_records_as: vault_context
|
|
81
|
+
ma_project: northstar-dispatch-analytics
|
|
82
|
+
ma_capabilities:
|
|
83
|
+
- maestro
|
|
84
|
+
- obsidian
|
|
85
|
+
- learning-loop
|
|
86
|
+
ma_source_workspace: northstar-dispatch-analytics
|
|
87
|
+
---
|
|
88
|
+
# Dispatch Release Objective
|
|
89
|
+
|
|
90
|
+
Northstar Logistics needs a production-safe release plan for dispatch analytics.
|
|
91
|
+
|
|
92
|
+
## Pain Points
|
|
93
|
+
|
|
94
|
+
- Missed gate ownership causes late release rollback risk. #release
|
|
95
|
+
- Unstructured knowledge lives in operations notes and is not visible to build planning. #knowledge
|
|
96
|
+
- Security and DX review happen after implementation instead of before build execution. #security #dx
|
|
97
|
+
|
|
98
|
+
## Links
|
|
99
|
+
|
|
100
|
+
- [[Northstar/Risk Register]]
|
|
101
|
+
- [[Meta-Architect/Core Brain Context]]
|
|
102
|
+
`,
|
|
103
|
+
);
|
|
104
|
+
await writeFile(
|
|
105
|
+
path.join(vaultPath, "Northstar", "Risk Register.md"),
|
|
106
|
+
`---
|
|
107
|
+
ma_records_as: vault_context
|
|
108
|
+
ma_project: northstar-dispatch-analytics
|
|
109
|
+
---
|
|
110
|
+
# Risk Register
|
|
111
|
+
|
|
112
|
+
Known risks:
|
|
113
|
+
|
|
114
|
+
- Third-party carrier API failures can block dispatch reconciliation.
|
|
115
|
+
- Customer PII must not be copied into prompt-bound release artifacts.
|
|
116
|
+
- [[Northstar/Dispatch Release Objective]] owns the business target.
|
|
117
|
+
`,
|
|
118
|
+
);
|
|
119
|
+
await writeFile(
|
|
120
|
+
path.join(vaultPath, "Meta-Architect", "Core Brain Context.md"),
|
|
121
|
+
`---
|
|
122
|
+
ma_records_as: vault_context
|
|
123
|
+
ma_project: northstar-dispatch-analytics
|
|
124
|
+
---
|
|
125
|
+
# Core Brain Context
|
|
126
|
+
|
|
127
|
+
MA should treat this vault as semantic brain context only.
|
|
128
|
+
Authoritative build evidence must return through $maestro or the owning lane.
|
|
129
|
+
`,
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function assertNoDemoBranding(value) {
|
|
134
|
+
const serialized = JSON.stringify(value);
|
|
135
|
+
assert.doesNotMatch(serialized, /Demo Account|Test Company|Sample Co|Acme/i);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
async function main() {
|
|
139
|
+
const originalCwd = process.cwd();
|
|
140
|
+
const workspace = createTestNamespace("ma-real-demo");
|
|
141
|
+
const vaultPath = path.join(workspace, "Northstar Vault");
|
|
142
|
+
await seedWorkspace(workspace);
|
|
143
|
+
await seedVault(vaultPath);
|
|
144
|
+
|
|
145
|
+
process.chdir(workspace);
|
|
146
|
+
try {
|
|
147
|
+
await runInit();
|
|
148
|
+
await runIdea(demoIdea);
|
|
149
|
+
await runMaestro();
|
|
150
|
+
|
|
151
|
+
const createdNote = await createObsidianNote({
|
|
152
|
+
vaultPath,
|
|
153
|
+
notePath: "Meta-Architect/Release Gate Plan.md",
|
|
154
|
+
overwrite: true,
|
|
155
|
+
content: `---
|
|
156
|
+
ma_records_as: vault_context
|
|
157
|
+
ma_project: northstar-dispatch-analytics
|
|
158
|
+
ma_source_workspace: northstar-dispatch-analytics
|
|
159
|
+
---
|
|
160
|
+
# Release Gate Plan
|
|
161
|
+
|
|
162
|
+
This note records the MA demo path for Northstar Logistics.
|
|
163
|
+
|
|
164
|
+
- Start at [[Meta-Architect/Map of Content]]
|
|
165
|
+
- Use [[Northstar/Dispatch Release Objective]] for buyer context
|
|
166
|
+
- Keep build evidence in MA lane artifacts
|
|
167
|
+
`,
|
|
168
|
+
});
|
|
169
|
+
await updateObsidianNote({
|
|
170
|
+
vaultPath,
|
|
171
|
+
notePath: "Meta-Architect/Release Gate Plan.md",
|
|
172
|
+
content: `${createdNote.relative_path ? "" : ""}---
|
|
173
|
+
ma_records_as: vault_context
|
|
174
|
+
ma_project: northstar-dispatch-analytics
|
|
175
|
+
ma_source_workspace: northstar-dispatch-analytics
|
|
176
|
+
---
|
|
177
|
+
# Release Gate Plan
|
|
178
|
+
|
|
179
|
+
This note records the MA demo path for Northstar Logistics.
|
|
180
|
+
|
|
181
|
+
- Start at [[Meta-Architect/Map of Content]]
|
|
182
|
+
- Use [[Northstar/Dispatch Release Objective]] for buyer context
|
|
183
|
+
- Use [[Northstar/Risk Register]] for security and rollback concerns
|
|
184
|
+
- Keep build evidence in MA lane artifacts
|
|
185
|
+
`,
|
|
186
|
+
});
|
|
187
|
+
const readNote = await readObsidianNote({
|
|
188
|
+
vaultPath,
|
|
189
|
+
notePath: "Meta-Architect/Release Gate Plan.md",
|
|
190
|
+
});
|
|
191
|
+
const vaultIndex = await writeObsidianVaultIndex({ vaultPath });
|
|
192
|
+
const directVaultIndex = await indexObsidianVault({ vaultPath });
|
|
193
|
+
|
|
194
|
+
const learningReadiness = evaluateLearningLoopReadiness(createDefaultLearningLoopCore());
|
|
195
|
+
const promptStrategy = validatePromptStrategyCore(createDefaultPromptStrategyCore());
|
|
196
|
+
const contextEconomy = createContextEconomyView({
|
|
197
|
+
text: "The architecture lane should preserve exact commands, risk language, and verification gaps while compressing low-value filler for the live demo operator.",
|
|
198
|
+
level: "full",
|
|
199
|
+
});
|
|
200
|
+
const environmentAwareness = await createDiscoveredEnvironmentAwarenessCore({ cwd: workspace });
|
|
201
|
+
const ralphContract = validateRalphPrdContract(
|
|
202
|
+
createRalphPrdContract({
|
|
203
|
+
project: "northstar-dispatch-analytics",
|
|
204
|
+
branchName: "ralph/northstar-release-gates",
|
|
205
|
+
description: "Prepare release-safe dispatch analytics execution handoff.",
|
|
206
|
+
buildSlice: [
|
|
207
|
+
"Verify MA release gates before Ralph-style execution begins.",
|
|
208
|
+
"Preserve Obsidian context as vault_context, not build_evidence.",
|
|
209
|
+
],
|
|
210
|
+
verificationPlan: [
|
|
211
|
+
"$arch, $sage, $flow, $vet, and $vibe are represented before $build.",
|
|
212
|
+
"Obsidian context is tagged as vault_context, not build_evidence.",
|
|
213
|
+
],
|
|
214
|
+
}),
|
|
215
|
+
);
|
|
216
|
+
const runtimeSnapshot = await loadRuntimeSnapshot();
|
|
217
|
+
|
|
218
|
+
const proof = {
|
|
219
|
+
record_type: "ma_real_demo_smoke_proof",
|
|
220
|
+
workspace,
|
|
221
|
+
vaultPath,
|
|
222
|
+
idea: demoIdea,
|
|
223
|
+
maestro: {
|
|
224
|
+
global_status: runtimeSnapshot.maestroState.global_status,
|
|
225
|
+
track_count: Object.keys(runtimeSnapshot.maestroState.runtime_tracks).length,
|
|
226
|
+
next_plan_exists: true,
|
|
227
|
+
},
|
|
228
|
+
obsidian: {
|
|
229
|
+
note_count: vaultIndex.note_count,
|
|
230
|
+
records_as: vaultIndex.records_as,
|
|
231
|
+
build_evidence: vaultIndex.build_evidence,
|
|
232
|
+
graph_map_present: vaultIndex.notes.some(
|
|
233
|
+
(note) => note.relative_path === "Meta-Architect/Map of Content.md",
|
|
234
|
+
),
|
|
235
|
+
linked_release_plan: readNote.content.includes("[[Meta-Architect/Map of Content]]"),
|
|
236
|
+
direct_index_note_count: directVaultIndex.note_count,
|
|
237
|
+
},
|
|
238
|
+
learning: {
|
|
239
|
+
domain_count: learningReadiness.domains,
|
|
240
|
+
verified_domain_count: learningReadiness.verified_domains,
|
|
241
|
+
ready: learningReadiness.ready,
|
|
242
|
+
},
|
|
243
|
+
prompt_strategy: {
|
|
244
|
+
lane_count: Object.keys(promptStrategy.lane_policy).length,
|
|
245
|
+
},
|
|
246
|
+
context_economy: {
|
|
247
|
+
mode: contextEconomy.mode,
|
|
248
|
+
preserved_exact_count: contextEconomy.preserved_exact.length,
|
|
249
|
+
},
|
|
250
|
+
environment_awareness: {
|
|
251
|
+
capability_count: environmentAwareness.capabilities.length,
|
|
252
|
+
capability_types: [
|
|
253
|
+
...new Set(environmentAwareness.capabilities.map((item) => item.capability_type)),
|
|
254
|
+
].sort(),
|
|
255
|
+
},
|
|
256
|
+
ralph: {
|
|
257
|
+
story_count: ralphContract.userStories.length,
|
|
258
|
+
authority: ralphContract.authority,
|
|
259
|
+
},
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
assert.equal(proof.obsidian.records_as, "vault_context");
|
|
263
|
+
assert.equal(proof.obsidian.build_evidence, false);
|
|
264
|
+
assert.equal(proof.obsidian.graph_map_present, true);
|
|
265
|
+
assert.equal(proof.obsidian.linked_release_plan, true);
|
|
266
|
+
assert.equal(proof.learning.ready, true);
|
|
267
|
+
assert.equal(proof.ralph.story_count, 1);
|
|
268
|
+
assertNoDemoBranding(proof);
|
|
269
|
+
|
|
270
|
+
await writeFile(
|
|
271
|
+
path.join(workspace, ".ma", "evidence", "real-demo-smoke-proof.json"),
|
|
272
|
+
`${JSON.stringify(proof, null, 2)}\n`,
|
|
273
|
+
);
|
|
274
|
+
console.log(JSON.stringify(proof, null, 2));
|
|
275
|
+
} finally {
|
|
276
|
+
process.chdir(originalCwd);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
try {
|
|
281
|
+
await main();
|
|
282
|
+
} catch (error) {
|
|
283
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
284
|
+
process.exitCode = 1;
|
|
285
|
+
}
|
package/scripts/doctor.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import fs from "node:fs";
|
|
4
|
+
import { printDoctorStatuses } from "../src/runtime/doctor-report.js";
|
|
4
5
|
import {
|
|
5
6
|
getDebArtifactName,
|
|
6
7
|
getPacmanArtifactName,
|
|
@@ -56,14 +57,15 @@ const checks = [
|
|
|
56
57
|
["prompts/architect.md", fs.existsSync("prompts/architect.md")],
|
|
57
58
|
];
|
|
58
59
|
|
|
59
|
-
|
|
60
|
+
const statuses = [];
|
|
60
61
|
for (const [label, ok] of checks) {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
}
|
|
62
|
+
statuses.push({
|
|
63
|
+
kind: ok ? "OK" : "BLOCKED",
|
|
64
|
+
label,
|
|
65
|
+
detail: ok ? "present" : "missing release artifact",
|
|
66
|
+
});
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
|
|
69
|
+
console.log("Scope: maintainer release/package artifacts (not installed environment health)");
|
|
70
|
+
const result = printDoctorStatuses("Meta-Architect Package Doctor", statuses);
|
|
71
|
+
process.exitCode = result === "READY" ? 0 : 1;
|