Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,15 @@ id: agent.golden.component-boundaries
title: Golden execution component boundaries
scope: local-component-tests
workflow:
- id: portfolio-normalization-unit
action: { verifier: agent.golden.portfolio-normalization-unit }
expect: { status: passed }
- id: portfolio-normalization-binding-unit
action: { verifier: agent.golden.portfolio-normalization-binding-unit }
expect: { status: passed }
- id: default-policy-binding-unit
action: { verifier: agent.golden.default-policy-binding-unit }
expect: { status: passed }
- id: derived-public-mode-unit
action: { verifier: agent.golden.derived-public-mode-unit }
expect: { status: passed }
Expand Down
4 changes: 4 additions & 0 deletions guarantees/agent/golden/sdk-complete.guarantee.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,14 @@ scene:
required: true
manifest: guarantees/agent/golden/scenes/sdk-complete.scene.yaml
acceptanceCriteria:
- criterion: 8ef82a4f4cb2b8e93d060e38cf8758944d2ba54baca44787811a1d76683f99d4
verifierRefs: [agent.golden.live.campaign-freeze]
- criterion: 2feaea9a8a706e1279affead3af5bacc467f12b285ba2570f183361c5d8203c7
verifierRefs: [agent.golden.live.campaign-freeze, agent.golden.live.campaign]
- criterion: 64ffc06b0d268ad11fbf692ca201cd75423c0afae2a6be3e2ae7cd2eea7fb17f
verifierRefs: [agent.golden.live.campaign, api.golden.execution-normal-sdk-clean-schema-live-1, agent.golden.architecture-record-custody-live-1, agent.golden.architecture-living-graph-live-1]
- criterion: 6e48b90ae52851e7b8fd728de8bb32610a60fc7c93dd445a93d3354aa00b652e
verifierRefs: [agent.golden.live.campaign-freeze, agent.golden.live.campaign, api.golden.execution-normal-sdk-clean-schema-live-1]
- criterion: 6c6e922d724fe9bf966e3f11456af2f176224cdff4792c9b7a73ce8047659e55
verifierRefs: [api.golden.execution-normal-sdk-clean-schema-live-1, agent.golden.architecture-record-custody-live-1]
- criterion: 2e5d3dfc2cd33fd0656866a59ce59153137c199b766309decab4f71ecbf4e8d7
Expand Down
15 changes: 15 additions & 0 deletions guarantees/verifiers/golden.verifiers.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,21 @@
schemaVersion: treeseed.guarantee-verifiers/v1
ownerPackage: "@treeseed/agent"
verifiers:
agent.golden.portfolio-normalization-unit:
kind: vitestCase
ownerPackage: "@treeseed/agent"
testFile: tests/modern/guarantees/preflight/campaign-freeze.test.ts
testName: "denies allocator normalization drift while retaining the frozen SDK and future portfolio inputs"
agent.golden.portfolio-normalization-binding-unit:
kind: vitestCase
ownerPackage: "@treeseed/agent"
testFile: tests/modern/guarantees/bindings.test.ts
testName: "binds portfolio normalization to the original prospective campaign freeze without adding a future passing receipt"
agent.golden.default-policy-binding-unit:
kind: vitestCase
ownerPackage: "@treeseed/agent"
testFile: tests/modern/guarantees/bindings.test.ts
testName: "binds default policy and immutable issued overrides to preflight campaign and original native SDK policy custody in order"
agent.golden.derived-public-mode-unit:
kind: vitestCase
ownerPackage: "@treeseed/agent"
Expand Down
17 changes: 16 additions & 1 deletion tests/acceptance/freeze-integrity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { mkdtempSync, readFileSync, rmSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { resolve } from 'node:path';
import { canonicalSeedBundlePayload, validateSeedBundle, workdayIntentRequestSchema, type SeedBundle } from '@treeseed/sdk/operator-contracts';
import { workdayPolicySchema, workdayProfileSchema } from '@treeseed/sdk/agent-capacity';
import { selectFairReadyNode, workdayPolicySchema, workdayProfileSchema } from '@treeseed/sdk/agent-capacity';
import { parse } from 'yaml';
import { portfolioRelations, readPortfolioLibraries } from './workday/support/portfolio-relations.ts';

Expand Down Expand Up @@ -67,6 +67,21 @@ export function verifyPreRunCampaignInputs(snapshot: unknown, slugs: readonly st
assert.deepEqual(allocation.projectPercentages, Object.fromEntries(selected.map(project =>
[project.projectId, key === 'all-project-portfolio' ? 1 : 100 / selected.length])), fail);
assert.deepEqual(allocation.agentClassPercentages, Object.fromEntries(selected.map(project => [project.projectId, classes])), fail);
// Check the current owning allocator's prospective projection. These
// ready nodes and empty usage are not future assignments or portfolio receipts.
const readyAt = parsed.data.startsAt ?? '1970-01-01T00:00:00.000Z';
assert.ok(typeof readyAt === 'string', fail);
const nodes = selected.flatMap(project => {
const projectId = project.projectId; assert.ok(typeof projectId === 'string', fail);
return Object.keys(classes).map(agentClass => ({ id: `${projectId}:${agentClass}`, projectId, agentClass, readyAt }));
});
const normalized = selectFairReadyNode(nodes, [], workdayPolicySchema.parse({ ...parsedPolicy.data, ...allocation, durationSeconds: input.durationSeconds }));
const normalization = 'ACCEPTANCE_CAMPAIGN_NORMALIZATION: Current owning allocator must normalize exact frozen project and class weights';
assert.ok(normalized && normalized.explanation && typeof normalized.explanation === 'object', normalization);
assert.ok(nodes.some(node => node.id === normalized.id && node.projectId === normalized.projectId && node.agentClass === normalized.agentClass), normalization);
assert.equal(normalized.explanation.readyNodeCount, nodes.length, normalization);
assert.equal(normalized.explanation.projectTargetPercent, 100 / selected.length, normalization);
assert.equal(normalized.explanation.classTargetPercent, 12.5, normalization);
if (key !== 'all-project-portfolio') {
assert.equal(input.durationSeconds, 3600, fail); assert.equal(allocation.planningPercent, 100 / 3, fail);
}
Expand Down
18 changes: 18 additions & 0 deletions tests/modern/guarantees/bindings.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,22 @@ for (const file of readdirSync(resolve(root, 'guarantees/verifiers')).filter(pat
}

describe('capacity-provider guarantee execution bindings', () => {
it('binds portfolio normalization to the original prospective campaign freeze without adding a future passing receipt', () => {
const manifest = parse(readFileSync(resolve(root, 'guarantees/agent/golden/sdk-complete.guarantee.yaml'), 'utf8'));
expect(manifest.acceptanceCriteria.filter((value: { criterion: string }) => value.criterion === '8ef82a4f4cb2b8e93d060e38cf8758944d2ba54baca44787811a1d76683f99d4'))
.toEqual([{ criterion: '8ef82a4f4cb2b8e93d060e38cf8758944d2ba54baca44787811a1d76683f99d4', verifierRefs: ['agent.golden.live.campaign-freeze'] }]);
});
it('binds default policy and immutable issued overrides to preflight campaign and original native SDK policy custody in order', () => {
const manifest = parse(readFileSync(resolve(root, 'guarantees/agent/golden/sdk-complete.guarantee.yaml'), 'utf8'));
const scene = parse(readFileSync(resolve(root, manifest.scene.manifest), 'utf8'));
const required = ['agent.golden.live.campaign-freeze', 'agent.golden.live.campaign', 'api.golden.execution-normal-sdk-clean-schema-live-1'];
expect(manifest.acceptanceCriteria.filter((value: { criterion: string }) => value.criterion === '6e48b90ae52851e7b8fd728de8bb32610a60fc7c93dd445a93d3354aa00b652e'))
.toEqual([{ criterion: '6e48b90ae52851e7b8fd728de8bb32610a60fc7c93dd445a93d3354aa00b652e', verifierRefs: required }]);
const refs: string[] = scene.workflow.map((step: { action: { verifier: string } }) => step.action.verifier);
for (const ref of required) expect(refs.filter(value => value === ref)).toHaveLength(1);
expect(refs.indexOf(required[1]!)).toBeGreaterThan(refs.indexOf(required[0]!));
expect(refs.indexOf(required[2]!)).toBeGreaterThan(refs.indexOf(required[1]!));
});
it('binds sole simulation mode to immediate campaign observation independent native Workday authority and unchanged canonical terminal records', () => {
const manifest = parse(readFileSync(resolve(root, 'guarantees/agent/golden/sdk-complete.guarantee.yaml'), 'utf8'));
const scene = parse(readFileSync(resolve(root, manifest.scene.manifest), 'utf8'));
Expand Down Expand Up @@ -179,8 +195,10 @@ describe('capacity-provider guarantee execution bindings', () => {
'b918b519ac545fdd61faab208687ccc64e1f3d03c9a84dfc57a5cfee6190f3f3',
].map(criterion => ({ criterion, verifierRefs: ['agent.golden.live.campaign-freeze'] }));
expect(manifest.acceptanceCriteria).toEqual([
{ criterion: '8ef82a4f4cb2b8e93d060e38cf8758944d2ba54baca44787811a1d76683f99d4', verifierRefs: ['agent.golden.live.campaign-freeze'] },
{ criterion: '2feaea9a8a706e1279affead3af5bacc467f12b285ba2570f183361c5d8203c7', verifierRefs: ['agent.golden.live.campaign-freeze', 'agent.golden.live.campaign'] },
{ criterion: '64ffc06b0d268ad11fbf692ca201cd75423c0afae2a6be3e2ae7cd2eea7fb17f', verifierRefs: ['agent.golden.live.campaign', 'api.golden.execution-normal-sdk-clean-schema-live-1', 'agent.golden.architecture-record-custody-live-1', 'agent.golden.architecture-living-graph-live-1'] },
{ criterion: '6e48b90ae52851e7b8fd728de8bb32610a60fc7c93dd445a93d3354aa00b652e', verifierRefs: ['agent.golden.live.campaign-freeze', 'agent.golden.live.campaign', 'api.golden.execution-normal-sdk-clean-schema-live-1'] },
{ criterion: '6c6e922d724fe9bf966e3f11456af2f176224cdff4792c9b7a73ce8047659e55', verifierRefs: ['api.golden.execution-normal-sdk-clean-schema-live-1', 'agent.golden.architecture-record-custody-live-1'] },
{ criterion: '2e5d3dfc2cd33fd0656866a59ce59153137c199b766309decab4f71ecbf4e8d7', verifierRefs: ['api.golden.execution-normal-sdk-clean-schema-live-1', 'agent.golden.architecture-record-custody-live-1'] },
...sdkPermissionCriteria.map(criterion => ({ criterion, verifierRefs: ['agent.golden.architecture-profile-custody-live-1', 'sdk.golden.live.product'] })),
Expand Down
29 changes: 28 additions & 1 deletion tests/modern/guarantees/preflight/campaign-freeze.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import { stringify } from 'yaml';
import { campaignOffers } from './campaign-offers-fixture.ts';

const state = vi.hoisted(() => ({ bytes: '{}', reads: [] as string[], files: new Map<string, string>(),
commands: vi.fn(), writes: vi.fn(), execute: vi.fn(), publicRead: vi.fn() }));
commands: vi.fn(), writes: vi.fn(), execute: vi.fn(), publicRead: vi.fn(),
selection: vi.fn<(value: ReturnType<typeof import('@treeseed/sdk/agent-capacity').selectFairReadyNode>) => unknown>() }));
vi.mock('node:fs', async importOriginal => ({
...await importOriginal<typeof import('node:fs')>(),
existsSync: (path: string) => !path.endsWith('sdk.freeze.json'),
Expand All @@ -16,6 +17,10 @@ vi.mock('node:fs', async importOriginal => ({
vi.mock('node:child_process', () => ({ execFileSync: (...args: unknown[]) => {
state.commands(...args); return state.execute(...args);
} }));
vi.mock('@treeseed/sdk/agent-capacity', async importOriginal => {
const actual = await importOriginal<typeof import('@treeseed/sdk/agent-capacity')>();
return { ...actual, selectFairReadyNode: (...args: Parameters<typeof actual.selectFairReadyNode>) => state.selection(actual.selectFairReadyNode(...args)) };
});
vi.mock('../../../acceptance/acceptance-cli.ts', async importOriginal => ({
...await importOriginal<typeof import('../../../acceptance/acceptance-cli.ts')>(), read: (...args: unknown[]) => {
state.commands(...args); return state.publicRead(...args);
Expand All @@ -31,6 +36,7 @@ const slugs = ['sdk', 'api', ...Array.from({ length: 15 }, (_, index) => `suppli

beforeEach(() => {
state.bytes = '{}'; state.reads = []; state.files.clear(); state.commands.mockClear(); state.writes.mockReset();
state.selection.mockReset().mockImplementation(value => value);
state.execute.mockReset().mockImplementation(() => { throw new Error('Unexpected native command before complete freeze validation'); });
state.publicRead.mockReset().mockImplementation(() => { throw new Error('Unexpected public command before complete freeze validation'); });
vi.stubEnv('TREESEED_ACCEPTANCE_PLATFORM_PATH', '/supplied-platform');
Expand Down Expand Up @@ -212,6 +218,27 @@ it('retains all twenty five prospective schema valid inputs with pending genuine
expect(state.commands).not.toHaveBeenCalled(); expect(state.writes).not.toHaveBeenCalled();
});

it('denies allocator normalization drift while retaining the frozen SDK and future portfolio inputs', () => {
const supplied = campaignInputs(slugs), held = structuredClone(supplied);
type Choice = ReturnType<typeof import('@treeseed/sdk/agent-capacity').selectFairReadyNode>;
const changes: Array<(value: Choice) => unknown> = [() => null, () => ({}),
value => ({ ...value, id: 'foreign-node' }), value => ({ ...value, explanation: {} }),
...['projectTargetPercent', 'classTargetPercent'].flatMap(field => [undefined, null, '100', NaN, Infinity, -1, 0, 1]
.map(invalid => (value: Choice) => ({ ...value, explanation: { ...value?.explanation, [field]: invalid } }))),
value => value?.explanation.readyNodeCount === 136 ? { ...value, explanation: { ...value.explanation, projectTargetPercent: 1 } } : value,
];
for (const change of changes) {
state.selection.mockImplementation(change);
expect(() => verifyPreRunCampaignInputs(supplied, slugs)).toThrow(/ACCEPTANCE_CAMPAIGN_NORMALIZATION/u);
expect(supplied).toEqual(held); expect(state.commands).not.toHaveBeenCalled(); expect(state.writes).not.toHaveBeenCalled();
}
state.selection.mockReset().mockImplementation(value => value); verifyPreRunCampaignInputs(supplied, slugs);
expect(state.selection).toHaveBeenCalledTimes(25);
const portfolio = state.selection.mock.calls.map(([value]) => value).find(value => value?.explanation.readyNodeCount === 136);
expect(portfolio?.explanation).toMatchObject({ projectTargetPercent: 100 / 17, classTargetPercent: 12.5 });
expect(supplied).toEqual(held);
});

it('denies every omitted run changed policy selection derived field and fault allocation without repairing supplied campaign inputs', () => {
type Campaign = ReturnType<typeof campaignInputs>;
const changes: Array<(value: Campaign) => void> = [
Expand Down
Loading