diff --git a/apps/website/scripts/agents-from-specs.mjs b/apps/website/scripts/agents-from-specs.mjs index f4dd9d4bb8..2b4f8098a6 100644 --- a/apps/website/scripts/agents-from-specs.mjs +++ b/apps/website/scripts/agents-from-specs.mjs @@ -101,7 +101,10 @@ export const FN_TRIGGERS = ['event', 'cron'] export const FN_ON_FAILURE = ['admin-telegram', 'log', 'refund+notify'] export const FN_SIDE_EFFECTS = ['charges-balance', 'paid-api', 'messages-user', 'messages-owners', 'messages-admin', 'db-write', 'external-webhook', 'none'] export const FN_PROBE_RESULTS = ['COMPLETED', 'FAILED-at-guard', 'skipped', 'not-deployed'] -export const FN_CONTROLS = ['spec+code', 'spec-only', 'code-only'] +// 'code-only/unregistered' (t27 specs/functions/README.md, 2026-09-17): the code +// exists in the bot tree but is withdrawn from registerFunctions.ts and not served; +// the spec's NOTE says why. The bot manifest uses the same value for `control`. +export const FN_CONTROLS = ['spec+code', 'spec-only', 'code-only', 'code-only/unregistered'] export const T27_REPO_URL = 'https://github.com/gHashTag/t27' // Repo root of gHashTag/trinity (BUNDLE_PATH is repo-relative). export const REPO_ROOT = resolve(SITE, '..', '..') diff --git a/apps/website/scripts/agents-from-specs.test.mjs b/apps/website/scripts/agents-from-specs.test.mjs index 30616a0112..2f54e6a6e2 100644 --- a/apps/website/scripts/agents-from-specs.test.mjs +++ b/apps/website/scripts/agents-from-specs.test.mjs @@ -803,6 +803,22 @@ test('a function the manifest does not list is spec-only (warn); a manifest id w assert.equal(r.functions.counts.deployUnknown, 1) }) +test('a withdrawn function: CONTROL code-only/unregistered is in the vocabulary, and agrees with a manifest control of the same value (ok, no distance)', () => { + // t27 specs/functions/README.md, 2026-09-17: five functions left registerFunctions.ts; + // the spec and the bot manifest both say code-only/unregistered, so the card is ok. + const src = fnSrc('neuro-image-generate').replace('"spec+code"', '"code-only/unregistered"') + const r = withFunctions(fnFiles(['neuro-image-generate', src]), [{ ...fnManifestEntry('neuro-image-generate'), control: 'code-only/unregistered' }]) + assert.deepEqual(r.problems, []) + const f = r.functions.functions[0] + assert.equal(f.fields.CONTROL, 'code-only/unregistered') + assert.equal(f.code.control, 'code-only/unregistered') + assert.deepEqual(f.differences, []) + assert.equal(f.health, 'ok') + // and a value outside the vocabulary is still a build problem + const bad = withFunctions(fnFiles(['neuro-image-generate', fnSrc('neuro-image-generate').replace('"spec+code"', '"withdrawn"')]), [fnManifestEntry('neuro-image-generate')]) + assert.ok(bad.problems.some((p) => p.includes('CONTROL "withdrawn"'))) +}) + test('no manifest at all: every function is spec-only and nothing is invented', () => { const r = withFunctions(fnFiles(['neuro-image-generate', fnSrc('neuro-image-generate')]), null) assert.deepEqual(r.problems, [])