@groundnuty/macf 0.2.36 → 0.2.38
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/dist/.build-info.json +2 -2
- package/dist/cli/claude-sh.d.ts +12 -10
- package/dist/cli/claude-sh.d.ts.map +1 -1
- package/dist/cli/claude-sh.js +13 -11
- package/dist/cli/claude-sh.js.map +1 -1
- package/dist/cli/commands/certs.d.ts.map +1 -1
- package/dist/cli/commands/certs.js +6 -2
- package/dist/cli/commands/certs.js.map +1 -1
- package/dist/cli/commands/doctor.d.ts +102 -3
- package/dist/cli/commands/doctor.d.ts.map +1 -1
- package/dist/cli/commands/doctor.js +349 -55
- package/dist/cli/commands/doctor.js.map +1 -1
- package/dist/cli/commands/init.d.ts +24 -0
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +81 -8
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/monitor.d.ts +16 -0
- package/dist/cli/commands/monitor.d.ts.map +1 -0
- package/dist/cli/commands/monitor.js +96 -0
- package/dist/cli/commands/monitor.js.map +1 -0
- package/dist/cli/commands/propose.d.ts +21 -0
- package/dist/cli/commands/propose.d.ts.map +1 -0
- package/dist/cli/commands/propose.js +128 -0
- package/dist/cli/commands/propose.js.map +1 -0
- package/dist/cli/commands/ps.d.ts +17 -0
- package/dist/cli/commands/ps.d.ts.map +1 -0
- package/dist/cli/commands/ps.js +69 -0
- package/dist/cli/commands/ps.js.map +1 -0
- package/dist/cli/commands/registry-prune.d.ts +44 -0
- package/dist/cli/commands/registry-prune.d.ts.map +1 -0
- package/dist/cli/commands/registry-prune.js +124 -0
- package/dist/cli/commands/registry-prune.js.map +1 -0
- package/dist/cli/commands/rules-refresh.d.ts +1 -0
- package/dist/cli/commands/rules-refresh.d.ts.map +1 -1
- package/dist/cli/commands/rules-refresh.js +22 -1
- package/dist/cli/commands/rules-refresh.js.map +1 -1
- package/dist/cli/commands/update.d.ts.map +1 -1
- package/dist/cli/commands/update.js +23 -2
- package/dist/cli/commands/update.js.map +1 -1
- package/dist/cli/config.d.ts +2 -0
- package/dist/cli/config.d.ts.map +1 -1
- package/dist/cli/config.js +16 -0
- package/dist/cli/config.js.map +1 -1
- package/dist/cli/env-files-update.d.ts.map +1 -1
- package/dist/cli/env-files-update.js +5 -1
- package/dist/cli/env-files-update.js.map +1 -1
- package/dist/cli/env-files.d.ts +38 -13
- package/dist/cli/env-files.d.ts.map +1 -1
- package/dist/cli/env-files.js +84 -14
- package/dist/cli/env-files.js.map +1 -1
- package/dist/cli/index.js +142 -5
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/monitor/digest.d.ts +89 -0
- package/dist/cli/monitor/digest.d.ts.map +1 -0
- package/dist/cli/monitor/digest.js +232 -0
- package/dist/cli/monitor/digest.js.map +1 -0
- package/dist/cli/monitor/github-reader.d.ts +38 -0
- package/dist/cli/monitor/github-reader.d.ts.map +1 -0
- package/dist/cli/monitor/github-reader.js +65 -0
- package/dist/cli/monitor/github-reader.js.map +1 -0
- package/dist/cli/monitor/reflections.d.ts +18 -0
- package/dist/cli/monitor/reflections.d.ts.map +1 -0
- package/dist/cli/monitor/reflections.js +72 -0
- package/dist/cli/monitor/reflections.js.map +1 -0
- package/dist/cli/monitor/run.d.ts +30 -0
- package/dist/cli/monitor/run.d.ts.map +1 -0
- package/dist/cli/monitor/run.js +67 -0
- package/dist/cli/monitor/run.js.map +1 -0
- package/dist/cli/proc-scan.d.ts +81 -0
- package/dist/cli/proc-scan.d.ts.map +1 -0
- package/dist/cli/proc-scan.js +172 -0
- package/dist/cli/proc-scan.js.map +1 -0
- package/dist/cli/project-rules.d.ts +105 -0
- package/dist/cli/project-rules.d.ts.map +1 -0
- package/dist/cli/project-rules.js +305 -0
- package/dist/cli/project-rules.js.map +1 -0
- package/dist/cli/propose/candidates.d.ts +95 -0
- package/dist/cli/propose/candidates.d.ts.map +1 -0
- package/dist/cli/propose/candidates.js +117 -0
- package/dist/cli/propose/candidates.js.map +1 -0
- package/dist/cli/propose/invariants.d.ts +49 -0
- package/dist/cli/propose/invariants.d.ts.map +1 -0
- package/dist/cli/propose/invariants.js +154 -0
- package/dist/cli/propose/invariants.js.map +1 -0
- package/dist/cli/propose/proposal-writer.d.ts +33 -0
- package/dist/cli/propose/proposal-writer.d.ts.map +1 -0
- package/dist/cli/propose/proposal-writer.js +53 -0
- package/dist/cli/propose/proposal-writer.js.map +1 -0
- package/dist/cli/propose/report.d.ts +49 -0
- package/dist/cli/propose/report.d.ts.map +1 -0
- package/dist/cli/propose/report.js +227 -0
- package/dist/cli/propose/report.js.map +1 -0
- package/dist/cli/propose/run.d.ts +41 -0
- package/dist/cli/propose/run.d.ts.map +1 -0
- package/dist/cli/propose/run.js +62 -0
- package/dist/cli/propose/run.js.map +1 -0
- package/dist/cli/role-settings-model.d.ts +70 -0
- package/dist/cli/role-settings-model.d.ts.map +1 -0
- package/dist/cli/role-settings-model.js +90 -0
- package/dist/cli/role-settings-model.js.map +1 -0
- package/dist/cli/settings-writer.d.ts +103 -6
- package/dist/cli/settings-writer.d.ts.map +1 -1
- package/dist/cli/settings-writer.js +259 -8
- package/dist/cli/settings-writer.js.map +1 -1
- package/dist/reconciler/reconcile.d.ts +31 -0
- package/dist/reconciler/reconcile.d.ts.map +1 -1
- package/dist/reconciler/reconcile.js +47 -3
- package/dist/reconciler/reconcile.js.map +1 -1
- package/dist/reconciler/run.d.ts +21 -1
- package/dist/reconciler/run.d.ts.map +1 -1
- package/dist/reconciler/run.js +106 -17
- package/dist/reconciler/run.js.map +1 -1
- package/package.json +2 -2
- package/plugin/rules/gh-token-attribution-traps.md +4 -0
- package/plugin/rules/observability-wiring.md +3 -3
- package/plugin/rules/reflection-staging.md +65 -0
- package/plugin/rules/silent-fallback-hazards.md +21 -4
- package/scripts/check-auditor-never-acts.sh +167 -0
- package/scripts/check-gh-attribution.sh +254 -0
- package/scripts/emit-turn-receipt.sh +1 -1
- package/scripts/harvest-reflection.sh +125 -0
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure formatters for the auditor Plan membrane (groundnuty/macf#503, DR-026 G1).
|
|
3
|
+
*
|
|
4
|
+
* Two outputs, both deterministic (no I/O, no clock):
|
|
5
|
+
* - `buildProposalBody` — the Markdown body of ONE ratifiable proposal issue,
|
|
6
|
+
* assembled from the AGENT-AUTHORED signal content (signal text + rationales)
|
|
7
|
+
* plus the mechanical metadata (tier, route, distinct-agent corroboration,
|
|
8
|
+
* invariant touchpoints, HIGH-RISK flag).
|
|
9
|
+
* - `buildReport` — the dry-run Markdown report printed to stdout/--output: the
|
|
10
|
+
* promoted candidates (each rendered as a proposal preview) PLUS a separate,
|
|
11
|
+
* visible "HELD (N<threshold)" section. The default mode opens NOTHING; this
|
|
12
|
+
* report IS the default-mode artifact.
|
|
13
|
+
*
|
|
14
|
+
* Every proposal makes its non-actuation explicit: the operator ratifies; the
|
|
15
|
+
* auditor never merges/applies (invariants #8 + #9).
|
|
16
|
+
*/
|
|
17
|
+
import { PROPOSAL_LABEL } from './proposal-writer.js';
|
|
18
|
+
/** Human-readable route label for the report + body. */
|
|
19
|
+
function routeLabel(route) {
|
|
20
|
+
switch (route) {
|
|
21
|
+
case 'needs-confirmation':
|
|
22
|
+
return 'NEEDS-CONFIRMATION (universal/canonical — never auto-routed)';
|
|
23
|
+
case 'project-draft':
|
|
24
|
+
return 'project-rule draft';
|
|
25
|
+
case 'review':
|
|
26
|
+
return 'operator review (unrecognised tier hint)';
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/** A short, stable proposal title from the candidate. */
|
|
30
|
+
export function proposalTitle(c) {
|
|
31
|
+
const flag = c.highRisk ? '[HIGH-RISK] ' : '';
|
|
32
|
+
const oneLine = c.signal.replace(/\s+/g, ' ').trim();
|
|
33
|
+
const truncated = oneLine.length > 90 ? `${oneLine.slice(0, 87)}…` : oneLine;
|
|
34
|
+
return `auditor-proposal: ${flag}${truncated}`;
|
|
35
|
+
}
|
|
36
|
+
/** Render the invariant-touchpoints block (SURFACED — never a drop). */
|
|
37
|
+
function invariantBlock(c) {
|
|
38
|
+
const lines = [];
|
|
39
|
+
lines.push('## Subordination check (protected invariants)');
|
|
40
|
+
lines.push('');
|
|
41
|
+
if (c.invariantTouches.length === 0) {
|
|
42
|
+
lines.push('_No protected invariant appears to be touched (heuristic match)._');
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
lines.push('This candidate plausibly TOUCHES the following protected invariant(s). ' +
|
|
46
|
+
'Touched ≠ rejected: `protected-invariants.md` permits the auditor to ' +
|
|
47
|
+
'*propose* an operator-ratified amendment, so this is SURFACED for the ' +
|
|
48
|
+
'operator to judge weaken-vs-amend — it is never auto-dropped (DR-026 G1).');
|
|
49
|
+
lines.push('');
|
|
50
|
+
for (const t of c.invariantTouches) {
|
|
51
|
+
lines.push(`- **#${t.index} ${t.title}** (matched: ${t.matchedKeywords.join(', ')})`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
lines.push('');
|
|
55
|
+
if (c.highRisk) {
|
|
56
|
+
lines.push('> **HIGH-RISK — apparent relaxation.** The candidate text reads like it ' +
|
|
57
|
+
'WEAKENS a touched invariant. An invariant-weakening proposal is wrong by ' +
|
|
58
|
+
'construction (reject at ratification) UNLESS it is a deliberate ' +
|
|
59
|
+
'constitutional amendment — route it as one. The operator distinguishes ' +
|
|
60
|
+
'(v1-manual; the automated weaken-vs-amend call is DR-026 G3).');
|
|
61
|
+
lines.push('');
|
|
62
|
+
}
|
|
63
|
+
return lines;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Build the Markdown body for one ratifiable proposal issue. Pure assembly of
|
|
67
|
+
* agent-authored content + mechanical metadata; no LLM judgment is encoded.
|
|
68
|
+
*/
|
|
69
|
+
export function buildProposalBody(c) {
|
|
70
|
+
const lines = [];
|
|
71
|
+
lines.push('> **Auditor proposal (DR-026 G1).** Generated by `macf propose` ' +
|
|
72
|
+
'from corroborated F2 reflection signals. The auditor PROPOSES only — the ' +
|
|
73
|
+
'operator ratifies. This issue is **never auto-merged or auto-applied** ' +
|
|
74
|
+
'(invariants #8 auditor-never-acts + #9 operator-as-ratifier).');
|
|
75
|
+
lines.push('');
|
|
76
|
+
lines.push('## Proposed rule signal');
|
|
77
|
+
lines.push('');
|
|
78
|
+
lines.push(c.signal.trim());
|
|
79
|
+
lines.push('');
|
|
80
|
+
lines.push('## Tier + routing');
|
|
81
|
+
lines.push('');
|
|
82
|
+
lines.push(`- Proposed tier (agent hint): \`${c.proposedTier}\``);
|
|
83
|
+
lines.push(`- Routing: ${routeLabel(c.route)}`);
|
|
84
|
+
lines.push(`- Dedup handle: \`${c.handle}\`${c.hasKey ? ' (explicit key)' : ' (from signal text)'}`);
|
|
85
|
+
lines.push('');
|
|
86
|
+
lines.push('## Corroboration (GATE 1 — distinct agents)');
|
|
87
|
+
lines.push('');
|
|
88
|
+
lines.push(`- Distinct agents: **${c.distinctAgents}** ` +
|
|
89
|
+
`(${c.corroboratingAgents.join(', ')})`);
|
|
90
|
+
lines.push(`- Raw occurrences: ${c.occurrences}`);
|
|
91
|
+
lines.push('- Promotability is gated on DISTINCT AGENTS, not occurrences: ' +
|
|
92
|
+
'one agent reflecting N times is N=1 (reflection ≠ verification).');
|
|
93
|
+
lines.push('');
|
|
94
|
+
lines.push('## Rationale (agent-authored)');
|
|
95
|
+
lines.push('');
|
|
96
|
+
if (c.rationales.length === 0) {
|
|
97
|
+
lines.push('_No rationale supplied in the reflection signal(s)._');
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
for (const r of c.rationales) {
|
|
101
|
+
lines.push(`- ${r.trim()}`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
lines.push('');
|
|
105
|
+
lines.push(...invariantBlock(c));
|
|
106
|
+
lines.push('---');
|
|
107
|
+
lines.push('');
|
|
108
|
+
lines.push('_Ratification is the operator\'s. To accept: distil into the appropriate ' +
|
|
109
|
+
'rule tier via a PR (universal → upstream; project → local project rule), ' +
|
|
110
|
+
'review + merge per `pr-discipline`. To reject: close with rationale. ' +
|
|
111
|
+
'A touched/HIGH-RISK invariant is an operator judgment call, not an ' +
|
|
112
|
+
'auto-drop (DR-026 G1; weaken-vs-amend automation is G3)._');
|
|
113
|
+
return lines.join('\n') + '\n';
|
|
114
|
+
}
|
|
115
|
+
/** Build the full `ProposalIssueInput` (title + body + labels) for a candidate. */
|
|
116
|
+
export function buildProposalIssueInput(repo, c) {
|
|
117
|
+
const labels = [PROPOSAL_LABEL];
|
|
118
|
+
if (c.route === 'needs-confirmation')
|
|
119
|
+
labels.push('needs-confirmation');
|
|
120
|
+
if (c.highRisk)
|
|
121
|
+
labels.push('high-risk');
|
|
122
|
+
return {
|
|
123
|
+
repo,
|
|
124
|
+
title: proposalTitle(c),
|
|
125
|
+
body: buildProposalBody(c),
|
|
126
|
+
labels,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
/** Render one promoted candidate as a compact preview in the report. */
|
|
130
|
+
function candidatePreview(c) {
|
|
131
|
+
const lines = [];
|
|
132
|
+
const flag = c.highRisk ? ' **[HIGH-RISK]**' : '';
|
|
133
|
+
lines.push(`### ${proposalTitle(c)}${flag}`);
|
|
134
|
+
lines.push('');
|
|
135
|
+
lines.push(`- Tier hint: \`${c.proposedTier}\` → ${routeLabel(c.route)}`);
|
|
136
|
+
lines.push(`- Distinct agents: **${c.distinctAgents}** ` +
|
|
137
|
+
`(${c.corroboratingAgents.join(', ')}) | occurrences: ${c.occurrences}`);
|
|
138
|
+
if (c.invariantTouches.length > 0) {
|
|
139
|
+
const list = c.invariantTouches.map((t) => `#${t.index} ${t.title}`).join('; ');
|
|
140
|
+
lines.push(`- Touches invariant(s): ${list} _(surfaced, not dropped)_`);
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
lines.push('- Touches invariant(s): none detected');
|
|
144
|
+
}
|
|
145
|
+
lines.push('- Signal:');
|
|
146
|
+
lines.push('');
|
|
147
|
+
for (const ln of c.signal.trim().split('\n')) {
|
|
148
|
+
lines.push(` > ${ln}`);
|
|
149
|
+
}
|
|
150
|
+
lines.push('');
|
|
151
|
+
return lines;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Build the dry-run Markdown report. Promoted candidates render as previews; the
|
|
155
|
+
* HELD set renders in its own clearly-labelled section so a sub-threshold
|
|
156
|
+
* candidate is VISIBLE, never silently dropped.
|
|
157
|
+
*/
|
|
158
|
+
export function buildReport(input) {
|
|
159
|
+
const { candidates } = input;
|
|
160
|
+
const lines = [];
|
|
161
|
+
lines.push(`# Auditor proposal report — ${input.project}`);
|
|
162
|
+
lines.push('');
|
|
163
|
+
lines.push(`- Repo: \`${input.repo}\``);
|
|
164
|
+
lines.push(`- Min distinct agents (GATE 1 threshold): ${candidates.minAgents}`);
|
|
165
|
+
lines.push(`- Mode: ${input.fileMode ? '**--file (artifacts opened)**' : '**dry-run (default — opens nothing)**'}`);
|
|
166
|
+
if (!input.invariantsLoaded) {
|
|
167
|
+
lines.push('- ⚠ `design/protected-invariants.md` not found — subordination-check ' +
|
|
168
|
+
'surfaced no invariants (loud-but-proceeds).');
|
|
169
|
+
}
|
|
170
|
+
lines.push(`- Reflection records: ${input.reflectionRecords} across ` +
|
|
171
|
+
`${input.reflectionFiles} ledger file(s) ` +
|
|
172
|
+
`(skipped malformed: ${input.reflectionsSkipped})`);
|
|
173
|
+
lines.push('');
|
|
174
|
+
lines.push('> The auditor PROPOSES only (DR-026 G1). Candidates below are corroborated ' +
|
|
175
|
+
'across distinct agents; HELD candidates fell below the distinct-agent ' +
|
|
176
|
+
'threshold. Nothing is auto-applied — the operator ratifies (invariants ' +
|
|
177
|
+
'#8 + #9).');
|
|
178
|
+
lines.push('');
|
|
179
|
+
// --- Promoted candidates ---
|
|
180
|
+
lines.push('## Candidate proposals (promoted)');
|
|
181
|
+
lines.push('');
|
|
182
|
+
if (candidates.promoted.length === 0) {
|
|
183
|
+
lines.push('_No candidate cleared the distinct-agent threshold._');
|
|
184
|
+
lines.push('');
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
for (const c of candidates.promoted) {
|
|
188
|
+
lines.push(...candidatePreview(c));
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
// --- HELD section (visible, never silently dropped) ---
|
|
192
|
+
lines.push(`## HELD (N < ${candidates.minAgents} distinct agents)`);
|
|
193
|
+
lines.push('');
|
|
194
|
+
lines.push('_These signals are real but under-corroborated — held, NOT dropped. ' +
|
|
195
|
+
'Reflection ≠ verification: one agent reflecting repeatedly is still N=1._');
|
|
196
|
+
lines.push('');
|
|
197
|
+
if (candidates.held.length === 0) {
|
|
198
|
+
lines.push('_None._');
|
|
199
|
+
lines.push('');
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
for (const h of candidates.held) {
|
|
203
|
+
const dedup = h.hasKey ? ` [key: \`${h.handle}\`]` : '';
|
|
204
|
+
lines.push(`- (\`${h.proposedTier}\`) ${h.signal.replace(/\s+/g, ' ').trim()}${dedup} ` +
|
|
205
|
+
`— ${h.distinctAgents} distinct agent(s), ${h.occurrences} occurrence(s)`);
|
|
206
|
+
}
|
|
207
|
+
lines.push('');
|
|
208
|
+
}
|
|
209
|
+
// --- Summary ---
|
|
210
|
+
lines.push('## Summary');
|
|
211
|
+
lines.push('');
|
|
212
|
+
lines.push(`- Promoted: ${candidates.promoted.length}`);
|
|
213
|
+
lines.push(`- Held (N<${candidates.minAgents}): ${candidates.held.length}`);
|
|
214
|
+
const highRisk = candidates.promoted.filter((c) => c.highRisk).length;
|
|
215
|
+
const needsConfirm = candidates.promoted.filter((c) => c.route === 'needs-confirmation').length;
|
|
216
|
+
lines.push(`- HIGH-RISK (apparent invariant relaxation): ${highRisk}`);
|
|
217
|
+
lines.push(`- NEEDS-CONFIRMATION (universal/canonical): ${needsConfirm}`);
|
|
218
|
+
lines.push('');
|
|
219
|
+
lines.push(input.fileMode
|
|
220
|
+
? `> \`--file\` mode: ${candidates.promoted.length} ratifiable ` +
|
|
221
|
+
`\`${PROPOSAL_LABEL}\` issue(s) opened (create-only; never merged/closed/edited). ` +
|
|
222
|
+
'The operator ratifies.'
|
|
223
|
+
: '> Dry-run: NOTHING was opened. Re-run with `--file` to open one ratifiable ' +
|
|
224
|
+
`\`${PROPOSAL_LABEL}\` issue per promoted candidate (create-only).`);
|
|
225
|
+
return lines.join('\n').replace(/\n{3,}/g, '\n\n') + '\n';
|
|
226
|
+
}
|
|
227
|
+
//# sourceMappingURL=report.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report.js","sourceRoot":"","sources":["../../../src/cli/propose/report.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { ProposalIssueWriter } from './proposal-writer.js';
|
|
2
|
+
export interface RunProposeOptions {
|
|
3
|
+
readonly project: string;
|
|
4
|
+
readonly repo: string;
|
|
5
|
+
/** Directory holding the F2 reflection JSONL ledgers. */
|
|
6
|
+
readonly reflectionsDir: string;
|
|
7
|
+
/**
|
|
8
|
+
* Framework-source repo root where `design/protected-invariants.md` lives.
|
|
9
|
+
* The subordination-check surfaces against this set; absence is loud-but-proceeds.
|
|
10
|
+
*/
|
|
11
|
+
readonly repoRoot: string;
|
|
12
|
+
/** Distinct-agent threshold for GATE 1 (default `DEFAULT_MIN_AGENTS`). */
|
|
13
|
+
readonly minAgents?: number;
|
|
14
|
+
/** When true, OPEN ratifiable artifacts via the writer. Default false (dry-run). */
|
|
15
|
+
readonly fileMode: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Create-only writer seam. REQUIRED when `fileMode` is true; ignored in
|
|
18
|
+
* dry-run (and must never be invoked there — GATE 2).
|
|
19
|
+
*/
|
|
20
|
+
readonly writer?: ProposalIssueWriter;
|
|
21
|
+
}
|
|
22
|
+
/** What a single `--file` create produced (or the error that aborted it). */
|
|
23
|
+
export interface CreatedProposal {
|
|
24
|
+
readonly title: string;
|
|
25
|
+
readonly url: string;
|
|
26
|
+
}
|
|
27
|
+
export interface RunProposeResult {
|
|
28
|
+
/** The Markdown report (always produced, in both modes). */
|
|
29
|
+
readonly report: string;
|
|
30
|
+
/** Issues opened in `--file` mode (empty in dry-run). */
|
|
31
|
+
readonly created: readonly CreatedProposal[];
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Run the Plan membrane. Returns the report + any created proposals.
|
|
35
|
+
*
|
|
36
|
+
* Read side is pure filesystem; the only write path is the injected writer,
|
|
37
|
+
* gated behind `fileMode` (GATE 2). A writer failure surfaces as a thrown error
|
|
38
|
+
* to the caller (the CLI command), which decides how to report it.
|
|
39
|
+
*/
|
|
40
|
+
export declare function runPropose(opts: RunProposeOptions): Promise<RunProposeResult>;
|
|
41
|
+
//# sourceMappingURL=run.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/cli/propose/run.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAEhE,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,yDAAyD;IACzD,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,0EAA0E;IAC1E,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,oFAAoF;IACpF,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,mBAAmB,CAAC;CACvC;AAED,6EAA6E;AAC7E,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,4DAA4D;IAC5D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,yDAAyD;IACzD,QAAQ,CAAC,OAAO,EAAE,SAAS,eAAe,EAAE,CAAC;CAC9C;AAED;;;;;;GAMG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAqCnF"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plan-membrane orchestrator for the auditor (groundnuty/macf#503, DR-026 G1).
|
|
3
|
+
*
|
|
4
|
+
* Reads F2 reflection ledgers (reusing F4's reflections reader), loads the
|
|
5
|
+
* ratified protected-invariant set, runs the deterministic candidate pipeline
|
|
6
|
+
* (distinct-agent GATE 1 + tier-router + invariant subordination-check GATE 3),
|
|
7
|
+
* and then EITHER:
|
|
8
|
+
*
|
|
9
|
+
* - dry-run (DEFAULT): returns a Markdown report (opens NOTHING); or
|
|
10
|
+
* - `--file`: opens one ratifiable proposal issue per promoted candidate via
|
|
11
|
+
* the injectable create-only writer seam, then returns the report.
|
|
12
|
+
*
|
|
13
|
+
* GATE 2 (dry-run-by-default) is enforced here: the writer is invoked ONLY when
|
|
14
|
+
* `fileMode` is true. In the default path the writer is never touched — tests
|
|
15
|
+
* inject a recording writer and assert zero creates by default.
|
|
16
|
+
*
|
|
17
|
+
* The writer is OPTIONAL in the options: dry-run callers pass none. When
|
|
18
|
+
* `fileMode` is true a writer MUST be supplied (the command wires the real one).
|
|
19
|
+
*/
|
|
20
|
+
import { readReflections } from '../monitor/reflections.js';
|
|
21
|
+
import { loadInvariants } from './invariants.js';
|
|
22
|
+
import { buildCandidates, DEFAULT_MIN_AGENTS } from './candidates.js';
|
|
23
|
+
import { buildReport, buildProposalIssueInput } from './report.js';
|
|
24
|
+
/**
|
|
25
|
+
* Run the Plan membrane. Returns the report + any created proposals.
|
|
26
|
+
*
|
|
27
|
+
* Read side is pure filesystem; the only write path is the injected writer,
|
|
28
|
+
* gated behind `fileMode` (GATE 2). A writer failure surfaces as a thrown error
|
|
29
|
+
* to the caller (the CLI command), which decides how to report it.
|
|
30
|
+
*/
|
|
31
|
+
export async function runPropose(opts) {
|
|
32
|
+
const minAgents = opts.minAgents ?? DEFAULT_MIN_AGENTS;
|
|
33
|
+
const reflections = readReflections(opts.reflectionsDir);
|
|
34
|
+
const invariants = loadInvariants(opts.repoRoot);
|
|
35
|
+
const candidates = buildCandidates(reflections.records, invariants, minAgents);
|
|
36
|
+
const report = buildReport({
|
|
37
|
+
project: opts.project,
|
|
38
|
+
repo: opts.repo,
|
|
39
|
+
candidates,
|
|
40
|
+
fileMode: opts.fileMode,
|
|
41
|
+
invariantsLoaded: invariants.length > 0,
|
|
42
|
+
reflectionRecords: reflections.records.length,
|
|
43
|
+
reflectionsSkipped: reflections.skipped,
|
|
44
|
+
reflectionFiles: reflections.files,
|
|
45
|
+
});
|
|
46
|
+
// GATE 2 — the writer is touched ONLY in --file mode. The default path never
|
|
47
|
+
// opens anything.
|
|
48
|
+
if (!opts.fileMode) {
|
|
49
|
+
return { report, created: [] };
|
|
50
|
+
}
|
|
51
|
+
if (!opts.writer) {
|
|
52
|
+
throw new Error('Internal error: --file mode requires a proposal writer but none was provided.');
|
|
53
|
+
}
|
|
54
|
+
const created = [];
|
|
55
|
+
for (const c of candidates.promoted) {
|
|
56
|
+
const input = buildProposalIssueInput(opts.repo, c);
|
|
57
|
+
const res = await opts.writer.createProposalIssue(input);
|
|
58
|
+
created.push({ title: input.title, url: res.url });
|
|
59
|
+
}
|
|
60
|
+
return { report, created };
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=run.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../../src/cli/propose/run.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAA0B,MAAM,iBAAiB,CAAC;AAC9F,OAAO,EAAE,WAAW,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAqCnE;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAuB;IACtD,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,kBAAkB,CAAC;IACvD,MAAM,WAAW,GAAG,eAAe,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IACzD,MAAM,UAAU,GAAG,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACjD,MAAM,UAAU,GAAG,eAAe,CAAC,WAAW,CAAC,OAAO,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;IAE/E,MAAM,MAAM,GAAG,WAAW,CAAC;QACzB,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,UAAU;QACV,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,gBAAgB,EAAE,UAAU,CAAC,MAAM,GAAG,CAAC;QACvC,iBAAiB,EAAE,WAAW,CAAC,OAAO,CAAC,MAAM;QAC7C,kBAAkB,EAAE,WAAW,CAAC,OAAO;QACvC,eAAe,EAAE,WAAW,CAAC,KAAK;KACnC,CAAC,CAAC;IAEH,6EAA6E;IAC7E,kBAAkB;IAClB,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACnB,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IACjC,CAAC;IAED,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CACb,+EAA+E,CAChF,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAsB,EAAE,CAAC;IACtC,KAAK,MAAM,CAAC,IAAI,UAAU,CAAC,QAAwC,EAAE,CAAC;QACpE,MAAM,KAAK,GAAG,uBAAuB,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QACpD,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC;QACzD,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC;IACrD,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;AAC7B,CAAC"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DR-028 — the canonical expected-`settings.json`-per-role model.
|
|
3
|
+
*
|
|
4
|
+
* A universal **floor** + per-role **deltas**: the single source of truth that
|
|
5
|
+
* BOTH `macf init` (emit) and `macf doctor` (validate / `--fix`) consume, so
|
|
6
|
+
* init-output and doctor-expectation can't diverge. See
|
|
7
|
+
* `design/decisions/DR-028-expected-settings-per-role.md`.
|
|
8
|
+
*
|
|
9
|
+
* **Doctrine** (DR-028 §Decision 1): the defense is the **`deny` list + the
|
|
10
|
+
* PreToolUse hooks**, NOT allow-enumeration — canonical macf commands embed
|
|
11
|
+
* `$GH_TOKEN`/`$MACF_WORKSPACE_DIR` ("Contains simple_expansion"), which defeat
|
|
12
|
+
* narrow `Bash(...)` patterns, so the floor uses broad `Bash(*)`.
|
|
13
|
+
*
|
|
14
|
+
* This module is the **data model only**. The `macf init` emit and the
|
|
15
|
+
* `macf doctor` validate/`--fix` wiring land in follow-up increments (gated on
|
|
16
|
+
* DR-028 ratification, macf#539). Importing the hook-command constants from
|
|
17
|
+
* `settings-writer` is one-directional (settings-writer does not import this),
|
|
18
|
+
* so there is no import cycle.
|
|
19
|
+
*/
|
|
20
|
+
import { ROLE_FLOOR_ALLOW, ROLE_FLOOR_DENY } from './settings-writer.js';
|
|
21
|
+
/** A hook the model expects in `.claude/settings.json`. */
|
|
22
|
+
export interface ExpectedHook {
|
|
23
|
+
readonly event: 'PreToolUse' | 'PostToolUse' | 'UserPromptSubmit' | 'PreCompact';
|
|
24
|
+
/** Tool matcher for tool-scoped events (e.g. `Bash`); omitted for prompt/compact hooks. */
|
|
25
|
+
readonly matcher?: string;
|
|
26
|
+
readonly command: string;
|
|
27
|
+
/**
|
|
28
|
+
* `true` → a missing/changed instance of this hook is an **error**, not
|
|
29
|
+
* drift (DR-028: the auditor's `never-acts` hook). `false` → recommended;
|
|
30
|
+
* absence is reported as drift the operator may `--fix`.
|
|
31
|
+
*/
|
|
32
|
+
readonly required: boolean;
|
|
33
|
+
}
|
|
34
|
+
export { ROLE_FLOOR_ALLOW, ROLE_FLOOR_DENY };
|
|
35
|
+
/** Universal floor hooks (every role) — DR-028 §Decision 1. */
|
|
36
|
+
export declare const ROLE_FLOOR_HOOKS: readonly ExpectedHook[];
|
|
37
|
+
/** Per-role additions beyond the floor (DR-028 §Decision 1, Per-role deltas). */
|
|
38
|
+
export interface RoleSettingsDelta {
|
|
39
|
+
/** Hooks this role adds beyond the floor. */
|
|
40
|
+
readonly hooks?: readonly ExpectedHook[];
|
|
41
|
+
/** Extra `allow` entries (e.g. the role's MCP servers) beyond the floor. */
|
|
42
|
+
readonly allow?: readonly string[];
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Per-role deltas. Roles not listed get the universal floor as-is
|
|
46
|
+
* (code / science / devops — they all file + review PRs).
|
|
47
|
+
*/
|
|
48
|
+
export declare const ROLE_SETTINGS_DELTAS: Readonly<Record<string, RoleSettingsDelta>>;
|
|
49
|
+
/**
|
|
50
|
+
* The roles the framework recognizes — ships an agent template / model handling
|
|
51
|
+
* for (macf#551). The floor applies to ALL roles; only some carry deltas
|
|
52
|
+
* (`ROLE_SETTINGS_DELTAS`). An `agent_role` OUTSIDE this set is a custom role
|
|
53
|
+
* (legitimate — floor-only), but `macf doctor` surfaces it (INFO) so a typo on
|
|
54
|
+
* a delta-bearing SAFETY-critical role — e.g. `auditor-agent` instead of the
|
|
55
|
+
* exact `auditor`, which would silently skip the never-acts hook AND its doctor
|
|
56
|
+
* ERROR — becomes visible instead of degrading silently. NOTE: `auditor` has no
|
|
57
|
+
* `-agent` suffix (unlike `code-agent`); use the exact strings here.
|
|
58
|
+
*/
|
|
59
|
+
export declare const KNOWN_ROLES: readonly string[];
|
|
60
|
+
/** True if `role` is a framework-recognized role (see `KNOWN_ROLES`). */
|
|
61
|
+
export declare function isKnownRole(role: string): boolean;
|
|
62
|
+
/** Expected hooks for a role = the floor + the role's delta hooks. */
|
|
63
|
+
export declare function expectedHooksForRole(role: string): readonly ExpectedHook[];
|
|
64
|
+
/**
|
|
65
|
+
* Expected base `allow` for a role = the floor + the role's extra allow
|
|
66
|
+
* entries. The emitter composes `PLUGIN_SKILL_PERMISSIONS` +
|
|
67
|
+
* `PLUGIN_MCP_TOOL_PERMISSIONS` onto this.
|
|
68
|
+
*/
|
|
69
|
+
export declare function expectedAllowForRole(role: string): readonly string[];
|
|
70
|
+
//# sourceMappingURL=role-settings-model.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"role-settings-model.d.ts","sourceRoot":"","sources":["../../src/cli/role-settings-model.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EASL,gBAAgB,EAChB,eAAe,EAChB,MAAM,sBAAsB,CAAC;AAE9B,2DAA2D;AAC3D,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,EAAE,YAAY,GAAG,aAAa,GAAG,kBAAkB,GAAG,YAAY,CAAC;IACjF,2FAA2F;IAC3F,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC5B;AAMD,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,CAAC;AAE7C,+DAA+D;AAC/D,eAAO,MAAM,gBAAgB,EAAE,SAAS,YAAY,EAQnD,CAAC;AAEF,iFAAiF;AACjF,MAAM,WAAW,iBAAiB;IAChC,6CAA6C;IAC7C,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,YAAY,EAAE,CAAC;IACzC,4EAA4E;IAC5E,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC;AAED;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAU5E,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,WAAW,EAAE,SAAS,MAAM,EAUxC,CAAC;AAEF,yEAAyE;AACzE,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEjD;AAED,sEAAsE;AACtE,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,YAAY,EAAE,CAG1E;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAGpE"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DR-028 — the canonical expected-`settings.json`-per-role model.
|
|
3
|
+
*
|
|
4
|
+
* A universal **floor** + per-role **deltas**: the single source of truth that
|
|
5
|
+
* BOTH `macf init` (emit) and `macf doctor` (validate / `--fix`) consume, so
|
|
6
|
+
* init-output and doctor-expectation can't diverge. See
|
|
7
|
+
* `design/decisions/DR-028-expected-settings-per-role.md`.
|
|
8
|
+
*
|
|
9
|
+
* **Doctrine** (DR-028 §Decision 1): the defense is the **`deny` list + the
|
|
10
|
+
* PreToolUse hooks**, NOT allow-enumeration — canonical macf commands embed
|
|
11
|
+
* `$GH_TOKEN`/`$MACF_WORKSPACE_DIR` ("Contains simple_expansion"), which defeat
|
|
12
|
+
* narrow `Bash(...)` patterns, so the floor uses broad `Bash(*)`.
|
|
13
|
+
*
|
|
14
|
+
* This module is the **data model only**. The `macf init` emit and the
|
|
15
|
+
* `macf doctor` validate/`--fix` wiring land in follow-up increments (gated on
|
|
16
|
+
* DR-028 ratification, macf#539). Importing the hook-command constants from
|
|
17
|
+
* `settings-writer` is one-directional (settings-writer does not import this),
|
|
18
|
+
* so there is no import cycle.
|
|
19
|
+
*/
|
|
20
|
+
import { MACF_HOOK_COMMAND, MACF_MENTION_HOOK_COMMAND, MACF_LGTM_HOOK_COMMAND, MACF_CLOSE_HOOK_COMMAND, MACF_AUDITOR_HOOK_COMMAND, MACF_TURN_RECEIPT_HOOK_COMMAND, MACF_ATTRIBUTION_HOOK_COMMAND, MACF_REFLECTION_HOOK_COMMAND, ROLE_FLOOR_ALLOW, ROLE_FLOOR_DENY, } from './settings-writer.js';
|
|
21
|
+
// DR-028 universal floor allow/deny live in settings-writer.ts (zero deps) to
|
|
22
|
+
// avoid an import cycle — this module imports the hook constants FROM there, so
|
|
23
|
+
// the floor data must not flow the other way. Re-exported below so the model's
|
|
24
|
+
// public surface (what `macf doctor` validates against) stays in one place.
|
|
25
|
+
export { ROLE_FLOOR_ALLOW, ROLE_FLOOR_DENY };
|
|
26
|
+
/** Universal floor hooks (every role) — DR-028 §Decision 1. */
|
|
27
|
+
export const ROLE_FLOOR_HOOKS = [
|
|
28
|
+
{ event: 'PreToolUse', matcher: 'Bash', command: MACF_HOOK_COMMAND, required: false },
|
|
29
|
+
{ event: 'PreToolUse', matcher: 'Bash', command: MACF_MENTION_HOOK_COMMAND, required: false },
|
|
30
|
+
{ event: 'PreToolUse', matcher: 'Bash', command: MACF_LGTM_HOOK_COMMAND, required: false },
|
|
31
|
+
{ event: 'PreToolUse', matcher: 'Bash', command: MACF_CLOSE_HOOK_COMMAND, required: false },
|
|
32
|
+
{ event: 'PostToolUse', matcher: 'Bash', command: MACF_ATTRIBUTION_HOOK_COMMAND, required: false },
|
|
33
|
+
{ event: 'UserPromptSubmit', command: MACF_TURN_RECEIPT_HOOK_COMMAND, required: false },
|
|
34
|
+
{ event: 'PreCompact', command: MACF_REFLECTION_HOOK_COMMAND, required: false },
|
|
35
|
+
];
|
|
36
|
+
/**
|
|
37
|
+
* Per-role deltas. Roles not listed get the universal floor as-is
|
|
38
|
+
* (code / science / devops — they all file + review PRs).
|
|
39
|
+
*/
|
|
40
|
+
export const ROLE_SETTINGS_DELTAS = {
|
|
41
|
+
// The auditor (DR-026): the `never-acts` hook is REQUIRED — a missing one is
|
|
42
|
+
// an error, not drift. It STILL gets `Write`/`Edit` from the floor (it writes
|
|
43
|
+
// proposals/digests locally); never-acts is hook-enforced on `gh pr merge` /
|
|
44
|
+
// `issue close` (DR-026 §1/§4), not permission-removed.
|
|
45
|
+
auditor: {
|
|
46
|
+
hooks: [
|
|
47
|
+
{ event: 'PreToolUse', matcher: 'Bash', command: MACF_AUDITOR_HOOK_COMMAND, required: true },
|
|
48
|
+
],
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* The roles the framework recognizes — ships an agent template / model handling
|
|
53
|
+
* for (macf#551). The floor applies to ALL roles; only some carry deltas
|
|
54
|
+
* (`ROLE_SETTINGS_DELTAS`). An `agent_role` OUTSIDE this set is a custom role
|
|
55
|
+
* (legitimate — floor-only), but `macf doctor` surfaces it (INFO) so a typo on
|
|
56
|
+
* a delta-bearing SAFETY-critical role — e.g. `auditor-agent` instead of the
|
|
57
|
+
* exact `auditor`, which would silently skip the never-acts hook AND its doctor
|
|
58
|
+
* ERROR — becomes visible instead of degrading silently. NOTE: `auditor` has no
|
|
59
|
+
* `-agent` suffix (unlike `code-agent`); use the exact strings here.
|
|
60
|
+
*/
|
|
61
|
+
export const KNOWN_ROLES = [
|
|
62
|
+
'auditor',
|
|
63
|
+
'code-agent',
|
|
64
|
+
'science-agent',
|
|
65
|
+
'devops-agent',
|
|
66
|
+
'writing-agent',
|
|
67
|
+
'exp-code-agent',
|
|
68
|
+
'exp-science-code-aware',
|
|
69
|
+
'exp-science-domain-only',
|
|
70
|
+
'exp-single-agent',
|
|
71
|
+
];
|
|
72
|
+
/** True if `role` is a framework-recognized role (see `KNOWN_ROLES`). */
|
|
73
|
+
export function isKnownRole(role) {
|
|
74
|
+
return KNOWN_ROLES.includes(role);
|
|
75
|
+
}
|
|
76
|
+
/** Expected hooks for a role = the floor + the role's delta hooks. */
|
|
77
|
+
export function expectedHooksForRole(role) {
|
|
78
|
+
const delta = ROLE_SETTINGS_DELTAS[role];
|
|
79
|
+
return delta?.hooks ? [...ROLE_FLOOR_HOOKS, ...delta.hooks] : ROLE_FLOOR_HOOKS;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Expected base `allow` for a role = the floor + the role's extra allow
|
|
83
|
+
* entries. The emitter composes `PLUGIN_SKILL_PERMISSIONS` +
|
|
84
|
+
* `PLUGIN_MCP_TOOL_PERMISSIONS` onto this.
|
|
85
|
+
*/
|
|
86
|
+
export function expectedAllowForRole(role) {
|
|
87
|
+
const delta = ROLE_SETTINGS_DELTAS[role];
|
|
88
|
+
return delta?.allow ? [...ROLE_FLOOR_ALLOW, ...delta.allow] : ROLE_FLOOR_ALLOW;
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=role-settings-model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"role-settings-model.js","sourceRoot":"","sources":["../../src/cli/role-settings-model.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EACL,iBAAiB,EACjB,yBAAyB,EACzB,sBAAsB,EACtB,uBAAuB,EACvB,yBAAyB,EACzB,8BAA8B,EAC9B,6BAA6B,EAC7B,4BAA4B,EAC5B,gBAAgB,EAChB,eAAe,GAChB,MAAM,sBAAsB,CAAC;AAgB9B,8EAA8E;AAC9E,gFAAgF;AAChF,+EAA+E;AAC/E,4EAA4E;AAC5E,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,CAAC;AAE7C,+DAA+D;AAC/D,MAAM,CAAC,MAAM,gBAAgB,GAA4B;IACvD,EAAE,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,KAAK,EAAE;IACrF,EAAE,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,yBAAyB,EAAE,QAAQ,EAAE,KAAK,EAAE;IAC7F,EAAE,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,sBAAsB,EAAE,QAAQ,EAAE,KAAK,EAAE;IAC1F,EAAE,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,uBAAuB,EAAE,QAAQ,EAAE,KAAK,EAAE;IAC3F,EAAE,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,6BAA6B,EAAE,QAAQ,EAAE,KAAK,EAAE;IAClG,EAAE,KAAK,EAAE,kBAAkB,EAAE,OAAO,EAAE,8BAA8B,EAAE,QAAQ,EAAE,KAAK,EAAE;IACvF,EAAE,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,4BAA4B,EAAE,QAAQ,EAAE,KAAK,EAAE;CAChF,CAAC;AAUF;;;GAGG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAgD;IAC/E,6EAA6E;IAC7E,8EAA8E;IAC9E,6EAA6E;IAC7E,wDAAwD;IACxD,OAAO,EAAE;QACP,KAAK,EAAE;YACL,EAAE,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,yBAAyB,EAAE,QAAQ,EAAE,IAAI,EAAE;SAC7F;KACF;CACF,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,WAAW,GAAsB;IAC5C,SAAS;IACT,YAAY;IACZ,eAAe;IACf,cAAc;IACd,eAAe;IACf,gBAAgB;IAChB,wBAAwB;IACxB,yBAAyB;IACzB,kBAAkB;CACnB,CAAC;AAEF,yEAAyE;AACzE,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,OAAO,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACpC,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,MAAM,KAAK,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;IACzC,OAAO,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,gBAAgB,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC;AACjF,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,MAAM,KAAK,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;IACzC,OAAO,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,gBAAgB,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC;AACjF,CAAC"}
|