@jstn-sdk/ma 0.1.12 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.codex/agents/Architect.toml +1 -2
- package/.codex/agents/Auditor.toml +1 -2
- package/.codex/agents/Builder.toml +1 -2
- package/.codex/agents/Flow.toml +1 -2
- package/.codex/agents/Sage.toml +1 -2
- package/.codex/agents/Vibe.toml +1 -2
- package/.codex/hooks.json +24 -13
- package/.codex/prompts/enforcement.md +4 -0
- package/.codex/prompts/onboarding.md +6 -1
- package/.codex/prompts/release-rules.md +0 -0
- package/.codex/prompts/skill-contract.md +4 -0
- package/COVERAGE.md +211 -0
- package/DEMO.md +274 -0
- package/LICENSE +0 -0
- package/README.md +132 -656
- package/bin/ma.js +748 -55
- package/data/clone-data.ledger.json +41 -0
- package/data/clone-data.proof.json +50 -0
- package/data/clone-data.rvf +37 -0
- package/docs/README.md +10 -1
- package/docs/autonomous-tasks.md +46 -0
- package/docs/codex-integration.md +16 -0
- package/docs/getting-started.md +62 -22
- package/docs/mcp-setup.md +64 -0
- package/docs/qa/release-issue-gates-0.14.0.json +644 -0
- package/docs/qa/release-readiness-0.1.5.md +1 -1
- package/docs/qa/{release-readiness-0.1.12.md → release-readiness-0.14.0.md} +25 -9
- package/docs/quality.md +24 -0
- package/docs/reference/native-security-playbooks.md +6 -0
- package/docs/reference/native-source-selection.md +6 -0
- package/docs/release-spec.md +39 -10
- package/docs/skills.md +14 -1
- package/index.js +295 -2
- package/mcp/collections.json +23 -6
- package/mcp/fallback.json +0 -0
- package/mcp/local/code-intel.js +179 -41
- package/mcp/local/context.js +180 -0
- package/mcp/local/memory.js +17 -6
- package/mcp/local/quality.js +39 -0
- package/mcp/local/state.js +7 -3
- package/mcp/local/team-run.js +56 -4
- package/mcp/local-capabilities.json +9 -0
- package/mcp/servers.json +24 -0
- package/package.json +29 -4
- package/plugins/meta-architect/.app.json +1 -1
- package/plugins/meta-architect/.codex-plugin/plugin.json +1 -1
- package/plugins/meta-architect/.mcp.json +1 -1
- package/plugins/meta-architect/README.md +8 -1
- package/plugins/meta-architect/obsidian/main.js +534 -0
- package/plugins/meta-architect/obsidian/manifest.json +9 -0
- package/plugins/meta-architect/obsidian/styles.css +7 -0
- package/plugins/meta-architect/skills/arch/SKILL.md +2 -0
- package/plugins/meta-architect/skills/build/SKILL.md +3 -0
- package/plugins/meta-architect/skills/flow/SKILL.md +2 -0
- package/plugins/meta-architect/skills/sage/SKILL.md +2 -0
- package/plugins/meta-architect/skills/sage/references/source-selection.md +8 -0
- package/plugins/meta-architect/skills/vet/SKILL.md +2 -0
- package/plugins/meta-architect/skills/vet/references/security-playbooks.md +7 -0
- package/plugins/meta-architect/skills/vibe/SKILL.md +2 -0
- package/schemas/autonomous-task-queue.schema.json +56 -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 +226 -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 +27 -12
- package/scripts/install.sh +57 -0
- package/scripts/install.sh.sha256 +1 -0
- package/scripts/linux-package-smoke.mjs +2 -2
- package/scripts/package-size-check.mjs +26 -0
- package/scripts/plugin-sync.js +83 -17
- package/scripts/postinstall.js +17 -10
- package/scripts/prepack.js +9 -0
- package/scripts/ralph/prompt.md +35 -0
- package/scripts/release-sync.js +72 -7
- package/scripts/release-verify.js +260 -2
- 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/arch/SKILL.md +2 -0
- package/skills/build/SKILL.md +3 -0
- package/skills/flow/SKILL.md +2 -0
- package/skills/index.json +0 -0
- package/skills/sage/SKILL.md +2 -0
- package/skills/sage/references/source-selection.md +8 -0
- package/skills/vet/SKILL.md +2 -0
- package/skills/vet/references/security-playbooks.md +7 -0
- package/skills/vibe/SKILL.md +2 -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 +0 -0
- package/src/agents.js +279 -0
- package/src/bootstrap.js +268 -62
- package/src/build-gate.js +2 -2
- 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 +28 -21
- package/src/mcp-config.js +9 -1
- package/src/mcp-live-client.js +422 -3
- package/src/paths.js +10 -1
- package/src/policy.js +3 -3
- package/src/prelaunch.js +189 -0
- package/src/quality/ai-quality-orchestrator.js +328 -0
- package/src/release-issue-gates.js +252 -0
- package/src/release-operations.js +62 -0
- package/src/release-state.js +0 -0
- package/src/runtime/active-autonomy-core.js +208 -0
- package/src/runtime/agent-compat.js +31 -0
- package/src/runtime/alignment-sentinel.js +165 -0
- package/src/runtime/architect-review.js +326 -0
- package/src/runtime/autonomous-tasks.js +408 -0
- package/src/runtime/build-readiness.js +28 -4
- package/src/runtime/code-graph-rehearse.js +113 -0
- package/src/runtime/codeburn-core.js +112 -0
- package/src/runtime/context-authority.js +40 -0
- package/src/runtime/context-economy-core.js +316 -0
- package/src/runtime/continuity-graph.js +201 -0
- package/src/runtime/continuity-notes.js +71 -26
- package/src/runtime/core-source-ingest.js +379 -0
- package/src/runtime/detached-provider.js +142 -0
- package/src/runtime/doctor-report.js +18 -0
- package/src/runtime/environment-awareness-core.js +460 -0
- package/src/runtime/exposure-catalog.js +276 -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 +307 -0
- package/src/runtime/hook-profiles.js +20 -0
- package/src/runtime/learning-loop-core.js +344 -0
- package/src/runtime/live-agent-verification.js +122 -0
- package/src/runtime/maestro-events.js +18 -0
- package/src/runtime/maestro-manager.js +19 -0
- package/src/runtime/maestro-output.js +58 -0
- package/src/runtime/maestro-state.js +125 -0
- package/src/runtime/managed-markdown.js +29 -0
- package/src/runtime/mcp-authority.js +147 -0
- package/src/runtime/mcp-policy.js +192 -0
- package/src/runtime/obsidian-integration-core.js +1089 -0
- package/src/runtime/obsidian-plugin-bridge.js +1045 -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 +230 -0
- package/src/runtime/quorum-review.js +90 -0
- package/src/runtime/ralph-execution-core.js +217 -0
- package/src/runtime/redaction-gateway.js +373 -0
- package/src/runtime/runtime-state.js +935 -2
- package/src/runtime/schema-migrations.js +162 -0
- package/src/runtime/semantic-recording-core.js +147 -0
- package/src/runtime/signal-hooks.js +28 -0
- package/src/runtime/skills-registry-export.js +754 -0
- package/src/runtime/task-contracts.js +83 -0
- package/src/runtime/universal-plugin-broker-core.js +898 -0
- package/src/runtime/workspace-intelligence-runtime.js +674 -0
- package/src/runtime/workspace-virtualizer.js +102 -0
- package/src/runtime-artifacts.js +225 -62
- 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 +1166 -96
- 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 -65
- package/docs/skills-publishing.md +0 -255
|
@@ -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,
|
|
@@ -28,7 +29,24 @@ const checks = [
|
|
|
28
29
|
[".codex/hooks.json", fs.existsSync(".codex/hooks.json")],
|
|
29
30
|
[".ma/decisions.json", fs.existsSync(".ma/decisions.json")],
|
|
30
31
|
[".ma/release.json", fs.existsSync(".ma/release.json")],
|
|
32
|
+
[
|
|
33
|
+
".ma/context/helper-orchestration-core.json",
|
|
34
|
+
fs.existsSync(".ma/context/helper-orchestration-core.json"),
|
|
35
|
+
],
|
|
36
|
+
[
|
|
37
|
+
".ma/context/environment-awareness-core.json",
|
|
38
|
+
fs.existsSync(".ma/context/environment-awareness-core.json"),
|
|
39
|
+
],
|
|
40
|
+
[
|
|
41
|
+
".ma/context/universal-plugin-broker-core.json",
|
|
42
|
+
fs.existsSync(".ma/context/universal-plugin-broker-core.json"),
|
|
43
|
+
],
|
|
31
44
|
["docs/release-spec.md", fs.existsSync("docs/release-spec.md")],
|
|
45
|
+
["DEMO.md", fs.existsSync("DEMO.md")],
|
|
46
|
+
["COVERAGE.md", fs.existsSync("COVERAGE.md")],
|
|
47
|
+
["data/clone-data.proof.json", fs.existsSync("data/clone-data.proof.json")],
|
|
48
|
+
["data/clone-data.ledger.json", fs.existsSync("data/clone-data.ledger.json")],
|
|
49
|
+
["data/clone-data.rvf", fs.existsSync("data/clone-data.rvf")],
|
|
32
50
|
[".agents/plugins/marketplace.json", fs.existsSync(".agents/plugins/marketplace.json")],
|
|
33
51
|
["plugins/meta-architect/.app.json", fs.existsSync("plugins/meta-architect/.app.json")],
|
|
34
52
|
[
|
|
@@ -36,21 +54,18 @@ const checks = [
|
|
|
36
54
|
fs.existsSync("plugins/meta-architect/.codex-plugin/plugin.json"),
|
|
37
55
|
],
|
|
38
56
|
["plugins/meta-architect/.mcp.json", fs.existsSync("plugins/meta-architect/.mcp.json")],
|
|
39
|
-
[
|
|
40
|
-
"missions/collaborative-whiteboard/mission.md",
|
|
41
|
-
fs.existsSync("missions/collaborative-whiteboard/mission.md"),
|
|
42
|
-
],
|
|
43
57
|
["prompts/architect.md", fs.existsSync("prompts/architect.md")],
|
|
44
58
|
];
|
|
45
59
|
|
|
46
|
-
|
|
60
|
+
const statuses = [];
|
|
47
61
|
for (const [label, ok] of checks) {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
62
|
+
statuses.push({
|
|
63
|
+
kind: ok ? "OK" : "BLOCKED",
|
|
64
|
+
label,
|
|
65
|
+
detail: ok ? "present" : "missing release artifact",
|
|
66
|
+
});
|
|
54
67
|
}
|
|
55
68
|
|
|
56
|
-
|
|
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;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
#!/usr/bin/env sh
|
|
2
|
+
set -eu
|
|
3
|
+
|
|
4
|
+
MA_PACKAGE="${MA_PACKAGE:-@jstn-sdk/ma@0.14.0}"
|
|
5
|
+
CODEX_PACKAGE="${CODEX_PACKAGE:-@openai/codex@latest}"
|
|
6
|
+
NO_SETUP=0
|
|
7
|
+
NO_SKILLS=0
|
|
8
|
+
DRY_RUN=0
|
|
9
|
+
|
|
10
|
+
for arg in "$@"; do
|
|
11
|
+
case "$arg" in
|
|
12
|
+
--no-setup) NO_SETUP=1 ;;
|
|
13
|
+
--no-skills) NO_SKILLS=1 ;;
|
|
14
|
+
--dry-run) DRY_RUN=1 ;;
|
|
15
|
+
*) echo "meta-architect install: unknown option: $arg" >&2; exit 2 ;;
|
|
16
|
+
esac
|
|
17
|
+
done
|
|
18
|
+
|
|
19
|
+
need_cmd() {
|
|
20
|
+
command -v "$1" >/dev/null 2>&1 || {
|
|
21
|
+
echo "meta-architect install: missing required command: $1" >&2
|
|
22
|
+
exit 1
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
need_cmd npm
|
|
27
|
+
need_cmd node
|
|
28
|
+
|
|
29
|
+
echo "meta-architect install: plan"
|
|
30
|
+
echo " install: $CODEX_PACKAGE $MA_PACKAGE"
|
|
31
|
+
echo " setup: $([ "$NO_SETUP" -eq 1 ] && echo disabled || echo enabled)"
|
|
32
|
+
echo " skills: $([ "$NO_SKILLS" -eq 1 ] && echo disabled || echo enabled)"
|
|
33
|
+
echo " undo: npm uninstall -g $MA_PACKAGE $CODEX_PACKAGE"
|
|
34
|
+
|
|
35
|
+
if [ "$DRY_RUN" -eq 1 ]; then
|
|
36
|
+
echo "meta-architect install: dry-run complete"
|
|
37
|
+
exit 0
|
|
38
|
+
fi
|
|
39
|
+
|
|
40
|
+
if [ "$NO_SKILLS" -eq 1 ]; then export MA_SKIP_SKILLS=1; fi
|
|
41
|
+
npm i -g "$CODEX_PACKAGE" "$MA_PACKAGE"
|
|
42
|
+
echo "meta-architect install: versions"
|
|
43
|
+
node --version
|
|
44
|
+
npm --version
|
|
45
|
+
command -v codex >/dev/null 2>&1 && codex --version || echo "codex: unavailable"
|
|
46
|
+
|
|
47
|
+
if command -v ma >/dev/null 2>&1 && [ "$NO_SETUP" -eq 0 ]; then
|
|
48
|
+
echo "meta-architect install: seeding local MA runtime"
|
|
49
|
+
ma setup
|
|
50
|
+
echo "meta-architect install: ready"
|
|
51
|
+
echo "start: ma --madmax --high"
|
|
52
|
+
elif [ "$NO_SETUP" -eq 1 ]; then
|
|
53
|
+
echo "meta-architect install: setup disabled by --no-setup"
|
|
54
|
+
else
|
|
55
|
+
echo "meta-architect install: ma command not found after npm install" >&2
|
|
56
|
+
exit 1
|
|
57
|
+
fi
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0a18d94ded8872eae750cd2cc4a5b6ab05a6c48796def3634bc2414b3d48f7f7 scripts/install.sh
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
import assert from "node:assert/strict";
|
|
4
4
|
import { spawnSync } from "node:child_process";
|
|
5
5
|
import fs from "node:fs/promises";
|
|
6
|
-
import os from "node:os";
|
|
7
6
|
import path from "node:path";
|
|
8
7
|
import process from "node:process";
|
|
8
|
+
import { createTestNamespace } from "../src/test-fixtures.js";
|
|
9
9
|
import {
|
|
10
10
|
getDebArtifactPath,
|
|
11
11
|
getPacmanArtifactPath,
|
|
@@ -61,7 +61,7 @@ async function main() {
|
|
|
61
61
|
throw new Error("Native Linux package smoke validation is supported only on Linux hosts");
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
const tempRoot =
|
|
64
|
+
const tempRoot = createTestNamespace("meta-architect-linux-smoke");
|
|
65
65
|
const debExtractRoot = path.join(tempRoot, "deb");
|
|
66
66
|
const pacmanExtractRoot = path.join(tempRoot, "pacman");
|
|
67
67
|
const rpmExtractRoot = path.join(tempRoot, "rpm");
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { spawnSync } from "node:child_process";
|
|
4
|
+
|
|
5
|
+
const budget = Number(process.env.MA_PACKAGE_SIZE_BUDGET ?? 5 * 1024 * 1024);
|
|
6
|
+
const result = spawnSync("npm", ["pack", "--dry-run", "--json", "--ignore-scripts"], {
|
|
7
|
+
encoding: "utf8",
|
|
8
|
+
});
|
|
9
|
+
if (result.status !== 0) throw new Error(result.stderr || "npm pack inspection failed");
|
|
10
|
+
const pack = JSON.parse(result.stdout)[0];
|
|
11
|
+
const excludedMedia = pack.files.filter((file) => /docs\/assets\//.test(file.path));
|
|
12
|
+
if (excludedMedia.length > 0)
|
|
13
|
+
throw new Error(
|
|
14
|
+
`Heavy demo media included: ${excludedMedia.map((file) => file.path).join(", ")}`,
|
|
15
|
+
);
|
|
16
|
+
const unexpectedExecutables = pack.files.filter(
|
|
17
|
+
(file) =>
|
|
18
|
+
file.mode === 493 && !file.path.startsWith("bin/") && !/^scripts\/[^/]+\.sh$/.test(file.path),
|
|
19
|
+
);
|
|
20
|
+
if (unexpectedExecutables.length > 0) {
|
|
21
|
+
throw new Error(
|
|
22
|
+
`Unexpected executable package files: ${unexpectedExecutables.map((file) => file.path).join(", ")}`,
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
console.log(`package size: ${pack.size} bytes (budget ${budget})`);
|
|
26
|
+
if (pack.size > budget) throw new Error(`Package exceeds ${budget} byte budget`);
|
package/scripts/plugin-sync.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import fs from "node:fs/promises";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import process from "node:process";
|
|
6
|
+
import { fileURLToPath } from "node:url";
|
|
6
7
|
|
|
7
8
|
const repoRoot = process.cwd();
|
|
8
9
|
const skillsRoot = path.join(repoRoot, "skills");
|
|
@@ -30,10 +31,23 @@ async function copyDir(src, dest) {
|
|
|
30
31
|
}
|
|
31
32
|
}
|
|
32
33
|
|
|
34
|
+
async function linkOrCopyDir(src, dest) {
|
|
35
|
+
if (process.env.MA_PLUGIN_SYNC_MODE !== "copy") {
|
|
36
|
+
try {
|
|
37
|
+
await fs.symlink(path.relative(path.dirname(dest), src), dest, "dir");
|
|
38
|
+
return "symlink";
|
|
39
|
+
} catch {
|
|
40
|
+
// Restricted worktrees and Windows may reject directory links.
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
await copyDir(src, dest);
|
|
44
|
+
return "copy";
|
|
45
|
+
}
|
|
46
|
+
|
|
33
47
|
async function listSkillDirs(root) {
|
|
34
|
-
const entries = await fs.readdir(root, { withFileTypes: true })
|
|
48
|
+
const entries = await fs.readdir(root, { withFileTypes: true });
|
|
35
49
|
return entries
|
|
36
|
-
.filter((entry) => entry.isDirectory())
|
|
50
|
+
.filter((entry) => entry.isDirectory() || entry.isSymbolicLink())
|
|
37
51
|
.map((entry) => entry.name)
|
|
38
52
|
.sort();
|
|
39
53
|
}
|
|
@@ -53,24 +67,74 @@ async function syncPluginSkills() {
|
|
|
53
67
|
const src = path.join(skillsRoot, name);
|
|
54
68
|
const dest = path.join(pluginSkillsRoot, name);
|
|
55
69
|
await fs.rm(dest, { recursive: true, force: true });
|
|
56
|
-
await
|
|
70
|
+
await linkOrCopyDir(src, dest);
|
|
57
71
|
}
|
|
58
72
|
|
|
59
73
|
return skillDirs;
|
|
60
74
|
}
|
|
61
75
|
|
|
62
|
-
async function
|
|
63
|
-
const
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
76
|
+
async function listFiles(root, current = root, files = []) {
|
|
77
|
+
const entries = await fs.readdir(current, { withFileTypes: true });
|
|
78
|
+
for (const entry of entries) {
|
|
79
|
+
const absolutePath = path.join(current, entry.name);
|
|
80
|
+
if (entry.isDirectory() || entry.isSymbolicLink()) {
|
|
81
|
+
await listFiles(root, absolutePath, files);
|
|
82
|
+
} else if (entry.isFile()) {
|
|
83
|
+
files.push(path.relative(root, absolutePath));
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return files.sort();
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export async function verifyPluginSkills(sourceRoot = skillsRoot, mirrorRoot = pluginSkillsRoot) {
|
|
90
|
+
await fs.access(sourceRoot);
|
|
91
|
+
await fs.access(mirrorRoot);
|
|
92
|
+
const sourceSkillDirs = await listSkillDirs(sourceRoot);
|
|
93
|
+
const mirrorSkillDirs = await listSkillDirs(mirrorRoot);
|
|
94
|
+
const filesForSkillDirs = async (root, skillDirs) => {
|
|
95
|
+
const files = [];
|
|
96
|
+
for (const skillDir of skillDirs) {
|
|
97
|
+
for (const relativePath of await listFiles(path.join(root, skillDir))) {
|
|
98
|
+
files.push(path.join(skillDir, relativePath));
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return files.sort();
|
|
102
|
+
};
|
|
103
|
+
const sourceFiles = await filesForSkillDirs(sourceRoot, sourceSkillDirs);
|
|
104
|
+
const mirrorFiles = await filesForSkillDirs(mirrorRoot, mirrorSkillDirs);
|
|
105
|
+
if (JSON.stringify(sourceFiles) !== JSON.stringify(mirrorFiles)) {
|
|
106
|
+
throw new Error("Plugin skill mirror drift: file set mismatch");
|
|
67
107
|
}
|
|
68
108
|
|
|
69
|
-
for (
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
)
|
|
109
|
+
for (const relativePath of sourceFiles) {
|
|
110
|
+
const sourcePath = path.join(sourceRoot, relativePath);
|
|
111
|
+
const mirrorPath = path.join(mirrorRoot, relativePath);
|
|
112
|
+
const [source, mirror, sourceStat, mirrorStat] = await Promise.all([
|
|
113
|
+
fs.readFile(sourcePath),
|
|
114
|
+
fs.readFile(mirrorPath),
|
|
115
|
+
fs.stat(sourcePath),
|
|
116
|
+
fs.stat(mirrorPath),
|
|
117
|
+
]);
|
|
118
|
+
if (!source.equals(mirror)) {
|
|
119
|
+
throw new Error(`Plugin skill mirror drift: content mismatch at ${relativePath}`);
|
|
120
|
+
}
|
|
121
|
+
if ((sourceStat.mode & 0o777) !== (mirrorStat.mode & 0o777)) {
|
|
122
|
+
throw new Error(`Plugin skill mirror drift: mode mismatch at ${relativePath}`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
for (const skillDir of sourceSkillDirs) {
|
|
126
|
+
const mirrorPath = path.join(mirrorRoot, skillDir);
|
|
127
|
+
const mirrorStat = await fs.lstat(mirrorPath);
|
|
128
|
+
if (mirrorStat.isSymbolicLink()) {
|
|
129
|
+
const [sourceRealPath, mirrorRealPath] = await Promise.all([
|
|
130
|
+
fs.realpath(path.join(sourceRoot, skillDir)),
|
|
131
|
+
fs.realpath(mirrorPath),
|
|
132
|
+
]);
|
|
133
|
+
if (sourceRealPath !== mirrorRealPath) {
|
|
134
|
+
throw new Error(`Plugin skill mirror drift: invalid symlink target at ${skillDir}`);
|
|
135
|
+
}
|
|
136
|
+
} else if (!mirrorStat.isDirectory()) {
|
|
137
|
+
throw new Error(`Plugin skill mirror drift: invalid mirror entry at ${skillDir}`);
|
|
74
138
|
}
|
|
75
139
|
}
|
|
76
140
|
}
|
|
@@ -87,7 +151,9 @@ async function main() {
|
|
|
87
151
|
console.log(pluginSkillsRoot);
|
|
88
152
|
}
|
|
89
153
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
154
|
+
if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
|
|
155
|
+
main().catch((error) => {
|
|
156
|
+
console.error(error.message);
|
|
157
|
+
process.exitCode = 1;
|
|
158
|
+
});
|
|
159
|
+
}
|