@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,208 @@
|
|
|
1
|
+
import { ensureDir, readJson, writeFileIfMissing } from "../fs-utils.js";
|
|
2
|
+
import { getRuntimeSubsystemPath } from "../paths.js";
|
|
3
|
+
|
|
4
|
+
export const activeAutonomyCoreSchemaVersion = "0.1.0";
|
|
5
|
+
|
|
6
|
+
export function getActiveAutonomyCorePath() {
|
|
7
|
+
return getRuntimeSubsystemPath("context", "active-autonomy-core.json");
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function createDefaultActiveAutonomyCore() {
|
|
11
|
+
return {
|
|
12
|
+
schemaVersion: activeAutonomyCoreSchemaVersion,
|
|
13
|
+
product: "Meta-Architect",
|
|
14
|
+
purpose:
|
|
15
|
+
"Canonical MA contract that prevents passive chatbot behavior across prompts, skills, runtime hooks, and contributor rules.",
|
|
16
|
+
autonomy_directive: {
|
|
17
|
+
placement: "top_of_workspace_contract_before_other_guidance",
|
|
18
|
+
text: [
|
|
19
|
+
"YOU ARE AN AUTONOMOUS META-ARCHITECT WORKSPACE AGENT.",
|
|
20
|
+
"EXECUTE CLEAR, SAFE, REVERSIBLE, ALREADY-REQUESTED WORK TO VERIFIED COMPLETION.",
|
|
21
|
+
"DO NOT ASK WHETHER TO PROCEED ON AUTO-CONTINUE BRANCHES.",
|
|
22
|
+
"ASK ONLY FOR DESTRUCTIVE, IRREVERSIBLE, CREDENTIAL-GATED, EXTERNAL-PRODUCTION, OR MATERIALLY SCOPE-CHANGING ACTIONS.",
|
|
23
|
+
],
|
|
24
|
+
},
|
|
25
|
+
decision_rule: {
|
|
26
|
+
modes: ["AUTO-CONTINUE", "ASK"],
|
|
27
|
+
auto_continue_when: [
|
|
28
|
+
"clear_user_requested_work",
|
|
29
|
+
"local_or_workspace_scoped",
|
|
30
|
+
"low_risk",
|
|
31
|
+
"reversible",
|
|
32
|
+
"non_destructive",
|
|
33
|
+
"verification_path_available",
|
|
34
|
+
],
|
|
35
|
+
ask_only_when: [
|
|
36
|
+
"destructive_action",
|
|
37
|
+
"irreversible_action",
|
|
38
|
+
"credential_gated_action",
|
|
39
|
+
"external_production_side_effect",
|
|
40
|
+
"material_scope_change",
|
|
41
|
+
"missing_authority_blocks_progress",
|
|
42
|
+
],
|
|
43
|
+
banned_auto_continue_phrasing: [
|
|
44
|
+
"Should I proceed?",
|
|
45
|
+
"Would you like me to continue?",
|
|
46
|
+
"If you want, I can",
|
|
47
|
+
"If you'd like, I can",
|
|
48
|
+
"Tell me if you want me to",
|
|
49
|
+
"I can continue if you want",
|
|
50
|
+
],
|
|
51
|
+
},
|
|
52
|
+
completion_loop_contract: {
|
|
53
|
+
required_for: [
|
|
54
|
+
"$maestro",
|
|
55
|
+
"$build",
|
|
56
|
+
"ralph_execution_core",
|
|
57
|
+
"executor_roles",
|
|
58
|
+
"team_workers",
|
|
59
|
+
],
|
|
60
|
+
stop_conditions: [
|
|
61
|
+
"verified_complete",
|
|
62
|
+
"user_cancelled",
|
|
63
|
+
"closed_ask_condition_requires_user_input",
|
|
64
|
+
"same_blocker_repeated_three_times_with_no_safe_alternative",
|
|
65
|
+
],
|
|
66
|
+
completion_requires: [
|
|
67
|
+
"fresh_verification_evidence",
|
|
68
|
+
"explicit_outcome",
|
|
69
|
+
"changed_artifacts_or_no_change_reason",
|
|
70
|
+
"known_gaps_or_none",
|
|
71
|
+
],
|
|
72
|
+
terminal_outcomes: ["finished", "blocked", "failed", "cancelled", "askuserQuestion"],
|
|
73
|
+
},
|
|
74
|
+
runtime_enforcement: {
|
|
75
|
+
hook_layer: "active_autonomy_runtime",
|
|
76
|
+
stall_patterns: [
|
|
77
|
+
"should i proceed",
|
|
78
|
+
"would you like me to continue",
|
|
79
|
+
"if you want, i can",
|
|
80
|
+
"if you'd like, i can",
|
|
81
|
+
"tell me if you want me to",
|
|
82
|
+
"i can continue if you want",
|
|
83
|
+
"let me know if you want me to continue",
|
|
84
|
+
],
|
|
85
|
+
default_response:
|
|
86
|
+
"AUTO-CONTINUE: continue the current safe branch, execute the next reversible step, then verify before reporting.",
|
|
87
|
+
native_stop_policy: "block_passive_permission_handoff_when_auto_continue_applies",
|
|
88
|
+
},
|
|
89
|
+
contributor_contract: {
|
|
90
|
+
required_surfaces: [
|
|
91
|
+
"workspace_contract",
|
|
92
|
+
"role_prompts",
|
|
93
|
+
"skill_contracts",
|
|
94
|
+
"runtime_hook_policy",
|
|
95
|
+
"docs",
|
|
96
|
+
"tests",
|
|
97
|
+
],
|
|
98
|
+
regression_targets: [
|
|
99
|
+
"closed_ask_list_present",
|
|
100
|
+
"auto_continue_mode_present",
|
|
101
|
+
"permission_handoff_banned",
|
|
102
|
+
"completion_requires_fresh_evidence",
|
|
103
|
+
"terminal_outcome_required",
|
|
104
|
+
"hook_stall_patterns_present",
|
|
105
|
+
],
|
|
106
|
+
},
|
|
107
|
+
hard_rules: [
|
|
108
|
+
"Prompt instructions alone are insufficient; runtime hook policy must backstop passive handoffs.",
|
|
109
|
+
"AUTO-CONTINUE branches must state next action or evidence-backed result, not request permission.",
|
|
110
|
+
"ASK branches must name the exact closed-list reason that requires the user.",
|
|
111
|
+
"Completion claims require fresh verification evidence or an explicit validation gap.",
|
|
112
|
+
"Contributor edits must preserve anti-passive prompt patterns and hook policy.",
|
|
113
|
+
],
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export function validateActiveAutonomyCore(value) {
|
|
118
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
119
|
+
throw new Error("active autonomy core must be an object");
|
|
120
|
+
}
|
|
121
|
+
if (value.schemaVersion !== activeAutonomyCoreSchemaVersion) {
|
|
122
|
+
throw new Error(`Unsupported active autonomy core schemaVersion: ${value.schemaVersion}`);
|
|
123
|
+
}
|
|
124
|
+
if (!value.decision_rule || typeof value.decision_rule !== "object") {
|
|
125
|
+
throw new Error("active autonomy core requires decision_rule");
|
|
126
|
+
}
|
|
127
|
+
if (!value.decision_rule.modes?.includes("AUTO-CONTINUE")) {
|
|
128
|
+
throw new Error("active autonomy core requires AUTO-CONTINUE mode");
|
|
129
|
+
}
|
|
130
|
+
if (!value.decision_rule.modes?.includes("ASK")) {
|
|
131
|
+
throw new Error("active autonomy core requires ASK mode");
|
|
132
|
+
}
|
|
133
|
+
if (
|
|
134
|
+
!Array.isArray(value.decision_rule.ask_only_when) ||
|
|
135
|
+
value.decision_rule.ask_only_when.length === 0
|
|
136
|
+
) {
|
|
137
|
+
throw new Error("active autonomy core requires closed ask_only_when list");
|
|
138
|
+
}
|
|
139
|
+
if (!value.runtime_enforcement?.stall_patterns?.includes("should i proceed")) {
|
|
140
|
+
throw new Error("active autonomy core requires passive stall pattern coverage");
|
|
141
|
+
}
|
|
142
|
+
if (
|
|
143
|
+
!value.completion_loop_contract?.completion_requires?.includes("fresh_verification_evidence")
|
|
144
|
+
) {
|
|
145
|
+
throw new Error("active autonomy core requires fresh verification evidence");
|
|
146
|
+
}
|
|
147
|
+
if (JSON.stringify(value).includes(".omx")) {
|
|
148
|
+
throw new Error("active autonomy core must not expose OMX runtime paths");
|
|
149
|
+
}
|
|
150
|
+
return value;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export function classifyAutonomyBranch({ core, requested = true, riskSignals = [] }) {
|
|
154
|
+
const policy = validateActiveAutonomyCore(core);
|
|
155
|
+
const signals = new Set(riskSignals.map((signal) => `${signal}`.toLowerCase()));
|
|
156
|
+
const askReason = policy.decision_rule.ask_only_when.find((reason) =>
|
|
157
|
+
signals.has(reason.toLowerCase()),
|
|
158
|
+
);
|
|
159
|
+
|
|
160
|
+
if (!requested) {
|
|
161
|
+
return {
|
|
162
|
+
mode: "ASK",
|
|
163
|
+
reason: "missing_authority_blocks_progress",
|
|
164
|
+
permission_handoff_allowed: true,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
if (askReason) {
|
|
169
|
+
return {
|
|
170
|
+
mode: "ASK",
|
|
171
|
+
reason: askReason,
|
|
172
|
+
permission_handoff_allowed: true,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
return {
|
|
177
|
+
mode: "AUTO-CONTINUE",
|
|
178
|
+
reason: "clear_safe_reversible_requested_work",
|
|
179
|
+
permission_handoff_allowed: false,
|
|
180
|
+
next_action_contract:
|
|
181
|
+
"state the next safe action or evidence-backed result; do not ask whether to proceed",
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
export function detectPassivePermissionHandoff(text, core = createDefaultActiveAutonomyCore()) {
|
|
186
|
+
const policy = validateActiveAutonomyCore(core);
|
|
187
|
+
const normalized = `${text}`.toLowerCase();
|
|
188
|
+
return policy.decision_rule.banned_auto_continue_phrasing.some((phrase) =>
|
|
189
|
+
normalized.includes(
|
|
190
|
+
phrase
|
|
191
|
+
.toLowerCase()
|
|
192
|
+
.replace(/\.\.\.$/, "")
|
|
193
|
+
.trim(),
|
|
194
|
+
),
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
export async function seedActiveAutonomyCoreArtifacts() {
|
|
199
|
+
await ensureDir(getRuntimeSubsystemPath("context"));
|
|
200
|
+
await writeFileIfMissing(
|
|
201
|
+
getActiveAutonomyCorePath(),
|
|
202
|
+
`${JSON.stringify(createDefaultActiveAutonomyCore(), null, 2)}\n`,
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
export async function loadActiveAutonomyCore() {
|
|
207
|
+
return validateActiveAutonomyCore(await readJson(getActiveAutonomyCorePath()));
|
|
208
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
import { Agents } from "@jstn-sdk/agents";
|
|
3
|
+
|
|
4
|
+
const require = createRequire(import.meta.url);
|
|
5
|
+
const agentCompatMetadata = require("@jstn-sdk/agents/package.json");
|
|
6
|
+
|
|
7
|
+
export const agentCompatPackage = "@jstn-sdk/agents";
|
|
8
|
+
export const agentCompatVersion = agentCompatMetadata.version;
|
|
9
|
+
|
|
10
|
+
export function listAgentCompatAdapters() {
|
|
11
|
+
return Agents.list().map(({ id, vendor, product, surface, support, verification }) => ({
|
|
12
|
+
id,
|
|
13
|
+
vendor,
|
|
14
|
+
product,
|
|
15
|
+
surface,
|
|
16
|
+
support,
|
|
17
|
+
verification,
|
|
18
|
+
}));
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function detectAgentEnvironments(root) {
|
|
22
|
+
return Agents.detect(root);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function compileAgentIntegrations(manifest, options = {}) {
|
|
26
|
+
return Agents.compile(manifest, options);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function validateAgentIntegrations(root, options = {}) {
|
|
30
|
+
return Agents.validate(root, options);
|
|
31
|
+
}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { readJson, writeFileIfMissing, writeJson } from "../fs-utils.js";
|
|
2
|
+
import { getRuntimeStatePath } from "../paths.js";
|
|
3
|
+
|
|
4
|
+
const driftRuleDefinitions = [
|
|
5
|
+
{
|
|
6
|
+
skill: "$arch",
|
|
7
|
+
expectedDecisionStatus: "APPROVED",
|
|
8
|
+
releaseField: "architecture_status",
|
|
9
|
+
allowedReleaseValues: ["APPROVED"],
|
|
10
|
+
findingCode: "architecture_status_regressed",
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
skill: "$sage",
|
|
14
|
+
expectedDecisionStatus: "VERIFIED",
|
|
15
|
+
releaseField: "evidence_status",
|
|
16
|
+
allowedReleaseValues: ["VERIFIED"],
|
|
17
|
+
findingCode: "evidence_status_regressed",
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
skill: "$flow",
|
|
21
|
+
expectedDecisionStatus: "GREEN",
|
|
22
|
+
releaseField: "logic_status",
|
|
23
|
+
allowedReleaseValues: ["GREEN"],
|
|
24
|
+
findingCode: "logic_status_regressed",
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
skill: "$vet",
|
|
28
|
+
expectedDecisionStatus: "GREEN",
|
|
29
|
+
releaseField: "security_status",
|
|
30
|
+
allowedReleaseValues: ["GREEN"],
|
|
31
|
+
findingCode: "security_status_regressed",
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
skill: "$vibe",
|
|
35
|
+
expectedDecisionStatus: "GREEN",
|
|
36
|
+
releaseField: "experience_status",
|
|
37
|
+
allowedReleaseValues: ["GREEN", "WAIVED"],
|
|
38
|
+
findingCode: "experience_status_regressed",
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
skill: "$build",
|
|
42
|
+
expectedDecisionStatus: "DONE",
|
|
43
|
+
releaseField: "build_status",
|
|
44
|
+
allowedReleaseValues: ["DONE"],
|
|
45
|
+
findingCode: "build_status_regressed",
|
|
46
|
+
},
|
|
47
|
+
];
|
|
48
|
+
|
|
49
|
+
export function getAlignmentSentinelPath() {
|
|
50
|
+
return getRuntimeStatePath("alignment-sentinel.json");
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function createDefaultAlignmentSentinelReport() {
|
|
54
|
+
return {
|
|
55
|
+
schemaVersion: "0.1.0",
|
|
56
|
+
lastRunAt: null,
|
|
57
|
+
driftStatus: "CLEAR",
|
|
58
|
+
rebootPlanned: false,
|
|
59
|
+
rebootReason: null,
|
|
60
|
+
resumeTrigger: "$maestro",
|
|
61
|
+
baselineArtifacts: [
|
|
62
|
+
".ma/release.json",
|
|
63
|
+
".ma/decisions.json",
|
|
64
|
+
".ma/state/manager-runs.json",
|
|
65
|
+
".ma/state/maestro-state.json",
|
|
66
|
+
],
|
|
67
|
+
findings: [],
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export async function seedAlignmentSentinelArtifacts() {
|
|
72
|
+
await writeFileIfMissing(
|
|
73
|
+
getAlignmentSentinelPath(),
|
|
74
|
+
`${JSON.stringify(createDefaultAlignmentSentinelReport(), null, 2)}\n`,
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export async function loadAlignmentSentinelReportOrDefault() {
|
|
79
|
+
try {
|
|
80
|
+
return await readJson(getAlignmentSentinelPath());
|
|
81
|
+
} catch (error) {
|
|
82
|
+
if (error && typeof error === "object" && "code" in error && error.code === "ENOENT") {
|
|
83
|
+
return createDefaultAlignmentSentinelReport();
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
throw error;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export async function saveAlignmentSentinelReport(report) {
|
|
91
|
+
await writeJson(getAlignmentSentinelPath(), report);
|
|
92
|
+
return report;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function getLatestDecisionBySkill(decisions = []) {
|
|
96
|
+
const latestBySkill = new Map();
|
|
97
|
+
for (const decision of decisions) {
|
|
98
|
+
if (!decision?.skill) {
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
latestBySkill.set(decision.skill, decision);
|
|
103
|
+
}
|
|
104
|
+
return latestBySkill;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export function evaluateAlignmentDrift({ releaseState, decisionLog }) {
|
|
108
|
+
const latestDecisions = getLatestDecisionBySkill(decisionLog?.decisions ?? []);
|
|
109
|
+
const findings = [];
|
|
110
|
+
|
|
111
|
+
for (const rule of driftRuleDefinitions) {
|
|
112
|
+
const latestDecision = latestDecisions.get(rule.skill);
|
|
113
|
+
if (!latestDecision || latestDecision.status !== rule.expectedDecisionStatus) {
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const actualReleaseValue = releaseState?.[rule.releaseField];
|
|
118
|
+
if (rule.allowedReleaseValues.includes(actualReleaseValue)) {
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
findings.push({
|
|
123
|
+
severity: "blocking",
|
|
124
|
+
findingCode: rule.findingCode,
|
|
125
|
+
skill: rule.skill,
|
|
126
|
+
expectedDecisionStatus: rule.expectedDecisionStatus,
|
|
127
|
+
releaseField: rule.releaseField,
|
|
128
|
+
expectedReleaseValues: rule.allowedReleaseValues,
|
|
129
|
+
actualReleaseValue,
|
|
130
|
+
decisionTimestamp: latestDecision.timestamp ?? null,
|
|
131
|
+
decisionSummary: latestDecision.decision ?? null,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return {
|
|
136
|
+
driftStatus: findings.length > 0 ? "DRIFTED" : "CLEAR",
|
|
137
|
+
rebootPlanned: findings.length > 0,
|
|
138
|
+
rebootReason:
|
|
139
|
+
findings.length > 0
|
|
140
|
+
? "Release state drifted from the latest approved lane-owned decisions."
|
|
141
|
+
: null,
|
|
142
|
+
resumeTrigger: "$maestro",
|
|
143
|
+
findings,
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export function createAlignmentRecoveryPlan(report) {
|
|
148
|
+
const findings = report?.findings ?? [];
|
|
149
|
+
return {
|
|
150
|
+
record_type: "alignment_recovery_plan",
|
|
151
|
+
driftStatus: report?.driftStatus ?? (findings.length > 0 ? "DRIFTED" : "CLEAR"),
|
|
152
|
+
rebootPlanned: findings.length > 0,
|
|
153
|
+
resumeTrigger: report?.resumeTrigger ?? "$maestro",
|
|
154
|
+
requiredActions: findings.map((finding) => ({
|
|
155
|
+
skill: finding.skill,
|
|
156
|
+
repairField: finding.releaseField,
|
|
157
|
+
expectedValues: finding.expectedReleaseValues,
|
|
158
|
+
actualValue: finding.actualReleaseValue,
|
|
159
|
+
action:
|
|
160
|
+
"Rehydrate from baseline runtime artifacts, then rerun the owning lane or restore lane-owned release state before worker dispatch resumes.",
|
|
161
|
+
})),
|
|
162
|
+
mayDispatchWorkers: findings.length === 0,
|
|
163
|
+
mayMutateReleaseStateDirectly: false,
|
|
164
|
+
};
|
|
165
|
+
}
|