mirror of
https://github.com/block/buzz.git
synced 2026-10-29 05:21:31 +00:00
beehive: keep public assignment and auth guidance credential-neutral
Signed-off-by: Logan Johnson <loganj@squareup.com>
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import { installationPublicSlots } from './slots.ts';
|
||||
import { provisionCredentialSlot, reconcileCredentialProvision, orphanCredentialSlots } from './credential-slots.ts';
|
||||
import { readHostIdentity } from './host-identity.ts';
|
||||
import { verifyHostRegistration } from './host-registration.ts';
|
||||
@@ -247,7 +248,7 @@ async function main() {
|
||||
importSlotKey(dir, agent, secret);
|
||||
console.log(`Local key restored for ${agent}; retained assignment and history unchanged. Start still requires this host's assignment. No keys or sessions transferred.`);
|
||||
} else if (command === 'assignment-export') {
|
||||
const entries = installationSlots(resolve(text(args[0])));
|
||||
const entries = installationPublicSlots(resolve(text(args[0])));
|
||||
const entry = args[2] ? entries.find(e => e.agent === args[2]) : entries.length === 1 ? entries[0] : undefined;
|
||||
if (!entry) throw Error('Specify agent public key after export filename for multi-slot host');
|
||||
const state = object(readPrivate(entry.path));
|
||||
@@ -266,6 +267,7 @@ async function main() {
|
||||
} finally { ui.close(); }
|
||||
} else if (command === 'conversation-setup') {
|
||||
const dir = resolve(text(args[0]));
|
||||
if (object(readPrivate(join(dir, 'setup.json'))).version === 3) throw Error('Immutable public bindings cannot be rewritten: use local-setup action normal to create a NEW reference; identity credentials are not required');
|
||||
const lock = join(dir, 'host.lock');
|
||||
mkdirSync(lock, { mode: 0o700 }); // Same atomic exclusion as host startup; never remove a competing lock.
|
||||
try {
|
||||
@@ -277,7 +279,7 @@ async function main() {
|
||||
throw Error('Immutable bindings cannot be rewritten: use migrate-slots first for a legacy installation, then local-setup action normal to convert the selected ACP binding to a NEW reference');
|
||||
} finally { rmdirSync(lock); }
|
||||
} else if (command === 'auth-info') {
|
||||
const entries = installationSlots(resolve(text(args[0])));
|
||||
const entries = installationPublicSlots(resolve(text(args[0])));
|
||||
const setup = args[1] ? entries[0]!.bindings[text(args[1])] : entries[0]!.setup;
|
||||
if (!setup) throw Error('Unknown local binding');
|
||||
if (setup.mode === 'diagnostic-acp') { console.log('Setup/diagnostic only: authentication unverified, no model/native profile contract. Configure locally as the service user; no login/probe was run.'); return; }
|
||||
|
||||
@@ -23,8 +23,8 @@ test('v3 actual local wizard: immutable replacement, neutral normal conversion,
|
||||
const directory = join(root, 'host'), file = join(root, 'credentials.json'), credentials = isolatedFileCredentials(file);
|
||||
const owner = newKey(), secret = newKey(), agent = publicKey(secret);
|
||||
const setup = validateSetup({ host: 'v3-local', ownerPublic: publicKey(owner), mode: 'goose', runner: realpathSync(process.execPath), args: ['acp'], workspace: root, serviceHome: root, configDirectory: root, gooseProvider: 'fixture', gooseModels: ['a'] });
|
||||
async function cli(responses: [string, string, (() => void)?][], success = true) {
|
||||
const child = spawn(process.execPath, ['--import', resolve('test/isolated-credentials-loader.ts'), 'src/cli.ts', 'local-setup', directory], { env: { PATH: '/usr/bin:/bin', HOME: root, BEEHIVE_TEST_CREDENTIAL_FILE: file }, stdio: ['pipe', 'pipe', 'pipe'] });
|
||||
async function cli(responses: [string, string, (() => void)?][], success = true, command = ['local-setup', directory]) {
|
||||
const child = spawn(process.execPath, ['--import', resolve('test/isolated-credentials-loader.ts'), 'src/cli.ts', ...command], { env: { PATH: '/usr/bin:/bin', HOME: root, BEEHIVE_TEST_CREDENTIAL_FILE: file }, stdio: ['pipe', 'pipe', 'pipe'] });
|
||||
let output = '', cursor = 0; child.stdout.on('data', b => output += b); child.stderr.on('data', b => output += b);
|
||||
const exited = new Promise(resolve => child.on('close', resolve));
|
||||
try {
|
||||
@@ -48,6 +48,11 @@ test('v3 actual local wizard: immutable replacement, neutral normal conversion,
|
||||
// A malformed synthetic credential file makes ANY read fail. Neutral wizard paths
|
||||
// must still work; the fixture loader prevents accidental native-store access.
|
||||
writeFileSync(file, 'invalid JSON');
|
||||
const genesisFile = join(root, 'exported-genesis.json');
|
||||
await cli([], true, ['assignment-export', directory, genesisFile, agent]);
|
||||
assert.deepEqual(readPrivate(genesisFile), (readPrivate(journal) as any).assignment.genesis);
|
||||
assert.match(await cli([], true, ['auth-info', directory]), /Goose/);
|
||||
assert.match(await cli([], false, ['conversation-setup', directory]), /NEW reference/);
|
||||
await cli(normal('yes'));
|
||||
const entries = installationPublicSlots(directory), fingerprint = bindingFingerprint(entries[0]!.bindings.default!);
|
||||
assert.equal(entries[0]!.bindings.default!.conversation, undefined);
|
||||
|
||||
Reference in New Issue
Block a user