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 @@ -684,6 +684,9 @@ workflow:
- id: standing-graph-order-unit
action: { verifier: sdk.golden.standing-graph-order-unit }
expect: { status: passed }
- id: fixed-permissions-unit
action: { verifier: sdk.golden.fixed-permissions-unit }
expect: { status: passed }
- id: assignment-workday-native
action: { verifier: sdk.golden.assignment-workday-native }
expect: { status: passed }
5 changes: 5 additions & 0 deletions guarantees/verifiers/golden.verifiers.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
schemaVersion: treeseed.guarantee-verifiers/v1
ownerPackage: "@treeseed/sdk"
verifiers:
sdk.golden.fixed-permissions-unit:
kind: vitestCase
ownerPackage: "@treeseed/sdk"
testFile: tests/unit/operator-contracts/golden-product.test.ts
testName: "rejects missing extra duplicate and alternate permission requests for every fixed authored SDK role without repairing original bytes"
sdk.golden.standing-graph-order-unit:
kind: vitestCase
ownerPackage: "@treeseed/sdk"
Expand Down
16 changes: 14 additions & 2 deletions tests/acceptance/golden-product.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import assert from 'node:assert/strict';
import { closeSync, constants, fstatSync, lstatSync, openSync, readFileSync, realpathSync } from 'node:fs';
import { basename, isAbsolute, resolve } from 'node:path';
import { exactEntityReferenceSchema, executionEdgeSchema } from '@treeseed/sdk/agent-capacity';
import { exactEntityReferenceSchema, executionEdgeSchema, activityProfileSchema } from '@treeseed/sdk/agent-capacity';
import { validatePortableContentData } from '@treeseed/sdk/content-validation';
import { createHash } from 'node:crypto';
import { parse, parseDocument, visit } from 'yaml';
Expand Down Expand Up @@ -92,13 +92,24 @@ function verifySdkGoldenAuthoredWork(proposal: Row, draft = false): void {
&& new Set(authored.map(item => item.id)).size === fixedRows.length,
`${graphCode}: Six unique original authored work items required`);
for (const [id, agentClass, workspace] of fixedRows) {
const item = authored.find(row => row.id === id);
const item: Row | undefined = authored.find(row => row.id === id);
assert.ok(item && item.agentClass === agentClass && item.workspace === workspace
&& item.activity === 'acting' && item.review === 'required' && item.maximumReviewCycles === 2
&& Array.isArray(item.dependsOn) && item.dependsOn.length === 0
&& ['objective', 'contextRefs', 'requestedPermissions', 'requiredCapabilities', 'acceptanceCriteria',
...(draft ? [] : ['estimate', 'reviewEstimate'])].every(field => Object.hasOwn(item, field)),
`${graphCode}: Original ${id} class workspace dependencies and review policy required`);
const permissionCode = `ACCEPTANCE_SDK_PERMISSIONS: ${graphCode}`;
const permissions = activityProfileSchema.shape.permissions.safeParse(item.requestedPermissions);
assert.ok(permissions.success, `${permissionCode}: Complete canonical original permission request required`);
const reads: string[] = ['book', 'knowledge', 'objective', 'proposal', 'decision', 'note', 'question'];
const writes: string[] = agentClass === 'researcher' ? ['knowledge', 'note', 'question']
: agentClass === 'architect' ? ['book', 'knowledge', 'note', 'question'] : [];
const tools: string[] = workspace === 'treedx' ? ['discussion', 'source.read']
: ['source.read', 'source.write', 'verification', ...(agentClass === 'releaser' ? ['release'] : [])];
const lists: [readonly string[], readonly string[]][] = [[permissions.data.content.read, reads], [permissions.data.content.write, writes], [permissions.data.tools, tools]];
for (const [actual, expected] of lists)
assert.deepEqual([...actual].sort(), [...expected].sort(), `${permissionCode}: Exact ${id} requested content and tools required`);
if (draft) assert.ok(['estimate', 'reviewEstimate', 'ownerEstimate', 'reviewerEstimate'].every(field => !Object.hasOwn(item, field))
&& typeof item.objective === 'string' && item.objective.trim()
&& Array.isArray(item.contextRefs) && item.contextRefs.length > 0
Expand Down Expand Up @@ -130,6 +141,7 @@ function verifySdkGoldenGraph(proposal: Row, attempt: Row, graph: Row | undefine
&& node.maximumReviewCycles === item.maximumReviewCycles && item.review === 'required',
`${code}: Authored Actor or generated Reviewer authority drifted`);
assert.deepEqual(node.sourceRef, attempt.sourceRef, `${code}: Pair must represent the exact original authored proposal`);
if (role === 'actor') assert.deepEqual(node.requestedPermissions, item.requestedPermissions, `${code}: Actor must retain its original authored permission request`);
}
const orderCode = 'ACCEPTANCE_SDK_GRAPH_ORDER';
assert.ok(Array.isArray(graph.edges), `${orderCode}: Independent complete public edges required`);
Expand Down
21 changes: 19 additions & 2 deletions tests/unit/operator-contracts/acceptance/golden-product-fixture.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,20 @@ import { createHash } from 'node:crypto';
import { parse, stringify } from 'yaml';
export const commit = 'a'.repeat(40);
const libraryCommit = 'c'.repeat(40);
export const permissionFailures = ['missing-read', 'extra-read', 'duplicate-read', 'missing-write', 'extra-write', 'missing-tool', 'extra-tool', 'duplicate-tool', 'unknown-field'] as const;
export const permissionCases = Array.from({ length: 6 }, (_, index) => permissionFailures.map(mode => `${index}-${mode}`)).flat();
export function mutatePermissionRequest(value: typeof proposal, failure: string): void {
const index = Number(failure[0]), mode = failure.slice(2), permissions = value.executionPlan.workItems[index]!.requestedPermissions;
if (mode === 'missing-read') permissions.content.read.pop();
if (mode === 'extra-read') permissions.content.read.push('discussion');
if (mode === 'duplicate-read') permissions.content.read.push(permissions.content.read[0]!);
if (mode === 'missing-write') Reflect.deleteProperty(permissions.content, 'write');
if (mode === 'extra-write') permissions.content.write.push('proposal');
if (mode === 'missing-tool') permissions.tools.pop();
if (mode === 'extra-tool') permissions.tools.push('external.publish');
if (mode === 'duplicate-tool') permissions.tools.push(permissions.tools[0]!);
if (mode === 'unknown-field') Reflect.set(permissions, 'alternateAuthority', true);
}
export const graphOrderFailures = ['missing-edges', 'malformed-edge', 'duplicate-edge', 'missing-pair', 'extra-pair', 'missing-profile',
'transitive-profile', 'actor-profile', 'research-profile', 'work-item-profile', 'foreign-edge-team', 'edge-source-id',
'edge-source-revision', 'edge-source-digest', 'edge-source-commit', 'edge-source-path', 'edge-source-repository', 'missing-edge-source',
Expand All @@ -28,14 +42,15 @@ export function mutateGraphOrder(graph: { edges: Array<Record<string, unknown>>
}
export const graphPairFailures = ['missing', 'foreign-team', 'duplicate-id', 'missing-node', 'extra-node', 'work-item',
'pair-role', 'kind', 'class', 'workspace', 'cycles', 'project', 'team', 'workday', 'source-id', 'source-revision',
'source-digest', 'source-commit', 'source-path', 'source-repository'] as const;
'source-digest', 'source-commit', 'source-path', 'source-repository', 'permission-request'] as const;
export function mutateGraphPair(graph: { teamId: string; nodes: Array<Record<string, unknown>> }, mode: string): void {
const node = graph.nodes[1]!;
if (mode === 'missing') Reflect.deleteProperty(graph, 'nodes');
else if (mode === 'foreign-team') graph.teamId = 'foreign';
else if (mode === 'duplicate-id') node.id = graph.nodes[0]!.id;
else if (mode === 'missing-node') graph.nodes.pop();
else if (mode === 'extra-node') graph.nodes.push({ ...node, id: 'extra-pair' });
else if (mode === 'permission-request') Reflect.set(graph.nodes[0]!, 'requestedPermissions', { content: { read: [], write: [] }, tools: [] });
else if (mode.startsWith('source-')) Reflect.set(node.sourceRef as object, mode.slice(7), mode === 'source-revision' ? 2 : mode === 'source-digest' ? `sha256:${'e'.repeat(64)}` : mode === 'source-commit' ? 'd'.repeat(40) : 'foreign');
else Reflect.set(node, ({ 'work-item': 'workItemId', 'pair-role': 'pairRole', class: 'agentClass', cycles: 'maximumReviewCycles',
project: 'projectId', team: 'teamId', workday: 'workdayId' } as Record<string, string>)[mode] ?? mode,
Expand Down Expand Up @@ -65,7 +80,9 @@ export const proposal = { schemaVersion: 'treeseed.proposal/v1', status: 'ready'
objective: `Controlled explicit ${id} objective`, estimate: { expectedSeconds: 120, maximumSeconds: 240 },
reviewEstimate: { expectedSeconds: 60, maximumSeconds: 120 },
contextRefs: [{ store: workspace, model: 'repository', id: 'sdk', repository: workspace === 'git' ? 'treeseed-ai/sdk' : 'repo_sdk_fixture', commit }],
requestedPermissions: { content: { read: ['proposal', 'decision'], write: [] }, tools: ['source.read'] },
requestedPermissions: { content: { read: ['book', 'knowledge', 'objective', 'proposal', 'decision', 'note', 'question'],
write: agentClass === 'researcher' ? ['knowledge', 'note', 'question'] : agentClass === 'architect' ? ['book', 'knowledge', 'note', 'question'] : [] },
tools: workspace === 'treedx' ? ['discussion', 'source.read'] : ['source.read', 'source.write', 'verification', ...(agentClass === 'releaser' ? ['release'] : [])] },
requiredCapabilities: ['source.read'], acceptanceCriteria: [`Verify controlled ${id} outcome.`] })) },
evidenceRefs: [{ store: 'url', model: 'issue', id: 'sdk-source-1', url: 'https://github.com/treeseed-ai/sdk/issues/299' }],
summary: 'Prove the SDK can express high-level decision-governed execution while keeping all derived execution state API-owned.' };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { resolve } from 'node:path';
import { createHash } from 'node:crypto';
import { parse } from 'yaml';
import { expect, it } from 'vitest';
import { commit, release, review, proposal, proposalReadback, graphPairFailures, mutateGraphPair, graphOrderFailures, mutateGraphOrder } from './golden-product-fixture.ts';
import { commit, release, review, proposal, proposalReadback, graphPairFailures, mutateGraphPair, graphOrderFailures, mutateGraphOrder, permissionCases, mutatePermissionRequest } from './golden-product-fixture.ts';
import { workdayStartFixture } from './workday-start-fixture.ts';

it('native public SDK proposal reads in isolated product verification reject changed stored identity title and summary and retain denied observations before unchanged retry', async () => {
Expand All @@ -17,6 +17,7 @@ it('native public SDK proposal reads in isolated product verification reject cha
: kind === 'reference-repository' ? bytes.replace('repository: repo_sdk_fixture', 'repository: repo_foreign')
: kind === 'reference-path' ? bytes.replace('path: proposals/governance/sdk-proposal.mdx', 'path: proposals/foreign.mdx') : bytes;
const original = structuredClone({ release, review, proposal });
const nativeBase = proposalReadback(proposal).original;
const retainedInput = workdayStartFixture(), inputPath = resolve(retainedInput.root, 'proposal-input.json');
const initial = { ...structuredClone(proposal), status: 'draft' };
for (const item of initial.executionPlan.workItems) { Reflect.deleteProperty(item, 'estimate'); Reflect.deleteProperty(item, 'reviewEstimate'); }
Expand All @@ -28,7 +29,8 @@ it('native public SDK proposal reads in isolated product verification reject cha
const fail = (error: Error) => { for (const item of pending.values()) { clearTimeout(item.timer); item.reject(error); } pending.clear(); };
const server = createServer((request, response) => {
let bytes = ''; request.setEncoding('utf8'); request.on('data', value => { bytes += String(value); }); request.on('end', () => {
const fixture = proposalReadback(proposal, mode === 'budget-boundary' ? 1_048_576 : undefined).original, path = request.method === 'POST' ? JSON.parse(bytes).paths?.[0] : undefined;
const fixture = mode === 'budget-boundary' ? proposalReadback(proposal, 1_048_576).original : structuredClone(nativeBase);
const path = request.method === 'POST' ? JSON.parse(bytes).paths?.[0] : undefined;
if (request.url === '/v1/teams/sdk-team/execution-graph') {
graphCalls.push(`${request.method} ${request.url}`); response.setHeader('content-type', 'application/json');
if (mode.startsWith('graph-')) graphFailures.push(mode);
Expand Down Expand Up @@ -69,6 +71,7 @@ it('native public SDK proposal reads in isolated product verification reject cha
}
if (mode === 'json') { response.end('{'); return; }
const returned: Record<string, unknown> = { ...proposal };
if (mode.startsWith('permissions-')) { const changed = structuredClone(proposal); mutatePermissionRequest(changed, mode.slice(12)); returned.executionPlan = changed.executionPlan; }
if (['reference-open', 'reference-repository', 'reference-path'].includes(mode)) returned.discussionRef = { ...proposal.discussionRef,
digest: `sha256:${createHash('sha256').update(fixture.referenceFiles[2]!.files[0]!.content).digest('hex')}` };
if (mode === 'populated-status') returned.status = 'draft';
Expand Down Expand Up @@ -255,6 +258,11 @@ Reflect.apply(verifySdkGoldenProduct,undefined,[actors,${JSON.stringify(commit)}
const preservedDrafts = structuredClone(deniedDrafts); writeFileSync(inputPath, inputBytes);
expect((await observe()).stdout).toBe('verified'); expect(deniedDrafts).toEqual(preservedDrafts);
expect(failed).toEqual(deniedReferences); expect(calls).toHaveLength(291);
const permissionStart = calls.length;
mode = 'exact'; expect((await Promise.all([observe(), observe()])).map(value => value.stdout)).toEqual(['verified', 'verified']);
for (const failure of permissionCases) { mode = `permissions-${failure}`; await expect.soft(observe(), mode).rejects.toThrow('ACCEPTANCE_SDK_PERMISSIONS'); }
const retainedPermissionFailures = structuredClone(failed); mode = 'exact'; expect((await observe()).stdout).toBe('verified');
expect(failed).toEqual(retainedPermissionFailures); expect(calls.slice(permissionStart)).toHaveLength((permissionCases.length + 3) * 3);
const graphStart = graphCalls.length;
mode = 'exact'; expect((await Promise.all([observe(), observe()])).map(value => value.stdout)).toEqual(['verified', 'verified']);
for (const denial of [...graphPairFailures, ...graphOrderFailures, 'denied', 'unavailable', 'interrupted', 'json']) {
Expand Down
26 changes: 25 additions & 1 deletion tests/unit/operator-contracts/golden-product.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,34 @@ import { readFileSync } from 'node:fs';
import { sdkGoldenSource, sdkGoldenLibraryFiles, verifySdkGoldenProposalReferences, verifySdkGoldenProduct as verifyProduct } from '../../acceptance/golden-product.ts';
import { stringify } from 'yaml';
import { createHash } from 'node:crypto';
import { commit, release, review, proposal, proposalReadback, graphPairFailures, mutateGraphPair, graphOrderFailures, mutateGraphOrder } from './acceptance/golden-product-fixture.ts';
import { commit, release, review, proposal, proposalReadback, graphPairFailures, mutateGraphPair, graphOrderFailures, mutateGraphOrder, permissionCases, mutatePermissionRequest } from './acceptance/golden-product-fixture.ts';
const verifySdkGoldenProduct = (items: Parameters<typeof verifyProduct>[0], source: string) =>
Reflect.apply(verifyProduct, undefined, [items, source, proposalReadback().governance, proposalReadback().original]);
describe('SDK golden product gate (fixtures are not acceptance)', () => {
it('rejects missing extra duplicate and alternate permission requests for every fixed authored SDK role without repairing original bytes', () => {
const exact = proposalReadback(), inspect = (value: typeof exact) => Reflect.apply(verifyProduct, undefined, [[release, review], commit, value.governance, value.original]);
expect(() => inspect(exact)).not.toThrow();
const substituted = structuredClone(exact); substituted.original.graph.nodes[0]!.requestedPermissions.tools = [];
const heldGraph = structuredClone(substituted);
expect.soft(() => inspect(substituted)).toThrow('ACCEPTANCE_SDK_GRAPH_PAIRS'); expect(substituted).toEqual(heldGraph);
const permuted = structuredClone(proposal);
for (const item of permuted.executionPlan.workItems) { item.requestedPermissions.content.read.reverse(); item.requestedPermissions.content.write.reverse(); item.requestedPermissions.tools.reverse(); }
const reordered = proposalReadback(permuted), actor = structuredClone(release), reviewer = structuredClone(review);
for (const item of permuted.executionPlan.workItems) {
reordered.original.initialProposal.executionPlan.workItems.find(value => value.id === item.id)!.requestedPermissions = structuredClone(item.requestedPermissions);
reordered.original.graph.nodes.find(value => value.workItemId === item.id && value.pairRole === 'actor')!.requestedPermissions = structuredClone(item.requestedPermissions);
}
for (const item of [actor, reviewer]) item.assignmentAttempt.sourceRef.digest = `sha256:${reordered.governance.activeContentHash}`;
const heldPermutation = structuredClone({ reordered, actor, reviewer });
expect(() => Reflect.apply(verifyProduct, undefined, [[actor, reviewer], commit, reordered.governance, reordered.original])).not.toThrow();
expect({ reordered, actor, reviewer }).toEqual(heldPermutation);
for (const mode of permissionCases) {
const changed = structuredClone(proposal); mutatePermissionRequest(changed, mode);
const observed = proposalReadback(changed), held = structuredClone(observed);
expect.soft(() => inspect(observed), mode).toThrow('ACCEPTANCE_SDK_PERMISSIONS'); expect(observed).toEqual(held);
}
expect(() => inspect(exact)).not.toThrow();
});
it('rejects counted graph pairs without independent research and exact immediate governed profile ordering', () => {
const observed = proposalReadback();
const inspect = (value: typeof observed) => Reflect.apply(verifyProduct, undefined, [[release, review], commit, value.governance, value.original]);
Expand Down
Loading