From bc18e3367ea15223a12f4ca2f71716e71cdde461 Mon Sep 17 00:00:00 2001 From: Adrian Webb Date: Tue, 20 Oct 2026 11:55:09 -0400 Subject: [PATCH 1/4] test: reproduce grouped proposal kernel rejection (#496) --- tests/modern/kernel/proposal-groups.test.ts | 29 +++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 tests/modern/kernel/proposal-groups.test.ts diff --git a/tests/modern/kernel/proposal-groups.test.ts b/tests/modern/kernel/proposal-groups.test.ts new file mode 100644 index 00000000..f4011d99 --- /dev/null +++ b/tests/modern/kernel/proposal-groups.test.ts @@ -0,0 +1,29 @@ +import { describe, expect, it } from 'vitest'; +import { parse } from 'yaml'; +import { prepareTreeDxContent } from '../../../src/kernel/treedx-content-commit.ts'; + +const target = { store: 'treedx' as const, model: 'proposal', id: 'complete-scoped-snapshots', + repository: 'treeseed-ai/ui-library', commit: 'a'.repeat(40), path: 'proposals/complete-scoped-snapshots.mdx' }; +const frontmatter = { schemaVersion: 'treeseed.proposal/v1', id: target.id, projectId: 'ui', + title: 'Support complete scoped activity snapshots in UI', status: 'draft', + request: 'Replace complete snapshots, including empty results, while retaining incremental activity updates.', + groupIds: ['portfolio-atlas'] }; + +describe('kernel proposal group custody', () => { + it('retains the shared team group when preparing a real planning product for TreeDX', () => { + const input = { frontmatter, body: 'The shared UI component owns snapshot replacement; Admin consumes the same contract.' }; + const before = structuredClone(input), result = prepareTreeDxContent(target, input); + expect(parse(result.content.split('---')[1]!)).toEqual(frontmatter); + expect(result.content).toContain(input.body); + expect(result.digest).toMatch(/^sha256:[a-f0-9]{64}$/u); + expect(input).toEqual(before); + }); + + it('rejects individual targeting and malformed shared membership before any write', () => { + for (const extra of [{ agentIds: ['ui/engineer'] }, { agentSlugs: ['engineer'] }, + { groupIds: ['portfolio-atlas', 'portfolio-atlas'] }, { groupIds: ['bad group'] }]) { + expect(() => prepareTreeDxContent(target, { frontmatter: { ...frontmatter, ...extra }, body: 'Bounded real UI work.' })) + .toThrow('treedx_content_invalid'); + } + }); +}); From 78ca028b7a8587df20e9207fc3a8c60c05d76ecd Mon Sep 17 00:00:00 2001 From: Adrian Webb Date: Tue, 20 Oct 2026 11:56:44 -0400 Subject: [PATCH 2/4] fix: align provider and guest with shared proposal groups (#496) --- .github/workflows/verify.yml | 2 +- package-lock.json | 21 ++++++++++++++++----- package.json | 2 +- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/.github/workflows/verify.yml b/.github/workflows/verify.yml index c70691f0..e2f60474 100644 --- a/.github/workflows/verify.yml +++ b/.github/workflows/verify.yml @@ -76,7 +76,7 @@ jobs: mkdir -p node_modules/@treeseed/deployment/node_modules/@treeseed/sdk tar -xzf .treeseed/tools/deployment-build-sdk/treeseed-sdk-0.13.0-rc.122.tgz --strip-components=1 -C node_modules/@treeseed/deployment/node_modules/@treeseed/sdk npm install --prefix node_modules/@treeseed/deployment/node_modules/@treeseed/sdk --omit=dev --ignore-scripts --package-lock=false --no-save --no-audit --no-fund - - uses: treeseed-ai/sdk/.github/actions/install-exact-sdk@8536de5233983765a049392f307244d741470480 + - uses: treeseed-ai/sdk/.github/actions/install-exact-sdk@69c07896708deaaed228cc6e14f12c41e5289981 with: github-token: ${{ github.token }} - name: Prepare disposable native relay CA diff --git a/package-lock.json b/package-lock.json index d9f5554d..984ddc15 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "dependencies": { "@openai/codex": "0.158.0", "@treeseed/deployment": "https://github.com/treeseed-ai/deployment/releases/download/0.1.0-rc.243/treeseed-deployment-runtime-0.1.0-rc.243.tgz", - "@treeseed/sdk": "0.13.0-rc.122", + "@treeseed/sdk": "github:treeseed-ai/sdk#69c07896708deaaed228cc6e14f12c41e5289981", "esbuild": "0.28.2", "typescript": "^5.9.3", "yaml": "^2.8.1" @@ -1514,16 +1514,18 @@ } }, "node_modules/@treeseed/sdk": { - "version": "0.13.0-rc.122", - "resolved": "https://registry.npmjs.org/@treeseed/sdk/-/sdk-0.13.0-rc.122.tgz", - "integrity": "sha512-JKk6yDA1SDV2rWscnr95XsIGUdOcTYC8Ac6adQXkXArMriSVn0g25IPOntj2l2TK8s83KoKUmPaa9QfXbqg5jg==", + "version": "0.13.0-rc.123", + "resolved": "git+ssh://git@github.com/treeseed-ai/sdk.git#69c07896708deaaed228cc6e14f12c41e5289981", + "integrity": "sha512-EE1BZxRRqI/JT/OfW50D/fs7iSSKIYGNXP4zJ+SwbhbgTXCb+m+xt3IJWraY8qTmQiIE2WEx8erhJFQQUhscWQ==", + "license": "Apache-2.0", "dependencies": { "@treeseed/treedx": "0.3.0-rc.17", "esbuild": "^0.28.0", "libsodium-wrappers-sumo": "0.8.4", "typescript": "^5.9.3", "yaml": "^2.8.1", - "zod": "^3.25.76" + "zod": "^3.25.76", + "zod-to-json-schema": "^3.25.1" }, "engines": { "node": ">=22" @@ -3296,6 +3298,15 @@ "funding": { "url": "https://github.com/sponsors/colinhacks" } + }, + "node_modules/zod-to-json-schema": { + "version": "3.25.2", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.2.tgz", + "integrity": "sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==", + "license": "ISC", + "peerDependencies": { + "zod": "^3.25.28 || ^4" + } } } } diff --git a/package.json b/package.json index 01e56441..99b9ba7a 100644 --- a/package.json +++ b/package.json @@ -68,7 +68,7 @@ "dependencies": { "@openai/codex": "0.158.0", "@treeseed/deployment": "https://github.com/treeseed-ai/deployment/releases/download/0.1.0-rc.243/treeseed-deployment-runtime-0.1.0-rc.243.tgz", - "@treeseed/sdk": "0.13.0-rc.122", + "@treeseed/sdk": "github:treeseed-ai/sdk#69c07896708deaaed228cc6e14f12c41e5289981", "esbuild": "0.28.2", "typescript": "^5.9.3", "yaml": "^2.8.1" From ddcc2cb62302ab0ca739f0bb95fe7859582a1586 Mon Sep 17 00:00:00 2001 From: Adrian Webb Date: Tue, 20 Oct 2026 12:14:22 -0400 Subject: [PATCH 3/4] test: keep group custody regression in existing kernel suite --- .../custody/context-custody-readback.test.ts | 29 ++++++++++++++++++- tests/modern/kernel/proposal-groups.test.ts | 29 ------------------- 2 files changed, 28 insertions(+), 30 deletions(-) delete mode 100644 tests/modern/kernel/proposal-groups.test.ts diff --git a/tests/modern/kernel/architecture/custody/context-custody-readback.test.ts b/tests/modern/kernel/architecture/custody/context-custody-readback.test.ts index 0f5c735a..f3db552b 100644 --- a/tests/modern/kernel/architecture/custody/context-custody-readback.test.ts +++ b/tests/modern/kernel/architecture/custody/context-custody-readback.test.ts @@ -1,7 +1,7 @@ import { describe, expect, it } from 'vitest'; import { state } from '../golden-readback-fixture.ts'; import { verifyDraftProposalHandoff, verifyUnfinishedDraftHandoff, verifyExactContextSource, verifyKnowledgeBookSource } from '../../../../acceptance/workday/support/assignment-authority.ts'; -import { stringify } from 'yaml'; +import { parse, stringify } from 'yaml'; import { exactContext } from '../portable/context-fixture.ts'; import { createHash } from 'node:crypto'; import { prepareTreeDxContent } from '../../../../../src/kernel/treedx-content-commit.ts'; @@ -210,3 +210,30 @@ function knowledgeFixture(status = 'review') { expect(state.calls).toEqual([]); }); }); + + +const target = { store: 'treedx' as const, model: 'proposal', id: 'complete-scoped-snapshots', + repository: 'treeseed-ai/ui-library', commit: 'a'.repeat(40), path: 'proposals/complete-scoped-snapshots.mdx' }; +const frontmatter = { schemaVersion: 'treeseed.proposal/v1', id: target.id, projectId: 'ui', + title: 'Support complete scoped activity snapshots in UI', status: 'draft', + request: 'Replace complete snapshots, including empty results, while retaining incremental activity updates.', + groupIds: ['portfolio-atlas'] }; + +describe('kernel proposal group custody', () => { + it('retains the shared team group when preparing a real planning product for TreeDX', () => { + const input = { frontmatter, body: 'The shared UI component owns snapshot replacement; Admin consumes the same contract.' }; + const before = structuredClone(input), result = prepareTreeDxContent(target, input); + expect(parse(result.content.split('---')[1]!)).toEqual(frontmatter); + expect(result.content).toContain(input.body); + expect(result.digest).toMatch(/^sha256:[a-f0-9]{64}$/u); + expect(input).toEqual(before); + }); + + it('rejects individual targeting and malformed shared membership before any write', () => { + for (const extra of [{ agentIds: ['ui/engineer'] }, { agentSlugs: ['engineer'] }, + { groupIds: ['portfolio-atlas', 'portfolio-atlas'] }, { groupIds: ['bad group'] }]) { + expect(() => prepareTreeDxContent(target, { frontmatter: { ...frontmatter, ...extra }, body: 'Bounded real UI work.' })) + .toThrow('treedx_content_invalid'); + } + }); +}); diff --git a/tests/modern/kernel/proposal-groups.test.ts b/tests/modern/kernel/proposal-groups.test.ts deleted file mode 100644 index f4011d99..00000000 --- a/tests/modern/kernel/proposal-groups.test.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { describe, expect, it } from 'vitest'; -import { parse } from 'yaml'; -import { prepareTreeDxContent } from '../../../src/kernel/treedx-content-commit.ts'; - -const target = { store: 'treedx' as const, model: 'proposal', id: 'complete-scoped-snapshots', - repository: 'treeseed-ai/ui-library', commit: 'a'.repeat(40), path: 'proposals/complete-scoped-snapshots.mdx' }; -const frontmatter = { schemaVersion: 'treeseed.proposal/v1', id: target.id, projectId: 'ui', - title: 'Support complete scoped activity snapshots in UI', status: 'draft', - request: 'Replace complete snapshots, including empty results, while retaining incremental activity updates.', - groupIds: ['portfolio-atlas'] }; - -describe('kernel proposal group custody', () => { - it('retains the shared team group when preparing a real planning product for TreeDX', () => { - const input = { frontmatter, body: 'The shared UI component owns snapshot replacement; Admin consumes the same contract.' }; - const before = structuredClone(input), result = prepareTreeDxContent(target, input); - expect(parse(result.content.split('---')[1]!)).toEqual(frontmatter); - expect(result.content).toContain(input.body); - expect(result.digest).toMatch(/^sha256:[a-f0-9]{64}$/u); - expect(input).toEqual(before); - }); - - it('rejects individual targeting and malformed shared membership before any write', () => { - for (const extra of [{ agentIds: ['ui/engineer'] }, { agentSlugs: ['engineer'] }, - { groupIds: ['portfolio-atlas', 'portfolio-atlas'] }, { groupIds: ['bad group'] }]) { - expect(() => prepareTreeDxContent(target, { frontmatter: { ...frontmatter, ...extra }, body: 'Bounded real UI work.' })) - .toThrow('treedx_content_invalid'); - } - }); -}); From 2a6c814b8132738963d6093318df9e832c405b23 Mon Sep 17 00:00:00 2001 From: Adrian Webb Date: Tue, 20 Oct 2026 13:13:19 -0400 Subject: [PATCH 4/4] fix: ship published group-aware SDK in installed provider consumers --- .github/workflows/publish.yml | 4 ++-- .github/workflows/verify.yml | 2 +- package-lock.json | 8 ++++---- package.json | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 74c58e22..0c207f1d 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -29,7 +29,7 @@ jobs: - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 with: { node-version: 24 } - run: npm ci --ignore-scripts --no-audit --no-fund - - uses: treeseed-ai/sdk/.github/actions/install-exact-sdk@8536de5233983765a049392f307244d741470480 + - uses: treeseed-ai/sdk/.github/actions/install-exact-sdk@b754118c8035913b20ca9663ca418d48fa4dce05 with: { github-token: "${{ github.token }}" } - run: npm run capacity-provider:build -- --prepare-only - uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f @@ -69,7 +69,7 @@ jobs: - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 with: { node-version: 24 } - run: npm ci --ignore-scripts --no-audit --no-fund - - uses: treeseed-ai/sdk/.github/actions/install-exact-sdk@8536de5233983765a049392f307244d741470480 + - uses: treeseed-ai/sdk/.github/actions/install-exact-sdk@b754118c8035913b20ca9663ca418d48fa4dce05 with: { github-token: "${{ github.token }}" } - run: npm run capacity-provider:build -- --prepare-only - uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f diff --git a/.github/workflows/verify.yml b/.github/workflows/verify.yml index e2f60474..f0aa435b 100644 --- a/.github/workflows/verify.yml +++ b/.github/workflows/verify.yml @@ -76,7 +76,7 @@ jobs: mkdir -p node_modules/@treeseed/deployment/node_modules/@treeseed/sdk tar -xzf .treeseed/tools/deployment-build-sdk/treeseed-sdk-0.13.0-rc.122.tgz --strip-components=1 -C node_modules/@treeseed/deployment/node_modules/@treeseed/sdk npm install --prefix node_modules/@treeseed/deployment/node_modules/@treeseed/sdk --omit=dev --ignore-scripts --package-lock=false --no-save --no-audit --no-fund - - uses: treeseed-ai/sdk/.github/actions/install-exact-sdk@69c07896708deaaed228cc6e14f12c41e5289981 + - uses: treeseed-ai/sdk/.github/actions/install-exact-sdk@b754118c8035913b20ca9663ca418d48fa4dce05 with: github-token: ${{ github.token }} - name: Prepare disposable native relay CA diff --git a/package-lock.json b/package-lock.json index 984ddc15..407e7aa6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "dependencies": { "@openai/codex": "0.158.0", "@treeseed/deployment": "https://github.com/treeseed-ai/deployment/releases/download/0.1.0-rc.243/treeseed-deployment-runtime-0.1.0-rc.243.tgz", - "@treeseed/sdk": "github:treeseed-ai/sdk#69c07896708deaaed228cc6e14f12c41e5289981", + "@treeseed/sdk": "0.13.0-rc.124", "esbuild": "0.28.2", "typescript": "^5.9.3", "yaml": "^2.8.1" @@ -1514,9 +1514,9 @@ } }, "node_modules/@treeseed/sdk": { - "version": "0.13.0-rc.123", - "resolved": "git+ssh://git@github.com/treeseed-ai/sdk.git#69c07896708deaaed228cc6e14f12c41e5289981", - "integrity": "sha512-EE1BZxRRqI/JT/OfW50D/fs7iSSKIYGNXP4zJ+SwbhbgTXCb+m+xt3IJWraY8qTmQiIE2WEx8erhJFQQUhscWQ==", + "version": "0.13.0-rc.124", + "resolved": "https://registry.npmjs.org/@treeseed/sdk/-/sdk-0.13.0-rc.124.tgz", + "integrity": "sha512-3dIHnrs4cQjhiUZJteSdqoxZ9+1lhYDGZTwk4COxOgFK4mD1opzY19K0nLqQfckhhyMcYXbSRi5MTK4VgvkKdw==", "license": "Apache-2.0", "dependencies": { "@treeseed/treedx": "0.3.0-rc.17", diff --git a/package.json b/package.json index 99b9ba7a..3af07ec3 100644 --- a/package.json +++ b/package.json @@ -68,7 +68,7 @@ "dependencies": { "@openai/codex": "0.158.0", "@treeseed/deployment": "https://github.com/treeseed-ai/deployment/releases/download/0.1.0-rc.243/treeseed-deployment-runtime-0.1.0-rc.243.tgz", - "@treeseed/sdk": "github:treeseed-ai/sdk#69c07896708deaaed228cc6e14f12c41e5289981", + "@treeseed/sdk": "0.13.0-rc.124", "esbuild": "0.28.2", "typescript": "^5.9.3", "yaml": "^2.8.1"