open source is social v-it.org
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

remix: use trust-gate for dangerous-accept bypass

Replace inline trust check with shouldBypassVet() from trust-gate.
When agent detected and ref not trusted, error now includes
dangerous-accept hint alongside the standard vet instructions.

Tests cover: untrusted ref error with hint, dangerous-accept bypass.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

+55 -16
+22 -11
src/cmd/remix.js
··· 5 5 import { CAP_COLLECTION } from '../lib/constants.js'; 6 6 import { restoreAgent } from '../lib/oauth.js'; 7 7 import { readProjectConfig, readFollowing, readLog } from '../lib/vit-dir.js'; 8 - import { requireAgent } from '../lib/agent.js'; 8 + import { requireAgent, detectCodingAgent } from '../lib/agent.js'; 9 + import { shouldBypassVet } from '../lib/trust-gate.js'; 9 10 import { resolveRef, REF_PATTERN } from '../lib/cap-ref.js'; 10 11 import { brand, name } from '../lib/brand.js'; 11 12 import { resolvePds, listRecordsFromPds } from '../lib/pds.js'; ··· 51 52 const trusted = readLog('trusted.jsonl'); 52 53 const trustedEntry = trusted.find(e => e.ref === ref); 53 54 if (!trustedEntry) { 54 - console.error(`cap '${ref}' is not trusted. ask the user to vet it first:`); 55 - console.error(''); 56 - console.error(` vit vet ${ref}`); 57 - console.error(''); 58 - console.error('after reviewing, they can trust it with:'); 59 - console.error(''); 60 - console.error(` vit vet ${ref} --trust`); 61 - process.exitCode = 1; 62 - return; 55 + const trustGate = shouldBypassVet(); 56 + if (!trustGate.bypass) { 57 + console.error(`cap '${ref}' is not trusted. ask the user to vet it first:`); 58 + console.error(''); 59 + console.error(` vit vet ${ref}`); 60 + console.error(''); 61 + console.error('after reviewing, they can trust it with:'); 62 + console.error(''); 63 + console.error(` vit vet ${ref} --trust`); 64 + if (detectCodingAgent()) { 65 + console.error(''); 66 + console.error('or, to trust all items without review:'); 67 + console.error(''); 68 + console.error(' vit vet --dangerous-accept --confirm'); 69 + } 70 + process.exitCode = 1; 71 + return; 72 + } 73 + if (verbose) console.log(`[verbose] vet gate bypassed: ${trustGate.reason}`); 63 74 } 64 - if (verbose) console.log(`[verbose] trusted entry found, uri: ${trustedEntry.uri}`); 75 + if (verbose && trustedEntry) console.log(`[verbose] trusted entry found, uri: ${trustedEntry.uri}`); 65 76 66 77 const { agent } = await restoreAgent(did); 67 78 if (verbose) console.log('[verbose] session restored');
+33 -5
test/remix.test.js
··· 3 3 4 4 import { describe, test, expect } from 'bun:test'; 5 5 import { run } from './helpers.js'; 6 - import { mkdirSync, rmSync } from 'node:fs'; 6 + import { mkdirSync, writeFileSync, rmSync } from 'node:fs'; 7 7 import { tmpdir } from 'node:os'; 8 8 import { join } from 'node:path'; 9 + 10 + const agentEnv = { CLAUDECODE: '1' }; 9 11 10 12 describe('vit remix', () => { 11 13 test('rejects when run outside a coding agent', () => { ··· 15 17 }); 16 18 17 19 test('fails with no arguments', () => { 18 - const result = run('remix', '/tmp', { CLAUDECODE: '1' }); 20 + const result = run('remix', '/tmp', agentEnv); 19 21 expect(result.exitCode).not.toBe(0); 20 22 }); 21 23 22 24 test('rejects invalid ref format', () => { 23 - const result = run('remix not-valid', '/tmp', { CLAUDECODE: '1' }); 25 + const result = run('remix not-valid', '/tmp', agentEnv); 24 26 expect(result.exitCode).not.toBe(0); 25 27 expect(result.stderr).toContain('invalid ref'); 26 28 }); ··· 28 30 test('errors when no DID configured', () => { 29 31 const configHome = join(tmpdir(), '.test-remix-config-' + Math.random().toString(36).slice(2)); 30 32 mkdirSync(configHome, { recursive: true }); 31 - const result = run('remix fast-cache-invalidation', '/tmp', { CLAUDECODE: '1', XDG_CONFIG_HOME: configHome }); 33 + const result = run('remix fast-cache-invalidation', '/tmp', { ...agentEnv, XDG_CONFIG_HOME: configHome }); 32 34 expect(result.exitCode).not.toBe(0); 33 35 expect(result.stderr).toContain('no DID configured'); 34 36 rmSync(configHome, { recursive: true, force: true }); 35 37 }); 36 38 37 39 test('errors when no beacon is set', () => { 38 - const result = run('remix fast-cache-invalidation --did did:plc:test123', '/tmp', { CLAUDECODE: '1' }); 40 + const result = run('remix fast-cache-invalidation --did did:plc:test123', '/tmp', agentEnv); 39 41 expect(result.exitCode).not.toBe(0); 40 42 expect(result.stderr).toContain('no beacon set'); 43 + }); 44 + 45 + // --- trust gate tests --- 46 + 47 + describe('trust gate', () => { 48 + test('untrusted ref without dangerous-accept: error includes hint', () => { 49 + const tmp = join(tmpdir(), '.test-remix-trust-' + Math.random().toString(36).slice(2)); 50 + mkdirSync(join(tmp, '.vit'), { recursive: true }); 51 + writeFileSync(join(tmp, '.vit', 'config.json'), JSON.stringify({ beacon: 'vit:github.com/test/test' })); 52 + const result = run('remix fast-cache-invalidation --did did:plc:test123', tmp, agentEnv); 53 + expect(result.exitCode).toBe(1); 54 + expect(result.stderr).toContain('not trusted'); 55 + expect(result.stderr).toContain('vit vet --dangerous-accept --confirm'); 56 + rmSync(tmp, { recursive: true, force: true }); 57 + }); 58 + 59 + test('untrusted ref with active dangerous-accept: bypasses trust gate', () => { 60 + const tmp = join(tmpdir(), '.test-remix-bypass-' + Math.random().toString(36).slice(2)); 61 + mkdirSync(join(tmp, '.vit'), { recursive: true }); 62 + writeFileSync(join(tmp, '.vit', 'config.json'), JSON.stringify({ beacon: 'vit:github.com/test/test' })); 63 + writeFileSync(join(tmp, '.vit', 'dangerous-accept'), JSON.stringify({ acceptedAt: '2026-03-26T14:30:00.000Z' })); 64 + const result = run('remix fast-cache-invalidation --did did:plc:test123', tmp, agentEnv); 65 + // Should bypass trust check — will fail later at auth/network, NOT at trust 66 + expect(result.stderr).not.toContain('not trusted'); 67 + rmSync(tmp, { recursive: true, force: true }); 68 + }); 41 69 }); 42 70 });