create-metamynd-agent 0.3.2 → 0.3.4

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.
Files changed (2) hide show
  1. package/index.mjs +46 -9
  2. package/package.json +1 -1
package/index.mjs CHANGED
@@ -18,7 +18,10 @@ import readline from 'node:readline';
18
18
  import crypto from 'node:crypto';
19
19
 
20
20
  const GUARD_PKG = '@metamynd/agentsafe-guard';
21
- const GUARD_VERSION = '^0.4.0';
21
+ // Must track the guard's MINOR line, not just its major. On a 0.x package `^0.4.0` means
22
+ // >=0.4.0 <0.5.0, so leaving this at ^0.4.0 would scaffold an agent whose `npm test` runs
23
+ // `agentsafe-guard verify` against a guard that has no such command.
24
+ const GUARD_VERSION = '^0.5.0';
22
25
  const DEFAULT_API = 'https://metamynd.ai/api/v1';
23
26
 
24
27
  // ---------- tiny ANSI ----------
@@ -209,6 +212,23 @@ const gatedBookFlight = guard.guardTool(
209
212
  }),
210
213
  );
211
214
 
215
+ // --- A tool the agent was NEVER granted. Wrapping it is the demonstration: there is no
216
+ // --- rule anywhere forbidding this. The mandate simply never mentioned the action.
217
+ async function raiseOwnLimit(args) {
218
+ return { updated: true, ...args }; // never runs, and that is the point
219
+ }
220
+
221
+ const gatedRaiseOwnLimit = guard.guardTool(
222
+ 'permissions.update', // an action NOT in the mandate
223
+ raiseOwnLimit,
224
+ (a) => ({
225
+ amount: a.amount,
226
+ currency: 'USD',
227
+ merchant: a.merchant,
228
+ context: { tool: 'permissions-update' },
229
+ }),
230
+ );
231
+
212
232
  const dim = (t) => '\\x1b[2m' + t + '\\x1b[0m';
213
233
  const bold = (t) => '\\x1b[1m' + t + '\\x1b[0m';
214
234
  const rule = (n) => ' ' + '-'.repeat(n);
@@ -219,6 +239,11 @@ const WHY = {
219
239
  SOP_SPEND_CAP: 'your SOP caps a single transaction at $${perTxnMax}',
220
240
  RISK_REVIEW: 'your SOP sends high-risk actions to a human first',
221
241
  MERCHANT_NOT_ALLOWED: 'the mandate lists which merchants this agent may pay',
242
+ // Both say the same thing from where you are standing: the mandate does not cover that
243
+ // action. Which one you see depends on whether the verdict was reached here or at the
244
+ // gate, and neither of them depends on the amount.
245
+ NO_PERMISSION_FOR_ACTION: 'the mandate never granted this action - at any amount',
246
+ NO_MANDATE: 'there is no mandate for this action at all',
222
247
  };
223
248
 
224
249
  // ---------------------------------------------------------------- 1. CONTEXT
@@ -226,9 +251,10 @@ console.log('');
226
251
  console.log(bold(' What this simulation shows'));
227
252
  console.log('');
228
253
  console.log(' An agent should not be the thing that decides what it is allowed to do.');
229
- console.log(' This run makes that concrete: the SAME code path is attempted three times');
230
- console.log(' and produces three different outcomes, because the decision is made');
231
- console.log(' outside your program - and cannot be argued with from inside it.');
254
+ console.log(' This run makes that concrete. Three attempts take the SAME code path and');
255
+ console.log(' produce three different outcomes. The fourth asks for something the agent');
256
+ console.log(' was never granted at all - and that is the one a prompt could not have');
257
+ console.log(' stopped, because the decision is not made inside your program.');
232
258
 
233
259
  // ---------------------------------------------------------------- 2. MECHANISM
234
260
  console.log('');
@@ -244,13 +270,13 @@ console.log(dim(' scope ${scope}'));
244
270
  console.log(dim(' cap $${perTxnMax} per transaction, set by your SOP'));
245
271
 
246
272
  // ---------------------------------------------------------------- 3. THE STEPS
247
- async function attempt(n, intent, args) {
273
+ async function attempt(n, intent, args, tool = gatedBookFlight) {
248
274
  console.log('');
249
- console.log(bold(' Step ' + n + ' of 3') + ' - ' + intent);
275
+ console.log(bold(' Step ' + n + ' of 4') + ' - ' + intent);
250
276
  console.log(dim(' signing the request locally, then asking the gate to decide...'));
251
277
  try {
252
- const r = await gatedBookFlight(args);
253
- console.log('\\x1b[32m ALLOWED\\x1b[0m your tool ran and returned ' + r.pnr);
278
+ const r = await tool(args);
279
+ console.log('\\x1b[32m ALLOWED\\x1b[0m your tool ran and returned ' + (r.pnr ?? 'ok'));
254
280
  console.log(dim(' ' + WHY.AUTHORIZED));
255
281
  } catch (e) {
256
282
  const g = e.governance ?? {};
@@ -272,6 +298,12 @@ console.log(rule(66));
272
298
  await attempt(1, 'a $${under} booking, low risk. Expected to pass.', { amount: ${under}, merchant: 'skyward-air', riskLevel: 'low' });
273
299
  await attempt(2, 'a $${over} booking, deliberately over the cap.', { amount: ${over}, merchant: 'skyward-air', riskLevel: 'low' });
274
300
  await attempt(3, 'a $${under} booking, but flagged high risk.', { amount: ${under}, merchant: 'skyward-air', riskLevel: 'high' });
301
+ await attempt(
302
+ 4,
303
+ 'the agent stops booking flights and asks to raise its OWN limit.',
304
+ { amount: 100000, merchant: 'skyward-air' },
305
+ gatedRaiseOwnLimit,
306
+ );
275
307
  console.log('');
276
308
  console.log(rule(66));
277
309
 
@@ -281,6 +313,8 @@ console.log(bold(' What this proved'));
281
313
  console.log('');
282
314
  console.log(dim(' - one code path, three outcomes. The rules decided, not this file'));
283
315
  console.log(dim(' and not the model driving it.'));
316
+ console.log(dim(' - step 4 needed no rule to stop it. The agent could not widen its own'));
317
+ console.log(dim(' authority, because it cannot name an action nobody delegated to it.'));
284
318
  console.log(dim(' - the blocked call never reached your tool at all.'));
285
319
  console.log(dim(' - every decision was recorded as tamper-evident evidence.'));
286
320
  console.log(dim(' - if the gate were unreachable the guard fails CLOSED: it blocks.'));
@@ -298,7 +332,10 @@ function examplePackageJson(slug) {
298
332
  version: '0.1.0',
299
333
  private: true,
300
334
  type: 'module',
301
- scripts: { start: 'node index.mjs' },
335
+ // `verify` is scaffolded in because governance that lives only in a dashboard is a
336
+ // thing someone has to remember to look at. As a build step it is a control: a change
337
+ // that widens this agent's authority fails `npm test`.
338
+ scripts: { start: 'node index.mjs', test: 'agentsafe-guard verify' },
302
339
  dependencies: { [GUARD_PKG]: GUARD_VERSION },
303
340
  },
304
341
  null,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-metamynd-agent",
3
- "version": "0.3.2",
3
+ "version": "0.3.4",
4
4
  "description": "Scaffold a MetaMynd/AgentSafe-governed AI agent in one command \u2014 logs in, provisions the agent (identity + mandate + SOP + Standards) in a single call, writes agent.metamynd.json, and drops a runnable example.",
5
5
  "type": "module",
6
6
  "bin": {