diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 00000000..9dbb6d39 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,57 @@ + + +## Outcome + + + +## Work authority + +- Work item / Issue: +- Proposal / decision: +- Assignment / checkpoint: +- Actor: +- Human authority: +- Agent / capacity provider: +- Exact base ref: +- Exact head ref: + +Contributor mode (select one): + +- [ ] Human-authored +- [ ] Agent-assisted under human authority +- [ ] Agent-authored under human authority + +## Plan + + + +## Changes and commits + + + +## Verification + + + +## Risk and rollback + + + +## Completion summary + + + +## Submission checklist + +- [ ] The change is bounded to the stated work item and target repository. +- [ ] Exact base and head refs are recorded and the branch is ready for review. +- [ ] Verification and compatibility evidence are recorded above. +- [ ] No plaintext secrets, credentials, machine state, or unrelated residue are included. +- [ ] Plan, status, commits, and completion summary form a complete durable record. +- [ ] Rollback or recovery steps are documented and executable. diff --git a/.github/workflows/pull-request-contract.yml b/.github/workflows/pull-request-contract.yml new file mode 100644 index 00000000..5d5232f0 --- /dev/null +++ b/.github/workflows/pull-request-contract.yml @@ -0,0 +1,103 @@ +name: Pull Request Submission Contract + +on: + pull_request_target: + types: [opened, edited, reopened, synchronize, ready_for_review, converted_to_draft] + +permissions: + contents: read + pull-requests: read + +jobs: + validate: + runs-on: ubuntu-latest + steps: + - name: Validate durable PR record + uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7 + with: + script: | + const pullRequest = context.payload.pull_request; + const body = (pullRequest?.body ?? '').replace(//gu, ''); + + const requiredSections = [ + 'Outcome', + 'Work authority', + 'Plan', + 'Changes and commits', + 'Verification', + 'Risk and rollback', + 'Completion summary', + 'Submission checklist', + ]; + const missingSections = requiredSections.filter( + (section) => !body.includes(`## ${section}`), + ); + + const requiredFields = [ + 'Work item / Issue', + 'Proposal / decision', + 'Assignment / checkpoint', + 'Actor', + 'Human authority', + 'Agent / capacity provider', + 'Exact base ref', + 'Exact head ref', + ]; + const fieldValues = new Map(requiredFields.map((field) => { + const escaped = field.replace(/[.*+?^$()|[\]\\]/gu, '\\$&'); + const match = body.match(new RegExp(`^- ${escaped}:\\s*(\\S.+)$`, 'mu')); + return [field, match?.[1]?.trim() ?? '']; + })); + const missingFields = requiredFields.filter((field) => !fieldValues.get(field)); + + const contributorModes = body.match( + /^- \[[xX]\] (?:Human-authored|Agent-assisted under human authority|Agent-authored under human authority)$/gmu, + ) ?? []; + + const errors = []; + if (missingSections.length > 0) { + errors.push(`missing sections: ${missingSections.join(', ')}`); + } + if (missingFields.length > 0) { + errors.push(`missing work-authority values: ${missingFields.join(', ')}`); + } + if (contributorModes.length !== 1) { + errors.push('select exactly one contributor mode'); + } + + for (const [field, expectedSha] of [ + ['Exact base ref', pullRequest?.base?.sha], + ['Exact head ref', pullRequest?.head?.sha], + ]) { + const recordedSha = fieldValues.get(field)?.match(/(?:^|[^0-9a-f])([0-9a-f]{40})(?:$|[^0-9a-f])/u)?.[1]; + if (!recordedSha) { + errors.push(`${field} must contain a full 40-character commit SHA`); + } else if (recordedSha !== expectedSha) { + errors.push(`${field} is stale: expected ${expectedSha}`); + } + } + + if (!pullRequest?.draft) { + const readinessItems = [ + 'The change is bounded to the stated work item and target repository.', + 'Exact base and head refs are recorded and the branch is ready for review.', + 'Verification and compatibility evidence are recorded above.', + 'No plaintext secrets, credentials, machine state, or unrelated residue are included.', + 'Plan, status, commits, and completion summary form a complete durable record.', + 'Rollback or recovery steps are documented and executable.', + ]; + const unchecked = readinessItems.filter( + (item) => !body.split(/\r?\n/u).some( + (line) => line.trim() === `- [x] ${item}` || line.trim() === `- [X] ${item}`, + ), + ); + if (unchecked.length > 0) { + errors.push(`ready PR has incomplete checklist items: ${unchecked.join(' | ')}`); + } + } + + if (errors.length > 0) { + core.setFailed( + `Complete .github/PULL_REQUEST_TEMPLATE.md in the PR description: ${errors.join('; ')}`, + ); + } diff --git a/docs/src/content/agents/architect.mdx b/docs/src/content/agents/architect.mdx index 5b02d33f..d0bfc2b5 100644 --- a/docs/src/content/agents/architect.mdx +++ b/docs/src/content/agents/architect.mdx @@ -144,6 +144,7 @@ activityProfiles: outputs: messageTypes: [] modelMutations: + - proposal:create - linked_note:create - proposal_feedback:create - question:create @@ -161,12 +162,14 @@ activityProfiles: activityType: estimating enabled: true handler: estimate + planningIntent: + subjectModel: proposal prompt: system: | You are the Architect for this TreeSeed project. Defines the project architecture, objectives, standards, and decision-aligned knowledge structure. Use TreeDX-backed content tools for all project content and keep work scoped to the current activity profile. task: estimating branchPolicy: - kind: read-only + kind: main-planning-content base: main permissions: content: @@ -241,7 +244,7 @@ activityProfiles: - validate - commit commit: - allowed: false + allowed: true tools: allowed: - treeseed.content.describe @@ -278,7 +281,7 @@ activityProfiles: You are the Architect for this TreeSeed project. Defines the project architecture, objectives, standards, and decision-aligned knowledge structure. Use TreeDX-backed content tools for all project content and keep work scoped to the current activity profile. task: reviewing branchPolicy: - kind: read-only + kind: main-planning-content base: main permissions: content: @@ -353,7 +356,7 @@ activityProfiles: - validate - commit commit: - allowed: false + allowed: true tools: allowed: - treeseed.content.describe diff --git a/docs/src/content/agents/engineer.mdx b/docs/src/content/agents/engineer.mdx index 347b9107..b6c89e3c 100644 --- a/docs/src/content/agents/engineer.mdx +++ b/docs/src/content/agents/engineer.mdx @@ -160,12 +160,14 @@ activityProfiles: activityType: estimating enabled: true handler: estimate + planningIntent: + subjectModel: proposal prompt: system: | You are the Engineer for this TreeSeed project. Implements decision-scoped code and configuration changes without modifying tests. Use TreeDX-backed content tools for all project content and keep work scoped to the current activity profile. task: estimating branchPolicy: - kind: read-only + kind: main-planning-content base: main permissions: content: @@ -240,7 +242,7 @@ activityProfiles: - validate - commit commit: - allowed: false + allowed: true tools: allowed: - treeseed.content.describe @@ -277,7 +279,7 @@ activityProfiles: You are the Engineer for this TreeSeed project. Implements decision-scoped code and configuration changes without modifying tests. Use TreeDX-backed content tools for all project content and keep work scoped to the current activity profile. task: reviewing branchPolicy: - kind: read-only + kind: main-planning-content base: main permissions: content: @@ -352,7 +354,7 @@ activityProfiles: - validate - commit commit: - allowed: false + allowed: true tools: allowed: - treeseed.content.describe @@ -386,8 +388,8 @@ activityProfiles: handler: actor prompt: system: | - You are the Engineer for this TreeSeed project. Implements decision-scoped code and configuration changes without modifying tests. Use TreeDX-backed content tools for all project content and keep work scoped to the current activity profile. - task: acting + You are the Engineer for this TreeSeed project. Begin only from an approved decision, ready execution node, accepted capacity plan, recorded exact base ref, and a verified failing-test integration ref from the Tester. Integrate that exact test ref through the assigned TreeSeed workflow operation, implement the smallest owning-abstraction change, and do not modify test files. Run focused and affected verification, use the assignment checkpoint tool to create the local implementation commit, record changed paths and command receipts, and return that commit ref for review. Use TreeDX for project content. Never push, merge, tag, deploy, or mutate provider infrastructure directly. + task: implement-against-failing-test branchPolicy: kind: assignment-feature base: staging @@ -492,6 +494,7 @@ activityProfiles: - treedx.commit_workspace - treeseed.changed_paths - treeseed.verify + - treeseed.checkpoint - treeseed.dev_plan outputs: messageTypes: [] @@ -508,6 +511,18 @@ activityProfiles: maxRuntimeSeconds: 1800 maxRetries: 2 verificationRequired: true + allowedPaths: + - src/** + - scripts/** + - package.json + - package-lock.json + - treeseed.package.yaml + - tsconfig*.json + forbiddenPaths: + - test/** + - tests/** + - spec/** + - specs/** --- Engineer for the agent TreeSeed project. diff --git a/docs/src/content/agents/releaser.mdx b/docs/src/content/agents/releaser.mdx index 2d2ae003..959e3c49 100644 --- a/docs/src/content/agents/releaser.mdx +++ b/docs/src/content/agents/releaser.mdx @@ -164,12 +164,14 @@ activityProfiles: activityType: estimating enabled: true handler: estimate + planningIntent: + subjectModel: proposal prompt: system: | You are the Releaser for this TreeSeed project. Verifies staged changes and coordinates reliable release from staging through TreeSeed release operations. Use TreeDX-backed content tools for all project content and keep work scoped to the current activity profile. task: estimating branchPolicy: - kind: read-only + kind: main-planning-content base: main permissions: content: @@ -244,7 +246,7 @@ activityProfiles: - validate - commit commit: - allowed: false + allowed: true tools: allowed: - treeseed.content.describe @@ -281,7 +283,7 @@ activityProfiles: You are the Releaser for this TreeSeed project. Verifies staged changes and coordinates reliable release from staging through TreeSeed release operations. Use TreeDX-backed content tools for all project content and keep work scoped to the current activity profile. task: reviewing branchPolicy: - kind: read-only + kind: main-planning-content base: main permissions: content: @@ -356,7 +358,7 @@ activityProfiles: - validate - commit commit: - allowed: false + allowed: true tools: allowed: - treeseed.content.describe @@ -390,8 +392,8 @@ activityProfiles: handler: releaser prompt: system: | - You are the Releaser for this TreeSeed project. Verifies staged changes and coordinates reliable release from staging through TreeSeed release operations. Use TreeDX-backed content tools for all project content and keep work scoped to the current activity profile. - task: acting + You are the Releaser for this TreeSeed project. Assess release readiness only after approved review, required revision completion, passing verification, documentation evidence, complete artifact manifests, and settled usage. Invoke only assignment-scoped TreeSeed operations-runner handles. Do not call git or hosting providers directly, and do not claim deployment while hosted deployment is suspended. Record the exact ref, guarantees, blockers, and permitted next operation through TreeDX. + task: verify-release-readiness-and-handoff branchPolicy: kind: staging-release base: staging diff --git a/docs/src/content/agents/researcher.mdx b/docs/src/content/agents/researcher.mdx index 1fb71d17..c8e27f92 100644 --- a/docs/src/content/agents/researcher.mdx +++ b/docs/src/content/agents/researcher.mdx @@ -161,12 +161,14 @@ activityProfiles: activityType: estimating enabled: true handler: estimate + planningIntent: + subjectModel: proposal prompt: system: | You are the Researcher for this TreeSeed project. Answers questions and improves project knowledge through TreeDX-backed research content. Use TreeDX-backed content tools for all project content and keep work scoped to the current activity profile. task: estimating branchPolicy: - kind: read-only + kind: main-planning-content base: main permissions: content: @@ -241,7 +243,7 @@ activityProfiles: - validate - commit commit: - allowed: false + allowed: true tools: allowed: - treeseed.content.describe @@ -278,7 +280,7 @@ activityProfiles: You are the Researcher for this TreeSeed project. Answers questions and improves project knowledge through TreeDX-backed research content. Use TreeDX-backed content tools for all project content and keep work scoped to the current activity profile. task: reviewing branchPolicy: - kind: read-only + kind: main-planning-content base: main permissions: content: @@ -353,7 +355,7 @@ activityProfiles: - validate - commit commit: - allowed: false + allowed: true tools: allowed: - treeseed.content.describe diff --git a/docs/src/content/agents/reviewer.mdx b/docs/src/content/agents/reviewer.mdx index 49d9e806..4d554965 100644 --- a/docs/src/content/agents/reviewer.mdx +++ b/docs/src/content/agents/reviewer.mdx @@ -161,12 +161,14 @@ activityProfiles: activityType: estimating enabled: true handler: estimate + planningIntent: + subjectModel: proposal prompt: system: | You are the Reviewer for this TreeSeed project. Reviews knowledge, proposals, deliverables, and staged work for accuracy, clarity, and risk. Use TreeDX-backed content tools for all project content and keep work scoped to the current activity profile. task: estimating branchPolicy: - kind: read-only + kind: main-planning-content base: main permissions: content: @@ -241,7 +243,7 @@ activityProfiles: - validate - commit commit: - allowed: false + allowed: true tools: allowed: - treeseed.content.describe @@ -278,7 +280,7 @@ activityProfiles: You are the Reviewer for this TreeSeed project. Reviews knowledge, proposals, deliverables, and staged work for accuracy, clarity, and risk. Use TreeDX-backed content tools for all project content and keep work scoped to the current activity profile. task: reviewing branchPolicy: - kind: read-only + kind: main-planning-content base: main permissions: content: @@ -353,7 +355,7 @@ activityProfiles: - validate - commit commit: - allowed: false + allowed: true tools: allowed: - treeseed.content.describe @@ -387,8 +389,8 @@ activityProfiles: handler: writer prompt: system: | - You are the Reviewer for this TreeSeed project. Reviews knowledge, proposals, deliverables, and staged work for accuracy, clarity, and risk. Use TreeDX-backed content tools for all project content and keep work scoped to the current activity profile. Finish every acting review by calling treeseed.review_decision with an evidence-based approved or rejected disposition. - task: acting + You are the Engineering Reviewer. Compare the approved decision, failing-test evidence, integration refs, implementation diff, verification receipts, architecture boundaries, security, recovery behavior, and documentation needs. Confirm the engineer did not weaken or rewrite the test. Create linked findings through TreeDX. A blocking finding must create revision work and prevent release readiness; approval must cite the exact reviewed refs and verification evidence. Finish by calling treeseed.review_decision with the evidence-based approved or rejected disposition. Never merge, push, tag, deploy, or mutate provider infrastructure directly. + task: review-implementation-and-test-evidence branchPolicy: kind: main-planning-content base: main diff --git a/docs/src/content/agents/technical-writer.mdx b/docs/src/content/agents/technical-writer.mdx index 00fef6de..136344d2 100644 --- a/docs/src/content/agents/technical-writer.mdx +++ b/docs/src/content/agents/technical-writer.mdx @@ -160,12 +160,14 @@ activityProfiles: activityType: estimating enabled: true handler: estimate + planningIntent: + subjectModel: proposal prompt: system: | You are the Technical Writer for this TreeSeed project. Maintains user, developer, and operator documentation for released and staged project capabilities. Use TreeDX-backed content tools for all project content and keep work scoped to the current activity profile. task: estimating branchPolicy: - kind: read-only + kind: main-planning-content base: main permissions: content: @@ -240,7 +242,7 @@ activityProfiles: - validate - commit commit: - allowed: false + allowed: true tools: allowed: - treeseed.content.describe @@ -277,7 +279,7 @@ activityProfiles: You are the Technical Writer for this TreeSeed project. Maintains user, developer, and operator documentation for released and staged project capabilities. Use TreeDX-backed content tools for all project content and keep work scoped to the current activity profile. task: reviewing branchPolicy: - kind: read-only + kind: main-planning-content base: main permissions: content: @@ -352,7 +354,7 @@ activityProfiles: - validate - commit commit: - allowed: false + allowed: true tools: allowed: - treeseed.content.describe @@ -383,14 +385,20 @@ activityProfiles: acting: activityType: acting enabled: true - handler: writer + handler: actor prompt: system: | - You are the Technical Writer for this TreeSeed project. Maintains user, developer, and operator documentation for released and staged project capabilities. Use TreeDX-backed content tools for all project content and keep work scoped to the current activity profile. - task: acting + You are the Technical Writer for this TreeSeed project. Begin only from an approved decision, ready execution node, accepted capacity plan, and recorded exact base ref. Update only documentation that is supported by verified implementation and test evidence. Use the assignment checkpoint tool to create the local documentation commit, record changed paths and verification receipts, and return that exact commit ref for review. Use TreeDX for project content and assignment-scoped workflow tools for repository operations. Never modify implementation or test code, push, merge, tag, deploy, or mutate provider infrastructure directly. + task: document-verified-project-behavior branchPolicy: - kind: staging-content + kind: assignment-feature base: staging + target: staging + branchNameTemplate: agent/{agentSlug}/{assignmentId} + worktree: new + updateBaseBeforeRun: true + mergeTargetBeforeSave: true + prefix: technical-writer permissions: content: question: @@ -484,6 +492,9 @@ activityProfiles: - treeseed.content.commit - treedx.apply_workspace_changeset - treedx.commit_workspace + - treeseed.changed_paths + - treeseed.verify + - treeseed.checkpoint outputs: messageTypes: [] modelMutations: @@ -498,7 +509,17 @@ activityProfiles: - agent-execution maxRuntimeSeconds: 1800 maxRetries: 2 - verificationRequired: false + verificationRequired: true + allowedPaths: + - docs/** + - README.md + - CHANGELOG.md + forbiddenPaths: + - src/** + - test/** + - tests/** + - spec/** + - specs/** --- Technical Writer for the agent TreeSeed project. diff --git a/docs/src/content/agents/tester.mdx b/docs/src/content/agents/tester.mdx index e5069c72..2c5c658f 100644 --- a/docs/src/content/agents/tester.mdx +++ b/docs/src/content/agents/tester.mdx @@ -160,12 +160,14 @@ activityProfiles: activityType: estimating enabled: true handler: estimate + planningIntent: + subjectModel: proposal prompt: system: | You are the Tester for this TreeSeed project. Creates tests before implementation and verifies behavior without modifying implementation code. Use TreeDX-backed content tools for all project content and keep work scoped to the current activity profile. task: estimating branchPolicy: - kind: read-only + kind: main-planning-content base: main permissions: content: @@ -240,7 +242,7 @@ activityProfiles: - validate - commit commit: - allowed: false + allowed: true tools: allowed: - treeseed.content.describe @@ -277,7 +279,7 @@ activityProfiles: You are the Tester for this TreeSeed project. Creates tests before implementation and verifies behavior without modifying implementation code. Use TreeDX-backed content tools for all project content and keep work scoped to the current activity profile. task: reviewing branchPolicy: - kind: read-only + kind: main-planning-content base: main permissions: content: @@ -352,7 +354,7 @@ activityProfiles: - validate - commit commit: - allowed: false + allowed: true tools: allowed: - treeseed.content.describe @@ -386,8 +388,8 @@ activityProfiles: handler: actor prompt: system: | - You are the Tester for this TreeSeed project. Creates tests before implementation and verifies behavior without modifying implementation code. Use TreeDX-backed content tools for all project content and keep work scoped to the current activity profile. - task: acting + You are the Tester for this TreeSeed project. Begin only from an approved decision, ready execution node, accepted capacity plan, and recorded exact base ref. Create the smallest regression or acceptance test that proves the requested behavior without modifying implementation. Run it and require an expected failure that demonstrates the missing behavior rather than a broken fixture. Use the assignment checkpoint tool to create the local test commit, then record commands, output, changed test paths, failure reason, exact worktree ref, and commit ref for the engineer. Use TreeDX for project content and assignment-scoped workflow tools for code operations. Never push, merge, tag, deploy, or mutate provider infrastructure directly. + task: create-and-prove-failing-test branchPolicy: kind: assignment-feature base: staging @@ -492,6 +494,7 @@ activityProfiles: - treedx.commit_workspace - treeseed.changed_paths - treeseed.verify + - treeseed.checkpoint - treeseed.dev_plan outputs: messageTypes: [] @@ -508,6 +511,14 @@ activityProfiles: maxRuntimeSeconds: 1800 maxRetries: 2 verificationRequired: true + allowedPaths: + - test/** + - tests/** + - spec/** + - specs/** + - fixtures/** + forbiddenPaths: + - src/** --- Tester for the agent TreeSeed project. diff --git a/package-lock.json b/package-lock.json index e050e97b..d6dcb9d4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "dependencies": { "@modelcontextprotocol/sdk": "^1.29.0", "@openai/codex-sdk": "^0.130.0", - "@treeseed/sdk": "github:treeseed-ai/sdk#f843c3cb11853db737d28ecc6bcc3d5df5e183e9", + "@treeseed/sdk": "github:treeseed-ai/sdk#92a66135fbda5575bee058b0ab25339c6c7d6398", "esbuild": "0.28.0", "hono": "^4.8.2", "typescript": "^5.9.3", @@ -3703,8 +3703,9 @@ }, "node_modules/@treeseed/sdk": { "version": "0.12.63-dev.fix-sdk-package-lock-integrity.20260818T124913Z", - "resolved": "git+ssh://git@github.com/treeseed-ai/sdk.git#f843c3cb11853db737d28ecc6bcc3d5df5e183e9", - "license": "AGPL-3.0-only", + "resolved": "git+ssh://git@github.com/treeseed-ai/sdk.git#92a66135fbda5575bee058b0ab25339c6c7d6398", + "integrity": "sha512-6w9qNqZCmHdgme7C3Ab14xUz5UnAz0HPq5+u1t3fE9Wb3OStn4TQbS6kGJ/l9wwPdoixjD0V2VOcjmjXIzsiuA==", + "license": "Apache-2.0", "dependencies": { "@github/copilot": "1.0.39", "@github/copilot-language-server": "1.480.0", @@ -3746,6 +3747,27 @@ "node": ">=22" } }, + "node_modules/@treeseed/sdk/node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@treeseed/sdk/node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, "node_modules/@tybys/wasm-util": { "version": "0.10.3", "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.3.tgz", diff --git a/package.json b/package.json index 64a4191b..58b3e73b 100644 --- a/package.json +++ b/package.json @@ -111,7 +111,7 @@ "dependencies": { "@modelcontextprotocol/sdk": "^1.29.0", "@openai/codex-sdk": "^0.130.0", - "@treeseed/sdk": "github:treeseed-ai/sdk#f843c3cb11853db737d28ecc6bcc3d5df5e183e9", + "@treeseed/sdk": "github:treeseed-ai/sdk#92a66135fbda5575bee058b0ab25339c6c7d6398", "esbuild": "0.28.0", "hono": "^4.8.2", "typescript": "^5.9.3", diff --git a/tests/unit/agents/definitions/agent-definition-compatibility.test.ts b/tests/unit/agents/definitions/agent-definition-compatibility.test.ts new file mode 100644 index 00000000..eb7ed14a --- /dev/null +++ b/tests/unit/agents/definitions/agent-definition-compatibility.test.ts @@ -0,0 +1,25 @@ +import { readdirSync,readFileSync } from 'node:fs'; +import { resolve } from 'node:path'; +import { pathToFileURL } from 'node:url'; +import { validateAgentDefinitionModel } from '@treeseed/sdk/agent-capacity'; +import { parse as parseYaml } from 'yaml'; +import { describe,expect,it } from 'vitest'; + +describe('Agent shipped agent definitions', () => { + it('remain compatible with the SDK authority and capacity-provider contract', async () => { + const { validateAgentActivityProfileCompatibility } = await import(pathToFileURL(resolve(process.cwd(),'node_modules/@treeseed/sdk/dist/agent-capacity/validation/compatibility/agent-definition-compatibility.js')).href); + const root = resolve(process.cwd(),'docs/src/content/agents'); + const names = readdirSync(root).filter((entry) => entry.endsWith('.mdx')).sort(); + expect(names.length).toBeGreaterThan(0); + for (const name of names) { + const source = readFileSync(resolve(root,name),'utf8'); + const match = source.match(/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/u); + expect(match,`${name} must contain YAML frontmatter`).not.toBeNull(); + const definition = parseYaml(match![1]) as Record; + expect(validateAgentDefinitionModel(definition),name).toMatchObject({ ok:true,diagnostics:[] }); + for (const [activityType,profile] of Object.entries(definition.activityProfiles ?? {}) as Array<[any,any]>) { + if (profile.enabled) expect(validateAgentActivityProfileCompatibility(activityType,profile),name).toMatchObject({ ok:true,diagnostics:[] }); + } + } + }); +});