@aiwg/cli 2026.9.24 → 2026.10.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/agentic/code/providers/capability-matrix.yaml +2 -1
- package/dist/src/artifacts/discovery-shadow-evaluator.js +177 -0
- package/dist/src/artifacts/discovery-shadow.js +195 -0
- package/dist/src/artifacts/index-builder.js +47 -9
- package/dist/src/artifacts/query-engine.js +94 -1
- package/dist/src/artifacts/types.js +1 -0
- package/dist/src/cli/handlers/decision.js +88 -0
- package/dist/src/cli/handlers/gates.js +154 -0
- package/dist/src/cli/handlers/index.js +5 -1
- package/dist/src/cli/handlers/sessions.js +10 -7
- package/dist/src/cli/handlers/utilities.js +20 -0
- package/dist/src/config/aiwg-config.js +15 -2
- package/dist/src/decision/acceptance.js +25 -0
- package/dist/src/decision/adapters/jev.js +24 -2
- package/dist/src/decision/calibration/registry.js +9 -0
- package/dist/src/decision/compose.js +74 -15
- package/dist/src/decision/context-live-promotion.js +344 -0
- package/dist/src/decision/context-live-qualification.js +591 -0
- package/dist/src/decision/context-pruning.js +847 -0
- package/dist/src/decision/driver.js +430 -0
- package/dist/src/decision/egress-live-qualification.js +874 -0
- package/dist/src/decision/ensemble/contract.js +64 -1
- package/dist/src/decision/ensemble/index.js +1 -0
- package/dist/src/decision/ensemble/report.js +8 -42
- package/dist/src/decision/ensemble/runtime.js +571 -0
- package/dist/src/decision/ensemble-study/artifacts.js +85 -0
- package/dist/src/decision/ensemble-study/calibration.js +443 -0
- package/dist/src/decision/ensemble-study/corpus.js +229 -0
- package/dist/src/decision/ensemble-study/multifact-artifacts.js +23 -0
- package/dist/src/decision/ensemble-study/multifact-study.js +596 -0
- package/dist/src/decision/ensemble-study/multifact.js +241 -0
- package/dist/src/decision/ensemble-study/protocol.js +77 -0
- package/dist/src/decision/ensemble-study/score.js +462 -0
- package/dist/src/decision/ensemble-study/staged.js +87 -0
- package/dist/src/decision/ensemble-study/statistics.js +84 -0
- package/dist/src/decision/evaluate.js +227 -14
- package/dist/src/decision/export.js +4 -0
- package/dist/src/decision/feature-export.js +1074 -0
- package/dist/src/decision/graph-index.js +16 -0
- package/dist/src/decision/graph-live-qualification.js +1041 -0
- package/dist/src/decision/graph-live-workload.js +245 -0
- package/dist/src/decision/graph-skill-bridge.js +21 -3
- package/dist/src/decision/heldout/calibration.js +140 -0
- package/dist/src/decision/heldout/collector.js +430 -0
- package/dist/src/decision/heldout/contract.js +309 -0
- package/dist/src/decision/heldout/d29-generator-ids.js +12 -0
- package/dist/src/decision/heldout/d29-passage-baseline-v2.js +93 -0
- package/dist/src/decision/heldout/d29-passage-baseline-v3.js +100 -0
- package/dist/src/decision/heldout/d29-passage-baseline.js +66 -0
- package/dist/src/decision/heldout/d29-pools-v8.js +575 -0
- package/dist/src/decision/heldout/d29-pools.js +288 -0
- package/dist/src/decision/heldout/d29-v6.js +169 -0
- package/dist/src/decision/heldout/d29-v7.js +202 -0
- package/dist/src/decision/heldout/d29-v8.js +586 -0
- package/dist/src/decision/heldout/generator-registry.js +67 -0
- package/dist/src/decision/heldout/generators.js +696 -0
- package/dist/src/decision/heldout/index.js +8 -0
- package/dist/src/decision/heldout/journal.js +346 -0
- package/dist/src/decision/heldout/study-generators.js +64 -0
- package/dist/src/decision/heldout/types.js +2 -0
- package/dist/src/decision/host-policy.js +61 -0
- package/dist/src/decision/index.js +11 -0
- package/dist/src/decision/interop-profile.v1.json +112 -0
- package/dist/src/decision/interop.js +653 -0
- package/dist/src/decision/issue-triage/index.js +3 -0
- package/dist/src/decision/issue-triage/runtime.js +1069 -0
- package/dist/src/decision/issue-triage/types.js +2 -0
- package/dist/src/decision/patterns/catalog.js +28 -8
- package/dist/src/decision/patterns/playground.js +28 -11
- package/dist/src/decision/patterns/specs.js +19 -10
- package/dist/src/decision/preprocessed-evidence.js +724 -0
- package/dist/src/decision/qualification/capture.js +8 -2
- package/dist/src/decision/qualification/gate-evidence.js +19 -4
- package/dist/src/decision/qualification/quality.js +57 -49
- package/dist/src/decision/qualification/release.js +76 -3
- package/dist/src/decision/qualification/runner.js +5 -2
- package/dist/src/decision/routing/contract.js +175 -0
- package/dist/src/decision/routing/index.js +5 -0
- package/dist/src/decision/routing/report.js +216 -0
- package/dist/src/decision/routing/runtime.js +685 -0
- package/dist/src/decision/routing/types.js +2 -0
- package/dist/src/decision/sdlc-screening.js +1157 -0
- package/dist/src/decision/sensitivity/comparative.js +154 -0
- package/dist/src/decision/sensitivity/contract.js +218 -0
- package/dist/src/decision/sensitivity/index.js +5 -0
- package/dist/src/decision/sensitivity/runtime.js +912 -0
- package/dist/src/decision/sensitivity/types.js +2 -0
- package/dist/src/decision/validate.js +26 -0
- package/dist/src/extensions/commands/definitions.js +38 -0
- package/dist/src/extensions/manifest.js +44 -0
- package/dist/src/gates/discovery.js +315 -0
- package/dist/src/gates/driver.js +388 -0
- package/dist/src/gates/evaluate.js +719 -0
- package/dist/src/gates/floors.js +255 -0
- package/dist/src/gates/index.js +17 -0
- package/dist/src/gates/providers/evidence.js +38 -0
- package/dist/src/gates/providers/index.js +21 -0
- package/dist/src/gates/providers/isolated-child-source.js +446 -0
- package/dist/src/gates/providers/loader.js +1069 -0
- package/dist/src/gates/providers/paired.js +52 -0
- package/dist/src/gates/providers/proportion.js +60 -0
- package/dist/src/gates/providers/registry.js +40 -0
- package/dist/src/gates/providers/scalar.js +41 -0
- package/dist/src/gates/providers/screening.js +53 -0
- package/dist/src/gates/providers/types.js +25 -0
- package/dist/src/gates/registry.js +1003 -0
- package/dist/src/gates/report.js +102 -0
- package/dist/src/gates/schema.js +56 -0
- package/dist/src/gates/stats/binomial.js +26 -0
- package/dist/src/gates/stats/bootstrap.js +62 -0
- package/dist/src/gates/stats/clopper-pearson.js +95 -0
- package/dist/src/gates/stats/digest.js +26 -0
- package/dist/src/gates/stats/error.js +5 -0
- package/dist/src/gates/stats/index.js +9 -0
- package/dist/src/gates/stats/normal.js +35 -0
- package/dist/src/gates/stats/paired.js +120 -0
- package/dist/src/gates/stats/splits.js +30 -0
- package/dist/src/gates/types.js +8 -0
- package/dist/src/governance/redaction.js +14 -4
- package/dist/src/mcp/muse-native-config.mjs +123 -0
- package/dist/src/mcp/tools/decision.mjs +188 -0
- package/dist/src/mcp/tools/subsystems.mjs +2 -0
- package/dist/src/providers/capability-matrix.yaml +2 -1
- package/dist/src/providers/provider-definitions.js +2 -1
- package/dist/src/sessions/adapters/muse.js +336 -39
- package/dist/src/sessions/batch-import.js +7 -0
- package/dist/src/sessions/workspace-discovery.js +13 -2
- package/package.json +1 -1
- package/schemas/decision/ConformalFrozenOpenData.v2.schema.json +371 -0
- package/schemas/decision/ConformalOpenDataReport.v2.schema.json +421 -0
- package/schemas/decision/ConformalPreregistration.v2.schema.json +529 -0
- package/schemas/decision/ContextPruningCandidate.v1.schema.json +47 -0
- package/schemas/decision/ContextPruningEvaluationReport.v1.schema.json +758 -0
- package/schemas/decision/ContextPruningPreregistration.v1.schema.json +175 -0
- package/schemas/decision/ContextPruningReceipt.v1.schema.json +72 -0
- package/schemas/decision/D17Multifact.v1.schema.json +1851 -0
- package/schemas/decision/D17StudyAnalysis.v1.schema.json +42 -0
- package/schemas/decision/D17StudyAnalysis.v2.schema.json +51 -0
- package/schemas/decision/D17StudyCalibration.v1.schema.json +819 -0
- package/schemas/decision/D17StudyDryRun.v1.schema.json +169 -0
- package/schemas/decision/D17StudyDryRun.v2.schema.json +239 -0
- package/schemas/decision/D17StudyGold.v1.schema.json +108 -0
- package/schemas/decision/D17StudyGuide.v1.schema.json +63 -0
- package/schemas/decision/D17StudyNativeTemplates.v1.schema.json +619 -0
- package/schemas/decision/D17StudyProtocol.v1.schema.json +241 -0
- package/schemas/decision/D17StudyReport.v1.schema.json +902 -0
- package/schemas/decision/D17StudyReport.v2.schema.json +1319 -0
- package/schemas/decision/D17StudyReview.v1.schema.json +175 -0
- package/schemas/decision/D17StudySplits.v1.schema.json +217 -0
- package/schemas/decision/D29Study.v1.schema.json +1903 -0
- package/schemas/decision/D29Study.v2.schema.json +1344 -0
- package/schemas/decision/D29Study.v3.schema.json +609 -0
- package/schemas/decision/D29Study.v4.schema.json +1133 -0
- package/schemas/decision/D29Study.v6.schema.json +1205 -0
- package/schemas/decision/D29Study.v7.schema.json +1471 -0
- package/schemas/decision/D29Study.v8.schema.json +671 -0
- package/schemas/decision/D29Study.v9.schema.json +778 -0
- package/schemas/decision/DecisionComparativeReplayAuditSample.v1.schema.json +137 -0
- package/schemas/decision/DecisionComparativeReplayCorpus.v1.schema.json +258 -0
- package/schemas/decision/DecisionComparativeReplayFreeze.v1.schema.json +74 -0
- package/schemas/decision/DecisionComparativeReplayGold.v1.schema.json +50 -0
- package/schemas/decision/DecisionComparativeReplayGoldAsset.v1.schema.json +37 -0
- package/schemas/decision/DecisionComparativeReplayIntegrity.v1.schema.json +81 -0
- package/schemas/decision/DecisionComparativeReplayMembers.v1.schema.json +52 -0
- package/schemas/decision/DecisionComparativeReplayPreregistration.v1.schema.json +113 -0
- package/schemas/decision/DecisionComparativeReplayReport.v1.schema.json +407 -0
- package/schemas/decision/DecisionComparativeReplayReviewPackets.v1.schema.json +260 -0
- package/schemas/decision/DecisionComparativeReplaySplit.v1.schema.json +84 -0
- package/schemas/decision/DecisionFeatureObservation.v1.schema.json +564 -0
- package/schemas/decision/DecisionFeatureSet.v1.schema.json +155 -0
- package/schemas/decision/DecisionInteropMapping.v1.schema.json +85 -0
- package/schemas/decision/DecisionIssueTriageEvaluationManifest.v1.schema.json +174 -0
- package/schemas/decision/DecisionIssueTriageEvaluationReport.v1.schema.json +280 -0
- package/schemas/decision/DecisionIssueTriagePilotPack.v1.schema.json +114 -0
- package/schemas/decision/DecisionRouteReceipt.v1.schema.json +155 -0
- package/schemas/decision/DecisionRoutingPolicy.v1.schema.json +132 -0
- package/schemas/decision/DecisionRoutingShadowReport.v1.schema.json +170 -0
- package/schemas/decision/DecisionRoutingTask.v1.schema.json +49 -0
- package/schemas/decision/DecisionRuleset.schema.json +8 -2
- package/schemas/decision/DecisionRuleset.v1alpha2.schema.json +8 -2
- package/schemas/decision/DecisionSensitivityPlan.v1.schema.json +191 -0
- package/schemas/decision/DecisionSensitivityReport.v1.schema.json +163 -0
- package/schemas/decision/HeldoutApproval.v1.schema.json +312 -0
- package/schemas/decision/HeldoutAttempt.v1.schema.json +211 -0
- package/schemas/decision/HeldoutBaseline.v1.schema.json +90 -0
- package/schemas/decision/HeldoutCalibrationPhase.v1.schema.json +87 -0
- package/schemas/decision/HeldoutCorpus.v1.schema.json +167 -0
- package/schemas/decision/HeldoutEvent.v1.schema.json +41 -0
- package/schemas/decision/HeldoutFrozen.v1.schema.json +142 -0
- package/schemas/decision/HeldoutPreregistration.v1.schema.json +222 -0
- package/schemas/decision/HeldoutSpendEvent.v1.schema.json +122 -0
- package/schemas/decision/HeldoutSpendHead.v1.schema.json +25 -0
- package/schemas/decision/HeldoutSpendHead.v2.schema.json +46 -0
- package/schemas/decision/HeldoutSummary.v1.schema.json +101 -0
- package/schemas/decision/OpaDecisionLogExport.v1.schema.json +65 -0
- package/schemas/decision/PreprocessedEvidence.v1.schema.json +306 -0
- package/schemas/decision/RulesetResult.v1alpha2.schema.json +175 -0
- package/schemas/decision/SdlcEvidenceScreening.v1.schema.json +499 -0
- package/schemas/decision/SdlcScreeningPreregistration.v1.schema.json +132 -0
- package/schemas/decision/SdlcScreeningPreregistration.v2.schema.json +138 -0
- package/schemas/decision/SdlcScreeningRelease.v1.schema.json +654 -0
- package/schemas/decision/SdlcScreeningRelease.v2.schema.json +654 -0
- package/tools/agents/deploy-agents.mjs +1 -1
- package/tools/agents/providers/base.mjs +26 -7
- package/tools/agents/providers/factory.mjs +10 -2
- package/tools/agents/providers/muse-hooks.mjs +1 -29
- package/tools/agents/providers/muse.mjs +6 -3
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { access, readFile } from 'node:fs/promises';
|
|
2
|
+
import { constants } from 'node:fs';
|
|
3
|
+
import { spawnSync } from 'node:child_process';
|
|
4
|
+
import { dirname, join } from 'node:path';
|
|
5
|
+
import os from 'node:os';
|
|
6
|
+
import { resolveMuseXdgSkillsDir } from '../providers/muse-paths.js';
|
|
7
|
+
|
|
8
|
+
// Mirrors tools/agents/providers/muse-hooks.mjs. src/ cannot import tools/:
|
|
9
|
+
// tools/ is not part of the compiled dist/ tree.
|
|
10
|
+
const MUSE_HOOKS_REL = join('.muse', 'hooks.json');
|
|
11
|
+
const MUSE_HOOKS_SIDECAR_REL = join('.muse', '.aiwg-hooks.json');
|
|
12
|
+
|
|
13
|
+
const MUSE_VERSION_TIMEOUT_MS = 5_000;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* JSONC-tolerant parse. String-aware twin of `stripJsonComments` in
|
|
17
|
+
* tools/agents/providers/base.mjs: `//` in URLs and `/*` in glob
|
|
18
|
+
* matchers survive.
|
|
19
|
+
*/
|
|
20
|
+
function parseJson(raw) {
|
|
21
|
+
const text = String(raw);
|
|
22
|
+
let out = '';
|
|
23
|
+
let i = 0;
|
|
24
|
+
while (i < text.length) {
|
|
25
|
+
const ch = text[i];
|
|
26
|
+
if (ch === '"') {
|
|
27
|
+
let j = i + 1;
|
|
28
|
+
while (j < text.length && text[j] !== '"') j += text[j] === '\\' ? 2 : 1;
|
|
29
|
+
out += text.slice(i, j + 1);
|
|
30
|
+
i = j + 1;
|
|
31
|
+
} else if (ch === '/' && text[i + 1] === '/') {
|
|
32
|
+
while (i < text.length && text[i] !== '\n') i++;
|
|
33
|
+
} else if (ch === '/' && text[i + 1] === '*') {
|
|
34
|
+
const end = text.indexOf('*/', i + 2);
|
|
35
|
+
i = end === -1 ? text.length : end + 2;
|
|
36
|
+
} else {
|
|
37
|
+
out += ch;
|
|
38
|
+
i++;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return JSON.parse(out);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function deepEqual(a, b) {
|
|
45
|
+
return JSON.stringify(a) === JSON.stringify(b);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function inspectMuseCli(env) {
|
|
49
|
+
const result = spawnSync('muse', ['--version'], {
|
|
50
|
+
env,
|
|
51
|
+
encoding: 'utf8',
|
|
52
|
+
timeout: MUSE_VERSION_TIMEOUT_MS,
|
|
53
|
+
});
|
|
54
|
+
if (result.error?.code === 'ENOENT') return 'absent';
|
|
55
|
+
if (result.error?.code === 'ETIMEDOUT') return 'present (version timeout)';
|
|
56
|
+
if (result.error) return 'absent';
|
|
57
|
+
const firstLine = String(result.stdout || result.stderr || '').split(/\r?\n/).find((line) => line.trim());
|
|
58
|
+
return firstLine ? `present (${firstLine.trim()})` : 'present (version unavailable)';
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async function inspectMuseHooks(projectDir) {
|
|
62
|
+
const hooksPath = join(projectDir, MUSE_HOOKS_REL);
|
|
63
|
+
try {
|
|
64
|
+
await access(hooksPath, constants.F_OK);
|
|
65
|
+
} catch {
|
|
66
|
+
return 'absent';
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
try {
|
|
70
|
+
const doc = parseJson(await readFile(hooksPath, 'utf8'));
|
|
71
|
+
const sessionStartGroups = Array.isArray(doc?.hooks?.SessionStart) ? doc.hooks.SessionStart : [];
|
|
72
|
+
// AIWG records every group it manages in the sidecar on deploy; a group
|
|
73
|
+
// counts as managed only when that recorded payload is present.
|
|
74
|
+
const sidecar = parseJson(await readFile(join(projectDir, MUSE_HOOKS_SIDECAR_REL), 'utf8'));
|
|
75
|
+
const recorded = Array.isArray(sidecar?.hooks)
|
|
76
|
+
? sidecar.hooks.filter((hook) => hook?.event === 'SessionStart' && hook.group)
|
|
77
|
+
: [];
|
|
78
|
+
return recorded.some((hook) => sessionStartGroups.some((group) => deepEqual(group, hook.group)))
|
|
79
|
+
? 'managed'
|
|
80
|
+
: 'operator-only';
|
|
81
|
+
} catch {
|
|
82
|
+
// Unreadable hooks or a missing/malformed sidecar: nothing proves AIWG
|
|
83
|
+
// owns these groups.
|
|
84
|
+
return 'operator-only';
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
async function inspectMuseMcp(options) {
|
|
89
|
+
// <xdg>/muse/skills -> <xdg>/muse/settings.json; bad XDG metadata yields
|
|
90
|
+
// no path (never ~/.muse).
|
|
91
|
+
const skillsDir = resolveMuseXdgSkillsDir(options.env || process.env, options.userHome || os.homedir());
|
|
92
|
+
if (!skillsDir) return 'unreadable';
|
|
93
|
+
const settingsPath = join(dirname(skillsDir), 'settings.json');
|
|
94
|
+
try {
|
|
95
|
+
const settings = parseJson(await readFile(settingsPath, 'utf8'));
|
|
96
|
+
return settings?.mcp_servers && typeof settings.mcp_servers === 'object'
|
|
97
|
+
&& Object.prototype.hasOwnProperty.call(settings.mcp_servers, 'aiwg')
|
|
98
|
+
? 'configured'
|
|
99
|
+
: 'absent';
|
|
100
|
+
} catch (error) {
|
|
101
|
+
if (error?.code === 'ENOENT') return 'absent';
|
|
102
|
+
return 'unreadable';
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export async function inspectMuseNative(options = {}) {
|
|
107
|
+
return {
|
|
108
|
+
cli: inspectMuseCli(options.env || process.env),
|
|
109
|
+
hooks: await inspectMuseHooks(options.projectDir || process.cwd()),
|
|
110
|
+
mcp: await inspectMuseMcp(options),
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export async function isMuseDeployedProject(projectDir = process.cwd()) {
|
|
115
|
+
try {
|
|
116
|
+
const raw = await readFile(join(projectDir, '.aiwg', 'aiwg.config'), 'utf8');
|
|
117
|
+
const config = parseJson(raw);
|
|
118
|
+
if (Array.isArray(config?.providers) && config.providers.includes('muse')) return true;
|
|
119
|
+
return Object.values(config?.installed || {}).some((entry) => entry?.deployedTo?.muse);
|
|
120
|
+
} catch {
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { mcpError, mcpJson } from '../helpers.mjs';
|
|
3
|
+
|
|
4
|
+
const STATUS = z.enum(['success', 'abstained', 'denied', 'unavailable', 'error', 'cancelled']);
|
|
5
|
+
const ENVELOPE = z.object({ schema: z.string() }).passthrough();
|
|
6
|
+
const LIVE_PLAN = z.object({ mode: z.literal('live'), status: z.enum(['ready', 'skipped', 'denied']), reason: z.string(), executes: z.literal(false) }).passthrough();
|
|
7
|
+
const PATTERN_SUMMARY = z.object({
|
|
8
|
+
id: z.string(),
|
|
9
|
+
version: z.string(),
|
|
10
|
+
status: z.string(),
|
|
11
|
+
primitive: z.string().optional(),
|
|
12
|
+
}).passthrough();
|
|
13
|
+
const PATTERN_LIST = z.object({
|
|
14
|
+
schema: z.literal('aiwg-decision-pattern-list/v1'),
|
|
15
|
+
patterns: z.array(PATTERN_SUMMARY),
|
|
16
|
+
}).passthrough();
|
|
17
|
+
const PATTERN_SHOW = z.object({
|
|
18
|
+
schema: z.literal('aiwg-decision-pattern-show/v1'),
|
|
19
|
+
pack: PATTERN_SUMMARY,
|
|
20
|
+
inputSchema: z.unknown(),
|
|
21
|
+
outputSchema: z.unknown(),
|
|
22
|
+
livePlan: LIVE_PLAN,
|
|
23
|
+
}).passthrough();
|
|
24
|
+
const COMPACT_EVALUATION = z.object({
|
|
25
|
+
status: STATUS,
|
|
26
|
+
reason: z.string(),
|
|
27
|
+
attempts: z.number(),
|
|
28
|
+
value: z.unknown().nullable(),
|
|
29
|
+
}).passthrough();
|
|
30
|
+
const COMPACT_RESULT = z.object({
|
|
31
|
+
status: STATUS,
|
|
32
|
+
rulesetStatus: z.string(),
|
|
33
|
+
reason: z.string(),
|
|
34
|
+
matchedRules: z.array(z.string()),
|
|
35
|
+
evaluations: z.record(z.string(), COMPACT_EVALUATION),
|
|
36
|
+
outcome: z.unknown().nullable(),
|
|
37
|
+
}).passthrough();
|
|
38
|
+
const EVALUATE = z.object({
|
|
39
|
+
schema: z.literal('aiwg-decision-evaluate/v1'),
|
|
40
|
+
status: STATUS,
|
|
41
|
+
reason: z.string(),
|
|
42
|
+
exitCode: z.number(),
|
|
43
|
+
compact: COMPACT_RESULT.nullable().optional(),
|
|
44
|
+
result: z.unknown().nullable(),
|
|
45
|
+
}).passthrough();
|
|
46
|
+
const VALIDATION = z.object({
|
|
47
|
+
schema: z.literal('aiwg-decision-validation/v1'),
|
|
48
|
+
target: z.enum(['request', 'definition', 'ruleset', 'binding']),
|
|
49
|
+
valid: z.boolean(),
|
|
50
|
+
summary: z.object({
|
|
51
|
+
kind: z.string().nullable().optional(),
|
|
52
|
+
apiVersion: z.string().nullable().optional(),
|
|
53
|
+
id: z.string().nullable().optional(),
|
|
54
|
+
version: z.string().nullable().optional(),
|
|
55
|
+
}).passthrough(),
|
|
56
|
+
errors: z.array(z.string()),
|
|
57
|
+
}).passthrough();
|
|
58
|
+
const CAPABILITIES = z.object({
|
|
59
|
+
schema: z.literal('aiwg-decision-driver-capabilities/v1'),
|
|
60
|
+
enabled: z.boolean(),
|
|
61
|
+
offlineReady: z.boolean(),
|
|
62
|
+
primitives: z.array(z.string()),
|
|
63
|
+
backend: z.object({ configured: z.boolean(), probed: z.boolean(), status: z.literal('not-probed') }).passthrough(),
|
|
64
|
+
}).passthrough();
|
|
65
|
+
const OFFLINE_RUN = z.object({
|
|
66
|
+
schema: z.literal('aiwg-decision-offline-run/v1'),
|
|
67
|
+
status: STATUS,
|
|
68
|
+
route: z.enum(['accept', 'review', 'deny']),
|
|
69
|
+
reason: z.string(),
|
|
70
|
+
evaluations: z.array(z.object({
|
|
71
|
+
alias: z.string(),
|
|
72
|
+
primitive: z.string(),
|
|
73
|
+
status: z.string(),
|
|
74
|
+
reason: z.string(),
|
|
75
|
+
attempts: z.number(),
|
|
76
|
+
value: z.unknown(),
|
|
77
|
+
}).passthrough()),
|
|
78
|
+
checks: z.array(z.unknown()),
|
|
79
|
+
}).passthrough();
|
|
80
|
+
const SYNTHETIC_SETUP = z.object({
|
|
81
|
+
schema: z.literal('aiwg-decision-synthetic-setup/v1'),
|
|
82
|
+
pattern: z.object({ id: z.string(), version: z.string() }).passthrough(),
|
|
83
|
+
files: z.record(z.string(), z.unknown()),
|
|
84
|
+
}).passthrough();
|
|
85
|
+
|
|
86
|
+
let driverPromise;
|
|
87
|
+
|
|
88
|
+
async function driver() {
|
|
89
|
+
driverPromise ??= import('../../decision/driver.js');
|
|
90
|
+
return driverPromise;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function options() {
|
|
94
|
+
return { cwd: process.cwd(), env: process.env };
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function registerJsonTool(server, name, config, handler, output = ENVELOPE) {
|
|
98
|
+
server.registerTool(name, {
|
|
99
|
+
outputSchema: { result: output },
|
|
100
|
+
...config,
|
|
101
|
+
}, async (args) => {
|
|
102
|
+
try {
|
|
103
|
+
const result = await handler(args);
|
|
104
|
+
return {
|
|
105
|
+
...mcpJson(result),
|
|
106
|
+
structuredContent: { result },
|
|
107
|
+
};
|
|
108
|
+
} catch (error) {
|
|
109
|
+
return mcpError(`${name}: ${error.message}`);
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export function registerDecisionToolset(server) {
|
|
115
|
+
registerJsonTool(server, 'decision-capabilities', {
|
|
116
|
+
title: 'Decision runtime capabilities',
|
|
117
|
+
description: 'Show offline readiness, primitives, experimental features and configured named request profiles.',
|
|
118
|
+
inputSchema: {},
|
|
119
|
+
annotations: { readOnlyHint: true },
|
|
120
|
+
}, async () => (await driver()).decisionCapabilities(options()), CAPABILITIES);
|
|
121
|
+
|
|
122
|
+
registerJsonTool(server, 'decision-patterns-list', {
|
|
123
|
+
title: 'List decision patterns',
|
|
124
|
+
description: 'List governed decision pattern packs.',
|
|
125
|
+
inputSchema: {},
|
|
126
|
+
annotations: { readOnlyHint: true },
|
|
127
|
+
}, async () => (await driver()).listPatterns(), PATTERN_LIST);
|
|
128
|
+
|
|
129
|
+
registerJsonTool(server, 'decision-pattern-show', {
|
|
130
|
+
title: 'Show decision pattern',
|
|
131
|
+
description: 'Show one pattern pack, schemas and disabled-by-default live plan.',
|
|
132
|
+
inputSchema: { id: z.string().describe('Decision pattern id') },
|
|
133
|
+
annotations: { readOnlyHint: true },
|
|
134
|
+
}, async ({ id }) => (await driver()).showPattern(id), PATTERN_SHOW);
|
|
135
|
+
|
|
136
|
+
registerJsonTool(server, 'decision-pattern-offline-run', {
|
|
137
|
+
title: 'Run offline decision pattern fixture',
|
|
138
|
+
description: 'Run a recorded offline fixture through the production decision runtime.',
|
|
139
|
+
inputSchema: { id: z.string(), fixture_id: z.string().optional() },
|
|
140
|
+
annotations: { readOnlyHint: true },
|
|
141
|
+
}, async ({ id, fixture_id }) => (await driver()).runOfflinePattern(id, fixture_id), OFFLINE_RUN);
|
|
142
|
+
|
|
143
|
+
registerJsonTool(server, 'decision-pattern-live-plan', {
|
|
144
|
+
title: 'Plan live decision pattern',
|
|
145
|
+
description: 'Report whether an explicitly opted-in synthetic live pattern would be ready; does not execute.',
|
|
146
|
+
inputSchema: {
|
|
147
|
+
id: z.string(),
|
|
148
|
+
explicit_opt_in: z.boolean().default(false),
|
|
149
|
+
credential_resolved: z.boolean().default(false),
|
|
150
|
+
egress_approved: z.boolean().default(false),
|
|
151
|
+
},
|
|
152
|
+
annotations: { readOnlyHint: true },
|
|
153
|
+
}, async ({ id, explicit_opt_in, credential_resolved, egress_approved }) => (await driver()).livePlan(id, {
|
|
154
|
+
explicitOptIn: explicit_opt_in,
|
|
155
|
+
credentialResolved: credential_resolved,
|
|
156
|
+
egressApproved: egress_approved,
|
|
157
|
+
}), LIVE_PLAN);
|
|
158
|
+
|
|
159
|
+
registerJsonTool(server, 'decision-validate', {
|
|
160
|
+
title: 'Validate decision artifact',
|
|
161
|
+
description: 'Validate a request, definition, ruleset or binding without importing modules or resolving secrets.',
|
|
162
|
+
inputSchema: {
|
|
163
|
+
target: z.enum(['request', 'definition', 'ruleset', 'binding']),
|
|
164
|
+
document: z.unknown().describe('Inline decision document or dispatcher request object'),
|
|
165
|
+
},
|
|
166
|
+
annotations: { readOnlyHint: true },
|
|
167
|
+
}, async ({ target, document }) => (await driver()).validateDecisionValue(target, document, 'mcp-inline'), VALIDATION);
|
|
168
|
+
|
|
169
|
+
registerJsonTool(server, 'decision-evaluate-profile', {
|
|
170
|
+
title: 'Evaluate named decision request profile',
|
|
171
|
+
description: 'Evaluate a server-configured named request profile only when env and per-call opt-in are present.',
|
|
172
|
+
inputSchema: {
|
|
173
|
+
profile: z.string().describe('Profile name from AIWG_DECISION_MCP_REQUESTS'),
|
|
174
|
+
opt_in: z.boolean().default(false).describe('Required per-call opt-in'),
|
|
175
|
+
},
|
|
176
|
+
annotations: { readOnlyHint: false, destructiveHint: false, openWorldHint: true },
|
|
177
|
+
}, async ({ profile, opt_in }) => (await driver()).evaluateMcpProfile(profile, opt_in, options()), EVALUATE);
|
|
178
|
+
|
|
179
|
+
registerJsonTool(server, 'decision-setup-synthetic-classification', {
|
|
180
|
+
title: 'Prepare synthetic classification artifacts',
|
|
181
|
+
description: 'Return reviewable pinned synthetic classification artifacts and a dispatcher request.',
|
|
182
|
+
inputSchema: {
|
|
183
|
+
allowed_options: z.array(z.string()).min(1).optional(),
|
|
184
|
+
text: z.string().optional(),
|
|
185
|
+
},
|
|
186
|
+
annotations: { readOnlyHint: true },
|
|
187
|
+
}, async ({ allowed_options, text }) => (await driver()).syntheticClassificationSetup({ allowedOptions: allowed_options, text }, options()), SYNTHETIC_SETUP);
|
|
188
|
+
}
|
|
@@ -18,6 +18,7 @@ import { z } from 'zod';
|
|
|
18
18
|
import { runAiwgCli, mcpError, mcpJson } from '../helpers.mjs';
|
|
19
19
|
import { registerFlowToolset, registerMissionToolset } from './orchestration.mjs';
|
|
20
20
|
import { registerAgenticSandboxToolset } from './agentic-sandbox.mjs';
|
|
21
|
+
import { registerDecisionToolset } from './decision.mjs';
|
|
21
22
|
|
|
22
23
|
/**
|
|
23
24
|
* Wrap an `aiwg <subsystem> <verb>` CLI call as an MCP tool.
|
|
@@ -588,6 +589,7 @@ const TOOLSET_REGISTRY = {
|
|
|
588
589
|
mc: registerMcToolset,
|
|
589
590
|
ops: registerOpsToolset,
|
|
590
591
|
sandbox: registerAgenticSandboxToolset,
|
|
592
|
+
decision: registerDecisionToolset,
|
|
591
593
|
};
|
|
592
594
|
|
|
593
595
|
/**
|
|
@@ -488,12 +488,13 @@ providers:
|
|
|
488
488
|
|
|
489
489
|
muse:
|
|
490
490
|
display_name: Muse Code
|
|
491
|
-
status:
|
|
491
|
+
status: stable
|
|
492
492
|
# Meta's terminal/CI coding agent (Muse Spark-powered). Explicitly not a
|
|
493
493
|
# model-API surface: Glimmer/Image/Voice are out of scope.
|
|
494
494
|
# Skill writer (.agents/skills + XDG user root), discover-first AGENTS.md
|
|
495
495
|
# bridge, managed .muse/hooks.json, and opt-in MCP settings profile.
|
|
496
496
|
# ADR: docs/architecture/adr-muse-provider-target.md · epic #223.
|
|
497
|
+
# #231: promoted stable — Linux PUW + security review; maintainer Linux-only waiver 2026-10-02.
|
|
497
498
|
daemon_tier: unsupported
|
|
498
499
|
daemon_pty_adapter: false
|
|
499
500
|
artifact_paths:
|
|
@@ -783,7 +783,8 @@ const BUILT_IN_SEEDS = [
|
|
|
783
783
|
displayName: 'Muse Code',
|
|
784
784
|
// #225: ADR fixes the canonical id as `muse` with no aliases.
|
|
785
785
|
aliases: [],
|
|
786
|
-
|
|
786
|
+
// #231: promoted stable — Linux PUW + security review; maintainer Linux-only waiver 2026-10-02.
|
|
787
|
+
status: 'stable',
|
|
787
788
|
builtIn: true,
|
|
788
789
|
surfaces: {
|
|
789
790
|
primary: 'muse',
|