diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 00000000..8005e322 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,2 @@ +blank_issues_enabled: false +contact_links: [] diff --git a/.github/ISSUE_TEMPLATE/implementation.yml b/.github/ISSUE_TEMPLATE/implementation.yml new file mode 100644 index 00000000..3100fe91 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/implementation.yml @@ -0,0 +1,65 @@ +name: Bounded implementation +description: Define one reviewable Platform integration outcome and its authoritative evidence. +title: "" +labels: [] +body: + - type: markdown + attributes: + value: >- + Issues are the plan and status authority. Update this body instead of posting + routine progress comments; retain detailed verification in GitHub Actions. + - type: textarea + id: objective + attributes: + label: Objective + description: State the concrete outcome and owning repository boundaries. + validations: + required: true + - type: textarea + id: exact-inputs + attributes: + label: Exact inputs + description: Record protected-branch heads, released artifacts, schemas, and dependencies. + validations: + required: true + - type: textarea + id: interfaces + attributes: + label: Interfaces and behavior + description: Define public commands, schemas, configuration, and failure behavior. + validations: + required: true + - type: textarea + id: acceptance + attributes: + label: Acceptance gates + description: List deterministic, package, integration, read-back, noop, and rollback evidence. + validations: + required: true + - type: textarea + id: dependencies + attributes: + label: Dependencies and authority + description: Link prerequisite Issues and identify any human or environment approval boundary. + validations: + required: true + - type: textarea + id: rollback + attributes: + label: Rollback + description: Identify the retained immutable state and exact recovery path. + validations: + required: true + - type: textarea + id: evidence + attributes: + label: Actions evidence + description: Maintain a compact table of authoritative workflow runs and artifacts. + value: | + | Gate | Run/artifact | Status | + |---|---|---| + | Focused verification | pending | pending | + | Release/read-back | pending | pending | + | Managed acceptance | pending | pending | + validations: + required: true diff --git a/.github/workflows/verify.yml b/.github/workflows/verify.yml index d9973f2e..1acecb94 100644 --- a/.github/workflows/verify.yml +++ b/.github/workflows/verify.yml @@ -15,12 +15,19 @@ concurrency: jobs: verify: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - uses: actions/setup-node@v4 - with: - node-version: 24 - - run: npm run verify + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 + with: { fetch-depth: 0 } + - uses: treeseed-ai/cli/.github/actions/setup-cli@0.13.0-rc.63 + with: { version: 0.13.0-rc.63 } + - run: trsd platform verify . --json + - run: trsd platform verify . --profile core --json + - run: trsd platform verify . --profile control-plane --profile capacity-provider --profile treeai --json + - name: Verify exact project-scoped skill lock + run: | + workspace="$(mktemp -d)" + cd "$workspace" + git init --quiet + npx --yes skills@1.5.23 add https://github.com/treeseed-ai/skill/tree/0.1.0-rc.1 --skill treeseed --agent codex --yes --copy + cmp skills-lock.json "$GITHUB_WORKSPACE/skills-lock.json" diff --git a/.gitignore b/.gitignore index a2db89e2..57655e42 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,8 @@ node_modules/ -.treeseed/ dist/ +.treeseed/ /packages/ -/templates/* -!/templates/platform-*/ +/.agents/skills/ +/.claude/skills/ +/.codex/skills/ /.fixtures/ -/products/market/ -/services/market-api/ diff --git a/AGENTS.md b/AGENTS.md index 55e1e892..2c6b0d46 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,7 +1,57 @@ # Platform workspace guidance +## CRITICAL: complete automated test coverage + +Every behavior, contract, state transition, failure path, and edge case must have automated unit, integration, and scene/guarantee-based acceptance coverage. This is mandatory for all projects, especially the capacity-provider and agent system. A behavior without all three layers is an unresolved delivery gap, not completed work. + +- Unit tests must prove exact outputs, validation, invariants, and boundary conditions. Cover valid and invalid inputs, missing/empty/malformed values, authorization denial, stale or moved refs, and every named prohibited field. +- Integration tests must exercise the real owning components and their public boundaries: handlers, provider/kernel execution, APIs, persistence, tools, and downstream consumers. Mocks, string assertions, compilation, or call-order checks alone are not integration proof. +- Coded scenes and guarantees must prove production-shaped end-to-end outcomes: exact governed artifacts and read-back, independent verification, actual usage, exactly-once settlement, and durable teardown. Use the project's existing native acceptance harness and respect package ownership; do not put TreeSeed-specific policy into product-neutral packages. +- Cover duplicate and concurrent execution, idempotency, partial failure, interruption, retry, resume, cancellation, expiry, provider/tool/subprocess errors, unsafe commands, and cleanup without residue. Preserve failed observations; do not fabricate dispositions, usage, citations, receipts, or passing replays. +- For every defect, first add a focused regression that reproduces the failure, then add or strengthen the corresponding integration and scene/guarantee cases. Fix the earliest owning contract. Retain previously covered behavior and all historical failed evidence. +- Never weaken assertions, remove negative cases, narrow acceptance criteria, disable type checks, extend deadlines, increase allowances, or relabel failures as passes to get green results. An unexpected agent timeout is a fatal architecture defect: agents must check authoritative remaining time frequently, reserve verification/closeout time, and produce authorized continuation proposals for unfinished work before the original deadline. +- Delivery requires passing evidence at all three layers on the exact candidate. Missing environments, credentials, skipped tests, or blocked layers remain explicitly unproven. Component passes, suite totals, line coverage, and process completion never substitute for full semantic acceptance. +- Before EVERY acceptance run (scene or guarantee), run ALL automated unit and integration tests for every participating project on the exact candidate. Focused regressions are additional checks, not substitutes for the complete suites. Failed, skipped, missing, empty, or inconclusive prerequisite coverage blocks acceptance; never launch a live campaign first and discover prerequisite failures afterward. Run the complete suites once per participating project per acceptance invocation, before any scene begins; do not reuse a previous invocation's passing receipt or omit tests to save time. Preserve exact command, candidate, run, and result evidence in the existing Issue and Actions artifacts. +- Keep the behavior-to-unit/integration/scene mapping and exact command, commit, run, and artifact evidence in the existing Issue body and Actions artifacts. Reproduce failures with cheap focused tests before another expensive activation or full campaign; batch known fixes, inspect failed jobs, and reuse only unchanged immutable evidence. No duplicate campaigns or new coverage side channels. + +## Agent configuration and handler ownership + +When this project defines or consumes agents, agent identity, task instructions, prompts, capabilities, permissions, parameters, and activity profiles must be governed YAML configuration. Adding or renaming an agent using existing handlers must not require provider, guest, kernel, or scheduler code changes. Do not hardcode named-role configuration in shared runtime code; shared rules must apply to any configured agent. + +Task-specific executable code belongs in the configured handler. Reuse existing class-based handlers and exact profile bindings; new coded functionality may require a pinned handler, but not a parallel dispatch path or duplicated policy. Test arbitrary YAML-defined agents, renamed identities, handler selection, changed prompts/parameters, denied permissions, and unknown/duplicate handlers through unit, real integration, and coded acceptance cases. + This is the public TreeSeed installer and integration workspace. Preserve independent package builds and route infrastructure changes through SDK reconciliation and `trsd`. Market and Market API are first-party portfolio projects governed through the same seed, reconciliation, and exact-ref custody model as the other TreeSeed repositories. Their hosted deployment remains fail-closed until the reviewed OpenTofu topology restores it. +## CRITICAL: simplicity and non-duplication are mandatory + +Always choose the simplest complete solution. Avoid new models, schemas, storage, services, abstractions, adapters, artifacts, workflows, configuration fields, and compatibility paths unless they are strictly necessary to produce a verified requirement. One fact must have one authority, one representation, and one implementation path. Reuse existing contracts, Git state, TreeDX content, receipts, commands, and runtime boundaries instead of copying or translating them. Do not encode the same policy in profiles, prompts, handlers, assignments, providers, and API services. Delete superseded paths as part of the replacement; do not preserve speculative flexibility or backward compatibility. Before adding any concept, identify why the current simplest mechanism cannot satisfy the requirement. If that necessity cannot be demonstrated, do not add it. + +Optimize first for the smallest end-to-end path that works and can be verified through the supported CLI. Prefer ordinary commits, branches, exact refs, typed assignment inputs/results, and small class-based handlers over new artifact taxonomies or orchestration layers. Do not create work whose only purpose is to reconcile duplication introduced by the design itself. Complexity and duplicated effort are critical defects, not acceptable tradeoffs. + +## First-party repository visibility and licensing + +All TreeSeed repositories are public, including Team Library and Market API. First-party repositories use Apache-2.0 except API and Market API, which use AGPLv3. Preserve their exact license notices. This policy does not relicense third-party dependencies or make customer repositories public. The TreeSeed seed must declare public repository visibility; license choice is independent of visibility. + +## Efficient delivery is mandatory + +Conserve human and AI capacity by optimizing for verified outcomes rather than repeated discussion or duplicated evidence. GitHub Issues are the planning and status authority, GitHub Actions are the verification authority, and agents must not post routine issue or pull-request comments. Keep the current decision-complete contract and evidence table in the Issue body; put implementation context in commits and the pull-request description; retain detailed logs as Actions artifacts. Read only the exact context needed, batch independent reads and checks, reuse immutable receipts, inspect failed jobs rather than rerunning successful work, and batch known defects into one replacement release candidate before repeating expensive activation. Stop at real authority boundaries instead of spending quota speculating around them. + +Every delivery follows `Issue -> branch -> pull request -> Actions -> staging merge -> release/read-back -> Platform composition -> managed acceptance -> main/production`. Before branching, merging, or releasing, fetch and verify the exact protected-branch head. Do not create undocumented side channels for plans, progress, or acceptance. + +During pre-launch integration, no human approval or review is required for pull requests (including `main`), releases, deployments, infrastructure plans, reconciliation, or acceptance. Authorized agents may merge after required automated checks pass; retain pull requests, exact-ref custody, and all unrelated protections. This temporary policy is tracked in Platform #489. Before public production launch, establish a separate reviewer identity and explicitly restore required human review for PRs to `main`; verify the restored settings before promoting a public production release. Do not reintroduce human-only gates for staging or non-production work. + +## TypeScript source standard + +Use TypeScript for handwritten application, infrastructure, CLI, tooling, and test code across the integrated projects. JavaScript is generated build output, not a parallel source implementation. Keep strict type-checking enabled; do not use unchecked JavaScript or disable TypeScript checks to bypass this standard. Convert handwritten JavaScript when extending that implementation, and update its build and test entrypoints together. Keep configuration declarative. This does not authorize implementation in Platform: functional code still belongs in its owning package. + +## Development selection lifetime + +Local development selections persist until explicitly switched or stopped through `trsd`. Do not add session expiration, wall-clock watchdog shutdowns, or time-based fallback to released code. Preserve process ownership, readiness checks, explicit stop/drain behavior, and normal credential/token expiration; those are separate from development selection lifetime. + +## Branch and deployment boundary + +`main` is the only production branch and maps only to the `production` deployment environment. `staging` is the only development-integration branch and maps only to the `staging` deployment environment. Short-lived pull-request branches may validate without deploying, but they must never define another deployment environment. Do not create or use `development`, `preview`, `stable`, or any other GitHub deployment environment; preview deployments are prohibited. Release tags may promote an exact reviewed `staging` commit to `production` without creating another branch or environment. Artifact channel names must never become GitHub deployment environments. + ## Project library The Platform library is `treeseed-ai/platform-library`; its TreeDX binding is authoritative. Start with `trsd library show platform` and `trsd library status platform`. Discover with `paths`, `search`, `query`, or `context`, and read a known file with `trsd library read platform --ref `. Use exact commits for reproducible work and protected `main` or `staging` only for deliberate moving-head inspection. diff --git a/README.md b/README.md index 61849e37..dc8363bc 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,37 @@ # TreeSeed Platform -Public Apache-2.0 installer and integration workspace for customer-centric TreeSeed deployments. Platform manages Admin, an optional sovereign Admin API control plane, Core, CLI, capacity providers, TreeDX, and AI services. +TreeSeed Platform is the public, portable configuration and documentation workspace for installing, composing, developing, and releasing the TreeSeed ecosystem. It owns no application runtime or service implementation. SDK operations reconcile its declarations; `trsd` is the operator surface; the host manager owns installed services. -Market is external and immutable at `https://api.treeseed.dev`. This repository cannot provision, deploy, or check out Market or Market API. +## Start developing -The active migration is tracked in [SDK-First Standards, GitHub, and Cluster Cutover Ledger](./docs/sdk-first-cutover-implementation-plan.md). The integrated single-machine and multi-node target is defined in [Cluster Architecture and Cutover](./docs/cluster-architecture-cutover.md), cross-project compatibility in [Standards-Based Independent Development](./docs/standards-dev.md), and provider-neutral GitHub Issues and pull-request synchronization in [GitHub Issues and Pull Request Integration](./docs/github-work-integration.md). +Install a released CLI, clone this repository, and plan the desired source workset before any local API exists: -## Workspace +```text +trsd platform verify . --json +trsd platform workset --profile core --plan --json +trsd platform workset --profile core --apply --yes --json +``` -`trsd platform workset --plan --json` reads the authenticated live team project inventory, observes exact repository refs, and previews assignment-owned custody. `trsd platform workset --apply --yes --json` materializes that disposable custody under `packages/`, `templates/`, and `.fixtures/`. The Platform Git repository contains no portfolio manifest or project gitlinks. Paired content repositories are logical TreeDX/R2 bindings and are never software workset checkouts. +Primary source repositories are materialized beneath `packages/`. Platform remains at the workspace root, knowledge libraries are never software checkouts, and `.treeseed/worksets` contains ignored exact-ref receipts. Existing checkouts are never reset, deleted, or overwritten. + +Install the governed TreeSeed skill at the exact release recorded in `config/skills/treeseed.lock.yaml`. Platform tracks the project lock but ignores installed skill files; skill updates are explicit lock-update pull requests. + +Profiles are composable: + +```text +trsd platform workset --profile control-plane --apply --yes --json +trsd platform workset --profile capacity-provider --apply --yes --json +trsd platform workset --profile control-plane --profile treeai --apply --yes --json +``` + +`core` contains every first-party source project. Runtime selection is independent: any target may remain released while selected targets run live or as candidates. + +## Installation and production + +One generic Debian bootstrap installs only the manager foundation. `trsd host initialize --profile ` selects the role after installation. A capacity provider needs only the control-plane URL and a prompted team registration code; approval binds its generated local identity and replaces the code with short-lived sessions. + +Production topology is declared under `config/topologies/` and remains fail-closed. Cloudflare hosts Admin, Railway hosts the control plane, and bare-metal providers run Agent. Market and Market API participate in development worksets but retain independent hosted-deployment authority. + +Staging and production use portable templates plus separately generated immutable artifact inputs. See [hosted deployment](docs/hosted-deployment.md) for state isolation, credential custody, planning, and the Ubuntu 26.04 capacity-provider fleet boundary. + +Current delivery work and evidence are tracked in [Platform issue #280](https://github.com/treeseed-ai/platform/issues/280). GitHub Issues are status authority and Actions are verification authority. diff --git a/config/hosts/capacity-provider.yaml b/config/hosts/capacity-provider.yaml new file mode 100644 index 00000000..ad9190c4 --- /dev/null +++ b/config/hosts/capacity-provider.yaml @@ -0,0 +1,7 @@ +schemaVersion: treeseed.platform-host-template/v1 +id: capacity-provider +profiles: [capacity-provider] +integration: { id: development, digest: 'sha256:fa3879fb8ba6ca5b1736929a1947741cd4bce0ac3f6c36dca50980731ea1d9ed' } +inputs: + - { name: controlPlaneUrl, required: true, sensitive: false } + - { name: teamRegistrationCode, required: true, sensitive: true } diff --git a/config/hosts/development.yaml b/config/hosts/development.yaml new file mode 100644 index 00000000..2a9113ce --- /dev/null +++ b/config/hosts/development.yaml @@ -0,0 +1,8 @@ +schemaVersion: treeseed.platform-host-template/v1 +id: development +profiles: [core] +integration: { id: development, digest: 'sha256:fa3879fb8ba6ca5b1736929a1947741cd4bce0ac3f6c36dca50980731ea1d9ed' } +inputs: + - { name: hostIdentity, required: false, sensitive: false } + - { name: initialAdministrator, required: false, sensitive: false } + - { name: recoveryBundle, required: true, sensitive: true } diff --git a/config/initialization/capacity-provider.json b/config/initialization/capacity-provider.json new file mode 100644 index 00000000..ca43cdfe --- /dev/null +++ b/config/initialization/capacity-provider.json @@ -0,0 +1,12 @@ +{ + "schemaVersion": "treeseed.host-initialization-profile/v1", + "id": "capacity-provider", + "role": "capacity-provider", + "runtime": { "management": "managed", "environment": "track-default" }, + "components": ["agent"], + "security": { "requirement": "required" }, + "inputs": [ + { "name": "controlPlaneUrl", "required": true, "sensitive": false, "description": "Control-plane API HTTPS URL" }, + { "name": "teamRegistrationCode", "required": true, "sensitive": true, "description": "Team capacity-provider registration code" } + ] +} diff --git a/config/initialization/control-plane.json b/config/initialization/control-plane.json new file mode 100644 index 00000000..b8eb38fa --- /dev/null +++ b/config/initialization/control-plane.json @@ -0,0 +1,9 @@ +{ + "schemaVersion": "treeseed.host-initialization-profile/v1", + "id": "control-plane", + "role": "control-plane", + "runtime": { "management": "managed", "environment": "track-default" }, + "components": ["identity", "api", "admin", "treedx", "lab"], + "security": { "requirement": "optional" }, + "inputs": [] +} diff --git a/config/initialization/core.json b/config/initialization/core.json new file mode 100644 index 00000000..e675942a --- /dev/null +++ b/config/initialization/core.json @@ -0,0 +1,9 @@ +{ + "schemaVersion": "treeseed.host-initialization-profile/v1", + "id": "core", + "role": "integrated", + "runtime": { "management": "managed", "environment": "track-default" }, + "components": ["identity", "api", "admin", "agent", "treedx", "lab"], + "security": { "requirement": "required" }, + "inputs": [] +} diff --git a/config/initialization/treeai.json b/config/initialization/treeai.json new file mode 100644 index 00000000..09bebfe6 --- /dev/null +++ b/config/initialization/treeai.json @@ -0,0 +1,9 @@ +{ + "schemaVersion": "treeseed.host-initialization-profile/v1", + "id": "treeai", + "role": "integrated", + "runtime": { "management": "managed", "environment": "track-default" }, + "components": ["identity", "api", "admin", "agent", "treedx", "lab", "ai-inference", "ai-training", "ai-lab"], + "security": { "requirement": "required" }, + "inputs": [] +} diff --git a/config/integrations/development.release.json b/config/integrations/development.release.json new file mode 100644 index 00000000..8abd1ab4 --- /dev/null +++ b/config/integrations/development.release.json @@ -0,0 +1,44 @@ +{ + "schemaVersion": "treeseed.integration-release/v1", + "release": "0.1.0~rc320", + "generation": 266, + "track": "development", + "compatibilityId": "treeseed-linux-amd64-v1", + "platform": {"repository":"treeseed-ai/platform","commit":"e227670f9a8b844a70658b9503752a643236ff99"}, + "deployment": {"repository":"treeseed-ai/deployment","commit":"2b7e036cf1e66261003e022fa26684469f2c1277","tag":"0.1.0-rc.320"}, + "hostPayloads": [ + {"id":"sdk","packageName":"@treeseed/sdk","version":"0.13.0-rc.121","artifact":{"url":"https://registry.npmjs.org/@treeseed/sdk/-/sdk-0.13.0-rc.121.tgz","sha256":"5211b3db5dbcd00211c73470ac406934539670ced2fc672d73e2ea57744d6144"}}, + {"id":"identity","packageName":"@treeseed/identity","version":"0.1.0-rc.23","artifact":{"url":"https://registry.npmjs.org/@treeseed/identity/-/identity-0.1.0-rc.23.tgz","sha256":"fda91830e4073be14db91a4b15b6c83d66a4a76b75c8f62218b37288cb344e7f"}}, + {"id":"jose","packageName":"jose","version":"6.2.12","artifact":{"url":"https://registry.npmjs.org/jose/-/jose-6.2.12.tgz","sha256":"32d9da2aaa0e110cacef2ae21e8dae866201f1428424f839001085fe7351ebfe"}}, + {"id":"oauth4webapi","packageName":"oauth4webapi","version":"3.8.8","artifact":{"url":"https://registry.npmjs.org/oauth4webapi/-/oauth4webapi-3.8.8.tgz","sha256":"bac088aecc7cc80e2469b08592c8eb01b9ae6d4a749d89a6016aa54bb1533690"}}, + {"id":"api","packageName":"@treeseed/api","version":"0.8.0-rc.112","artifact":{"url":"https://github.com/treeseed-ai/api/releases/download/0.8.0-rc.112/treeseed-api-0.8.0-rc.112.tgz","sha256":"bf0d1106624ba2adcdce1492e18339a34103a95127c0a24b1bcc308543a2fcdb"}}, + {"id":"ui","packageName":"@treeseed/ui","version":"0.12.18-rc.19","artifact":{"url":"https://registry.npmjs.org/@treeseed/ui/-/ui-0.12.18-rc.19.tgz","sha256":"9f31d328fc4ee818049c45f6b870bd2b291b5fc7ad72c09a31268fe114f4c519"}}, + { "id": "core", "packageName": "@treeseed/core", "version": "0.12.60-rc.8", "artifact": { "url": "https://registry.npmjs.org/@treeseed/core/-/core-0.12.60-rc.8.tgz", "sha256": "7a499718b285ec179a20fd85f85f5702d8c05ae00a9d4931f82d58e38cf888f2" } }, + {"id":"admin","packageName":"@treeseed/admin","version":"0.12.59-rc.38","artifact":{"url":"https://github.com/treeseed-ai/admin/releases/download/0.12.59-rc.38/treeseed-admin-0.12.59-rc.38.tgz","sha256":"d81a5b3585977a63393a155b586575681c53c8ad1f04d879bf02daa4b8288c50"}}, + { "id": "reviewer", "packageName": "@treeseed/reviewer", "version": "0.1.0-rc.13", "artifact": { "url": "https://github.com/treeseed-ai/reviewer/releases/download/0.1.0-rc.13/treeseed-reviewer-0.1.0-rc.13.tgz", "sha256": "f30fc8697fd06f26b8278fe07e28e5065819d2962043693447a77d1ace070b14" } }, + { "id": "playwright-core", "packageName": "playwright-core", "version": "1.60.0", "artifact": { "url": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.60.0.tgz", "sha256": "8b1df81ba75e90a41eb5c996350ea7ecc1c915ea643ec55138f91c949c5a25bf" } }, + {"id":"cli","packageName":"@treeseed/cli","version":"0.13.0-rc.85","artifact":{"url":"https://registry.npmjs.org/@treeseed/cli/-/cli-0.13.0-rc.85.tgz","sha256":"289d64e668eb747c07b675e599892a66f97ffeedbc2fb3a0c103594057a454ce"}}, + {"id":"treedx","packageName":"@treeseed/treedx","version":"0.3.0-rc.18","artifact":{"url":"https://github.com/treeseed-ai/treedx/releases/download/0.3.0-rc.18/treeseed-treedx-0.3.0-rc.18.tgz","sha256":"8940c30f39d80cbdd99c71dc085eca09103846ac1377ff3d6d87158d77dd69f0"}}, + { "id": "yaml", "packageName": "yaml", "version": "2.9.0", "artifact": { "url": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz", "sha256": "008fa204cb1ba700e0272ba045abbf09a6ffe63456e8146ba97cac6c2ad1ef91" } }, + { "id": "zod", "packageName": "zod", "version": "3.25.76", "artifact": { "url": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", "sha256": "9e1f1a05f0dd0c1dab64ee91ceb9bf55cd44d35368c70edda80a2fdc70a88377" } } + ], + "hostProfiles": [ + { "id": "core", "artifact": { "url": "https://raw.githubusercontent.com/treeseed-ai/platform/e54a28744253d220a44119ee700854fdf76c3e9d/config/initialization/core.json", "sha256": "4f2203b3e02c900f71c81cb72970c40532b7959c1b45c00159e4f0f486d07a10" } }, + { "id": "control-plane", "artifact": { "url": "https://raw.githubusercontent.com/treeseed-ai/platform/e54a28744253d220a44119ee700854fdf76c3e9d/config/initialization/control-plane.json", "sha256": "3cb3f6da30f852963944adcbf6cbed0eb7d8fe30000d289780cfe13d1e670056" } }, + { "id": "capacity-provider", "artifact": { "url": "https://raw.githubusercontent.com/treeseed-ai/platform/e54a28744253d220a44119ee700854fdf76c3e9d/config/initialization/capacity-provider.json", "sha256": "feec8c90c15fbd15ecf9a15779b847432beb9fff6f7146b7e33c623930adff68" } }, + { "id": "treeai", "artifact": { "url": "https://raw.githubusercontent.com/treeseed-ai/platform/e54a28744253d220a44119ee700854fdf76c3e9d/config/initialization/treeai.json", "sha256": "bbe2083772140e0abe883d3787fc43cd4823b26c426d89e48805b91c80440191" } } + ], + "components": [ + {"componentId":"identity","release":"0.1.0~rc298-1","manifest":{"url":"https://github.com/treeseed-ai/deployment/releases/download/0.1.0-rc.298/identity-component-release.json","sha256":"37a1b9a0a2f52323d07257ec2bb2ed417e8fac143ab926a9f7c90cac41342f25"},"files":[{"path":"compose.yml","artifact":{"url":"https://github.com/treeseed-ai/deployment/releases/download/0.1.0-rc.298/identity-compose.yml","sha256":"226e851488bab8738e1fdbf98e259d8d9b04ac89d9adf3b0893d45fd3f886ab8"}}]}, + {"componentId":"postgres","release":"0.1.0~rc288-1","manifest":{"url":"https://github.com/treeseed-ai/deployment/releases/download/0.1.0-rc.288/postgres-component-release.json","sha256":"8b16128fd584af603e96ec8865c9b102319a587ca9600a09cfc6e5281fa3e0f4"},"files":[{"path":"compose.yml","artifact":{"url":"https://github.com/treeseed-ai/deployment/releases/download/0.1.0-rc.288/postgres-compose.yml","sha256":"07620d83ca8fcae3791063cc34854ca98740cc167d65c57d9e0838c5bb9b4105"}}]}, + {"componentId":"api","release":"0.8.0~rc112-1","manifest":{"url":"https://github.com/treeseed-ai/api/releases/download/0.8.0-rc.112/component-release.json","sha256":"0c4000d3ef672b471b0ed5e4910e5e0769ad3c770a6c559e0dce0c29ee1432e2"},"files":[{"path":"compose.yml","artifact":{"url":"https://github.com/treeseed-ai/api/releases/download/0.8.0-rc.112/compose.yml","sha256":"24e0de50ed70d8d6d27c0b901f866fe3f31a6c12ff68b9219d2b3c5a8b2d25c2"}}]}, + {"componentId":"admin","release":"0.12.59~rc38-1","manifest":{"url":"https://github.com/treeseed-ai/admin/releases/download/0.12.59-rc.38/component-release.json","sha256":"f2858d3089fec5e4f9598acf72e15aae138c589a8df9fc3d7567fdd70b2dfb5c"},"files":[{"path":"compose.yml","artifact":{"url":"https://github.com/treeseed-ai/admin/releases/download/0.12.59-rc.38/compose.yml","sha256":"1182f6127d1d48edbc8280ca192b6b65008eaa9839cbc213dcdf8bc792e09f1e"}}]}, + {"componentId":"agent","release":"0.13.0~rc57-1","manifest":{"url":"https://github.com/treeseed-ai/agent/releases/download/0.13.0-rc.57/component-release.json","sha256":"013c9d0c962a75d853adbcda32f1dadc5fc24b095dde2e49ee2f25f05f7cf238"},"files":[{"path":"compose.yml","artifact":{"url":"https://github.com/treeseed-ai/agent/releases/download/0.13.0-rc.57/compose.yml","sha256":"90c1615a337bbfba8807b8a3a5aa0ab7eff804cb8b73babf6e7a129095d3024e"}}]}, + {"componentId":"treedx","release":"0.3.0~rc18-1","manifest":{"url":"https://github.com/treeseed-ai/treedx/releases/download/0.3.0-rc.18/component-release.json","sha256":"a754a933e0a20ce79e83021a01ec8dc0755583a265fab8cca5c61c5b6091ed66"},"files":[{"path":"compose.yml","artifact":{"url":"https://github.com/treeseed-ai/treedx/releases/download/0.3.0-rc.18/compose.yml","sha256":"f6864cc88329585dd9b92ef02eefb12180bea68b36cc3074d5a8c6071e09679f"}}]}, + {"componentId":"lab","release":"0.1.0~rc293-1","manifest":{"url":"https://github.com/treeseed-ai/deployment/releases/download/0.1.0-rc.293/component-release.json","sha256":"c2f50382c3ceca7b46d438022a3d18ca1e15e9ad0e556594f0aac9eb5b7d0a6b"},"files":[{"path":"compose.yml","artifact":{"url":"https://github.com/treeseed-ai/deployment/releases/download/0.1.0-rc.293/compose.yml","sha256":"9fd0ffe67ee9ed9d3d1b740a8480f271aa004a311dc2a8dbe5bbcfc7ec4c6275"}}]}, + {"componentId":"ai-inference","release":"0.11.0~rc24-1","manifest":{"url":"https://github.com/treeseed-ai/ai/releases/download/0.11.0-rc24/ai-inference-component-release.json","sha256":"6537a314a3d90147988d7393675bfc254bf5b5639f7e7ab57092ae88455da2e0"},"files":[{"path":"ai-inference-compose.yml","artifact":{"url":"https://github.com/treeseed-ai/ai/releases/download/0.11.0-rc24/ai-inference-compose.yml","sha256":"101257f93e89f8cc6a1d9c65e11269990a06adc4733f4515c90a2527f929756c"}}]}, + {"componentId":"ai-training","release":"0.11.0~rc24-1","manifest":{"url":"https://github.com/treeseed-ai/ai/releases/download/0.11.0-rc24/ai-training-component-release.json","sha256":"9d293d087a7a38f2d80efc1f8fdd13e38849e78dcfa2fe986658b39c40161bfe"},"files":[{"path":"ai-training-compose.yml","artifact":{"url":"https://github.com/treeseed-ai/ai/releases/download/0.11.0-rc24/ai-training-compose.yml","sha256":"440ac53d4f3b91dc443e4e5e7bdaa958c504c758661de7d73a0b63e8fd4294e8"}}]}, + {"componentId":"ai-lab","release":"0.11.0~rc24-1","manifest":{"url":"https://github.com/treeseed-ai/ai/releases/download/0.11.0-rc24/ai-lab-component-release.json","sha256":"042dce565a244be9d7efac7f55e4acf7e3722ec7285e32495c40504cef9ef88c"},"files":[{"path":"ai-lab-compose.yml","artifact":{"url":"https://github.com/treeseed-ai/ai/releases/download/0.11.0-rc24/ai-lab-compose.yml","sha256":"8211ec5612a84ae55eae066442fdbbe903fd822f9b6e6f6b60905b0fd02e49b5"}}]} + ], + "createdAt": "2026-09-19T22:04:04Z" +} diff --git a/config/integrations/development.yaml b/config/integrations/development.yaml new file mode 100644 index 00000000..7a225196 --- /dev/null +++ b/config/integrations/development.yaml @@ -0,0 +1,15 @@ +schemaVersion: treeseed.platform-integration-lock/v1 +release: development-227 +components: + - {"id":"deployment","version":"0.1.0-rc.276","commit":"58edba89e806171417bb8bfc5102ca086859c9b4","digest":"sha256:d8cebe781f3d05a71a088c2ade6d83af44343fbbedf04b8d89061b66e2628510","artifact":"https://github.com/treeseed-ai/deployment/releases/download/0.1.0-rc.276/exact-head.json"} + - {"id":"sdk","version":"0.13.0-rc.99","commit":"4f36c713a65931304bd0d92e73b6a743d7ceb85d","digest":"sha256:5a52cb26df4a446f0f19fcae0ad8572945a94dbd2ec8885ecb1cc9ad9a7646f3","artifact":"https://github.com/treeseed-ai/sdk/releases/tag/0.13.0-rc.99"} + - {"id":"cli","version":"0.13.0-rc.67","commit":"87f98871d1eff3b5b2a8caccd3f52f0446dfa31f","digest":"sha256:98e357650d8712d973e6ce2ecc04692899c0b32bcf424fde8415ba028d7891a3","artifact":"https://github.com/treeseed-ai/cli/releases/tag/0.13.0-rc.67"} + - {"id":"api","version":"0.8.0-rc.96","commit":"d360ef3d54500666e77ad330b28f6cc5a900a1a0","digest":"sha256:fca9b1ecfd2deca01800ac9e96408fb8fb44ff53f30fd76eba16cd0a5ff433a2","artifact":"https://github.com/treeseed-ai/api/releases/tag/0.8.0-rc.96"} + - {"id":"admin","version":"0.12.59-rc.35","commit":"cff98fdb777385f50370d1dc4c959198375851a8","digest":"sha256:1911171cffcb12cff350ac99cd027928eb8a193f6c6d536eb082ea762c4a4d75","artifact":"https://github.com/treeseed-ai/admin/releases/tag/0.12.59-rc.35"} + - {"id":"agent","version":"0.13.0-rc.47","commit":"c342fd04f0504f1707eccde08827c2929084f2ec","digest":"sha256:2450729922300c13da1b1e77fa99bb954ad1a26561e6fae10a7c4cb52c4d7cbe","artifact":"https://github.com/treeseed-ai/agent/releases/tag/0.13.0-rc.47"} + - {"id":"treedx","version":"0.3.0-rc.17","commit":"07b25f226743e7718b52813e87ea929cb82c32ca","digest":"sha256:53f5c0645d99c14fd4360c3a62f7a03c6637ce1505f24650c9b01baa268ec169","artifact":"https://github.com/treeseed-ai/treedx/releases/tag/0.3.0-rc.17"} + - {"id":"treeai-inference","version":"0.11.0-rc22","commit":"e3a462f30bfdc3539d3a5511932f28212f06a936","digest":"sha256:bac812df51527df513e6a52668a64904c8554ab6be5019237e04e7f59c34129f","artifact":"https://github.com/treeseed-ai/ai/releases/download/0.11.0-rc22/ai-inference-component-release.json"} + - {"id":"treeai-training","version":"0.11.0-rc22","commit":"e3a462f30bfdc3539d3a5511932f28212f06a936","digest":"sha256:07b32a13db84826ae75d7e7725ac99e78342151161bb8afd556762a8f0a5198b","artifact":"https://github.com/treeseed-ai/ai/releases/download/0.11.0-rc22/ai-training-component-release.json"} + - {"id":"treeai-lab","version":"0.11.0-rc22","commit":"e3a462f30bfdc3539d3a5511932f28212f06a936","digest":"sha256:695f0461edae24c548b4765ff2572d00193c7c6d2212b8dcae68345ca0184df4","artifact":"https://github.com/treeseed-ai/ai/releases/download/0.11.0-rc22/ai-lab-component-release.json"} + - {"id":"ui","version":"0.12.18-rc.19","commit":"ed8bbbc44a323650f13156e64b4fd3a919808971","digest":"sha256:9f31d328fc4ee818049c45f6b870bd2b291b5fc7ad72c09a31268fe114f4c519","artifact":"https://github.com/treeseed-ai/ui/releases/tag/0.12.18-rc.19"} +digest: sha256:fa3879fb8ba6ca5b1736929a1947741cd4bce0ac3f6c36dca50980731ea1d9ed diff --git a/deployment/integration-releases/stable.json b/config/integrations/stable.release.json similarity index 89% rename from deployment/integration-releases/stable.json rename to config/integrations/stable.release.json index f11dbf13..6c182f24 100644 --- a/deployment/integration-releases/stable.json +++ b/config/integrations/stable.release.json @@ -1,11 +1,11 @@ { "schemaVersion": "treeseed.integration-release/v1", "release": "0.1.0", - "generation": 29, + "generation": 36, "track": "stable", "compatibilityId": "treeseed-linux-amd64-v1", - "platform": { "repository": "treeseed-ai/platform", "commit": "b4ae096f8838a9acff4f6e775289ff503d478f22" }, - "deployment": { "repository": "treeseed-ai/deployment", "commit": "41b07f44a3b1ddb71b3b68578843868bd4db0c79", "tag": "0.1.0-rc.79" }, + "platform": { "repository": "treeseed-ai/platform", "commit": "43691da87ad5c145b3511311f4f28489564bf23a" }, + "deployment": { "repository": "treeseed-ai/deployment", "commit": "5936b657219e6dbd2cedf8d1898203a4035e2717", "tag": "0.1.0-rc.113" }, "hostPayloads": [ { "id": "sdk", "packageName": "@treeseed/sdk", "version": "0.13.0-rc.34", "artifact": { "url": "https://registry.npmjs.org/@treeseed/sdk/-/sdk-0.13.0-rc.34.tgz", "sha256": "0413cbeab3314ac7f90c5e6420fec2f3790f38ffa1e41b86dd571a364ae38a79" } }, { "id": "cli", "packageName": "@treeseed/cli", "version": "0.13.0-rc.16", "artifact": { "url": "https://registry.npmjs.org/@treeseed/cli/-/cli-0.13.0-rc.16.tgz", "sha256": "3b26bdeca38ef33fa94c4487f65eea76c454c4d0c82829afae8a8f707e8034cb" } }, @@ -14,5 +14,5 @@ { "id": "zod", "packageName": "zod", "version": "3.25.76", "artifact": { "url": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", "sha256": "9e1f1a05f0dd0c1dab64ee91ceb9bf55cd44d35368c70edda80a2fdc70a88377" } } ], "components": [], - "createdAt": "2026-08-25T20:35:53.000Z" + "createdAt": "2026-08-28T06:02:00.000Z" } diff --git a/config/promotions/stable.yaml b/config/promotions/stable.yaml new file mode 100644 index 00000000..df0dcdec --- /dev/null +++ b/config/promotions/stable.yaml @@ -0,0 +1,5 @@ +schemaVersion: treeseed.platform-promotion/v1 +id: stable +state: blocked +candidate: development +blockers: [clean-host-acceptance, universal-installer-acceptance, complete-uninstall-acceptance, cloudflare-railway-readback, three-provider-canary-and-rollout, rollback-acceptance] diff --git a/config/skills/treeseed.lock.yaml b/config/skills/treeseed.lock.yaml new file mode 100644 index 00000000..11cbaebf --- /dev/null +++ b/config/skills/treeseed.lock.yaml @@ -0,0 +1,11 @@ +schemaVersion: treeseed.skill-lock/v1 +id: treeseed +source: https://github.com/treeseed-ai/skill +release: 0.1.0-rc.1 +sourceCommit: 9b17b2f35570f6fce998891e901e2e8f4b527ac3 +skillsCliVersion: 1.5.23 +computedHash: 9f7ee249da009916505cf5d4ca9ad1091080221ae5f17577f17d824a1ec710f6 +installedPath: .agents/skills/treeseed +install: { command: 'npx skills@1.5.23 add https://github.com/treeseed-ai/skill/tree/0.1.0-rc.1 --skill treeseed --agent codex --yes' } +update: { command: 'npx skills@1.5.23 update treeseed --project --yes' } +state: accepted-release-candidate diff --git a/config/topologies/capacity-providers.yaml b/config/topologies/capacity-providers.yaml new file mode 100644 index 00000000..a4dae4c2 --- /dev/null +++ b/config/topologies/capacity-providers.yaml @@ -0,0 +1,9 @@ +schemaVersion: treeseed.capacity-provider-fleet/v1 +id: treeseed-production-capacity +environment: production +count: 3 +host: { operatingSystem: { distribution: ubuntu, release: "26.04" }, architecture: amd64 } +installer: { package: treeseed, profile: capacity-provider } +enrollment: { controlPlaneUrl: installation-input, teamRegistrationCode: prompted, approval: required, identity: generated-locally } +sessions: { authentication: short-lived, renewal: automatic } +placement: { hostIdentities: runtime-only, addresses: runtime-only } diff --git a/config/topologies/production.yaml b/config/topologies/production.yaml new file mode 100644 index 00000000..5a05c6a7 --- /dev/null +++ b/config/topologies/production.yaml @@ -0,0 +1,72 @@ +schemaVersion: treeseed.hosted-topology-template/v1 +id: treeseed-production +deploymentId: treeseed-cloud +stackId: control-plane +environment: production +mutation: agent-authorized +stateBackend: { connectionRef: cloudflare-state-production } +providerConnections: + cloudflare: { connectionRef: cloudflare-hosting-production } + railway: { connectionRef: railway-hosting-production } +artifactBindings: + admin: { input: admin-pages, kind: archive } + api-proxy: { input: api-proxy-worker, kind: file } + api: { input: control-plane-api-image, kind: oci-image } + operations: { input: operations-runner-image, kind: oci-image } + postgres: { input: postgres-image, kind: oci-image } + treedx: { input: treedx-image, kind: oci-image } +resources: + - id: postgres + provider: railway + kind: postgresql + dependsOn: [] + parameters: { name: { input: postgres-service-name }, artifact: { artifact: postgres }, volume-name: { input: postgres-volume-name }, volume-mount-path: { literal: /var/lib/postgresql/data } } + adoption: { mode: adopt-or-create, replacement: forbidden } + - id: api + provider: railway + kind: control-plane-api + dependsOn: [postgres] + parameters: { name: { input: api-service-name }, artifact: { artifact: api }, healthcheck-path: { literal: /health }, variable.TREESEED_DATABASE_URL: { resourceOutput: { resourceId: postgres, output: database-url } }, variable.TREESEED_WEB_SERVICE_ID: { literal: operations-runner } } + adoption: { mode: adopt-or-create, replacement: forbidden } + - id: operations + provider: railway + kind: operations-runner + dependsOn: [api, postgres] + parameters: { name: { input: operations-service-name }, artifact: { artifact: operations }, healthcheck-path: { literal: /health }, variable.TREESEED_DATABASE_URL: { resourceOutput: { resourceId: postgres, output: database-url } }, variable.TREESEED_API_BASE_URL: { resourceOutput: { resourceId: api, output: private-url } } } + adoption: { mode: adopt-or-create, replacement: forbidden } + - id: treedx + provider: railway + kind: treedx-service + dependsOn: [api] + parameters: { name: { input: treedx-service-name }, artifact: { artifact: treedx }, healthcheck-path: { literal: /health }, variable.TREESEED_API_BASE_URL: { resourceOutput: { resourceId: api, output: private-url } } } + adoption: { mode: adopt-or-create, replacement: forbidden } + - id: api-proxy + provider: cloudflare + kind: api-proxy + dependsOn: [api] + parameters: { name: { input: api-proxy-worker-name }, artifact: { artifact: api-proxy }, compatibility-date: { literal: 2026-09-01 }, variable.TREESEED_UPSTREAM_URL: { input: api-public-url } } + adoption: { mode: adopt-or-create, replacement: forbidden } + - id: admin + provider: cloudflare + kind: pages-application + dependsOn: [api-proxy] + parameters: { name: { input: admin-pages-project-name }, artifact: { artifact: admin }, artifact-format: { literal: tar+gzip }, production-branch: { literal: main }, destination-dir: { literal: . } } + adoption: { mode: adopt-or-create, replacement: forbidden } + - id: api-dns + provider: cloudflare + kind: dns-record + dependsOn: [api-proxy] + parameters: { name: { input: api-dns-name }, type: { literal: CNAME }, content: { input: api-proxy-dns-target }, proxied: { literal: true } } + adoption: { mode: adopt-or-create, replacement: forbidden } + - id: admin-dns + provider: cloudflare + kind: dns-record + dependsOn: [admin] + parameters: { name: { input: admin-dns-name }, type: { literal: CNAME }, content: { input: admin-pages-dns-target }, proxied: { literal: true } } + adoption: { mode: adopt-or-create, replacement: forbidden } + - id: tls + provider: cloudflare + kind: tls-policy + dependsOn: [api-dns, admin-dns] + parameters: { mode: { literal: strict } } + adoption: { mode: adopt-or-create, replacement: forbidden } diff --git a/config/topologies/staging.yaml b/config/topologies/staging.yaml new file mode 100644 index 00000000..431bafd2 --- /dev/null +++ b/config/topologies/staging.yaml @@ -0,0 +1,27 @@ +schemaVersion: treeseed.hosted-topology-template/v1 +id: treeseed-staging +deploymentId: treeseed-cloud +stackId: control-plane +environment: staging +mutation: agent-authorized +stateBackend: { connectionRef: cloudflare-state-staging } +providerConnections: + cloudflare: { connectionRef: cloudflare-hosting-staging } + railway: { connectionRef: railway-hosting-staging } +artifactBindings: + admin: { input: admin-pages, kind: archive } + api-proxy: { input: api-proxy-worker, kind: file } + api: { input: control-plane-api-image, kind: oci-image } + operations: { input: operations-runner-image, kind: oci-image } + postgres: { input: postgres-image, kind: oci-image } + treedx: { input: treedx-image, kind: oci-image } +resources: + - { id: postgres, provider: railway, kind: postgresql, dependsOn: [], parameters: { name: { input: postgres-service-name }, artifact: { artifact: postgres }, volume-name: { input: postgres-volume-name }, volume-mount-path: { literal: /var/lib/postgresql/data } }, adoption: { mode: adopt-or-create, replacement: forbidden } } + - { id: api, provider: railway, kind: control-plane-api, dependsOn: [postgres], parameters: { name: { input: api-service-name }, artifact: { artifact: api }, healthcheck-path: { literal: /health }, variable.TREESEED_DATABASE_URL: { resourceOutput: { resourceId: postgres, output: database-url } }, variable.TREESEED_WEB_SERVICE_ID: { literal: operations-runner } }, adoption: { mode: adopt-or-create, replacement: forbidden } } + - { id: operations, provider: railway, kind: operations-runner, dependsOn: [api, postgres], parameters: { name: { input: operations-service-name }, artifact: { artifact: operations }, healthcheck-path: { literal: /health }, variable.TREESEED_DATABASE_URL: { resourceOutput: { resourceId: postgres, output: database-url } }, variable.TREESEED_API_BASE_URL: { resourceOutput: { resourceId: api, output: private-url } } }, adoption: { mode: adopt-or-create, replacement: forbidden } } + - { id: treedx, provider: railway, kind: treedx-service, dependsOn: [api], parameters: { name: { input: treedx-service-name }, artifact: { artifact: treedx }, healthcheck-path: { literal: /health }, variable.TREESEED_API_BASE_URL: { resourceOutput: { resourceId: api, output: private-url } } }, adoption: { mode: adopt-or-create, replacement: forbidden } } + - { id: api-proxy, provider: cloudflare, kind: api-proxy, dependsOn: [api], parameters: { name: { input: api-proxy-worker-name }, artifact: { artifact: api-proxy }, compatibility-date: { literal: 2026-09-01 }, variable.TREESEED_UPSTREAM_URL: { input: api-public-url } }, adoption: { mode: adopt-or-create, replacement: forbidden } } + - { id: admin, provider: cloudflare, kind: pages-application, dependsOn: [api-proxy], parameters: { name: { input: admin-pages-project-name }, artifact: { artifact: admin }, artifact-format: { literal: tar+gzip }, production-branch: { literal: staging }, destination-dir: { literal: . } }, adoption: { mode: adopt-or-create, replacement: forbidden } } + - { id: api-dns, provider: cloudflare, kind: dns-record, dependsOn: [api-proxy], parameters: { name: { input: api-dns-name }, type: { literal: CNAME }, content: { input: api-proxy-dns-target }, proxied: { literal: true } }, adoption: { mode: adopt-or-create, replacement: forbidden } } + - { id: admin-dns, provider: cloudflare, kind: dns-record, dependsOn: [admin], parameters: { name: { input: admin-dns-name }, type: { literal: CNAME }, content: { input: admin-pages-dns-target }, proxied: { literal: true } }, adoption: { mode: adopt-or-create, replacement: forbidden } } + - { id: tls, provider: cloudflare, kind: tls-policy, dependsOn: [api-dns, admin-dns], parameters: { mode: { literal: strict } }, adoption: { mode: adopt-or-create, replacement: forbidden } } diff --git a/deployment/host-configs/capacity-provider-development.json b/deployment/host-configs/capacity-provider-development.json deleted file mode 100644 index 47fc4de7..00000000 --- a/deployment/host-configs/capacity-provider-development.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "schemaVersion": "treeseed.host/v1", - "configurationId": "capacity-provider-development", - "generation": 2, - "host": { "id": "provider-development-01", "role": "capacity-provider", "architecture": "amd64" }, - "runtime": { "management": "managed", "environment": "production" }, - "updates": { - "defaultTrack": "development", - "stable": { - "metadataPollSeconds": 86400, - "maintenanceWindow": { "weekday": "sunday", "localTime": "03:00", "jitterMinutes": 20 } - }, - "development": { "pollSeconds": 60 } - }, - "components": { - "agent": { - "enabled": true, - "track": "development", - "profile": "capacity-provider", - "aliases": {}, - "resources": { "cpuCores": 8, "memoryBytes": 17179869184, "gpuDevices": [] }, - "connections": { - "control-plane": { - "kind": "remote", - "url": "https://api.treeseed.example", - "audience": "https://api.treeseed.example", - "tls": { "trust": "system", "serverName": "api.treeseed.example" }, - "authentication": { "mode": "bearer", "secretRef": "provider-registration" }, - "healthGate": { "protocol": "https", "path": "/v1/health", "timeoutSeconds": 30 } - } - }, - "configuration": { - "environment": { "TREESEED_PROVIDER_MODE": "development" }, - "providerEnrollment": { - "connectionId": "primary", - "teamId": "team:treeseed", - "offer": { - "maxConcurrentRunners": 4, - "capabilities": ["communication", "agent-execution", "engineering", "research", "planning", "acting", "verification"] - } - }, - "files": { - "treeseed.capacity-provider.yaml": "schemaVersion: 3\nownership:\n type: team\n teamId: team:treeseed\nconfiguration:\n generation: managed-provider-development-v2\nidentity:\n privateKeyRef: data://identity-v3.json\n displayName: TreeSeed managed capacity provider\ncapacity:\n maxConcurrentWorkers: 4\n cpuCores: 8\n memoryBytes: 17179869184\n maxActiveSeconds: 28800\n maxInputTokens: 4000000\n maxOutputTokens: 1000000\n maxCost: 100\n currency: USD\n maxAttempts: 3\ncredentialProfiles:\n - { id: codex-auth, source: process-environment, reference: TREESEED_CODEX_AUTH_FILE, required: true }\n - { id: codex-executable, source: process-environment, reference: TREESEED_CODEX_EXECUTABLE, required: true }\nlanes:\n - id: communication\n purpose: communication\n priority: 100\n reservedConcurrentWorkers: 1\n maxConcurrentWorkers: 2\n borrowWhenIdle: true\n lendWhenIdle: true\n reclaimPolicy: admission\n queueLimit: 100\n timeoutSeconds: 120\n capabilities: [communication, agent-execution, research, planning]\n - id: platform\n purpose: platform\n priority: 70\n reservedConcurrentWorkers: 0\n maxConcurrentWorkers: 4\n borrowWhenIdle: true\n lendWhenIdle: true\n reclaimPolicy: admission\n queueLimit: 100\n timeoutSeconds: 900\n capabilities: [agent-execution, engineering, verification, repository_work]\n - id: workday\n purpose: workday\n priority: 50\n reservedConcurrentWorkers: 0\n maxConcurrentWorkers: 4\n borrowWhenIdle: true\n lendWhenIdle: true\n reclaimPolicy: admission\n queueLimit: 100\n timeoutSeconds: 900\n minimumAssignmentDuration: { amount: 600, unit: seconds }\n capabilities: [agent-execution, engineering, research, planning, acting, verification, repository_work]\nadapters:\n - id: codex-local\n adapter: codex\n isolation: process\n module: module:codex-chat\n profile: subscription\n protocol: responses\n credentialProfiles: [codex-auth, codex-executable]\n laneIds: [communication, platform, workday]\n maxConcurrentWorkers: 4\n minimumAssignmentDuration: { amount: 600, unit: seconds }\n nativeLimits: { availableAgentSeconds: 28800 }\n capabilities: [communication, agent-execution, engineering, research, planning, acting, verification]\nconnections: []\nmetadata:\n custody: manager-owned\n sharedBattery: true\n" - } - } - } - }, - "network": { - "manager": { "binding": "127.0.0.1:4790", "aliases": [], "sans": ["127.0.0.1"], "trustedLanCidrs": [] } - }, - "fleet": { - "rolloutGroup": "capacity-providers-development", - "receiptReporting": { "enabled": false, "intervalSeconds": 300 } - }, - "secrets": { - "provider-registration": { "provider": "file", "reference": "/etc/treeseed/credentials/provider-registration" }, - "agent-codex-auth": { "provider": "file", "reference": "/etc/treeseed/credentials/agent-codex-auth" } - } -} diff --git a/deployment/host-configs/development-workstation.json b/deployment/host-configs/development-workstation.json deleted file mode 100644 index b5ab5c67..00000000 --- a/deployment/host-configs/development-workstation.json +++ /dev/null @@ -1,130 +0,0 @@ -{ - "schemaVersion": "treeseed.host/v1", - "configurationId": "development-workstation", - "generation": 10, - "host": { - "id": "adrian-workstation", - "role": "integrated", - "architecture": "amd64" - }, - "runtime": { - "management": "managed", - "environment": "development", - "dataRoot": "/home/adrian/Projects/treeseed/platform/.treeseed/data" - }, - "updates": { - "defaultTrack": "development", - "stable": { - "metadataPollSeconds": 86400, - "maintenanceWindow": { "weekday": "sunday", "localTime": "03:00", "jitterMinutes": 20 } - }, - "development": { "pollSeconds": 60 } - }, - "components": { - "api": { - "enabled": true, - "track": "development", - "aliases": { "api.api.http": "api.treeseed.localhost" }, - "configuration": { - "environment": { - "NODE_ENV": "production", - "TREESEED_ENVIRONMENT": "local", - "TREESEED_LOCAL_DEV_MODE": "1", - "POSTGRES_USER": "treeseed", - "POSTGRES_DB": "treeseed_api", - "TREESEED_API_BASE_URL": "https://api.treeseed.localhost", - "TREESEED_SITE_URL": "https://api.treeseed.localhost", - "TREESEED_API_BOOTSTRAP_ADMIN_ALLOWLIST": "adrian.webb@knowledge.coop", - "TREESEED_MAILPIT_SMTP_HOST": "mailpit", - "TREESEED_MAILPIT_SMTP_PORT": "1025", - "TREESEED_TREEDX_URL": "http://treedx:4000", - "TREESEED_TREEDX_JWT_ISSUER": "https://api.treeseed.localhost/treedx", - "TREESEED_TREEDX_JWT_AUDIENCE": "treedx" - }, - "secretEnvironment": { - "POSTGRES_PASSWORD": "api-postgres-password", - "TREESEED_DATABASE_URL": "api-database-url", - "SESSION_SECRET": "api-session-secret", - "TREESEED_TREEDX_DELEGATION_PRIVATE_KEY": "api-treedx-delegation-private-key", - "TREESEED_TREEDX_CREDENTIAL_BROKER_ASSERTION": "treedx-credential-broker-assertion", - "TREESEED_GITHUB_TOKEN": "github-repository-token" - } - } - }, - "agent": { - "enabled": true, - "track": "development", - "aliases": {}, - "connections": { - "control-plane": { "kind": "local", "componentId": "api", "serviceId": "api", "endpointId": "http" } - }, - "configuration": { - "environment": { - "TREESEED_PROVIDER_MODE": "development" - }, - "files": { - "treeseed.capacity-provider.yaml": "schemaVersion: 3\nownership:\n type: team\n teamId: team:treeseed\nconfiguration:\n generation: managed-development-v2\nidentity:\n privateKeyRef: data://identity-v3.json\n displayName: TreeSeed managed development provider\ncapacity:\n maxConcurrentWorkers: 4\n cpuCores: 8\n memoryBytes: 17179869184\n maxActiveSeconds: 28800\n maxInputTokens: 4000000\n maxOutputTokens: 1000000\n maxCost: 100\n currency: USD\n maxAttempts: 3\ncredentialProfiles:\n - { id: codex-auth, source: process-environment, reference: TREESEED_CODEX_AUTH_FILE, required: true }\n - { id: codex-executable, source: process-environment, reference: TREESEED_CODEX_EXECUTABLE, required: true }\nlanes:\n - id: communication\n purpose: communication\n priority: 100\n reservedConcurrentWorkers: 1\n maxConcurrentWorkers: 2\n borrowWhenIdle: true\n lendWhenIdle: true\n reclaimPolicy: admission\n queueLimit: 100\n timeoutSeconds: 120\n capabilities: [communication, agent-execution, research, planning]\n - id: platform\n purpose: platform\n priority: 70\n reservedConcurrentWorkers: 0\n maxConcurrentWorkers: 4\n borrowWhenIdle: true\n lendWhenIdle: true\n reclaimPolicy: admission\n queueLimit: 100\n timeoutSeconds: 900\n capabilities: [agent-execution, engineering, verification, repository_work]\n - id: workday\n purpose: workday\n priority: 50\n reservedConcurrentWorkers: 0\n maxConcurrentWorkers: 4\n borrowWhenIdle: true\n lendWhenIdle: true\n reclaimPolicy: admission\n queueLimit: 100\n timeoutSeconds: 900\n minimumAssignmentDuration: { amount: 600, unit: seconds }\n capabilities: [agent-execution, engineering, research, planning, acting, verification, repository_work]\nadapters:\n - id: codex-local\n adapter: codex\n isolation: process\n module: module:codex-chat\n profile: subscription\n protocol: responses\n credentialProfiles: [codex-auth, codex-executable]\n laneIds: [communication, platform, workday]\n maxConcurrentWorkers: 4\n minimumAssignmentDuration: { amount: 600, unit: seconds }\n nativeLimits: { availableAgentSeconds: 28800 }\n capabilities: [communication, agent-execution, engineering, research, planning, acting, verification]\nconnections: []\nmetadata:\n custody: manager-owned\n sharedBattery: true\n" - } - } - }, - "treedx": { - "enabled": true, - "track": "development", - "aliases": { "treedx.treedx.http": "treedx.treeseed.localhost" }, - "connections": { - "control-plane": { "kind": "local", "componentId": "api", "serviceId": "api", "endpointId": "http" } - }, - "configuration": { - "environment": { - "TREEDX_GIT_EXTERNAL_TRANSPORT_ENABLED": "true", - "TREEDX_GIT_ALLOWED_HOSTS": "github.com", - "TREEDX_REMOTE_CREDENTIAL_BROKER_SERVICE_ID": "node_local", - "TREEDX_BOOTSTRAP_TRUST_ACTOR_ID": "treeseed-api", - "TREEDX_BOOTSTRAP_TRUST_TENANT_ID": "treeseed-control-plane", - "TREEDX_JWT_ISSUER": "https://api.treeseed.localhost/treedx", - "TREEDX_JWT_AUDIENCE": "treedx", - "TREEDX_JWT_ALLOWED_ALGS": "RS256" - }, - "secretEnvironment": { - "TREEDX_REMOTE_CREDENTIAL_BROKER_ASSERTION": "treedx-credential-broker-assertion" - } - } - }, - "lab": { - "enabled": true, - "track": "development", - "aliases": { - "lab.mailpit.web": "mail.treeseed.localhost", - "lab.diagnostics.http": "lab.treeseed.localhost" - }, - "configuration": { "environment": {} } - }, - "ai": { - "enabled": false, - "track": "stable", - "aliases": {}, - "configuration": {} - } - }, - "network": { - "manager": { - "binding": "127.0.0.1:4790", - "aliases": ["manager.treeseed.localhost"], - "sans": ["manager.treeseed.localhost", "127.0.0.1"], - "trustedLanCidrs": [] - } - }, - "fleet": { - "rolloutGroup": "development-workstation", - "receiptReporting": { "enabled": false, "intervalSeconds": 300 } - }, - "secrets": { - "agent-codex-auth": { "provider": "file", "reference": "/etc/treeseed/credentials/agent-codex-auth" }, - "api-postgres-password": { "provider": "file", "reference": "/etc/treeseed/credentials/api-postgres-password" }, - "api-database-url": { "provider": "file", "reference": "/etc/treeseed/credentials/api-database-url" }, - "api-session-secret": { "provider": "file", "reference": "/etc/treeseed/credentials/api-session-secret" }, - "api-treedx-delegation-private-key": { "provider": "file", "reference": "/etc/treeseed/credentials/api-treedx-delegation-private-key" }, - "treedx-credential-broker-assertion": { "provider": "file", "reference": "/etc/treeseed/credentials/treedx-credential-broker-assertion" }, - "github-repository-token": { "provider": "file", "reference": "/etc/treeseed/credentials/github-repository-token" } - } -} diff --git a/deployment/integration-releases/development.json b/deployment/integration-releases/development.json deleted file mode 100644 index f1caf280..00000000 --- a/deployment/integration-releases/development.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "schemaVersion": "treeseed.integration-release/v1", - "release": "0.1.0~rc79", - "generation": 54, - "track": "development", - "compatibilityId": "treeseed-linux-amd64-v1", - "platform": { "repository": "treeseed-ai/platform", "commit": "b4ae096f8838a9acff4f6e775289ff503d478f22" }, - "deployment": { "repository": "treeseed-ai/deployment", "commit": "41b07f44a3b1ddb71b3b68578843868bd4db0c79", "tag": "0.1.0-rc.79" }, - "hostPayloads": [ - { "id": "sdk", "packageName": "@treeseed/sdk", "version": "0.13.0-rc.38", "artifact": { "url": "https://registry.npmjs.org/@treeseed/sdk/-/sdk-0.13.0-rc.38.tgz", "sha256": "afe26c7f48ef180679c7983e7dc4bbb21e2a8745fd470b2d3441b4512f04cdef" } }, - { "id": "cli", "packageName": "@treeseed/cli", "version": "0.13.0-rc.23", "artifact": { "url": "https://registry.npmjs.org/@treeseed/cli/-/cli-0.13.0-rc.23.tgz", "sha256": "7e10d0f64a7a0b9ae042f5a19eed82e90bccf41d10140eeafe17769811fc9ba7" } }, - { "id": "treedx", "packageName": "@treeseed/treedx", "version": "0.3.0-rc.9", "artifact": { "url": "https://registry.npmjs.org/@treeseed/treedx/-/treedx-0.3.0-rc.9.tgz", "sha256": "892f51d2626d275e966e9271492e3fc6edb62e14eed8020a002b4016a9b262e7" } }, - { "id": "yaml", "packageName": "yaml", "version": "2.9.0", "artifact": { "url": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz", "sha256": "008fa204cb1ba700e0272ba045abbf09a6ffe63456e8146ba97cac6c2ad1ef91" } }, - { "id": "zod", "packageName": "zod", "version": "3.25.76", "artifact": { "url": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", "sha256": "9e1f1a05f0dd0c1dab64ee91ceb9bf55cd44d35368c70edda80a2fdc70a88377" } } - ], - "components": [ - { "componentId": "api", "release": "0.8.0~rc37-1", "manifest": { "url": "https://github.com/treeseed-ai/api/releases/download/0.8.0-rc.37/component-release.json", "sha256": "4fb2fe3fefe43c4c9d87b3560b23d33bdf441f54b15563b46328075bd70634a8" }, "files": [{ "path": "compose.yml", "artifact": { "url": "https://github.com/treeseed-ai/api/releases/download/0.8.0-rc.37/compose.yml", "sha256": "7d6d58107a19f2761547d806d83de6b3c78da3a01d14821f080bb7d428951306" } }] }, - { "componentId": "agent", "release": "0.13.0~rc24-1", "manifest": { "url": "https://github.com/treeseed-ai/agent/releases/download/0.13.0-rc.24/component-release.json", "sha256": "9af9dcff181e0e1146920e999d29440040e24ba8f1c1df72a572ac1995fe0f5b" }, "files": [{ "path": "compose.yml", "artifact": { "url": "https://github.com/treeseed-ai/agent/releases/download/0.13.0-rc.24/compose.yml", "sha256": "c265e73fdede0687b5be2deee4711f85f4ceb21f1d09140f07af1f9151cc774d" } }] }, - { "componentId": "treedx", "release": "0.3.0~rc9-1", "manifest": { "url": "https://github.com/treeseed-ai/treedx/releases/download/0.3.0-rc.9/component-release.json", "sha256": "6a4a9d91c4ced612ac4a8c09f9d53e82128e298819b922efe459cde08a11a8cf" }, "files": [{ "path": "compose.yml", "artifact": { "url": "https://github.com/treeseed-ai/treedx/releases/download/0.3.0-rc.9/compose.yml", "sha256": "f2fb2013ff2170b299d84c8c2701fc32c0542c5dd4cc5476af322cc75cef8054" } }] }, - { "componentId": "lab", "release": "0.1.0~rc34-1", "manifest": { "url": "https://github.com/treeseed-ai/deployment/releases/download/0.1.0-rc.34/component-release.json", "sha256": "553e9bcfd99755a5f55eae2b59da7c3be6c35e9dcb985515bce79ed2d1a399a7" }, "files": [{ "path": "compose.yml", "artifact": { "url": "https://github.com/treeseed-ai/deployment/releases/download/0.1.0-rc.34/compose.yml", "sha256": "ef646932604e580762c1a26a1f6fb973c5d669b141158f6be930f05c5e965115" } }] } - ], - "createdAt": "2026-08-26T05:30:00.000Z" -} diff --git a/docs/agent-acceptance.md b/docs/agent-acceptance.md new file mode 100644 index 00000000..35a7af2d --- /dev/null +++ b/docs/agent-acceptance.md @@ -0,0 +1,842 @@ +# Agent execution acceptance + +**Status:** authoritative acceptance specification +**Scope:** proposal governance, activity profiles, living execution graph, workdays, capacity allocation, isolated workspaces, review, simulated release, reporting, and portfolio coordination +**Contract:** [`docs/agent.schema.yml`](./agent.schema.yml) +**Architecture:** [`docs/agent-assignments.md`](./agent-assignments.md) and [`docs/agent-architecture.md`](./agent-architecture.md) + +## Purpose + +This document fixes the golden proposals and the evidence required to call the agent system accepted. The implementation agent must not invent easier proposals, substitute fixture-only work, skip agent classes, treat a terminal workday as proof, or change a proposal after a failed run merely to make the run pass. + +Each software, service, product, platform, template, or skill project in the TreeSeed seed has one project-relevant golden proposal. Team Library is excluded because it is the shared content project rather than an engineering project. The resulting acceptance portfolio contains these 17 projects: + +1. SDK +2. API +3. Agent +4. TreeDX +5. CLI +6. Deployment +7. Identity +8. UI +9. Core +10. Admin +11. Reviewer +12. Engineering Template +13. Research Template +14. Market +15. Market API +16. Skill +17. Platform + +The first two proposals are SDK and API because they exercise the portable contract and its authoritative control-plane implementation. They must pass independently, then together in one workday, before the remaining projects proceed. + +## Non-negotiable rules + +### Automated execution authority + +Every criterion in this specification must be bound to executable package-owned +guarantees and scenes. Manual observation, ad-hoc CLI sequences, fixture-only +passes, and terminal status do not satisfy acceptance. Unit/integration scenes +protect components; live campaign scenes drive and monitor the genuine proposal +and workday lifecycle and verify its authoritative evidence. + +Packages ship their own guarantee definitions and executable verifier assets. +Reviewer provides the unified discovery, selection, execution and receipt +interface; it must not copy owner guarantees into a central catalog. Small +scenes cover individual boundaries and compose into project, joint, portfolio +and controlled-failure suites using the same assertions. Installed-package +execution, not just source-checkout execution, is required. + +Whole-specification coverage must fail closed when a criterion is new, changed, +unbound, backed by a missing verifier, or supported only by partial evidence. +Coverage bindings identify the exact authoritative requirement and its coded +assertions; they do not duplicate its prose or change the fixed golden request. +A partial suite pass is never a full campaign pass. Current implementation and +coverage gaps are tracked in Platform #520, Agent #168 and Reviewer #65; this +requirement does not claim that complete automation already exists. + +- Every acceptance workday has the one authoritative `executionMode: simulation`. Assignments execute under that workday mode; graph, result, settlement, and CLI views derive it rather than owning independent mode values. A contradictory derived label is a failed run. +- Simulation may read and modify any file in a disposable repository workspace, run builds and tests, combine candidates, create local commits and tags, and exercise release logic. +- Simulation must not push to an upstream source or library repository, create or update a remote pull request or issue, publish a package or release, deploy, rotate credentials, mutate live data, or call another externally mutating service. +- Upstream Git remotes are read-only. No upstream write credential may enter an assignment. Local simulation repositories are the only push targets. +- TreeDX authoring uses campaign-local repositories or refs with upstream synchronization disabled. Proposal, discussion, note, question, decision, knowledge, and report commits remain locally auditable but are not published upstream. +- Source candidates remain ordinary Git commits. Content products remain ordinary TreeDX commits. Do not add a source-candidate model, acceptance-artifact taxonomy, or secondary status system. +- PostgreSQL remains authoritative for workdays, graph revisions, nodes, edges, attempts, leases, reservations, results, and settlements. +- Every model-backed assignment makes an authoritative clock call as its first execution action and another as its final tool action. Both readings and their timestamps are retained. +- The deterministic Reporter uses the same assignment, result, reservation, settlement, and teardown path, but does not call a model. +- A workday reaching `ended` or an assignment reaching `completed` is necessary but never sufficient. Acceptance is determined only by the evidence checks in this document. +- No legacy field, record, route, or compatibility translation may be used to make a golden run pass. + +### Required contract correction + +`Workday.executionMode` is required with supported values `simulation` and `production`. It is the sole mode authority. The immutable assignment identifies its workday and receives the exact grants, remotes, workspace, and provider instructions compiled for that mode; it does not own another independently mutable mode field. Stage 0 must verify this existing contract end to end. + +For `simulation`, grant compilation must remove every upstream or external mutation capability and replace writable Git destinations with the local simulation repository. For `production`, ordinary governed authority applies. Do not add compatibility aliases, separate run mode, assignment mode, provider mode, or result mode. + +## Simulation custody and repeatability + +### Campaign freeze + +Before the first run, create one acceptance campaign record outside the product object model as an operator-owned test manifest. It records only reproducibility inputs: + +- campaign ID; +- seed name, version, and digest; +- exact protected `staging` commit for every primary and library repository; +- exact SDK, API, Agent, Deployment, TreeDX, CLI, guest-image, and provider runtime build digests; +- exact governed agent-profile refs; +- exact workday-policy revision; +- provider offer revision; +- the proposal IDs and exact draft bytes, fixed work-item topology and acceptance criteria, and subsequently the ready proposal bytes containing genuine agent estimates. + +The campaign manifest is test configuration, not a new control-plane resource. Once frozen, subject repository bases, proposal objectives, work-item topology, permissions and acceptance criteria do not change during retries. Agent estimates are measured planning outputs, not prescribed inputs. Record each ready revision/digest and its contributing estimating results; do not coerce estimates to make a run pass. Runtime-under-test builds may change as defects are repaired; every run records their new exact digests. + +### High-level allocation inputs + +Freeze the resolved workday policy and actual provider offer/configuration alongside the campaign. The campaign manifest must contain one fully expanded, schema-validated workday input for **every** individual project, the SDK/API joint run, the portfolio run, and each controlled failure rerun. The table below is the authoring rule; submit canonical seeded project IDs and canonical `AgentDefinition.agentClass` values, and retain the exact submitted input and resolved policy snapshot with each run. Project-agent-class database row IDs are inventory references, not allocator class keys. A table entry is not permission to omit fields from a submitted input. + +| Run | Selected projects and `projectPercentages` | `agentClassPercentages` | +|---|---|---| +| SDK | `sdk: 100` | SDK: eight classes at `12.5` each | +| API | `api: 100` | API: eight classes at `12.5` each | +| Agent | `agent: 100` | Agent: eight classes at `12.5` each | +| TreeDX | `treedx: 100` | TreeDX: eight classes at `12.5` each | +| CLI | `cli: 100` | CLI: eight classes at `12.5` each | +| Deployment | `deployment: 100` | Deployment: eight classes at `12.5` each | +| Identity | `identity: 100` | Identity: eight classes at `12.5` each | +| UI | `ui: 100` | UI: eight classes at `12.5` each | +| Core | `core: 100` | Core: eight classes at `12.5` each | +| Admin | `admin: 100` | Admin: eight classes at `12.5` each | +| Reviewer | `reviewer: 100` | Reviewer: eight classes at `12.5` each | +| Engineering Template | `template-engineering: 100` | Engineering Template: eight classes at `12.5` each | +| Research Template | `template-research: 100` | Research Template: eight classes at `12.5` each | +| Market | `market: 100` | Market: eight classes at `12.5` each | +| Market API | `market-api: 100` | Market API: eight classes at `12.5` each | +| Skill | `skill: 100` | Skill: eight classes at `12.5` each | +| Platform | `platform: 100` | Platform: eight classes at `12.5` each | +| SDK + API | `sdk: 50, api: 50` | Both projects: eight classes at `12.5` each | +| All-project portfolio | All 17 seeded projects, each with equal positive weight `1`; the allocator normalizes to `100/17` percent per project | Every project: eight classes at `12.5` each | +| Controlled failure | Reuse the exact accepted run's selection and allocation snapshot | Reuse the exact accepted run's class targets; only the specified injected fault changes | + +The eight classes are `architect`, `researcher`, `tester`, `engineer`, `technical-writer`, `releaser`, `reviewer`, and `reporter`. Every submitted input must also record `executionMode: simulation`, `profileId: default`, the profile revision, `durationSeconds`, `maximumConcurrency`, `communicationConcurrency`, `planningPercent`, `allocationWeight: 1`, `planningTurnMaximumSeconds: 180`, the selected proposal/decision IDs, the provider offer revision, capability/model daily caps, reservations, and remaining supply read-back. Initial debugging runs use `durationSeconds: 3600`, `planningPercent: 33.333333333333336` (`100/3`: exactly 1,200 seconds), `maximumConcurrency: 5`, and `communicationConcurrency: 5`. Configure these concurrency values through the version-checked workday policy, and verify host, connection, adapter and lane ceilings before admission. Acceptance requires measured overlap of at least five actual executions, not merely configured slots; preserve graph dependencies. This explicit workday override does not change the team's ordinary 20% planning default. Do not automatically extend the hour, truncate viable assignments, or waive acceptance criteria: report a measured shortfall or failed boundary. Version-check any required policy update and freeze the resulting revision before starting. Expand all class and project mappings into the manifest; do not infer missing mappings from this Markdown table at execution time. + +Use the team's canonical `default` policy (`--profile default`). Freeze its revision and the resolved workday snapshot. Update team defaults through version-checked `workdays profiles update default --input `; explicit workday allocation overrides do not change that policy or existing assignments. Repository allocation profiles, tiers, borrowing, and fixed assignment budgets are not campaign inputs. + +```yaml +durationSeconds: 3600 +allocation: + planningPercent: 33.333333333333336 # 20 minutes planning; 40 minutes execution/closeout + allocationWeight: 1 + planningTurnMaximumSeconds: 180 + projectPercentages: {sdk: 100} + agentClassPercentages: + sdk: + architect: 12.5 + researcher: 12.5 + tester: 12.5 + engineer: 12.5 + technical-writer: 12.5 + releaser: 12.5 + reviewer: 12.5 + reporter: 12.5 +``` + +Resolve project and class keys to their canonical seeded identities before submission. Project/class percentages are redistributable opportunity targets, not per-assignment durations. Each assignment read-back must identify its workday-policy snapshot, genuine estimate and rationale, allocator-selected active duration and deadline, limiting constraint, reservation, measured usage, and settlement. Provider-owned capability caps, shared execution-provider/model caps, assignment bounds, remaining usage and reservations must be read back and frozen; a simulation consumes the same real supply as other workdays. Duration and concurrency remain explicit workday inputs. Never insert reservations directly or supply hand-authored assignment allocations. + +For this local campaign, configure both `codex-research` and `codex-implementation` with Luna/Low to conserve quota, retaining separate 7,200- and 28,800-active-second daily caps respectively. These are installation inputs, not universal release defaults. Both reuse the Codex harness; capability identity remains independent of the execution-provider ID so other providers can supply the same capability. Freeze actual model and capability limits from provider read-back before running the campaign. + +For the all-project portfolio run only, calculate required planning, acting, bounded review, and Reporter supply from the individually accepted genuine estimates. If the normal caps cannot support that work inside the eight-hour window at actual safe concurrency, raise test capability/model caps through versioned provider configuration, preflight again, and freeze the exact temporary offer. Never lower a viable assignment minimum or exceed host/model limits to force admission. Restore and verify the ordinary caps after settlement. If the host cannot supply a viable plan, do not start the portfolio workday; report the exact shortfall. + +Admission must explain weighted workday entitlement, the initial planning pool, project/class opportunity, scoped calibration measurements, limiting constraint, active-duration reservation and hard deadline. Agent-authored expected/maximum estimates and rationale remain unchanged content authority. With no eligible history, acting starts from the maximum estimate subject to real supply/provider ceilings; later allocations use measured calibration. Insufficient capacity defers a node without changing its dependencies. After the initial planning window, unused planning entitlement becomes acting/review capacity when accepted work is ready; otherwise planning continues. + +Selecting a governed proposal must automatically generate estimating turns for its work owners and Reviewer through the ordinary graph, after planning contributions. Do not require an operator activity override to obtain genuine estimates. Without a selected proposal, autonomous planning remains valid and no subjectless estimating work is generated. + +### Local Git custody + +For each project and run, the provider creates a disposable checkout from the campaign's exact upstream base and a local bare simulation repository: + +```text +upstream (read-only exact base) + -> disposable assignment branch/worktree + -> local simulation bare repository + -> reviewed local integration commit/tag +``` + +Candidate branches use `simulation///`. The Releaser may integrate and tag only in the local simulation repository. The control plane catalogs the exact repository identity, commit, branch or tag, verification, and producing result. Simulation refs are retained until the campaign is accepted or explicitly discarded. + +Before and after every run, compare upstream branch heads, tags, releases, pull requests, issues, package registries, and deployment selections. Any external mutation fails the campaign immediately. + +### Reset between retries + +A retry must begin from all of the following original inputs: + +- the same proposal identity and bytes; +- the same proposal source base and evidence refs; +- the same primary and library repository base commits; +- the same workday policy and provider offer, unless the failure specifically proves one of those implementations defective; +- no surviving candidate branch, mutable TreeDX workspace, lease, reservation, assignment eligibility, provider session, or sandbox from the prior run. + +Failed historical records remain auditable, but they cannot satisfy dependencies in the retry. The new workday receives a new ID. Deterministic source projection must reproduce the same initial graph digest. + +Use the existing scoped `trsd workdays stop ` path for an active failed simulation; do not reset the team, provider, or host. Before a retry, read back that run as terminal with zero unfinished/deferred assignments and settlement errors, no team lease belonging to it, and only stale/cancelled graph nodes. Verify its assignment workspaces and sandboxes are closed, and catalog or explicitly discard only that run's local candidate refs under their normal custody rules. If any of these checks cannot be proven, the reset gate remains open and the retry is not accepted. A new workday ID isolates attempts; it does not excuse leaked resources. + +## The canonical proposal lifecycle + +Every project follows the same lifecycle. The project sections below supply the exact project-specific request and expected products. + +1. Submit the fixed proposal as `draft` with its objective, evidence, and six work items. +2. Start the simulation workday with the frozen high-level allocation policy, then open one proposal discussion addressed to Architect, Researcher, Tester, Engineer, Technical Writer, Releaser, Reviewer, and Reporter. Planning/estimating turns use ordinary graph admission against actual remaining supply. +3. Run one relevant `chat` probe for all eight project agents while the discussion is open. Chat must use the communication lane, must not inherit standing work dependencies, and must not create graph edges. +4. Collect one discussion contribution from each of the eight project agents. Contributions identify risks, questions, dependencies, verification, documentation, release, and reporting concerns without changing the fixed objective. +5. During allocator-driven planning, run estimating assignments for Researcher, Architect, Tester, Engineer, Technical Writer, and Releaser work plus one Reviewer assignment covering all paired-review estimates. Every estimate contains `expectedSeconds`, `maximumSeconds`, and a rationale, with `expected <= maximum`. These inform a bounded maximum allocation, never a minimum execution time. +6. Update the same proposal to `ready` using genuine estimating outputs, preserving its fixed objective, topology, permissions and acceptance criteria. Record the exact revision/digest; differing estimate values are not a plan-review failure. Resolve blocking questions through planning discussion, not a separate proposal-feasibility review assignment. +7. Obtain external approval through the proposal-approval CLI, either before or after estimates. Approval alone does not admit acting. The API requires both approval of the unchanged proposal authority and complete owner/Reviewer estimates, then records one classed `proposal` decision bound to that exact content. No decision carries a separate plan, graph, role map, source commit, or capacity plan. +8. Reconcile the accepted content into the living team execution graph. Multiple proposals may be discussed and estimated in parallel in one planning phase. +9. The first planning percentage is a minimum initial window. After it, the API admits graph-ready acting work when available; otherwise it continues planning and may return to planning whenever no accepted work is ready. Acting never occurs inside the initial planning window. +10. Continue through generated Reviewer pairs, simulated release, Reporter closeout, and exactly-once settlement. Agents may finish early. An unfinished graph at the end of the one-hour diagnostic workday is reported honestly and remains eligible for a later workday; it does not by itself fail that workday or constitute a golden pass. + +An explicit continuation uses `trsd workdays plan --continue-from --decision ` with the same project/mode/provider custody and high-level allocation inputs. The API rejects outstanding leases or reservations and retains exact completed predecessor results and consumed review allowances from existing workday records. It creates fresh assignments only for unfinished nodes; no result, estimate, review, usage or candidate is copied or fabricated. This is not a fresh golden reset: ordinary new simulations omit `--continue-from` and retain the reset boundary above. Package-owned scenes must distinguish complete campaign proof from an incomplete one-hour segment; a continued result alone cannot retroactively pass a failed segment. + +If the current implementation cannot represent this lifecycle without an alternate assignment path or duplicate plan authority, stop. Do not simplify the acceptance case to match the implementation. + +## Common activity-profile expectations + +These expectations apply to every project and are not repeated in each proposal. + +| Activity | Agents | Required exact input | Required output | +|---|---|---|---| +| `chat` | All eight agents | Addressed message, exact subject refs, profile prompt and grant | One general result or discussion message that answers only the addressed question; no graph mutation | +| `planning`, round 1 | All eight agents | Proposal, project objectives and knowledge, exact source base, own profile | Independent contribution from that agent's responsibility; questions use the core `question` model | +| `planning`, later cycles | Same eight agents | Prior published contributions plus unchanged source context | A synthesis that explicitly cites consumed predecessor result IDs and identifies any changed recommendation | +| `estimating` | Six work owners plus Reviewer | Exact work item, acceptance criteria, dependencies, workspace and grants | Expected/maximum estimate and rationale; Reviewer estimates each generated review independently | +| `acting` | Researcher, Architect, Tester, Engineer, Technical Writer, Releaser | Immutable assignment, exact proposal/decision, predecessor results, profile, grant, base and deadline | One `AssignmentResult` with ordinary TreeDX or Git refs, verification, non-zero observed usage when time elapsed, diagnostics and two clock checks | +| `reviewing` | Reviewer only | Exact objective, acceptance criteria, candidate result/ref, verification and immutable source authority | Notes/questions as needed and one classed `work-review` decision bound to the exact candidate; Reviewer never mutates it | +| `reporting` | Reporter only | Ended planning rounds, complete graph/attempt/result/settlement records and workday-closing event | Deterministic note-based report and exact `Workday.reportRef` through the ordinary result path | + +### Expected planning contributions + +- Architect: boundaries, ownership, simplest design, affected contracts, and forbidden duplication. +- Researcher: authoritative source evidence, unresolved facts, and citations or exact repository references. +- Tester: failure model, test-first strategy, negative cases, and observable acceptance evidence. +- Engineer: smallest implementation path, likely files, integration risks, and verification commands. +- Technical Writer: affected user/operator/reference documentation and terminology drift. +- Releaser: integration order, compatibility consequences, local release simulation, and rollback/read-back checks. +- Reviewer: ambiguity, authority, security, correctness, and evidence weaknesses. +- Reporter: evidence completeness, expected workday narrative, accounting checks, and closeout omissions that must prevent acceptance. + +At least two complete cycles must prove collaboration by consuming the preceding cycle's eight results. Merely receiving them in context is insufficient; the result must identify the material contribution consumed from each. Two cycles are a minimum acceptance observation, not a fixed runtime round limit. Turns follow standing dependencies and fit within their allocator-issued active duration; no implementation, deployment or release is permitted during planning. + +## Common proposal work-item contract + +Every golden proposal is a `treeseed.proposal/v1` object with these populated fields: + +```yaml +schemaVersion: treeseed.proposal/v1 +id: +projectId: +title: +request: +summary: +status: ready +objectiveRefs: [] +evidenceRefs: [] +discussionRef: +executionPlan: + workItems: +``` + +The shorthand in this document must be expanded into the actual schema before submission. The stored proposal may not contain shorthand, inherited defaults, YAML anchors, or references to this Markdown file as missing configuration. + +### Fixed work-item graph + +| ID | Class | Workspace | Depends on | Review cycles | +|---|---|---|---|---:| +| `research-context` | Researcher | `treedx` | none | 2 | +| `architecture-contract` | Architect | `treedx` | none | 2 | +| `tests-first` | Tester | `git` | none | 2 | +| `implement-change` | Engineer | `git` | none | 2 | +| `document-change` | Technical Writer | `git` | none | 2 | +| `simulate-release` | Releaser | `git` | none | 2 | + +Every ready row has `activity: acting`, `review: required`, a non-empty project-specific objective, its owner's genuine estimate and the Reviewer's genuine review estimate, `maximumReviewCycles: 2`, exact `contextRefs`, requested permissions, required capabilities, and project-specific acceptance criteria. Draft intake must support estimating before those values exist; fabricating seed estimates does not satisfy acceptance. + +The proposal does not duplicate generic role ordering. The accepted activity profiles are its single authority: question-driven Researcher → generated Reviewer runs in parallel with Architect → Tester → Engineer → Technical Writer → Releaser, and reconciliation inserts a generated Reviewer after every required acting result. `dependsOn` is reserved for proposal-specific domain dependencies that are not already standing workflow rules. + +Reconciliation generates one Reviewer node for each row. Generated Reviewer nodes are not written into the proposal. A downstream work item becomes ready only after the predecessor's exact review decision is approved. + +### Fixed permissions and assignment workspaces + +- Researcher requests content read for `book`, `knowledge`, `objective`, `proposal`, `decision`, `note`, and `question`; content write for `knowledge`, `note`, and `question`; tools `discussion` and `source.read`. +- Architect requests the same reads; content write for `book`, `knowledge`, `note`, and `question`; tools `discussion` and `source.read`. +- Tester, Engineer, and Technical Writer request the same content reads, no content writes, and tools `source.read`, `source.write`, and `verification`. +- Releaser requests the same content reads, no content writes, and tools `source.read`, `source.write`, `verification`, and `release`. +- Generated Reviewer assignments receive exact candidate read authority, discussion/content decision authority, and verification tools, but no source or candidate write authority. +- Simulation Git assignments use the local simulation repository, the exact predecessor-approved base, a unique assignment branch, and `writablePaths: ['.']`. +- TreeDX assignments receive one campaign-local workspace and only their exact acceptance paths. No assignment has both a mutable Git and mutable TreeDX workspace. + +### Fixed product chain + +1. In response to its assigned question, Researcher returns an exact TreeDX note or knowledge reference containing source evidence and unresolved questions; its review proceeds independently and never blocks the engineering branch. +2. Architect independently returns exact ` Architecture` book/knowledge refs describing the smallest design and ownership boundaries. +3. Tester returns a Git commit containing tests that fail against the frozen base for the intended reason and pass against the expected implementation. Existing unrelated failures are recorded separately. +4. Engineer starts from the approved Tester candidate, makes the implementation pass those tests, and adds no self-authored substitute tests unless the Tester explicitly requested them in its result. +5. Technical Writer starts from the approved implementation/test chain and updates the repository's actual user, operator, API, or contributor documentation. +6. Releaser combines the exact approved Git predecessors in the local simulation repository, runs the project verification and package/release dry run, and returns a local integration commit and optional local tag. It cannot push, publish, merge upstream, or deploy. +7. Reporter references every planning result, assignment result, review decision, candidate, settlement, failure, retry, and teardown result in one deterministic workday note. + +### Reporter selection + +Each workday has exactly one closeout Reporter and one `Workday.reportRef`. Individual project runs use that project's Reporter. The SDK/API joint run uses `sdk/reporter`; the all-project run uses `platform/reporter`. The applied workday plan records this selection before activation. Other participating Reporter agents still perform chat and repeated planning cycles, but reconciliation must not create duplicate project reports or a second summary layer. + +## Project golden proposals + +The source issue is evidence for choosing the work. The golden proposal below is the acceptance authority when an older issue mentions legacy capacity plans, compatibility, publication, or deployment behavior that conflicts with the current architecture. + +### 1. SDK — decision-governed workday intent + +- `id`: a fresh unique SDK golden proposal ID for each estimate-free campaign, preserving the six fixed work items and exact SDK Book/library and Git commits captured in that campaign's freeze. Prior terminal workdays provide defect evidence only; their estimates and assignment results are not reused. CLI parser/executor implementation and API digest/persistence behavior are separate from this SDK-only workday. Researcher → Reviewer remains independent of Architect → Tester → Engineer → Technical Writer → Releaser. Freeze the current policy and runtime before starting; Platform #520 owns detailed run evidence. +- Source: `treeseed-ai/sdk#299` +- Architecture Book: `sdk-core` at `books/sdk-core.md` in the pinned SDK library commit. Its published title is **SDK Core**. The Architect publishes architecture Knowledge associated with this exact Book reference; there is no separate “SDK Architecture” book. Preflight must read back the Book before the proposal opens. +- Title: **Select accepted decisions in portable workday intent** +- Request: Add normalized repeated accepted-decision identities to the public SDK `WorkdayIntent` and generated operation contract. Implement one SDK normalization/strict-validation function in `src/operator-contracts/workday-lifecycle.ts` and call it from the SDK `ControlPlaneClient.invoke` request path for `workdays.plan` and the nested intent of `workdays.schedules.create`, before body schema parsing and JSON serialization. Trim each ID, reject empty IDs and duplicates after trimming, and serialize IDs in ascending, case-sensitive Unicode code-point order so input permutations produce identical outbound request bytes. Omitted `decisionIds` preserve both `planningOnly: false` and `planningOnly: true`; an explicit empty selection is invalid. Verify one repeatable/CSV `--decision` binding in each generated `workdays plan` and `workdays schedules start` descriptor; CLI parser/executor behavior belongs to the separate CLI proposal. SDK mock-transport tests prove the normalized outbound API request bytes and prove the SDK computes neither `intentDigest` nor `preflightDigest`; API incorporation of selection into those digests belongs to the separate API proposal. Decision IDs select authority but never contain or grant derived graph, assignment, source, role, estimate, or capacity state. Reject caller-authored `executionPlanId`, `capacityPlanId`, `executionInputId`, and `demandSetId` on both direct SDK intent calls and the generated-operation request path before permissive parsing can discard unknown fields; do not add compatibility aliases. These fields are absent from the current SDK intent, so do not invent a deletion. Preserve distinct `planningOnly`, `proposalIds`, `agentSelection`, and `allocation` controls and their SDK contracts; the proposal's governed `executionPlan` and API-derived capacity provenance (including persisted `capacityPlanId`) remain separate authorities, not SDK request fields or SDK persistence proofs. +- Summary: Prove the SDK can express high-level decision-governed execution while keeping all derived execution state API-owned. + +| Work item | Project-specific objective and expected output | +|---|---| +| Researcher | Trace `WorkdayIntent`, `ControlPlaneClient.invoke`, `workdays.plan`, `workdays.schedules.create`, both generated `--decision` descriptors, and preflight receipt declarations with exact source refs. For each prohibited caller-authored field, distinguish its absence at the SDK request boundary from any existing API-owned receipt or path evidence; cite the actual source location of each finding rather than implying every field is an SDK intent export. On the initial acting attempt, publish a real preliminary finding with only the exact `WorkdayIntent` and `ControlPlaneClient.invoke` citations, marking operation bindings, generated descriptors, and per-field provenance explicitly pending. Do not claim those missing findings or full criterion coverage. On a later correction attempt, address the actual paired Reviewer findings and supply all original research criteria using exact source evidence. | +| Architect | Publish SDK architecture Knowledge associated with the existing SDK Core book (`sdk-core`, `books/sdk-core.md`). Define one normalization/strict-validation function at the SDK request boundary, generated descriptor bindings, SDK serialization versus API digest/persistence ownership, and all four prohibited fields. Preserve separate `planningOnly`, `proposalIds`, `agentSelection`, `allocation`, governed proposal `executionPlan`, and API-derived capacity provenance. | +| Tester | Commit focused SDK tests that fail for a missing behavior on the frozen base: trim IDs; reject empty, explicit-empty and duplicate-after-trim IDs; sort in case-sensitive Unicode code-point order; prove permuted selections produce identical outbound JSON bytes through `ControlPlaneClient.invoke` with mock transport; prove omitted IDs preserve each `planningOnly` state. Check one repeated/CSV `--decision` binding in each generated command descriptor, without treating CLI parser execution as SDK acceptance. Pass each of `executionPlanId`, `capacityPlanId`, `executionInputId`, and `demandSetId` through both direct workday intent and nested schedule intent request shapes; assert each SDK call throws before the mock transport is invoked, so permissive schema parsing cannot silently discard it. Assert the SDK computes neither digest; API digest incorporation and persisted capacity provenance are outside this SDK test. | +| Engineer | Implement the single SDK `WorkdayIntent` normalization/strict-validation function and invoke it from `ControlPlaneClient.invoke` for `workdays.plan` and nested `workdays.schedules.create` before body parsing and JSON serialization. Trim, reject empty/duplicate IDs and forbidden caller-authored fields, sort case-sensitive Unicode code points, and preserve omitted-ID planning behavior and the separate `proposalIds`, `agentSelection`, and `allocation` controls. Generate each command descriptor with one repeated/CSV `--decision` binding. Do not compute SDK digests or alter governed `executionPlan` or API-derived capacity provenance. | +| Technical Writer | Update SDK API/reference examples for descriptor-level repeated `--decision` selection, normalized outbound intent, omission with both `planningOnly` states, API-only digest/persistence ownership, and the four prohibited caller-authored fields. | +| Releaser | On the exact unpushed local candidate, run the public `npm run release:verify` aggregate, `npm pack`, and `npm run standards:acceptance -- --archive .tgz` using the actual current-directory archive. Retain each measured command receipt. The aggregate owns strict build, standards generation/acceptance, and the full contract/release suite; do not duplicate those subordinate commands. Inspect exports/types through the public archive command, not an internal script alias. | + +Each Actor is reviewed against its own deliverable: Researcher supplies exact SDK source refs for `WorkdayIntent`, `ControlPlaneClient.invoke`, both operation bindings, request-boundary absence of all four prohibited caller fields, and separate API-owned receipt/path evidence where it exists; Architect publishes SDK Core Knowledge at `books/sdk-core.md` defining one strict request-boundary normalization and validation path, one repeatable/CSV `--decision` binding in each generated descriptor, rejection of `executionPlanId`, `capacityPlanId`, `executionInputId`, and `demandSetId` as caller input, preservation of `planningOnly`, `proposalIds`, `agentSelection`, and `allocation`, and the boundary between SDK serialization, governed proposal `executionPlan`, and API digest/persistence and capacity provenance; Tester commits failing-on-base SDK tests for trimming, empty and explicit-empty selection rejection, duplicate-after-trim rejection, case-sensitive Unicode code-point ordering, byte-identical outbound JSON for permuted selections through both request shapes, both omitted-ID `planningOnly` states, both descriptor bindings, pre-transport rejection of each prohibited caller field through direct `workdays.plan` and nested `workdays.schedules.create`, and absence of SDK-computed digests; Engineer implements those same normalization, descriptor, omission, and per-field rejection behaviors through one strict SDK path for direct and generated-operation calls without computing API digests or changing governed `executionPlan` or API-derived capacity provenance; Technical Writer commits SDK reference examples showing both generated descriptors, normalized outbound selections, omission with `planningOnly: false` and `planningOnly: true`, API-only digest/persistence ownership, and all four prohibited caller-authored fields; Releaser retains measured passing receipts for exactly `npm run release:verify`, `npm pack`, and `npm run standards:acceptance -- --archive .tgz` on the exact unpushed candidate, with the actual current-directory archive inspected for export/type identity. The paired Reviewer must independently replay those public commands against the same candidate; lower-level aliases and narrative claims do not satisfy these receipts. The integrated-candidate gates below apply to the final candidate, not each earlier Actor workspace. Generated Reviewers give actionable findings against these exact work-item boundaries; no decision is forced. + +The preliminary Researcher artifact is a controlled, truthful negative input for the existing revision check, not an accepted final deliverable. Its full research criterion is unchanged. Reviewers inspect the actual first and corrected artifacts against that criterion; neither a finding nor an approval is prescribed or manufactured. A correction counts only after a real request-changes result, a later Actor contribution addressing its actual findings, and a separate later approval. Researcher remains independent of the engineering branch, so this exercise adds no dependency, estimate, allowance, or work item. + +Required acceptance for the final integrated SDK candidate: selected IDs are trimmed, nonempty, unique after trimming, and sorted in ascending case-sensitive Unicode code-point order. Mock transport proves different input orders yield identical outbound JSON bytes for `workdays.plan` and nested `workdays.schedules.create`; omission preserves each `planningOnly` state. Both generated command descriptors declare one repeatable/CSV `--decision` binding; CLI parser/executor behavior is tested in the CLI campaign. Direct SDK and generated-operation calls reject caller-authored `executionPlanId`, `capacityPlanId`, `executionInputId`, and `demandSetId` before permissive parsing; the fields were not SDK exports to delete. The SDK computes neither `intentDigest` nor `preflightDigest`; API digest incorporation and persisted capacity provenance are tested in the API campaign. Preserve `proposalIds`, `agentSelection`, `planningOnly`, `allocation`, governed proposal `executionPlan`, and API-owned capacity provenance as distinct authorities. Researcher → Reviewer remains independent of Architect → Tester → Engineer → Technical Writer → Releaser. + +### 2. API — content-derived acting promotion + +- `id`: `golden-api-content-derived-acting-promotion` +- Source: `treeseed-ai/api#356`, corrected to the living-graph architecture +- Title: **Project accepted decisions directly into living-graph work** +- Request: Resolve SDK-owned decision identities against current accepted proposal authority, exact project scope, estimates, source refs, profiles, and conditions; reconcile affected content directly into the living graph and admit ready nodes during an active workday. Reject caller-authored graph, assignment, source, role, execution-input, demand, or capacity-plan state, and delete the superseded promotion path. +- Summary: Prove the API turns governed content into assignments without a second plan or scheduling authority. + +| Work item | Project-specific objective and expected output | +|---|---| +| Researcher | Trace proposal decision resolution, reconciliation, admission, retries, and legacy promotion/storage paths with exact refs. | +| Architect | Record the transaction and authority boundaries from accepted content through graph revision, assignment, reservation, result, and settlement. | +| Tester | Add positive, stale, wrong-team, wrong-project, unaccepted, superseded, missing-estimate/profile/source, replay, and mid-workday-admission tests. | +| Engineer | Implement direct content-derived reconciliation/admission and remove capacity-plan, execution-input, demand-row, and alternate synthesis behavior. | +| Technical Writer | Document public API behavior, failure explanations, watch/readback fields, and the absence of caller-authored internals. | +| Releaser | Run database migration from a clean pre-launch schema, API/runner builds and tests, local service smoke, replay-as-noop, and rollback simulation. | + +Required acceptance: one exact accepted proposal revision creates one deterministic connected component; replay is noop; content accepted mid-workday becomes eligible without restart; transactional claim creates one assignment/lease/reservation; each attempt settles once; no legacy records are read or written. + +### 3. Agent — fail-closed AgentKernel execution + +- `id`: `golden-agent-fail-closed-kernel-execution` +- Source: `treeseed-ai/agent#122` +- Title: **Execute every activity through one fail-closed AgentKernel** +- Request: Complete the isolated provider-to-AgentKernel path so every enabled activity selects exactly one compiled handler, enforces its immutable grant/workspace/deadline, emits one general result, records real usage, and tears down. Remove remaining provider semantic branches and prove actionable failures. +- Summary: Prove the Agent package executes profiles rather than reimplementing their workflow semantics. + +| Work item | Project-specific objective and expected output | +|---|---| +| Researcher | Inventory runtime semantic branches, provider/Kata boundaries, sandbox lifecycle, usage sources, and known failure gaps. | +| Architect | Specify the one entry point, handler registry, runtime services, timing boundary, cancellation, teardown, and forbidden responsibilities. | +| Tester | Add fail-closed tests for unknown handler/build, denied service, invalid result, timeout, cancellation, teardown, usage, and no alternate path. | +| Engineer | Complete the minimal kernel/provider implementation and delete superseded routing and dynamic behavior. | +| Technical Writer | Update package runtime, handler-authoring, diagnostics, and local Kata guidance. | +| Releaser | Build provider and guest locally, run all activity profiles in Kata, verify teardown and local artifact identity, and retain no upstream effect. | + +Required acceptance: every model profile and deterministic Reporter uses the same kernel; clock evidence brackets productive work; observed usage is not zero when elapsed time is non-zero; no sandbox/worktree survives; failure diagnostics identify the exact boundary. + +### 4. TreeDX — byte-exact unified changesets + +- `id`: `golden-treedx-byte-exact-changesets` +- Source: `treeseed-ai/treedx#54` +- Title: **Apply standard patches with byte-exact Git semantics** +- Request: Correct unified changeset application for creation, update, deletion, empty files, terminal-newline transitions, trailing blanks, Unicode, and CRLF. Validate hunk counts and context and reject malformed, truncated, or overlapping patches atomically without changing valid bytes. +- Summary: Prove TreeDX preserves exact repository bytes and trustworthy commit/digest custody. + +| Work item | Project-specific objective and expected output | +|---|---| +| Researcher | Compare applicable unified-diff rules and current TreeDX behavior against exact Git fixtures without relying on prose-only assumptions. | +| Architect | Define byte, parsing, atomicity, error, and service ownership boundaries with no TreeSeed-specific model logic. | +| Tester | Build a shared byte matrix and malformed-patch suite that demonstrates the frozen defect and exact expected digests. | +| Engineer | Repair the Elixir patch engine minimally and preserve atomic changeset behavior. | +| Technical Writer | Document supported patch semantics, digest guarantees, and diagnostic behavior. | +| Releaser | Run TreeDX tests, compare every fixture to `git apply`, exercise local API read-back, and create only a local candidate. | + +Required acceptance: Git and TreeDX bytes/digests agree for the complete matrix; invalid patches mutate nothing; no trimming or newline normalization occurs. + +### 5. CLI — decision-governed operator surface + +- `id`: `golden-cli-decision-governed-workday` +- Source: `treeseed-ai/cli#216` +- Title: **Expose decision-governed workday execution without derived internals** +- Request: Generate and expose repeatable/comma-separated decision selection on workday planning and start, normalize IDs, bind start to the exact preflight digest, and provide graph/assignment/workday watch and explanation output without implementing business logic or exposing legacy plans. +- Summary: Prove `trsd` is a complete human and automation surface over the canonical SDK/API contracts. + +| Work item | Project-specific objective and expected output | +|---|---| +| Researcher | Audit generated command descriptors, handwritten exceptions, JSON stability, help, and missing acceptance-observation commands. | +| Architect | Define the smallest generated command/readback surface and strict CLI/API responsibility boundary. | +| Tester | Cover repeated/comma-separated parsing, empty/duplicate rejection, body mapping, digest binding, JSON output, watch cursors, and terminal cleanup. | +| Engineer | Implement generated command wiring and delete aliases or handwritten duplicate schemas. | +| Technical Writer | Update command help and one complete proposal-to-report operator story. | +| Releaser | Build/pack locally and run the complete simulation through installed-package-style `trsd` with machine-readable receipts. | + +Required acceptance: `--decision` cannot directly select acting activity or author graph state; JSON remains parseable without warning pollution; operators can explain every gate and inspect all acceptance evidence. + +### 6. Deployment — manager-owned sandbox rebuild and restoration + +- `id`: `golden-deployment-manager-owned-sandbox-rebuild` +- Source: `treeseed-ai/deployment#743` +- Title: **Rebuild and restore Agent Kata guests through manager custody** +- Request: Provide a manager-owned development target that performs fixed guest build, import, digest binding, broker restart, active-assignment exclusion, and restoration without caller Docker authority, host-path parameters, package publication, or productive-time charging. +- Summary: Prove sandbox runtime development is privileged, exact, reversible, and independent of assignment time. + +| Work item | Project-specific objective and expected output | +|---|---| +| Researcher | Trace manager, supervisor, container runtime, broker, digest, and active-assignment boundaries and known restoration evidence. | +| Architect | Define fixed privileged operations, state transitions, exclusion gates, rollback, and untrusted caller inputs. | +| Tester | Add security, active/recoverable assignment, idempotency, digest, archive cleanup, restart, and restoration tests. | +| Engineer | Implement the minimal manager target and remove any caller-owned privileged path. | +| Technical Writer | Document operator behavior, diagnostics, timing separation, and explicit restoration. | +| Releaser | Build/import a changed guest locally, prove Kata observes it, then restore the prior digest and verify no residue. | + +Required acceptance: no sudo/Docker-group requirement enters the assignment; active work blocks replacement; released selection restores the exact prior digest; preparation time is not billed as productive assignment time. + +### 7. Identity — stable source watcher boundaries + +- `id`: `golden-identity-stable-development-watcher` +- Source: `treeseed-ai/identity#36` +- Title: **Prevent generated Identity assets from retriggering source builds** +- Request: Make persistent Identity development watch only handwritten package/theme sources, ignore generated theme output and `.treeseed` state, produce one atomic build marker per real input change, and remain compatible with direct build and tests. +- Summary: Prove a sovereign identity package can run persistently without self-triggered rebuild loops. + +| Work item | Project-specific objective and expected output | +|---|---| +| Researcher | Trace source, generated theme, build marker, watcher, and manager interactions with exact file/event evidence. | +| Architect | Define source/generated ownership, event coalescing, atomic readiness, and recovery boundaries. | +| Tester | Add unchanged-start, one-change, generated-output, `.treeseed`, burst, failure, and restart watcher tests. | +| Engineer | Implement minimal watch filters/coalescing and atomic marker behavior. | +| Technical Writer | Document watched inputs, ignored state, diagnostics, and recovery. | +| Releaser | Run direct verify and a timed local watch simulation proving one build per source change and no loop. | + +Required acceptance: generated output never retriggers; real changes are not lost; no live Identity service, account, issuer, or credential is mutated. + +### 8. UI — reusable capacity and AI management primitives + +- `id`: `golden-ui-operational-management-primitives` +- Source: `treeseed-ai/ui#48` +- Title: **Provide reusable operational lists and focused management wizard** +- Request: Complete reusable capacity/AI operational list and management-wizard primitives with authoritative states, retained drafts, validation, direct navigation, accessibility, responsive behavior, and no fabricated inventory or application business logic. +- Summary: Prove shared UI owns reusable presentation and interaction contracts while Admin owns workflows. + +| Work item | Project-specific objective and expected output | +|---|---| +| Researcher | Inventory current consumers, accessibility guidance, responsive failures, and duplicated list/wizard implementations. | +| Architect | Define generic component props/events/state ownership and the boundary against Admin/API semantics. | +| Tester | Add unit/component and browser tests for search, filters, empty/unavailable, drafts, errors, keyboard use, and 390px layout. | +| Engineer | Implement or simplify the primitives and remove duplicate component paths. | +| Technical Writer | Update component API, examples, accessibility behavior, and migration guidance. | +| Releaser | Build package/sandbox, run unit and Playwright checks locally, pack, and verify exports/assets. | + +Required acceptance: no horizontal overflow; no invented service instances; consumers need no copied controller; no credentials or live provider state are mutated. + +### 9. Core — atomic direct-build readiness + +- `id`: `golden-core-atomic-build-readiness` +- Source: `treeseed-ai/core#8` +- Title: **Make direct package builds publish atomic readiness** +- Request: Ensure the declared direct package build writes `dist/.treeseed-build-complete.json` last and atomically, retains watch behavior, and cannot expose a stale or partial generation to dependent UI/Core/Admin development rebuilds. +- Summary: Prove Core's package development contract has one reliable readiness authority. + +| Work item | Project-specific objective and expected output | +|---|---| +| Researcher | Trace build/watch marker writers, overlay consumers, dependency rebuilds, and stale-marker failure modes. | +| Architect | Define one marker schema/write owner, atomic replacement, generation identity, and failure cleanup. | +| Tester | Add direct build, watch build, interrupted build, stale marker, atomicity, and dependent-consumption tests. | +| Engineer | Make the ordinary build own the final atomic marker and reuse it from watch without duplicate implementations. | +| Technical Writer | Document direct/watch readiness and dependency-consumption semantics. | +| Releaser | Run Core build/test/fixture checks and a local UI -> Core -> Admin rebuild simulation. | + +Required acceptance: a failed build never advertises readiness; successful direct and watched builds use the same marker implementation; no timeout after a valid direct build. + +### 10. Admin — truthful assignment-permission management + +- `id`: `golden-admin-assignment-permission-authoring` +- Source: `treeseed-ai/admin#96` remaining permission-authoring gate +- Title: **Author and explain assignment permissions from authoritative policy** +- Request: Complete the Admin capacity workflow for viewing and authoring the simplified content/tool permission ceilings and exact assignment grants. Use current API/SDK authority, expose denials and provenance, and never fabricate policy digests, provider grants, credentials, or alternate permission models. +- Summary: Prove administrators can understand and manage the one permission architecture safely. + +| Work item | Project-specific objective and expected output | +|---|---| +| Researcher | Trace current Admin/API/SDK permission displays, six-policy ambiguity, authorization, CSRF/CAS/idempotency, and help gaps. | +| Architect | Define screen/workflow ownership and the exact ceiling -> policy -> grant explanation without duplicating evaluation. | +| Tester | Add authorization, stale-CAS, invalid ceiling, denied grant, idempotency, redaction, accessibility, and browser-flow tests. | +| Engineer | Implement the focused workflow against generated operations and delete fabricated/legacy permission paths. | +| Technical Writer | Update contextual help for ceilings, policies, grants, denials, and provider capabilities. | +| Releaser | Build Node/Cloudflare variants, run unit/browser simulation with disposable records, and verify cleanup and no live approval. | + +Required acceptance: Admin displays API explanations rather than recomputing policy; no secret appears in HTML/results; disposable changes clean up; no provider is approved/revoked and no paid capacity is activated. + +### 11. Reviewer — correlated fixture identity and cleanup + +- `id`: `golden-reviewer-correlated-fixture-cleanup` +- Source: `treeseed-ai/reviewer#47` +- Title: **Correlate browser identities and clean failed fixture campaigns** +- Request: Derive bounded deterministic fixture identities from complete correlated run IDs, preserve profile-scoped immutable evidence, and run blocked deletion producers as best-effort cleanup without reporting their functional guarantees as passed. +- Summary: Prove Reviewer separates guarantee evidence from cleanup evidence and leaves no destructive fixture residue. + +| Work item | Project-specific objective and expected output | +|---|---| +| Researcher | Trace run/profile/scene identity derivation, evidence roots, prerequisite blocking, and cleanup residue. | +| Architect | Define deterministic identity, evidence immutability, cleanup scheduling, loopback safety, and pass/fail semantics. | +| Tester | Add repeated-profile collision, failed prerequisite, blocked delete, cleanup failure/success, evidence, and non-loopback rejection tests. | +| Engineer | Implement bounded full-correlation IDs and independent best-effort cleanup execution. | +| Technical Writer | Document guarantee versus cleanup outcomes and evidence interpretation. | +| Releaser | Run repeated local browser campaigns with injected failure and verify residue removal and truthful summaries. | + +Required acceptance: cleanup never converts a failed guarantee to passed; profile evidence IDs remain distinct; all target origins remain loopback-only. + +### 12. Engineering Template — governed generated-project adoption + +- `id`: `golden-template-engineering-governed-adoption` +- Source: `treeseed-ai/template-engineering#4` +- Title: **Generate and adopt an engineering project idempotently** +- Request: Complete the template-owned contract for authenticated project creation by generating a disposable project from the exact template release, validating only portable substitutions, proving build/test, adopting Git/TreeDX resources, and replaying as noop without credentials or host-specific state. +- Summary: Prove the engineering starter is portable, governed, buildable, and idempotently consumable. + +| Work item | Project-specific objective and expected output | +|---|---| +| Researcher | Audit template placeholders, lockfile, tracked archive, generated outputs, adoption preconditions, and rc supersession. | +| Architect | Define template versus Platform/API/CLI ownership and exact create/adopt/noop/rollback boundaries. | +| Tester | Add clean generation, invalid substitution, archive identity, collision, partial failure, adoption, and noop tests. | +| Engineer | Complete only template-owned initialization behavior and remove obsolete template paths. | +| Technical Writer | Update generated contributor and project-creation guidance. | +| Releaser | Generate a disposable local project, run its checks/build, simulate Git/TreeDX adoption twice, and prove second run noop. | + +Required acceptance: generated source has no credentials/personal paths; exact pins and lockfile remain; only tracked files enter the archive; no remote repository is created in simulation. + +### 13. Research Template — reproducible evidence-backed research project + +- `id`: `golden-template-research-reproducible-evidence-project` +- Source: `treeseed-ai/template-research#5`, expanded to project purpose +- Title: **Generate a reproducible source-backed research project** +- Request: Complete a source-only development and template contract that generates a disposable research project containing a book, gathered-source registry, synthesis notes, knowledge pages, citation validation, and exact provenance without a service endpoint or release publication. +- Summary: Prove the research starter supports governed evidence-to-knowledge work and verifies as source-only. + +| Work item | Project-specific objective and expected output | +|---|---| +| Researcher | Use a fixed local evidence corpus to specify provenance, citation, conflicting-source, and synthesis requirements. | +| Architect | Define the smallest generated repository/library structure and boundaries among source, note, knowledge, and book. | +| Tester | Add generation, missing/invalid citation, conflicting evidence, deterministic output, source-check, and no-endpoint tests. | +| Engineer | Implement the portable template/development declaration and validation fixtures. | +| Technical Writer | Produce the generated research workflow and contributor guidance. | +| Releaser | Generate twice from identical inputs, compare bytes, run source-check, and prove no process, endpoint, RC, or upstream change. | + +Required acceptance: repeated generation is byte-stable; every synthesized claim resolves to fixed evidence; the project declares no false runtime target. + +### 14. Market — canonical shared brand assets + +- `id`: `golden-market-canonical-ui-brand-assets` +- Source: `treeseed-ai/market#4` +- Title: **Consume canonical TreeSeed brand assets from UI** +- Request: Remove Market ownership of duplicated logo/favicon bytes. Synchronize them from the selected local `@treeseed/ui` package during development and build, prove byte identity, and preserve Market-specific application content and independent deployment authority. +- Summary: Prove cross-package asset ownership without copied source authority. + +| Work item | Project-specific objective and expected output | +|---|---| +| Researcher | Inventory Market/UI asset copies, build paths, consumers, licenses, and drift history with exact digests. | +| Architect | Define UI ownership, Market synchronization timing, generated-file treatment, and failure/readiness behavior. | +| Tester | Add missing-export, byte-drift, dev/build, stale-output, favicon/logo, and independent-build tests. | +| Engineer | Implement one synchronization path and remove Market-owned duplicate source bytes. | +| Technical Writer | Document asset ownership and local package-development behavior. | +| Releaser | Build/test Market against the local UI candidate, compare digests, and produce an unpushed web candidate only. | + +Required acceptance: Market and UI emitted bytes match exactly; Market does not gain authority over UI source; no hosted deployment occurs. + +### 15. Market API — resource-bound workload credentials + +- `id`: `golden-market-api-resource-bound-workload-credentials` +- Source: `treeseed-ai/market-api#6` +- Title: **Replace shared gateway assertions with scoped workload credentials** +- Request: Integrate resource-specific workload credentials that preserve caller and workload actor independently, reject issuer/audience/client/scope crossover, and remove HS256 shared-service assertion handling without fallback. Keep all live authentication and data unchanged during simulation. +- Summary: Prove Market API authenticates delegated workloads without conflating service and user identity. + +| Work item | Project-specific objective and expected output | +|---|---| +| Researcher | Trace current gateway assertions, caller/workload propagation, SDK/Identity interfaces, and threat boundaries. | +| Architect | Define verification, principal representation, authorization separation, failure, migration, and rollback boundaries. | +| Tester | Add valid delegation plus issuer, audience, client, scope, signature, expiry, replay, actor-confusion, and legacy-token rejection tests. | +| Engineer | Implement strict adapters/middleware and delete shared-secret compatibility behavior. | +| Technical Writer | Document configuration, principal semantics, errors, migration, and no-role-from-token boundary. | +| Releaser | Run local provider fixtures/build/tests with disposable keys and verify no key, live account, database, or deployment mutation. | + +Required acceptance: caller and workload remain distinct; authentication grants no application role by itself; old assertions fail after the simulated cutover. + +### 16. Skill — current source-only TreeSeed operating skill + +- `id`: `golden-skill-current-source-only-guidance` +- Source: `treeseed-ai/skill#7`, expanded to skill purpose +- Title: **Verify the TreeSeed operating skill against the current CLI and architecture** +- Request: Make the versioned TreeSeed skill source-only developable and verify that its instructions use current generated `trsd` commands, exact-ref custody, living graph, simulation safety, and issue/Actions authority without retired commands, compatibility paths, or a false service runtime. +- Summary: Prove the skill teaches the same architecture the system actually exposes. + +| Work item | Project-specific objective and expected output | +|---|---| +| Researcher | Compare every documented command and workflow to current SDK/CLI descriptors and architecture plans. | +| Architect | Define skill scope, progressive disclosure, exact authority boundaries, and source-only development contract. | +| Tester | Add link/command/schema/reference checks, forbidden-term checks, representative task simulations, and no-runtime assertions. | +| Engineer | Update the skill and verification tooling with the smallest non-duplicated instruction set. | +| Technical Writer | Edit user-facing operating guidance for clarity, recovery, and evidence interpretation. | +| Releaser | Run source-check and skill validation from a clean checkout; prove no process, endpoint, RC, install, or upstream mutation. | + +Required acceptance: every command exists in the generated catalog; retired architecture terms do not survive; the skill remains a skill rather than another CLI/business-logic implementation. + +### 17. Platform — complete declarative development composition + +- `id`: `golden-platform-declarative-development-composition` +- Source: `treeseed-ai/platform#518` +- Title: **Compose every first-party project for persistent local development** +- Request: Complete the canonical seed/profile/site declarations and documentation so every first-party project is selectable according to its actual runtime type, dependency closure, and source-only or runnable behavior without RC publication. Platform remains declarative and contains no package implementation, credentials, host identity, or duplicate runtime policy. +- Summary: Prove the portfolio composes as one development system while package ownership remains independent. + +| Work item | Project-specific objective and expected output | +|---|---| +| Researcher | Inventory all seed projects, repositories, libraries, runtime declarations, profiles, dependencies, and development gaps. | +| Architect | Record the canonical declarative composition, ownership boundaries, dependency closure, persistent selection, and failure restoration. | +| Tester | Add seed/profile/site validation, complete-inventory, runtime-type, forbidden-environment, visibility/license, closure, and source-only tests. | +| Engineer | Correct only Platform-owned declarations/docs and remove stale composition paths. | +| Technical Writer | Update the one no-RC local development and verification story. | +| Releaser | Validate/plan the seed without applying externally, exercise local development selection in simulation, and verify exact composition/readback. | + +Required acceptance: all 17 engineering projects and their libraries are represented; Identity is not silently omitted from eligible simulation capacity; only `staging` and `production` environments exist; Platform contains no functional package implementation. + +## Execution order + +### Stage 0 — preflight + +- [ ] Refreeze the campaign manifest and exact proposal bytes against the current integrated runtime. The corrected 17-project manifest validated at `sha256:559db20ad4bb0b057d4cad2139012b8c50eda1a831436bd51e421cba3599d3e3`, but capture finished after the provisional SDK planning run began; the pre-run freeze boundary is not yet proven (Platform #520). +- [x] Validate all 17 proposal objects against `docs/agent.schema.yml` and semantic rules. The corrected campaign validator accepted all 17 draft objects, 136 project agents, and provider offer revision 1; exact TreeDX read-back of SDK v4 commit `34664812cb8303f61eb93d3d31d1c325f3ac3303` confirms six role-scoped criteria and no inherited estimates (Platform #520). +- [x] Confirm all eight agent definitions exist for all 17 projects and every required activity resolves one handler from the pinned runtime build. +- [x] Confirm the simulation provider offers every required capability/tool group and is allowed to serve all 17 projects, including Identity. +- [x] Confirm upstream write credentials and all external mutation tools are absent. +- [ ] Confirm local simulation Git and TreeDX custody, retention, reset, watch, and teardown work. Prior simulation assignments were terminalized with zero unfinished/deferred work and no settlement errors; sandbox and candidate-ref teardown remain unproven. +- [ ] Capture pre-run upstream branch/tag/release/issue/registry/deployment state for the current campaign. The previous baseline `sha256:be62f1c8c1109fa06b8348541956ab77989f68ede93761b7de6e5765b8e740da` predates the SDK v4 correction and Issue #520 update; recapture before judging the active run. + +### Stage 1 — SDK alone + +- [ ] Run the complete SDK proposal lifecycle and workday until it passes this document. +- [ ] On an implementation defect, repair the owning package/runtime, reset, and rerun the identical SDK proposal from the frozen source. +- [ ] Do not proceed on missing evidence, unexplained retry, zero usage, contradictory mode, stale planning state, or leaked workspace. + +### Stage 2 — API alone + +- [ ] Run the complete API proposal lifecycle and workday under the same rules. +- [ ] Reset and rerun the identical API proposal after each implementation repair. +- [ ] Require direct content-to-graph projection and prove no capacity-plan/execution-input compatibility path participates. + +### Stage 3 — SDK and API together + +- [ ] Reset both projects to their campaign bases and restore the identical proposal bytes. +- [ ] Start one simulation workday with the accepted SDK proposal. +- [ ] At the deterministic trigger `SDK tests-first review approved`, accept the already-ready API proposal through its normal proposal decision. Do not call a graph mutation operation. +- [ ] Observe the API proposal's nodes enter the existing living graph and compete fairly for current capacity without restarting the workday. +- [ ] Require the one workday Reporter to include both projects' evidence and require isolated project grants/workspaces/settlements. +- [ ] Reconcile again and prove noop. + +### Stage 4 — remaining projects individually + +Run in the numbered order above, beginning with Agent and ending with Platform. A project advances only when all its lifecycle, graph, assignment, output, review, usage, settlement, teardown, and no-upstream-mutation checks pass. + +- [ ] Agent +- [ ] TreeDX +- [ ] CLI +- [ ] Deployment +- [ ] Identity +- [ ] UI +- [ ] Core +- [ ] Admin +- [ ] Reviewer +- [ ] Engineering Template +- [ ] Research Template +- [ ] Market +- [ ] Market API +- [ ] Skill +- [ ] Platform + +### Stage 5 — all projects in one workday + +- [ ] Reset all 17 projects and use the same campaign bases and proposal bytes proven individually. +- [ ] Add the fixed cross-project relations below through the existing ordinary TreeDX relation/link mechanism, bound to exact proposal refs and work-item anchors. Do not modify the proposals or create a portfolio plan object. +- [ ] Start one simulation workday with the first eight accepted proposal decisions selected. +- [ ] At the deterministic trigger `every selected project has one approved acting result`, accept the other nine proposals normally and verify content-driven graph expansion during the active workday. +- [ ] Apply project and agent-class weighted fairness with stable ties and automatic idle-share flow; no project or class may starve while an eligible provider has capacity. +- [ ] Exercise provider-global team fairness without combining project grants, workspaces, branches, results, or settlements. +- [ ] Require all 17 simulated release candidates, all review decisions, one deterministic portfolio report, complete settlement, teardown, and noop reconciliation. +- [ ] Compare post-run external state to Stage 0 and prove no upstream mutation. + +Fixed cross-project relations for the portfolio run: + +| Approved predecessor | Dependent work item | Reason | +|---|---|---| +| SDK `simulate-release` | API `tests-first` | API validates the accepted portable contract candidate | +| SDK `simulate-release` and API `simulate-release` | CLI `tests-first` | CLI validates the generated contract and live operation behavior | +| Agent `simulate-release` | Deployment `tests-first` | Deployment validates the exact guest/provider candidate | +| TreeDX `simulate-release` | API `simulate-release` | API acceptance uses byte-exact content custody | +| Identity `simulate-release` | Market API `tests-first` | Market API validates the exact workload-credential adapter | +| Identity, UI, Core, and API `simulate-release` | Admin `tests-first` | Admin validates its exact integrated dependency chain | +| UI and Core `simulate-release` | Market `tests-first` | Market validates canonical shared assets and web runtime | +| Engineering Template, Research Template, Skill, CLI, and Deployment `simulate-release` | Platform `tests-first` | Platform validates the exact portfolio composition inputs | + +The accepted architecture already requires explicit TreeDX relations for cross-project dependencies. If no one canonical existing content operation can express these exact source/target relations and grants, classify that as `PLAN_REVIEW_REQUIRED`; do not invent a hidden portfolio graph or silently omit cross-project dependency acceptance. + +### Stage 6 — controlled failure campaigns + +Run these only after the normal golden portfolio passes. Faults belong to the acceptance harness, not to the proposal or agent prompt. + +- [ ] Corrupt one SDK Actor summary so it disagrees with its structured Git reference; Reviewer must request changes and the same Actor/Reviewer pair must advance once to approval. +- [ ] Repeat a deterministic review defect through the configured maximum; the work item must block for a new decision rather than loop or silently pass. +- [ ] Interrupt one provider after candidate creation; retry must preserve exact evidence, create no duplicate execution or settlement, and clean both attempts. +- [ ] Make one provider ineligible by capability and one by time; admission must explain both and choose only an eligible provider. +- [ ] Let a content question open and resolve mid-workday; only its affected connected component may change. +- [ ] Attempt upstream Git, TreeDX synchronization, publication, deployment, and credential mutation; every attempt must fail before external effect. + +## Mandatory live monitoring + +The automated campaign scene must watch every workday while it runs and retain +the transitions below. Starting a workday and checking terminal status later, +or substituting manual spot-checks for the coded monitor, is not acceptance. + +At minimum, inspect and retain a snapshot on: + +- every GraphRevision; +- every node becoming ready, blocked, assigned, awaiting review, approved, exhausted, or complete; +- every assignment creation, claim, clock check, completion, failure, return, cancellation, or retry; +- every lease/reservation transition and settlement; +- every candidate/content commit and review decision; +- workday activation, planning-round transition, closing, Reporter completion, and end; +- every provider health, eligibility, timing, sandbox, and teardown transition. + +For each new assignment, compare its exact source/authority/context refs, predecessor result IDs, effective profile, handler and origin, grant, workspace/base/branch/writable paths, estimate, deadline, provider/runtime build, execution mode, and node revision with the expected graph before allowing the run to continue. + +The coded monitor must immediately stop new admissions through the supported +scoped workday operation and retain a failed guarantee receipt when an +assignment has the wrong project, class, activity, handler, dependency, context, +grant, base, workspace, mode, estimate, or deadline; when an agent mutates outside +its workspace; when a Reviewer mutates a candidate; when an expected node is +skipped; or when a result cannot support its summary. Missing observation or +incomplete pagination is an evidence failure, never permission to infer a pass. + +## Pass criteria for one project + +A project passes only when all checks below are evidenced from authoritative records. + +### Governance and graph + +- [ ] The accepted decision binds one exact ready proposal revision and digest. +- [ ] Discussion, questions, estimates, authority, and acceptance criteria are complete before decision. +- [ ] The initial graph is deterministic; identical reconciliation is noop. +- [ ] Exactly six authored Actor nodes and six generated Reviewer nodes represent the proposal work. +- [ ] Every edge has source provenance and downstream readiness waits for approved review, not merely Actor completion. +- [ ] Researcher → Reviewer has no edge into the engineering branch; Architect → Tester → Engineer → Technical Writer → Releaser uses only immediate reviewed predecessors. +- [ ] Mid-workday content changes affect only the connected component. + +### Profiles and collaboration + +- [ ] All eight chat probes use exact addressed context and create no workflow edges. +- [ ] All eight agents complete at least two bounded, dependency-ordered planning cycles; later turns materially cite all eight predecessor contributions. +- [ ] Seven valid estimating results supply the accepted owner/review estimates without manually prescribed allocation values. +- [ ] Researcher, Architect, Tester, Engineer, Technical Writer, Releaser, Reviewer, and Reporter all perform their distinct responsibilities. +- [ ] Tester authors the tests before Engineer implementation; Engineer consumes the approved Tester result rather than replacing it. + +### Assignments and outputs + +- [ ] Every ready node creates exactly one assignment, lease, and reservation transactionally. +- [ ] Normal golden runs have no failed, returned, unexpectedly cancelled, duplicated, or unexplained extra node revisions. An unfinished planning/estimating turn may be cancelled only at its authoritative phase handoff, with verified teardown and exactly-once measured settlement; it does not count as a completed contribution. +- [ ] Every assignment belongs to the authoritative simulation workday, receives a simulation-compiled immutable grant, and has at most one mutable workspace; no record owns a contradictory mode. +- [ ] Every completed assignment has exactly one valid general result with a truthful summary and resolvable exact refs. +- [ ] Every model result retains two correctly ordered clock checks and real elapsed/token/native usage. +- [ ] Every verification record contains command, status, exit code, duration, and output digest. +- [ ] Every Reviewer decision binds the exact candidate and criteria; Reviewer changes no candidate bytes. +- [ ] The final local integration candidate contains exactly the approved predecessor chain and passes project verification. + +### Workday, capacity, and cleanup + +- [ ] All admitted planning turns are terminal and list their exact assignment IDs; at least two complete collaborative cycles are proven. +- [ ] Admitted seconds by project and agent class are populated and agree with reservations/results. +- [ ] Assignment elapsed usage agrees with timestamps within an explained tolerance; visibly elapsed work is not stored as zero. +- [ ] Every attempt has exactly one UsageSettlement, including failed controlled attempts. +- [ ] Closing begins only when ordinary admissions stop and required Reporter capacity is available. +- [ ] Reporter finishes and `Workday.reportRef` resolves before the workday becomes `ended`. +- [ ] Every sandbox, worktree, mutable TreeDX workspace, lease, and provider session is closed or removed. +- [ ] Upstream refs, releases, issues, registries, deployments, credentials, and live data are unchanged. + +### Clean architecture + +- [ ] CLI/API records match `docs/agent.schema.yml` and expose no retired compatibility fields. +- [ ] No assignment plan/status/summary TreeDX model, frozen signal graph, capacity-plan work unit, demand row, execution input, source-candidate record, or alternate synthesis path participates. +- [ ] One fact has one authority and one representation. + +## Failure classification and retry instruction + +The implementation agent must classify every failure before changing code: + +- `IMPLEMENTATION_DEFECT`: the fixed proposal is valid, but a contract, projection, scheduler, provider, handler, workspace, result, review, accounting, CLI, or teardown implementation violated it. Fix the owning implementation, reset completely, and rerun the same proposal from the same source bases. +- `ENVIRONMENT_DEFECT`: required local supply or infrastructure is unhealthy. Repair the environment without changing proposal semantics, reset, and rerun. +- `PLAN_REVIEW_REQUIRED`: the fixed proposal is ambiguous, impossible, unsafe, contradicts project ownership/current source, lacks a necessary input, or cannot be represented by the agreed architecture without adding duplicate authority. + +On `PLAN_REVIEW_REQUIRED`, stop the project and portfolio campaign. Do not edit the golden proposal, invent a replacement, weaken acceptance, skip the project, or continue to later stages. Report: + +```text +PLAN_REVIEW_REQUIRED +project: +proposal: +workday: +failed expectation: +observed evidence: +why implementation repair is insufficient: +smallest proposed plan correction: +``` + +Continue retrying implementation and environment defects from the frozen start while each retry produces new, useful evidence. Stop and request review if the same unexplained failure repeats three times, because repeated blind retries are not progress. + +## Progress record + +The agent running this campaign must update only this section's checkboxes and tables plus concise observations/blockers. It must not rewrite proposal definitions or pass criteria during execution. + +| Stage/project | Latest workday | Attempts | Result | Evidence/report ref | Observation or blocker | +|---|---|---:|---|---|---| +| Preflight | — | 10 | prior Stage 0 freeze invalidated by guest repair | Platform #520; prior campaign `sha256:64941f7bc58bf83328c5d42a7192decb89d8ecbf7acd4e19ffb9b6b1971e4b7f`; external baseline `sha256:be62f1c8c1109fa06b8348541956ab77989f68ede93761b7de6e5765b8e740da` | Seventeen proposals, 136 profiles, 25 CLI allocation inputs, and Luna/low supply were validated. Refreeze the rebuilt guest and prove real Codex schema acceptance before the next golden run. | +| SDK | `workday-38e96044-e9d7-4448-9985-2897b14db703` | 15 | no golden pass; O cancelled | Platform #520; estimate-free proposal O from exact TreeDX source `ade82437cbe53c2a573c111758e781f11b23eeeb` | O completed eight chat replies, seven estimates, and two eight-role planning cycles without failed assignments. Proposal review became graph-ready but could not fit the remaining 20% planning entitlement after earlier runs consumed most of today's 28,800-second implementation-model cap. Refreeze a fresh attempt only when read-back proves sufficient daily supply. | +| API | — | 0 | not started | — | — | +| SDK + API | — | 0 | not started | — | — | +| Agent | — | 0 | not started | — | — | +| TreeDX | — | 0 | not started | — | — | +| CLI | — | 0 | not started | — | — | +| Deployment | — | 0 | not started | — | — | +| Identity | — | 0 | not started | — | — | +| UI | — | 0 | not started | — | — | +| Core | — | 0 | not started | — | — | +| Admin | — | 0 | not started | — | — | +| Reviewer | — | 0 | not started | — | — | +| Engineering Template | — | 0 | not started | — | — | +| Research Template | — | 0 | not started | — | — | +| Market | — | 0 | not started | — | — | +| Market API | — | 0 | not started | — | — | +| Skill | — | 0 | not started | — | — | +| Platform | — | 0 | not started | — | — | +| All projects | — | 0 | not started | — | — | +| Failure campaigns | — | 0 | not started | — | — | + +## Completion + +Agent execution is accepted only when every project proposal passes alone, SDK and API pass together, all 17 pass in one living-graph workday, the controlled failure campaigns behave exactly as specified, every result and transition is auditable, all simulation effects remain local and cataloged, all mutable resources are torn down, external state is byte-for-byte or identity-for-identity unchanged, and no legacy or alternate implementation path remains. diff --git a/docs/agent-architecture.md b/docs/agent-architecture.md new file mode 100644 index 00000000..8eeb5d12 --- /dev/null +++ b/docs/agent-architecture.md @@ -0,0 +1,596 @@ +# Agent Architecture and Capacity Allocation Implementation Plan + +**Status:** in progress +**Plan created:** 2026-09-12 +**Last architecture review:** 2026-09-15 +**Scope:** agent profiles, handlers, AgentKernel, assignment workspaces, workday planning, capacity allocation, and provider selection +**Related plan:** [`docs/agent-assignments.md`](./agent-assignments.md) owns proposal planning, decisions, living-graph projection, assignments, results, review, and reconciliation +**Explicit non-goal:** UI implementation + +## Objective + +Restore the original configuration-plus-code agent model and replace the capacity hierarchy with one understandable workday allocator. + +```text +ready execution node + ↓ +workday admission and provider selection + ↓ +immutable assignment with effective activity profile + ↓ +provider isolation → AgentKernel → selected Handler + ↓ +general assignment result +``` + +Profiles explain who an agent is and how each activity behaves. Reusable handlers provide executable behavior. AgentKernel enforces every assignment through one path. The API owns scheduling and capacity. Providers supply execution environments but never define agent behavior. + +Reviewed acting work remains one objective while execution alternates between independently assigned profiles: + +```text +Actor acting assignment → immutable candidate → Reviewer reviewing assignment + ↑ │ + └──────── exact request-changes ───────┘ + approved → work item complete +``` + +## Progress Reporting + +Whoever implements this plan must update its checkboxes and the short **Observations and blockers** section in the same change. Mark an item complete only when its listed CLI, test, Actions, or exact-ref evidence exists. Keep detailed logs in Actions artifacts and the governing GitHub Issue; do not duplicate them here. + +Checkboxes report implementation status only: + +- `[ ]` not implemented or not verified +- `[x]` implemented and verified +- `BLOCKED:` requires an active entry under **Observations and blockers** + +## Local Development Loop + +Persistent development mode is the only implementation loop before coordinated acceptance. A changed package rebuilds with its actual dependents, becomes active only after compilation and readiness succeed, and leaves the previous known-good process serving on failure. Assignment diagnostics expose the exact SDK, API, Agent, Deployment, guest image, provider offer, source authority, workspace, grant, sandbox lifecycle, result, settlement, and successor outcome from existing records rather than creating another tracking system. + +The golden proposal and agent-assisted workflow are owned by [`docs/agent-assignments.md`](./agent-assignments.md). Architecture work must move that same live path forward; component tests alone do not prove an activity profile. Publish one coordinated RC set only after local end-to-end acceptance. + +Once that receipt exists, use the SDK agent team on real bounded development and clone it to eligible projects only through the native plan/apply operation defined by the assignments plan. Unrelated defects are recorded in the owning GitHub issue and deferred unless they prevent the active assignment frontier. + +## Decisions + +- The Agent package owns AgentKernel and the reusable default handlers. +- Every enabled activity profile selects one effective handler. +- First-party profiles select Agent-package defaults. A project may select a project-owned handler compiled into its runtime build. +- There are no separate default/override fields, handler versions, handler digests, downloads, marketplaces, or runtime source loading. +- Activity profiles may declare standing dependencies by agent class or lifecycle event. The API resolves them into the graph defined by `docs/agent-assignments.md`. +- An accepted acting work item deterministically expands into an Actor → Reviewer pair when review is required. Rejection repeats that pair against the same work-item objective through bounded node revisions. +- Only the Reviewer agent normally enables `reviewing`; the generated reviewing node selects that profile and receives the exact acting result. +- Every activity profile declares a simple deny-by-default content and tool permission ceiling. The profile is not a runtime grant. +- The API creates exact assignment grants within the profile ceiling and team/project policy. AgentKernel enforces that immutable grant at every runtime service. +- Handlers share one assignment context and one result contract. Do not create schemas for every handler or work product. +- Every model-backed assignment receives one API-authoritative productive window. Its prompt states the total budget, its first execution action must query the live remaining time, and its final tool action before the response must query it again. The provider rejects completion retryably unless both boundary checks are proven, and agents must use each reading to reduce scope, reserve verification time, and finish within the window. +- AgentKernel has one public assignment entry point. Providers do not dispatch behavior by prompt or activity. +- Assignments, not profiles or agents, select and own their one mutable workspace and any Git branch. +- Workdays guarantee self-directed and collaborative planning before proposal-driven work can consume the remaining capacity. +- Ready graph nodes are the only assignment demand. +- No legacy implementation or backward compatibility remains after cutover. + +## Ownership + +| Component | Owns | Must not own | +|---|---|---| +| SDK | Portable profile, permission-ceiling, handler-selection, dependency-selector, workspace, assignment-context/result, capacity, and CLI contracts | Runtime handler code, scheduling, provider execution | +| API | Graph readiness, workday lifecycle, admission, grant compilation, workspace selection, fair selection, assignments, leases, accounting, and settlement | Prompts, handler implementation, provider-local execution | +| Agent package | AgentKernel, default handlers, build-time registry, assignment-scoped runtime services, result validation | Scheduling, graph mutation, capacity allocation, settlement | +| Project runtime | Project-owned handlers compiled into that project's runtime build | Remote handler loading, hidden scheduling policy, provider credentials | +| Capacity provider | Offers, availability, isolation, runtime/model/tool supply, credentials, native quotas, and execution transport | Agent semantics, graph topology, team priorities | +| TreeDX | Governed profiles, books, knowledge, notes, questions, proposals, decisions, and reports | Operational graph state, leases, reservations, provider availability | +| CLI | Generated operator and acceptance surface | Duplicate business logic or a second scheduler | + +## Agent Profile + +### Minimal complete shape + +```yaml +id: sdk/engineer +name: SDK Engineer +agentClass: engineer +purpose: Implement accepted SDK behavior through scoped TypeScript changes. +responsibilities: + - Participate in self-directed and collaborative planning. + - Estimate engineering work. + - Implement authorized source changes and return exact verification. +capabilities: + - code-change + - refactoring + - build-verification +context: + include: + - project-objectives + - accepted-decisions + - repository-structure + - assignment-subject + - predecessor-results + +activityProfiles: + planning: + handler: writer + dependsOn: + agents: [tester] + permissions: + content: + read: [book, knowledge, objective, proposal, decision, note, question] + write: [proposal, question, knowledge] + tools: [discussion, source.read] + prompt: + system: Study the authorized SDK context and identify valuable work. + + estimating: + handler: estimate + dependsOn: + agents: [tester] + permissions: + content: + read: [book, knowledge, objective, proposal, decision, note, question] + write: [proposal, question] + tools: [discussion, source.read] + prompt: + system: Estimate complete work items, dependencies, and acceptance criteria. + + acting: + handler: actor + dependsOn: + agents: [tester] + permissions: + content: + read: [book, knowledge, objective, proposal, decision, note, question] + write: [] + tools: [source.read, source.write, verification] + additionalContext: + - assigned-source-scope + prompt: + system: Implement the accepted SDK work with the smallest strict TypeScript change. + + chat: + handler: writer + permissions: + content: + read: [book, knowledge, objective, proposal, decision, note, question, discussion] + write: [discussion] + tools: [discussion] + prompt: + system: Answer within SDK engineering scope and preserve authority boundaries. +``` + +Required fields are identity, agent class, responsibilities, capabilities, common context, and enabled activity profiles. Each enabled activity requires a handler, meaningful prompt, and permissions. `dependsOn`, `additionalContext`, and handler parameters are optional and appear only when needed. + +Common context is declared once. Activities add context rather than restating the common list. Context byte, token, time, and item limits belong to the immutable assignment and provider capacity envelope, not every profile. + +Permissions are ceilings, not grants. Content permissions use model groups with `read` and `write`; write includes governed create, update, link, validate, and commit behavior. Tool permissions use stable human-readable groups such as `discussion`, `source.read`, `source.write`, `verification`, and `release`. The SDK expands those groups into concrete operations. There is no separate allow/deny pair, commit flag, authority preset, raw tool list, shell-command list, network-domain list, or branch policy in a profile. Anything not allowed is denied. + +Profiles do not contain provider selection, credentials, runtime images, generated graph IDs, estimates, concrete work items, exact paths, output taxonomies, reviewer mappings, or collaborator lists. + +### Core content usage + +Do not introduce `architecture` or `review` content models in the initial implementation. They are subjects and workflows, not yet distinct data contracts. + +- Each project has a conventional ` Architecture` `book`. +- The Architect extends that book with validated `knowledge` pages. +- Reviewer findings and concerns are `note` content. +- Unresolved review matters are `question` content. +- Workday reports are `note` content referencing the exact workday, assignments, results, usage, releases, and publications they summarize. +- `decision` content has an explicit class: `proposal`, `work-review`, or `publication`, plus an authority, approval, or vote method and its exact decision-maker evidence. Proposal acceptance and formal approved/request-changes review dispositions use that one model. +- Assignment results reference the exact TreeDX revisions and Git commits involved. + +Extend the generic content entity reference once and use it consistently on notes, questions, and decisions so each can identify an exact model, item, commit, path, optional heading anchor, and optional start/end line. Do not create architecture-note or review-note variants. Exact commit plus anchor/range keeps feedback and dispositions precise while allowing later pages to evolve. + +Add a new content model only when existing core models cannot express a required validated field structure, lifecycle, authorization rule, control-plane action, or query. A directory name or subject category alone is not sufficient. + +[`docs/agent.schema.yml`](./agent.schema.yml) is the machine-readable target object model. The SDK remains the runtime contract owner: implementation must generate SDK types and validators from the schema or prove exact structural equivalence in CI. API storage, Agent context/results, CLI schemas, and fixtures must use that same generated contract rather than restating it. + +The Reviewer is the only first-party agent that normally enables `reviewing`: + +```yaml +activityProfiles: + reviewing: + handler: writer + permissions: + content: + read: [book, knowledge, objective, proposal, decision, note, question] + write: [note, question, decision] + tools: [source.read, verification] + prompt: + system: Review the assigned candidate against its objective, acceptance criteria, exact references, and verification. Record findings as notes or questions and finish with an exact approved or request-changes decision. Never modify the reviewed candidate. +``` + +### Standing dependency defaults + +Use readable selectors only: + +```yaml +dependsOn: + agents: [engineer, tester] + events: [] +``` + +`docs/agent-assignments.md` defines their fixed scope and graph semantics. Profiles never resolve or mutate the resulting edges. + +Initial first-party defaults: + +| Agent | Default handlers by activity | Standing dependency | +|---|---|---| +| Architect | planning/chat: `writer`; estimating: `estimate`; acting: `writer` | none | +| Engineer | planning/chat: `writer`; estimating: `estimate`; acting: `actor` | planning, estimating, and acting require Tester | +| Tester | planning/chat: `writer`; estimating: `estimate`; acting: `actor` | planning, estimating, and acting require Architect | +| Releaser | planning/chat: `writer`; estimating: `estimate`; acting: `releaser` | planning, estimating, and acting require Technical Writer | +| Reporter | planning/chat: `writer`; reporting: `reporter` | reporting requires `workday-closing` | +| Researcher | planning/chat/acting: `writer`; estimating: `estimate` | none; admitted research answers a question in parallel with engineering | +| Reviewer | planning/reviewing/chat: `writer`; estimating: `estimate` | no standing agent dependency; reviewing depends on the exact work being reviewed | +| Technical Writer | planning/chat: `writer`; estimating: `estimate`; acting: `actor` | planning, estimating, and acting require Engineer | + +Standing dependencies apply to scheduled planning, estimating, and acting work. They do not apply automatically to chat, because an addressed message must not wait for an unrelated workflow node. Reviewing is subject-bound: reconciliation creates an edge from each exact reviewed node to its Reviewer node rather than placing every possible review target in the profile. + +The first-party default is two parallel branches: question-driven Researcher → Reviewer, and Architect → Tester → Engineer → Technical Writer → Releaser, with each acting result independently reviewed. The Tester returns an exact test commit; the Engineer receives that approved commit as its base and normally receives no grant to modify test paths. Incorrect tests return to the Tester as revision work instead of being silently rewritten by the Engineer. + +Use one Reviewer class. A required acting work item automatically gets a paired reviewing node; no profile attaches itself to another agent and no user authors the generated node. The pair shares one work-item objective. The actor produces an immutable candidate, the Reviewer evaluates it, and rejection advances both stable nodes to another bounded revision with the exact findings. The work item becomes complete only after approval. + +Proposal review is also performed by the Reviewer `reviewing` profile, but it is generated from proposal governance rather than an acting work item. A different review subject does not require another Reviewer class. + +## Handlers + +### Shared interface + +```ts +interface Handler { + readonly id: string; + run(context: AssignmentContext, runtime: AgentRuntime): Promise; +} +``` + +The Agent package provides: + +- `WriterHandler` +- `ActorHandler` +- `EstimateHandler` +- `ReleaserHandler` +- `ReporterHandler` + +These handlers are reusable across agent classes. The activity profile supplies identity, prompt, context, and standing dependencies. The assignment supplies concrete work, authority, predecessor results, limits, and workspace. + +`EstimateHandler` uses the one proposal work-item estimate contract. This is a domain contract shared by all estimators, not a handler-specific artifact schema. + +### Project-owned handlers + +A project may change the activity profile's single `handler` value to a project-owned implementation. That class may call or compose a default handler, or implement `Handler` directly. It is registered when the project runtime is built and is available only when the assignment pins that exact build. + +Do not copy a default handler merely to change a prompt or context selector; those changes belong in the activity profile. Create project code only when executable behavior differs. + +One build-time registry contains Agent defaults plus handlers from the selected project runtime. Missing selections fail before execution. + +## AgentKernel + +```ts +interface AgentKernel { + runAssignment(request: KernelAssignmentRequest): Promise; +} +``` + +AgentKernel performs seven steps: + +1. Validate assignment identity, authority, deadline, profile, handler, runtime build, grants, and context limits. +2. Materialize context only from assignment-authorized references. +3. Resolve the selected handler from the build-time registry. +4. Create assignment-scoped runtime services and workspace. +5. Run the handler once under cancellation and hard limits. +6. Validate the shared result and exact references. +7. Return the canonical result or failure to the provider runner. + +AgentKernel does not schedule, evaluate graph readiness, allocate capacity, select providers, renew leases, approve decisions, or settle usage. + +### Runtime services + +```ts +interface AgentRuntime { + readContext(ref: AuthorizedContextRef): Promise; + invokeModel(request: ModelInvocationRequest): Promise; + runVerification(request: VerificationRequest): Promise; + commitTreeDx(request: TreeDxCommitRequest): Promise; + commitSource(request: SourceCommitRequest): Promise; +} +``` + +The activity profile defines the maximum content and tool authority appropriate for that activity. The API validates the assignment's requested authority against that ceiling and team/project policy, verifies that the provider supplies the required capabilities, and freezes the exact narrower grant on the assignment. Missing required authority blocks admission with an explanation; it is never silently removed. The runtime enforces the assignment grant whenever a handler calls a service. Do not duplicate required-service declarations in handler metadata. + +Deterministic handlers never invoke a model. Model-assisted handlers cannot bypass deterministic input, authority, reference, or result validation. + +## Assignment Workspaces and Git + +An assignment has at most one mutable workspace. Its mode identifies where mutable work may be staged; it does not restrict which exact Git or TreeDX references the assignment may read. + +| Mode | Mutable authority | Use | +|---|---|---| +| `read-only` | none | Analysis and deterministic inspection; exact Git and TreeDX context may be read | +| `treedx` | one governed TreeDX workspace | Books, knowledge, proposals, estimates, notes, questions, decisions, reports, and other governed content | +| `git` | one isolated Git worktree and branch | Tests, implementation, repository documentation, integration, and release | + +The accepted work item identifies its workspace mode. The profile permission ceiling must allow the requested mutation, and the assignment contains the exact paths, content scope, references, and grants. A `treedx` assignment may read exact Git refs; a `git` assignment may read exact TreeDX refs. `read-only` means no mutable workspace, not a third storage system. Merge and release permission comes from assignment grants, not another workspace mode. + +If one outcome requires commits to both Git and TreeDX, represent it as two dependent work items. Do not introduce a dual-write workspace or cross-system commit protocol. + +For Git work: + +- the API supplies an exact base commit; +- each source-changing attempt receives one isolated worktree and short-lived branch; +- handlers cannot share mutable worktrees or write directly to `staging` or `main`; +- completion returns repository, exact commit, and optional branch in the general result; +- retry or revision uses a new branch and never rewrites a reviewed commit; and +- branches may be removed after normal pull-request integration because Git history and assignment results retain custody. + +A single predecessor commit may be the next assignment's base. When several predecessor commits must be combined, create an explicit integration assignment. Do not hide automatic composite-base construction inside admission or context loading. + +`staging` remains the only development-integration branch and `main` remains production. Integration and release follow graph order and normal Actions verification. + +## Workday Capacity + +### Minimal policy + +```yaml +durationSeconds: 28800 +maximumConcurrency: 8 +planningPercent: 20 +allocationWeight: 1 +planningTurnMaximumSeconds: 180 +communicationConcurrency: 1 +projectPercentages: + sdk: 60 + api: 40 +agentClassPercentages: + sdk: + engineer: 60 + reviewer: 30 + reporter: 10 + api: + engineer: 60 + reviewer: 30 + reporter: 10 +``` + +Do not add allocation sets, minimum/target/maximum tiers, priority bands, borrow rules, a generic reserve, or separate capacity-plan and demand records. + +Manual and recurring workdays use one high-level intent and the same preflight/start admission path. Intent selects simulation or production custody; the resolved Workday remains the sole execution-mode authority. Recurrence retains canonical intent and existing receipts, not separate time tiers or manually supplied capacity. Allocation receipts expose weighted supply opportunities and the SDK selector's project/class deficits. + +### Planning phase + +Planning has a minimum initial window of `planningPercent` of wall-clock duration. Repeated short turns follow activity dependencies, give eligible agents equal turn ceilings, and load previous contributions through TreeDX. Class/project percentages govern opportunity frequency. Planning requires no existing proposal and admits no implementation, deployment, or release. Estimates are authored during planning; proposals may originate in any authorized activity. After the initial window, act only when approved, estimated graph work is ready; otherwise continue or return to planning. Agents may finish before their maximum allocation. + +Provider-owned capability caps and a shared execution-provider/model cap bound every workday. Normalize active workday weights (default 1), preserve existing reservations, and redistribute idle project/class target shares only to admissible graph-ready work. Both production and simulation consume real supply. Charge active harness/model/tool time, including model-backed preparation and closeout; record infrastructure setup, queueing, and teardown separately. + +Cold-start acting uses the task's maximum estimate, bounded by provider limits and available allocations. Replay the latest 20 eligible measurements within the same provider/model, capability, class, and activity, normalized by expected task duration. Successful completion targets 1.25 times observed duration with at most 10% downward adjustment per sample, weighted by the smaller expected task duration divided by the larger one; very different task sizes supply weaker evidence for reducing the current ceiling. Expiration increases allocation by at least 25%. Other failure classes do not calibrate task duration. Insufficient viable capacity defers work without changing the graph. + +The read-only `workday plan` operation and mutating `workday start` use the same compiler. The workday stores the applied plan rather than creating another scheduling authority. + +### Lifecycle and Reporter + +Workday lifecycle is: + +```text +planned → active → closing → ended +``` + +- `active` admits phase-eligible graph nodes and addressed communication; acting waits until the planning boundary. +- `closing` stops ordinary admissions and satisfies the `workday-closing` condition. +- Reporter and any required settlement/closeout nodes run during closing. +- `ended` is reached only after required closeout nodes finish and usage settles. + +Preflight reserves capacity from the estimated required closeout nodes. There is no separately configured generic reserve. + +### Admission and fairness + +Admission first applies hard gates: + +- current graph/node and decision authority; +- effective profile, handler, runtime build, and grants; +- node-required capabilities; +- eligible provider offer, availability, native limits, and concurrency; +- remaining workday time and assignment deadline. + +Among eligible nodes: + +1. select the project furthest below its weighted share of actual admitted seconds; +2. within it, select the agent class furthest below its weighted share; +3. within that class, select canonical integer node priority projected unchanged from the governed Proposal work item (higher first, omission means zero), then oldest readiness using stable ties; and +4. select the eligible provider with available concurrency and the least recent fair usage. + +Unused weighted share flows automatically to other ready work. Add a strict cap only for a verified external limit. + +Provider arbitration compares eligible teams globally so one busy team cannot monopolize provider concurrency. It compares scheduling metadata only and preserves team/project isolation. + +Charge actual attempt seconds, including failures and retries, and settle each attempt exactly once. Provider-native usage remains separate from fairness seconds. + +## Implementation Checklist + +### Phase 1 — Profiles and contracts + +- [x] Replace the current profile schema with the minimal complete shape above. +- [x] Keep common context once and activity-specific additions only where needed. +- [x] Require one effective handler, meaningful prompt, and simple content/tool permission ceiling for each enabled activity; keep parameters optional. +- [x] Permit `reviewing` only on the Reviewer profile by default; remove reviewing profiles from Architect, Engineer, Tester, Releaser, Researcher, and Technical Writer. +- [x] Replace authority presets, raw tool allow/deny lists, commit flags, branch policy, and per-model operation matrices with deny-by-default `content.read`, `content.write`, and stable tool groups. +- [x] Use only registered core content models in permission ceilings; add no `architecture`, `review`, or `workday-report` model. +- [x] Extend the one generic entity-reference contract with exact path, commit, optional heading anchor, and optional line range; use it on notes, questions, and decisions. +- [x] Add explicit `proposal`, `work-review`, and `publication` classes plus authority/approval/vote evidence to the one decision model. +- [ ] Generate SDK types/validators from `docs/agent.schema.yml` or enforce exact structural equivalence in CI. +- [x] Add simple `dependsOn.agents` and `dependsOn.events` selectors with no cardinality or scope configuration. +- [x] Add the shared `Handler`, assignment context/result/reference, workspace, workday, and capacity contracts. +- [x] Accept built-in and project-owned handler IDs structurally; validate availability against the exact runtime build. +- [ ] Generate CLI descriptors from the SDK and delete old profile/allocation schemas without compatibility unions. + +Acceptance: + +- [x] Complete first-party profiles validate and missing handlers, prompts, permissions, invalid dependencies, non-Reviewer reviewing profiles, or unavailable runtime handlers fail clearly. +- [ ] CLI profile inspection shows the effective handler, origin, prompt, context, permission ceiling, and unresolved dependency selectors for each activity. + +### Phase 2 — AgentKernel and deterministic Reporter + +- [x] Implement the single AgentKernel entry point and build-time handler registry. +- [x] Route the existing isolated provider transport through AgentKernel. +- [x] Compile exact grants within the activity ceiling and team/project policy; block admission when required authority is unavailable. +- [ ] Enforce immutable assignment grants at runtime-service calls and validate the one result contract. BLOCKED: Agent312's native Kernel regressions permit handler-side source-write grant/path widening and deadline mutation before real Git publication. +- [x] Implement deterministic `ReporterHandler` with no model dependency. +- [x] Commit the report through TreeDX and return its ordinary exact reference. +- [ ] Remove Reporter-specific scheduling/provider behavior. + +Acceptance: + +- [x] One real closing Reporter assignment executes API → provider → AgentKernel → Reporter → result → settlement through the CLI. +- [x] Identical authorized inputs produce identical report bytes. +- [ ] Unknown handler, wrong build, expired assignment, denied service, invalid result, cancellation, and timeout fail closed. +- [ ] Every model-backed activity receives its authoritative productive window, uses the clock as its first execution and final tool actions, and scopes its work to finish within that window. Chat, planning, estimating, Architect acting, Tester acting, Engineer acting, and Reviewer reviewing are proven; Releaser, Researcher, and Technical Writer acting remain to be proven against the strengthened boundary-order gate. + +### Phase 3 — Reusable and project-owned handlers + +- [x] Implement `WriterHandler`, `ActorHandler`, `EstimateHandler`, `ReleaserHandler`, and `ReporterHandler` against the shared interface. +- [x] Migrate Architect, Engineer, Tester, Releaser, Reporter, Researcher, Reviewer, and Technical Writer to the default matrix above with complete prompts. +- [ ] Prove parallel Researcher → Reviewer and Architect → Tester → Engineer → Technical Writer → Releaser ordering for planning, estimating, and acting, with generated review pairs and no cross-branch edge. +- [ ] Make the Architect maintain a conventional ` Architecture` book of validated knowledge pages. +- [x] Route Reviewer findings through notes/questions and formal dispositions through decisions, all bound to exact candidate references. +- [ ] Remove Reviewer acting behavior and separate proposal-feasibility review; route each required acting-work review through the Reviewer `reviewing` profile. The external approval and agent estimates jointly gate acting. +- [ ] Add one project-owned handler that reuses or implements the shared interface and prove selection without changing Agent-package code. +- [ ] Keep books, knowledge, proposals, notes, questions, classed decisions, proposal-embedded estimates, and note-based workday reports on ordinary TreeDX operations. +- [ ] Remove TreeDX assignment-plan, assignment-status, and assignment-summary content; consume PostgreSQL assignment state and general results instead. +- [ ] Keep source work on ordinary Git commit/push and general-result references. +- [ ] Delete generic guest/provider semantic branches replaced by handlers. + +Acceptance: + +- [ ] Every enabled activity resolves exactly one handler from its pinned runtime build. +- [ ] Default handlers are reused across agent classes. +- [ ] Project prompt/context customization requires no handler copy. +- [x] One reviewed acting work item automatically dispatches Actor then Reviewer assignments without either profile naming the generated node. +- [x] Request changes returns exact findings to a new actor attempt against the same objective and then dispatches the next Reviewer attempt. +- [ ] One project-owned behavior override passes a real CLI assignment. + +### Phase 4 — Workday planning and fair capacity + +- [x] Implement `workday plan` and `workday start` with one shared compiler. +- [ ] Guarantee repeated dependency-ordered planning turns within the planning percentage/window; fixed two-round evidence does not prove this replacement requirement. +- [ ] Admit ready graph nodes directly; create no capacity-plan or demand records. +- [ ] Implement project and agent-class weighted fairness with stable ties and automatic idle-share flow. +- [ ] Implement provider-global team fairness and hard provider-native gates. +- [ ] Enforce UTC-day capability and shared model caps at provider and atomic API admission, including restart/monotonic-report safety. +- [ ] Allocate concurrent workdays by weight, then phase/project/class shares, preserving reservations and redistributing only idle opportunities. +- [ ] Calibrate task budgets from scoped terminal usage, including censored timeouts, and issue one active duration/deadline through AgentKernel. +- [ ] Replace fixed planning/profile contracts in SDK/API/CLI/schema and remove the retired allocator without compatibility paths. +- [x] Implement active → closing → ended lifecycle and derive closeout capacity from required closeout estimates. +- [ ] Keep communication concurrency independent from ordinary work. +- [ ] Settle every attempt exactly once and expose allocation explanations through the CLI. + +Acceptance: + +- [ ] A zero-proposal workday gives every participating agent allocation-derived repeated planning opportunities and can create new proposals; earlier fixed-round evidence is insufficient. +- [ ] Later planning cycles load prior published contributions through TreeDX; earlier second-round evidence does not prove repeating cycles. +- [ ] Mid-workday content changes add eligible work without restarting the workday. +- [ ] Multi-project, multi-class, multi-team, retries, failures, idle share, and stable ties pass deterministic tests. +- [ ] Reporter runs during closing and the workday ends only after report completion and settlement. Focused lifecycle tests pass; complete report evidence and stored exact reference still require live acceptance (see `agent-assignments.md`). + +### Phase 5 — Integration, clean cutover, and managed acceptance + +- [x] Consume ready nodes and predecessor results only through the contracts owned by `docs/agent-assignments.md`. +- [x] Use one assignment-selected `read-only`, `treedx`, or `git` workspace mode and permit reads from exact refs in either custody system. +- [ ] Split required Git and TreeDX mutations into dependent assignments; add no dual-write workspace. +- [ ] Create explicit integration assignments whenever several Git predecessors must be combined. +- [ ] Delete AgentKernelProfile/Policy, metadata-only handler routing, dynamic module/process loading, duplicate authority presets/raw tools/branch policies/context, old allocation hierarchy, fixed team polling, and alternate provider execution paths. +- [ ] Remove every compatibility field, parser, alias, route, table, fixture, test, document, and feature switch associated with the retired architecture. +- [ ] Run architecture-specific CLI acceptance, then reference the assignment plan's graph acceptance receipt rather than repeating it. Earlier synthetic workdays are diagnostic evidence only. +- [ ] Publish and read back one coordinated compatible release set. + +Architecture CLI surface: + +```text +trsd agents handlers list --json +trsd agents handlers show --json +trsd agents profiles validate --json +trsd agents profiles show --json +trsd workdays plan --team --profile default --json +trsd workdays start --team --preflight --digest --yes --json +trsd workdays show --team --json +trsd workdays stop --team --json +trsd capacity explain --team --json +``` + +Handler inspection identifies Agent-package or project-runtime origin. Profile inspection shows one effective handler per activity. Capacity explanation shows gates, fair-share state, provider choice, and reservation evidence. + +## Delivery Order + +```text +Profile/handler contracts + ├── AgentKernel + Reporter + └── assignment graph dependency projection + ↓ +default/project handlers + profile migration + ↓ +workday planning + fair capacity + ↓ +clean cutover + managed acceptance +``` + +AgentKernel and API graph work may proceed concurrently after shared SDK contracts are fixed. Do not parallelize final schema cutover, generated catalogs, deletion audit, coordinated releases, or managed acceptance. + +Stop and record a blocker if exact authority, isolation, project access, provider capability, or clean cutover cannot be proven. Do not add compatibility behavior to work around a blocker. + +## Verified Baseline + +| Date | Verified fact | Evidence | +|---|---|---| +| 2026-09-14 | One build-time handler registry and AgentKernel execute the isolated provider transport | Focused Agent kernel/provider suites; source-backed Kata acceptance retained in Issue #520 | +| 2026-09-14 | Deterministic Reporter commits through TreeDX and settles through the ordinary completion path | Focused Agent/API tests; live Reporter receipt retained in Issue #520 | +| 2026-09-14 | Persistent development selections run the touched SDK, API, Agent, and TreeDX components | Managed development status read-back; no RC required | + +## Observations and Blockers + +### Current integrated state + +- Five concurrent Kata assignments and complete planning cycles are proven in simulation with `gpt-6-luna:low` on the ChatGPT subscription; graph and review outcomes belong to `agent-assignments.md` (Platform #520). + +### Current active blocker + +- Human-approved priority clarification (October 4): the governed Proposal work item owns optional safe integer priority, projected unchanged onto its Actor and Reviewer nodes; higher values rank first only after eligibility and project/class fairness, and omission means zero. SDK validation/selection, native API producer/persistence/admission, and managed historical selection replay tests are authored in [API #490](https://github.com/treeseed-ai/api/issues/490), but remain unexecuted. This target clarification is not an implementation or passing acceptance claim. + +- Architecture-first test correction (October 2): [Agent312](https://github.com/treeseed-ai/agent/issues/312) now tests profile-owned instructions, class-rename invariance, exact-grant output selection, explicit integration, ordinary deterministic-handler admission/closure, immutable grants/paths/deadlines, and identity-neutral observed verification through native Node/Kernel/Git/runner boundaries. Focused regressions reproduce violations; component scene bindings are declared, not executed acceptance. Per the direct user instruction, unrelated testing and Agent319 delivery are held while these architectural gates are corrected. Full architecture/assignment acceptance remains open; the older observations below are historical, not the current frontier. + +- The same test-first audit now reproduces API name-dependent reporting and wrongly scoped lifecycle edges through actual SQL persistence. Seven existing graph guarantee contracts were corrected to the desired architecture, but remain planned without complete executable CLI/managed proof. API strict checking still fails on existing source/dependency declarations; no check was disabled. All three test layers must be aligned before product repair or unrelated testing resumes; implementation failures must not change the test oracle. + +- SDK schema regressions now reject the implementation-generated five-model subset as complete target verification. Native Git-backed repository verification currently accepts incomplete declarations and unchecked assignment definitions; union/exclusion constraints are also ignored. The previously excluded schema test is now in the active suite. Whole-target equivalence and CLI/managed semantic acceptance remain unproven; local component bindings do not close the Phase 1 gate ([Agent312](https://github.com/treeseed-ai/agent/issues/312)). + +- The SDK tests now consume the exact tracked canonical document through declared development-workspace authority, without copying its model registry. The unchanged canonical input passes, while target-derived definition, field, required-field, closure, reference and conditional mutations expose ignored contracts; real Git commits reproduce undetected stored/runtime definition changes. These are focused failing tests, not whole-system equivalence or executed managed acceptance. Missing canonical input blocks coverage, and standalone CI input wiring remains open. Product work stays held under the pure test-first gate. + +- Calibration tests now prove exact eligible sample selection, hard-ceiling arithmetic, independent public SDK execution, and original-DDL SQL selection without changing persisted graph or reservation authority. The managed read-back verifier rejects absent or malformed allocation receipts and immutable-limit drift after three genuine verifier regressions. These component and verifier-unit passes do not prove live sample custody, atomic admission, concurrent fairness, or complete managed acceptance; the all-three-layer architectural test gate remains open (Agent312). + +- Proposal-readiness tests now reject estimate-only scope, malformed review bounds, coerced estimates, and non-local or cyclic dependency graphs. Native Git/SQL/official-client tests preserve exact source bytes through repeated and concurrent reads, and expose the SDK's rejection of a canonical optional-capability omission. The existing managed graph verifier now requires exact typed Proposal and Decision authorities after a genuine verifier regression. These focused diagnostics and declared component bindings do not prove profile-grant admission, independent content joins, or complete managed acceptance; product repair stays held (Agent312). Package-owned test branches now reside in durable Git worktrees outside `/tmp`; diagnostic reports remain separate. + +- Decision-authority tests now reproduce acceptance of an operational SQL substitute without governed Decision content, unassigned review makers, conflicting dispositions, and out-of-window review evidence through unit and original-DDL/native content-reader boundaries. The existing managed verifier independently reads proposal and final review Decisions and checks exact source/candidate/identity/time after genuine verifier-unit failures. Its synthetic unit passes and component bindings are not live acceptance, full decision-policy/evidence retrieval, or complete three-layer alignment. Preserve the REDs and keep product repair held (Agent312). + +- Admission-replay tests now reproduce acceptance of changed grants, profiles, source/decision authority, runtime builds, deadlines, graph context, estimates and unrelated principals through unit and original-DDL/owning SQL repository boundaries. Exact replay remains read-only. The managed verifier now checks typed grants against frozen ceilings, context and one mutable workspace after six genuine verifier regressions. These checks do not prove independent policy retrieval, initial atomic admission, authenticated transport, provider isolation or full managed acceptance; the all-three-layer test-first gate remains open (Agent312). + +- Planning tests now require exact cycle membership, unchanged source context, all eight predecessor result identities and exact published contribution read-back. Native configured-Writer/content-serialization/Git tests reproduce publication with omitted, ID-only or foreign contribution evidence. The actual managed verifier and campaign monitor were strengthened after failing verifier regressions; later and terminal collaboration must be rechecked. Controlled transport responses are not live model/clock/usage proof, structural citations do not establish material correctness, and full per-event monitoring and three-layer alignment remain open. Product repair stays held (Agent312). +- Workday-observation tests now reproduce missing/unavailable/malformed scheduling and incomplete/moving event evidence being accepted, including failure counts hidden by a completed run. The actual campaign assertions fail closed after verifier REDs. Original-DDL SQL/API reads prove a failed event can reside beyond the first 50-event page, while SDK and independent native CLI regressions still fail because the existing paginated event operation has no command binding. No product repair, live campaign or full transition-snapshot/semantic-join proof; architecture test completion remains open (Agent312). +- Assignment-collection regressions now require explicit terminal page authority, exact cursor/row binding, ordered unique records and original workday clocks. The actual managed read-back gate was strengthened after verifier REDs; original-DDL SQL/service and independent native CLI tests read a failed assignment beyond page 50. These scoped diagnostics do not prove hidden-tail producer completeness, all-attempt usage pagination, independently expected assignment semantics or full managed acceptance. Product repair remains held while three-layer architecture test alignment is open (Agent312). +- Usage-collection regressions now require complete scoped pages, finite measured time/native usage and accounting-mode authority rather than an ID suffix. The actual managed assertions were strengthened after verifier REDs; original-DDL SQL/service tests still admit a corrupt creation clock and zero recorded active time with positive elapsed time. Native CLI page read-back is scoped transport proof, not actual provider usage, canonical UsageSettlement equivalence, timestamp agreement, transactional exactly-once settlement or full managed acceptance. Those three-layer gaps remain open (Agent312). +- Settlement authority regressions now reproduce accepted native/provider/model replay changes, coerced attempt identities, incomplete frozen attempts and corrupt native units through the actual owning accounting functions and transactional SQL. Matching retry, real late-write rollback/retry and truthful overrun/no-cap-raise controls pass only at their scoped boundaries. The managed gate now compares aggregate measurements with completed-result usage; provider-generated measurements, independent clock agreement, full canonical settlements, separate-server concurrency and durable teardown remain unproven. Product repairs remain held (Agent312). +- Provider-facing accounting tests now reproduce coerced values, conflicting provider identity, invalid nonterminal accounting modes and lost incremental token counts through the owning service and original SQL. Matching incremental/terminal replay, cleanup replay and refusal of zero-release with unaccounted seconds pass only at those isolated boundaries. Managed assertions were strengthened after verifier REDs to reject informational productive time and incremental seconds outside the sole attempt or above its aggregate. Authentication, live provider usage, canonical settlement and complete recovery/teardown remain open; API395 preserves continuing evidence because Agent312 is at its body limit. Product repairs stay held. +- Cancellation/recovery tests now reproduce fabricated zero settlement after a stored execution clock started, unsafe retry classification with unknown productive usage, and a real recovery SQL parameter failure. Active cancellation remains a request and measured cleanup replay stays exactly once at the isolated SQL boundary. The managed stopped gate now rejects zero usage after visible productive time following a verifier RED. Full canonical attempt/settlement joins, provider-generated measurements, authenticated transport, server concurrency and physical durable teardown remain unproven; all-three-layer alignment and product repairs stay held (API395). +- Workday-level SQL tests also reproduce zero-usage terminalization after productive execution and a false complete-cleanup result with an orphan running node. Scoped lease preservation, measured cleanup replay, actual transition rollback/retry, and continued recovery past a corrupt historical run pass only at their isolated boundaries. The managed stopped verifier now rejects retained lease state, expiry and renewal after a verifier RED; historical runner identity alone is not an open-session receipt. Physical cleanup, independent graph/resource joins and full acceptance remain open. API395 retains the exact failed evidence; product repair remains held. + +- Workspace cleanup tests now reproduce an open remote resource being skipped after SQL handle revocation, an interrupted operator close not being retried, unqualified upstream 404 denial being accepted as absence, and success responses being accepted without exact closed-resource agreement. Real owning SQL and the official TreeDX HTTP client exercise a controlled endpoint, not a native TreeDX server or physical sandbox. Managed verifier regressions also exposed issued or malformed handles despite claimed verified teardown; the acceptance-only checks now deny those contradictions. Independent resource/session closure and the all-three-layer test gate remain open; exact failures are preserved in API395. +- Independent workspace read-back tests now reproduce successful public API replies with a foreign or missing workspace identity despite the correct repository. Exact open/closed reads and scope denials pass through the owning catalog, original SQL and official client against controlled HTTP resources. Five managed-verifier regressions exposed missing independent reads; its terminal gates now require an exact closed resource and project receipt through the existing project-scoped CLI command, failing closed on unavailable or denied reads. Native CLI transport tests preserve both open status and denials; they do not prove native TreeDX, physical workspace/session teardown or complete acceptance. All-three-layer alignment and product repair remain held (API395). +- Provider terminal-report tests now reproduce synthesized or coerced performance facts, a changed terminal attempt ordinal, and SQL revocation while an independently read workspace remains open. Original transactional SQL preserves matching replay and rolls back an injected late revocation failure; controlled upstream resources and supplied usage are not native provider or physical cleanup proof. Two managed-verifier regressions exposed missing immutable-ordinal joins; the acceptance-only gate now checks the presented assignment and measurement against that ordinal. Retry/recovery races, complete canonical records, generated usage and full scene acceptance remain open; product repair stays held (API395). +- Provider-return SQL tests now reproduce an unchanged retry node revision with a rewritten historical attempt ordinal, missing measured settlement, and duplicate successful transitions/graph revisions from concurrent matching reports. Wrong-owner/token/expired-return denials and sequential replay remain read-only at the isolated SQL boundary. A managed-verifier regression exposed acceptance of returned history at the completed retry's same node revision; the acceptance-only graph gate now rejects that contradiction. Embedded SQL concurrency and supplied measurements are not independent PostgreSQL connections, actual provider charges or full scene proof. All-three-layer alignment and product repair remain held (API395). +- Successful-completion tests now reproduce accepted canonical result clocks before the original start or beyond the original productive/reporting interval. The actual provider sequence settles usage before completion; an initial unsupported expectation that completion itself creates that charge is preserved as an oracle error, not a product failure. The managed result gate rejects missing or contradictory clocks after a verifier RED. Exact Git content, independently generated clock/usage evidence, separate-server races, canonical settlements and physical cleanup remain unproven; scoped SQL and component declarations do not complete three-layer acceptance. Product repairs remain held (API395). + +- Source-publication receipt tests now reproduce accepted foreign repositories and branches through the owning wrapper and real broker client with isolated Git. The endpoint is a controlled input, not the actual Deployment broker or its authorization/verifier. After a genuine verifier RED, the managed results gate requires a Git candidate in the sole immutable repository and agreement for any presented optional branch; read-only citations remain valid. Native broker publication, base/grant/path verification, sandbox closure, complete canonical content read-back and full scene proof remain open. Product receipt failures are preserved in API395; product repair stays held. + +- Native Reporter closure is proven by the passing continuation; SDK #347/#348 calibration and Agent #277/#278 observed-red evidence repairs are integrated. Fresh DR stopped before acting when a chat response lacked its exact invocation binding. API #468/#469 repairs a reproduced denied-admission binding defect with package-owned SQL scenes; checked staging delivery and live proof remain required. DR's missing teardown receipt remains failed evidence, not proof of a physical leak. No full SDK pass (Platform #520). + +### Next acceptance milestone + +- Prove the fresh one-hour full SDK golden through AgentKernel, measured accounting and teardown using package-owned scenes; see `agent-assignments.md` for the graph and product gates. + +## Completion + +This plan is complete only when every assignment executes through one AgentKernel and one handler from the pinned Agent/project build; every first-party activity has a complete profile, default handler, meaningful prompt, simplified permission ceiling, and applicable standing dependencies; only Reviewer normally enables reviewing; architecture, review, and workday reporting use registered core models and classed decisions; `docs/agent.schema.yml` matches runtime contracts; TreeDX contains no assignment plan/status/summary authority; every assignment has one exact enforced grant and at most one mutable workspace; workdays guarantee planning and fairly allocate ready graph work; managed CLI acceptance passes; and no legacy implementation or backward compatibility remains. diff --git a/docs/agent-assignments.md b/docs/agent-assignments.md new file mode 100644 index 00000000..30003af5 --- /dev/null +++ b/docs/agent-assignments.md @@ -0,0 +1,456 @@ +# Living Agent Assignment Graph Implementation Plan + +**Status:** in progress +**Plan created:** 2026-09-12 +**Last architecture review:** 2026-09-15 +**Scope:** proposal planning, decisions, living execution graph, assignments, results, review, and graph reconciliation +**Related plan:** [`docs/agent-architecture.md`](./agent-architecture.md) owns profiles, handlers, AgentKernel, workspaces, workday allocation, and provider selection +**Explicit non-goal:** UI implementation + +## Objective + +Replace the frozen planning DAG, per-decision assignment graphs, capacity-plan work units, and demand records with one continuously reconciled team execution graph. + +```text +TreeDX content or assignment result + ↓ +deterministic API reconciliation + ↓ +living execution nodes and dependencies + ↓ +ready node → immutable assignment attempt + ↓ +general result → reconciliation +``` + +Agents author governed content and return assignment results. They never mutate graph nodes, edges, readiness, or scheduling state. A ready node is assignment demand. + +For reviewed acting work, the graph treats Actor and Reviewer assignments as alternating phases of one accepted work-item objective. Candidate return enables review; request changes advances the same pair; approval completes the work item. + +## Progress Reporting + +Whoever implements this plan must update its checkboxes and the short **Observations and blockers** section in the same change. Mark an item complete only when its listed CLI, test, Actions, or exact-ref evidence exists. Keep detailed logs in Actions artifacts and the governing GitHub Issue; do not duplicate them here. + +Checkboxes report implementation status only: + +- `[ ]` not implemented or not verified +- `[x]` implemented and verified +- `BLOCKED:` requires an active entry under **Observations and blockers** + +## Golden Development Acceptance + +[`docs/agent-acceptance.md`](./agent-acceptance.md) is the complete and exclusive testing guide. This plan records only implementation TODOs and fully proven completion. Earlier synthetic or reduced workdays are diagnostics and do not satisfy acceptance. The current frontier is the unchanged SDK proposal's generated Actor/Reviewer path; see Observations and Blockers. Do not broaden scenarios or cut an RC before the full path passes. + +## Decisions + +- TreeDX is the durable authority for proposals, questions, answers, decisions, reviews, reports, and other planning content. +- PostgreSQL stores only operational graph projections, graph revisions, assignments, leases, reservations, provider state, and exact TreeDX references. +- There is one team execution graph. Project and decision graphs are filtered views. +- Graph changes are deterministic reactions to content changes, assignment results, and lifecycle state. There is no user-authored graph-change object. +- Activity profiles may declare standing dependencies using agent-class and lifecycle-event names. Profiles never contain generated node or assignment IDs. +- Accepted proposal work may add work-specific dependencies between stable work-item IDs. +- All concrete dependencies become the same execution-node edges. +- Every acting work item declares whether independent review is required. Required review deterministically projects an Actor → Reviewer pair for the same work-item objective. +- Rejection advances that same stable pair through bounded node revisions; it does not create unrelated revision work items. +- Activity-profile permissions are deny-by-default ceilings. Assignments receive exact narrower grants; profiles never grant runtime authority directly. +- Each accepted work item selects one workspace mode: `read-only`, `treedx`, or `git`. An assignment has at most one mutable workspace. +- Workdays govern admission and accounting but never freeze the graph. +- Running assignments are immutable snapshots. Graph evolution creates later node revisions or assignment attempts. +- No legacy implementation or backward compatibility remains after cutover. + +## Canonical Planning Content + +### Proposal-owned execution plan + +Use one proposal document as the authority for both the proposal and its executable plan: + +```yaml +id: pagination-reliability +request: Make pagination behavior reliable across the SDK. +summary: Generated and refined during planning. +executionPlan: + workItems: + - id: architecture + activity: acting + agentClass: architect + workspace: treedx + review: required + objective: Define the required behavior and boundaries. + estimate: + expectedSeconds: 900 + maximumSeconds: 1200 + reviewEstimate: + expectedSeconds: 300 + maximumSeconds: 600 + maximumReviewCycles: 2 + dependsOn: [] + requestedPermissions: + content: + read: [book, knowledge, objective, proposal, decision, note, question] + write: [book, knowledge] + tools: [source.read] + requiredCapabilities: [] + acceptanceCriteria: + - Public behavior and failure cases are explicit. +``` + +Agents may estimate several work items in one planning contribution, and several agents may propose alternatives during discussion. The accepted estimate for each work item is written into the proposal-owned plan. Alternative values remain in TreeDX history or discussion; they are not separate operational scheduling authorities. + +A decision accepts one exact proposal revision and digest. There is no separate execution-plan record, structured-estimate database authority, or decision-time plan reconstruction. + +An optional safe integer `priority` on the governed work item is the sole priority authority. Projection carries that value unchanged onto its Actor and Reviewer nodes; omission means zero for selection. Higher priority ranks first only after provider eligibility and project/class fairness. Profiles, providers, and operational node edits do not define another priority. + +### Proposal readiness + +A proposal may be decided only when: + +- every executable work item has an activity, agent class, workspace mode, review policy, objective, a valid expected/maximum estimate (`expectedSeconds <= maximumSeconds`), and acceptance criteria; +- every required review has its own valid estimate and bounded maximum cycle count; +- the selected workspace and required authority fit the activity profile's permission ceiling and team/project policy; +- every work-specific dependency references another work item in the same plan and the plan is acyclic; +- blocking questions and feedback are resolved or withdrawn; +- decision-authority prerequisites reference exact current content revisions; and +- the exact proposal revision presented for decision is the revision that will be executed. + +### Discussion and conditions + +Questions, answers, feedback, approvals, external state, and authority validity remain ordinary governed content. Reconciliation represents anything that blocks execution as a condition node. A question addressed to an agent class may also create an answer or research work node. + +### Core content + +Use the registered core content vocabulary. Do not introduce `architecture` or `review` models merely to name a subject or activity. + +- Architect output extends a conventional ` Architecture` `book` through validated `knowledge` pages. +- Review findings and concerns are `note` content. +- Unresolved review matters are `question` content. +- Workday reports are `note` content referencing the exact workday, assignments, results, usage, releases, and publications they summarize. +- `decision` content has an explicit class: `proposal`, `work-review`, or `publication`, plus an authority, approval, or vote method and its exact decision-maker evidence. Proposal acceptance and formal approved/request-changes review dispositions use that one model. +- The general assignment result references the exact TreeDX revisions and Git commits. + +The generic entity-reference contract supports an exact model, item, commit, path, optional heading anchor, and optional start/end line and is shared by notes, questions, and decisions. Reuse it for review evidence and workday reports. Add a new content model only when a required validated structure, lifecycle, authorization rule, control-plane action, or query cannot be expressed by a core model. + +[`docs/agent.schema.yml`](./agent.schema.yml) is the machine-readable target object model for this plan. Runtime SDK types, generated validators, API storage, Agent assignment context, CLI schemas, and fixtures must be derived from or verified against that one contract; do not maintain a second handwritten schema with different fields. + +## Dependency Model + +### Profile dependencies + +Activity profiles express permanent workflow rules in language suitable for an agent builder: + +```yaml +dependsOn: + agents: [architect] + events: [] +``` + +Initial semantics are fixed: + +- every listed dependency is required; +- an agent selector matches all applicable nodes for that class; +- decision work matches within the same decision; +- proposal work matches within the same proposal revision; +- workday activity matches within the same workday; +- a missing required dependency leaves the node blocked with an explanation; and +- self-dependencies and cycles are invalid. + +Standing agent dependencies apply only to the scheduled activity profiles that declare them. They do not implicitly constrain chat. A dependency on reviewed acting work is satisfied only when its work-item pair is approved, not when the actor merely returns a candidate. Reviewer nodes are subject-bound and generated by reconciliation; the Reviewer profile never lists every possible producer. + +Lifecycle events are projected as condition nodes. Use `workday-closing`, not `workday-ended`: regular admissions stop at closing, required closeout assignments run, and the workday becomes ended only after closeout and settlement complete. + +### Work-specific dependencies + +Proposal work items may add ordering needed only for that proposal: + +```yaml +- id: integration + agentClass: releaser + dependsOn: [implementation, verification] +``` + +Profile dependencies are invariant minimums. Work-specific dependencies may add edges but cannot remove profile requirements. + +The initial first-party workflow has two parallel branches. Research exists to answer a question and is reviewed independently; it is never an implicit predecessor of architecture or execution work: + +```text +question → Researcher acting → Reviewer approval + +Architect acting → Reviewer approval + ↓ +Tester acting ───→ Reviewer approval + ↓ +Engineer acting ─→ Reviewer approval + ↓ +Technical Writer acting → Reviewer approval + ↓ +Releaser acting ─→ Reviewer approval + +workday-closing → Reporter +``` + +For planning, estimating, and acting, the engineering branch uses immediate predecessors only: Tester depends on Architect, Engineer on Tester, Technical Writer on Engineer, and Releaser on Technical Writer. Researcher has no standing dependency and runs only for an admitted research question or research work item. Reviewer has no standing agent dependency because reconciliation generates each exact Actor → Reviewer edge. Chat remains independent. + +Use one Reviewer class and its `reviewing` activity. Every acting work item with `review: required` expands into two stable internal nodes: the declared actor node and a Reviewer node. `review: required` is the default; `review: none` must be explicit and is reserved initially for deterministic release, integration, or closeout work whose accepted predecessors are already reviewed. Do not create Reviewer subclasses, enable reviewing on producer agents, or require users to author the generated review node. + +Proposal review also uses the Reviewer `reviewing` profile, but it is projected from proposal governance rather than an acting pair. The Releaser depends on approved work-item pairs and all applicable required review decisions. + +### Concrete edges + +The API resolves both sources into one edge table: + +```text +from_node_id → to_node_id +``` + +Edges, not node JSON, are the storage authority for dependencies. Each edge records whether it came from a profile agent selector, profile lifecycle selector, or proposal work-item relation. Assignment IDs are attempts and are never dependency targets. + +A node becomes ready when all predecessor work nodes have completed successfully and all predecessor condition nodes are satisfied. Downstream assignments receive the completed predecessor results. + +## Operational Model + +### Execution node + +An execution node contains only facts required to identify and execute work: + +```yaml +id: deterministic-id +teamId: team-id +projectId: project-id +workItemId: architecture +pairRole: actor | reviewer | null +kind: planning | estimating | acting | reviewing | reporting | condition +sourceRef: + model: proposal + id: pagination-reliability + revision: 3 + digest: sha256 +ruleRevision: 1 +nodeRevision: 2 +agentClass: engineer +status: proposed | blocked | ready | assigned | running | completed | failed | cancelled | stale +estimate: + expectedSeconds: 1800 + maximumSeconds: 3600 +requiredCapabilities: [] +workspace: read-only | treedx | git +``` + +Node identity is deterministic from team, project, source content, rule revision, activity, agent class, work-item identity, and pair role. A reviewed acting work item has stable actor and reviewer node IDs. Reconciliation replay cannot create a duplicate. + +Do not duplicate edges, active assignment IDs, or derived blocking explanations inside canonical node JSON. API read models may display those values by joining their authoritative stores. + +### Graph revision + +Use one append-only graph-revision record as revision, reconciliation receipt, audit summary, and watch cursor. It contains: + +- revision number; +- changed source and lifecycle refs; +- reconciliation-rule revision; +- resulting graph digest; and +- compact added, changed, completed, blocked, and stale node/edge IDs. + +Do not add a second reconciliation-event or receipt authority. + +### Assignment attempt + +An assignment is an immutable attempt to execute one node revision. It freezes: + +- graph and node revision; +- source content and decision authority; +- proposal-plan revision; +- effective activity profile and handler; +- required capabilities, profile permission ceiling, and exact assignment grants; +- provider offer and runtime build; +- authorized context and predecessor results; and +- selected workspace mode and exact mutable scope; +- workday capacity envelope, deadline, lease, and reservation. + +The actor and reviewer assignments reserve and settle their own accepted estimates and actual usage. Work-item usage is the derived sum of those attempts. Failure, return, retry, or review rejection creates another attempt against an advanced node revision. Existing assignments are never rewritten. + +### Assignment result + +Use one result contract: + +```yaml +status: completed | blocked | failed +summary: concise outcome +references: + - kind: git | treedx | url +verification: [] +usage: {} +diagnostics: [] +``` + +Git references contain repository, exact commit, and optional branch. TreeDX references contain project, path, and exact commit. Do not create source-candidate records, bundles, artifact manifests, output taxonomies, or per-operation result schemas. + +### Review and revision + +- The actor assignment returns an immutable candidate result and completes that actor attempt; the reviewed work item remains awaiting review. +- Its paired Reviewer node becomes ready and receives the exact candidate, objective, acceptance criteria, references, verification, and relevant ` Architecture` knowledge. +- The Reviewer cannot mutate the candidate. Findings are notes, unresolved matters are questions, and the formal disposition is a decision bound to the exact candidate. +- Approval completes the Reviewer attempt and the work item. Only then are work-item dependencies satisfied. +- Request changes advances the same actor and Reviewer nodes to their next revisions. The actor receives the exact decision and findings; the prior candidate and review remain immutable. +- Each revision repeats Actor → Reviewer against the same objective and accepted plan. No new work item or alternate graph path is created. +- Exhausting `maximumReviewCycles` blocks the work item and requires an explicit new decision; it never silently approves or continues. +- Proposal review uses the same Reviewer profile and core content outputs but gates decision readiness rather than an acting work item. + +This preserves the internal act/review loop while keeping the two attempts independently assigned, permissioned, metered, and auditable. + +### Capability demand + +Reconciliation compiles activity-profile and accepted-work requirements once into `node.requiredCapabilities`. Admission compares that demand with provider supply. The assignment snapshots the result. AgentKernel enforces assignment grants but does not recalculate scheduling demand. + +At admission, the API compiles the work item's requested content and tool authority within the activity profile ceiling and team/project policy. It verifies provider support and freezes the exact result on the assignment. Missing required authority blocks the node with an explanation; it is not silently removed. Exact paths, content scope, and external grants belong only to the assignment. + +## Implementation Checklist + +### Phase 1 — Canonical proposal and plan + +- [x] Draft proposal intake accepts the human request plus optional title, objective refs, and evidence refs. +- [ ] Replace separate execution-plan and operational estimate authorities with the proposal-owned `executionPlan.workItems` contract. +- [ ] Support several work items per estimating contribution and collaborative refinement of their canonical estimates. +- [ ] Require workspace mode, review policy, actor/reviewer estimates, bounded review cycles, acceptance criteria, acyclic work dependencies, satisfiable permission ceilings, and resolved blockers before decision. +- [ ] Use `book`, `knowledge`, `note`, `question`, and classed `decision` content for architecture, review, workday reporting, and publication workflows; record authority/approval/vote evidence inside the decision and add no `architecture`, `review`, or `workday-report` content model. +- [ ] Extend generic entity references with exact path, commit, optional heading anchor, and optional line range and use them on notes, questions, and decisions. +- [ ] Generate or verify SDK types, validators, API records, CLI schemas, and fixtures against `docs/agent.schema.yml`. +- [x] Bind every accepted decision to one exact executable proposal revision and digest. +- [ ] Project questions, answers, feedback, approvals, external state, and authority prerequisites as conditions. +- [ ] Delete obsolete content schemas, routes, and parsers in the same cutover; add no compatibility translation. + +Acceptance: + +- [ ] `trsd` can create, read, discuss, estimate, validate, and decide the proposal through normal TreeDX operations. +- [ ] Invalid estimates, dependencies, blockers, or stale authority prevent decision without mutating graph state. + +### Phase 2 — Living graph and dependency projection + +- [x] Add monotonic team graph revisions and deterministic projection from test TreeDX fixtures. +- [x] Make projection replay order-independent and idempotent. +- [x] Store nodes, edges, assignments, and graph revisions once each; remove duplicated node JSON fields. +- [x] Resolve activity-profile agent selectors and lifecycle selectors into concrete edges. +- [ ] Apply dependencies only to the declaring activity; exclude chat from implicit workflow dependencies. +- [x] Expand every `review: required` acting work item into stable actor and Reviewer nodes under the same work-item identity. +- [x] Project proposal governance review through the same Reviewer `reviewing` profile without creating an acting pair. +- [ ] Project lifecycle events as condition nodes, including `workday-closing`. +- [ ] Union profile and work-item edges with deterministic provenance and cycle validation. +- [ ] Reconcile only the affected connected component after a source change. +- [ ] Expose graph, node, edge provenance, blocking explanation, and read-only reconciliation plan through generated CLI operations. + +Acceptance: + +- [ ] Researcher → Reviewer remains parallel to Architect → Tester → Engineer → Technical Writer → Releaser, and every required actor is independently reviewed, without profile-authored graph IDs. +- [ ] Proposal review gates decision and every required Actor → Reviewer pair gates downstream work-item readiness. +- [ ] Releaser waits for approved Engineer and Technical Writer work-item pairs and every other applicable required review. +- [x] `workday-closing` → Reporter materializes as an ordinary condition dependency. +- [x] Replaying identical inputs produces no changes, duplicate nodes, or duplicate edges. + +### Phase 3 — Direct assignment lifecycle + +- [x] Treat every ready assignable node as demand for the allocator defined in `docs/agent-architecture.md`. +- [ ] Claim a node and create its immutable assignment, lease, reservation, and idempotency receipt transactionally. +- [x] Compile required capabilities during reconciliation and compare them directly with provider offers during admission. +- [x] Validate requested content/tool authority against the activity profile ceiling and team/project policy; freeze the exact grant on the assignment. +- [x] Select the accepted work item's `read-only`, `treedx`, or `git` workspace and permit exact read context from either custody system. +- [ ] Enforce one mutable workspace per assignment and reject dual Git/TreeDX mutation work items. +- [ ] Preserve running assignments when the graph changes; cancel or supersede only through explicit lifecycle rules. +- [x] Advance node revision for retry or replacement so a new assignment has a distinct deterministic identity. +- [ ] Remove decision execution inputs, capacity-plan work units, workday demand rows, and alternate assignment-synthesis paths. + +Acceptance: + +- [x] One CLI-visible ready node produces exactly one assignment and reservation. +- [x] The assignment exposes its profile ceiling, exact grant, workspace mode, mutable scope, and denied or missing authority explanation. +- [x] Replay produces no duplicate assignment or charge. +- [ ] Ineligible providers and blocked dependencies have exact explanations. + +### Phase 4 — Results, review, revision, and multiple projects + +- [x] Accept only the one general result contract and ordinary Git, TreeDX, or URL references. +- [x] Complete an actor attempt on candidate return while keeping its work item incomplete until the paired review is approved. +- [x] Pass predecessor results into dependent assignment context. +- [x] Record review findings as notes/questions and formal disposition as a decision bound to the exact candidate. +- [x] Advance the same actor/reviewer node pair on request changes; create no unrelated revision work item. +- [ ] Enforce bounded review cycles and block for a new decision when exhausted. +- [ ] Support one team graph spanning multiple projects and decisions. +- [ ] Preserve project-scoped content and repository authority across cross-project scheduling. +- [ ] Fail closed when a cross-project dependency lacks an explicit TreeDX relation and read grant. +- [x] Admit newly ready work during the current active workday. + +Acceptance: + +- [ ] Proposal review → decision and each required Actor → Reviewer pair → downstream readiness pass through the CLI. The earlier reduced proposal did not include the six fixed SDK work items required by the acceptance specification. +- [ ] Request changes → same actor revision → same Reviewer revision → approval passes without changing prior candidates or reviews. This remains to be replayed inside the approved SDK v4 golden campaign. +- [ ] Two projects progress in one team graph without copying project graphs or leaking context. + +### Phase 5 — Clean cutover and managed CLI acceptance + +- [ ] Route planning, estimating, acting, reviewing, reporting, and communication exclusively through living graph nodes. +- [ ] Remove TreeDX `assignment_plan`, `assignment_status`, and `assignment_summary`; proposal content owns planning and PostgreSQL owns assignment state and results. +- [ ] Delete frozen signal scheduling, fixed engineering graph compilation, decision graph documents, execution inputs, capacity plans, demand records, duplicate estimate storage, source-candidate storage, and superseded operations. +- [ ] Remove all compatibility fields, aliases, parsers, routes, tables, tests, fixtures, documentation, and feature switches for retired paths. +- [ ] Initialize a clean pre-launch schema and rebuild operational graph state from exact TreeDX refs. +- [ ] Run the complete CLI story below locally and in managed staging. +- [ ] Publish and read back one coordinated compatible release set. + +Final CLI story: + +1. Create and collaboratively complete a proposal-owned execution plan. +2. Resolve a blocking question and validate the exact proposal revision. +3. Accept the proposal and observe deterministic graph reconciliation. +4. Explain profile-derived and work-specific dependencies. +5. Admit and execute the required Architect, Tester, Engineer, Technical Writer, Reviewer, Releaser, and Reporter nodes in graph order. +6. Verify each assignment's permission ceiling, exact grant, workspace mode, and mutable scope. +7. Request changes on one candidate, repeat the same Actor → Reviewer pair, and approve the replacement. +8. Add a proposal or answer during the active workday and observe immediate graph evolution. +9. Read exact results, references, usage, settlement, and final graph state. +10. Replay reconciliation and prove zero duplicate nodes, edges, assignments, reservations, or settlements. + +Required CLI surface: + +```text +trsd execution graph show --team --json +trsd execution graph watch --team --json-stream +trsd execution node show --json +trsd execution node explain --json +trsd execution reconcile --team --plan --json +trsd execution assignments list --team --json +trsd execution assignments show --json +``` + +## Package Responsibilities + +This plan adds only assignment-specific responsibilities to the ownership table in `docs/agent-architecture.md`: + +- SDK: proposal-plan, graph, edge, condition, assignment, result, and CLI contracts; permission and workspace contracts remain owned by the architecture plan. +- API: projection, storage, readiness, exact-grant compilation, workspace selection, assignment lifecycle, result reconciliation, and explanation. +- Agent: enforce the immutable assignment grant, operate only in the selected workspace, return the general result, and never mutate graph state. + +## Verified Baseline + +| Date | Verified fact | Evidence | +|---|---|---| +| 2026-09-14 | Draft proposal intake, exact proposal revision/digest binding, and proposal-governance review use the living graph contracts | Focused SDK/API proposal and projection suites; current development read-back | +| 2026-09-14 | Ready-node admission compiles provider capability demand and closing Reporter dependency from the same graph | Focused API admission/projector suites; Reporter settlement receipt retained in Issue #520 | + +## Observations and Blockers + +### Current integrated state + +- No full SDK golden pass. The package-owned exact-decision continuation passed release, paired approval, exact Reporter read-back, all-attempt settlement/teardown and unchanged-upstream gates; historical failed runs remain failed (Platform #520). + +### Current active blocker + +- Architecture-first test correction (October 2): [Agent312](https://github.com/treeseed-ai/agent/issues/312) reproduces handler-side grant/path widening and deadline mutation through real isolated Git publications, implicit integration guidance outside an explicit integration assignment, and name-dependent handling of native failed verification. The original assignment input remains unchanged, which does not prove immutable authority inside the Kernel. The architecture plan records the reopened enforcement gate. These focused failures block further unrelated testing; proposal/graph/review/settlement and full CLI acceptance remain separately unproven. Preserve the historical DQ/DR evidence below; it is not the current frontier. + +- API lifecycle unit and real SQL tests now require YAML-owned activity dependencies and identity-neutral reporting, with exactly one selected workday closeout Reporter. Six focused cases fail. Existing graph guarantees now require the living team graph, exact content/decision/review authority and ordinary weighted admission, not retired group/signal graphs, deliverable manifests or capacity tiers. Their full executable acceptance coverage remains open. Pure test-first development is required after all three layers are aligned; no expectation may be changed merely to fit implementation. + +- Exact canonical-schema tests now derive stored/runtime definitions and mutation cases from the tracked target itself. Public SDK verification accepts real committed assignment/operational definition drift despite changed Git and file digests. Unit and native Git counterexamples are preserved in [Agent312](https://github.com/treeseed-ai/agent/issues/312); generated CLI, API/Agent semantic equivalence and full managed scene coverage remain open. Component bindings do not satisfy those missing layers. + +- DQ proved planning, external approval and genuine Tester correction but failed re-review; that evidence repair is integrated. DR then failed chat invocation binding before acting. API #468/#469 guards binding with the exact admitted assignment; `agent-architecture.md` records delivery and receipt limitations. All six pairs, completed re-review, closeout and the product gate still require one passing fresh run; the continuation is not full acceptance (Platform #520). + +### Next acceptance milestone + +- Run the fresh full SDK golden from proposal through six reviewed work items and closeout within the one-hour simulation boundary, then API and joint acceptance only after SDK passes. + +## Completion + +This plan is complete only when all phase checkboxes are verified, one content-derived graph and assignment path remains, agents have no graph mutation capability, required acting work deterministically completes bounded Actor → Reviewer cycles against one objective, architecture/review/reporting workflows use registered core content models and classed decisions, `docs/agent.schema.yml` matches runtime contracts, TreeDX contains no assignment plan/status/summary authority, every assignment has an enforceable exact grant and at most one mutable workspace, the managed CLI story passes, and no legacy implementation or backward compatibility remains. diff --git a/docs/agent-chat-readiness.md b/docs/agent-chat-readiness.md new file mode 100644 index 00000000..cbee6964 --- /dev/null +++ b/docs/agent-chat-readiness.md @@ -0,0 +1,50 @@ +# Authenticated agent-chat readiness + +This handoff records the platform boundary proven before agent-chat UI work begins. It does not add a chat route, placeholder, or new authority. + +## Browser identity and credential custody + +- Admin is an OAuth browser BFF. PKCE verifier and state are short-lived sealed HttpOnly cookies; access and rotating refresh tokens remain HttpOnly and are never exposed to browser JavaScript. +- API remains the issuer and owns credentials, authorization decisions, revocation, audit, and durable identity state. +- Browser mutations require same-origin CSRF protection and safe return paths. Session responses are `no-store`; logout revokes and clears both token classes. +- The generation-85 immutable Reviewer runs proved registration, email confirmation, sign-in, consent, refresh, logout, password reset, account, and team guarantees across desktop, tablet, and mobile: 66 active guarantees with no failures or blocked cases. + +## User, team, project, and permission boundary + +- The current user and active team are resolved through catalog descriptors rather than handwritten route strings. +- Project access is subordinate to API-owned team membership and permission checks. A browser session does not grant access merely because an identifier is known. +- Mutations retain ETag/concurrency checks, signed confirmation for high-risk operations, last-owner protection, audit evidence, redaction, and the standard error envelope. +- Agent chat must carry current team and project context into every catalog operation and render forbidden, missing, or unavailable state truthfully. + +## Agent and communication addressing + +- Agent identity is the accepted project-scoped definition, not a UI label or provider process. Recipients resolve to frozen team, project, agent, and definition-revision identifiers before a source message is committed. +- Communication status, provider availability, invocation/operation state, and durable responses are read through SDK catalog descriptors. +- API admission and the assignment-scoped TreeDX facade remain authoritative. Admin must not proxy Reviewer evidence or broaden provider authority. + +## Workday, assignment, and terminal state + +- Monitoring composes catalogued agent, communication, provider, workday, assignment, usage, ledger, and operation reads. Unsupported data is unavailable, never a manufactured zero. +- A terminal communication must have durable response state and exact settlement. Acceptance requires no remaining assignment, lease, reservation, child process, temporary credential custody, usage, or accounting residue attributable to the test. +- Team/project authorization and response redaction apply to monitoring reads as they do to mutations. + +## Reviewer evidence boundary + +- Reviewer remains loopback-only and consumes immutable run evidence. The generation-85 desktop run was independently discovered by Reviewer `0.1.0-rc.13`, annotated with a local note, read back, and copied into local workplan `2026-08-28T07-37-04-870Z-generation-85-authenticated-platform-baseline` with its evidence manifest. +- Device profiles have distinct run identities; desktop evidence cannot satisfy tablet or mobile requirements. +- Transport diagnostics may include method, origin, pathname, and nested TLS/network cause. Query strings, bodies, credentials, and tokens are excluded. +- Admin displays a Reviewer handoff only when an explicit local capability URL is configured; it never hosts or remotely starts Reviewer. + +## First chat project gate + +The first authenticated chat implementation may build on these invariants, but it must separately prove: authorized recipient resolution, one committed source message, observable assignment/provider state, one durable response, exact settlement, browser-safe rendering, audit evidence, and zero residue. Planned MFA/provider linking and advanced Agent Lab projections remain outside this claim. + +## Generation 85 closeout certification + +- Exact composition: Platform generation 85 / Deployment `0.1.0-rc.115`, restored receipt `receipt-1787903649377`, catalog digest `sha256:270b7cb7af0608abe24971a1ab3d88bd2525f3dc3eb971f64e310e766e1f17b0`. +- Guarantee runs: `gen85-desktop-chromium-20260828-r3`, `gen85-tablet-chromium-20260828`, and `gen85-mobile-chromium-20260828`; each passed 22 of 22 active authentication, account, and team guarantees with a distinct evidence identity. +- Reviewer copied both browser and direct API evidence into the workplan manifest. Exact copied evidence SHA-256 values are `6e3f70b3418f8958e1d6594dd4174419ad26ab462502954066ce25e758f218e0` and `94cdfa92ec4d21df7240116214149e6376cb1178b166649c782c37918020e777`. +- Real communication monitoring used SDK project `0f9d94ba-ed45-4078-baf6-c85f97e0044d`, technical-writer assignment `assignment_WXj8uUgIIazqzLcYVksuGcMoz2AB-PT7`, and workday `workday-conversation-invocation-e991785bcad120935e791f4c46034d37-sdk`. Catalog reads proved provider `codex-local` available, assignment returned, lease released, six active/elapsed seconds, and a matching `task_completed_actual_settlement` ledger entry releasing 894 reserved seconds. Native usage remained an explicit empty object; it was not presented as zero. +- The exact generation-73 baseline was restored as receipt `receipt-1787903533155`; Admin, API, Agent, TreeDX, and Mailpit readiness all returned HTTP 200. Generation 85 was then restored, and two consecutive reconciliations retained `receipt-1787903649377`, proving no-op behavior. +- Historical APT payload drift encountered during rollback is tracked in [Deployment #233](https://github.com/treeseed-ai/deployment/issues/233). Recovery used the immutable Deployment rc103 GitHub release asset, whose SHA-256 matched its release custody record. +- Final closeout state has no development session, Reviewer server, forwarding process, test account, assignment lease, or unrevoked test token. Development updates are resumed. diff --git a/docs/agent-communication-readiness.md b/docs/agent-communication-readiness.md index 085b63d1..25a88356 100644 --- a/docs/agent-communication-readiness.md +++ b/docs/agent-communication-readiness.md @@ -6,7 +6,7 @@ The local control plane and TreeDX service are live. The canonical `treeseed` se The owner memberships are: -- Adrian Webb, bound to `adrian.webb@knowledge.coop` as an interactive human owner. +- An installation-supplied interactive human owner. - `service-principal:treeseed/automation`, bound as a non-login service owner. Provider workers do not inherit this owner's authority. The unified local capacity provider is enrolled and owner-approved as `provider_LtqmnSGecDlhDPb2-7WgyLkKwxI8VDAO`. Its manager is renewing availability session `5e033c5a-c8c2-439d-8a0c-96dff8da1e24`, and its runner is live and polling without claiming work. `codex-local` is available only on the `communication` lane with one reserved worker and two-worker maximum. Exactly fifteen active project grants are narrowed to that adapter and lane. `platform-local` remains unavailable and the `workday` lane is paused, so global seed closure truthfully retains `lane_execution_unavailable:platform` and `lane_execution_unavailable:workday` without blocking communication. diff --git a/docs/agent-intermediate-plan.md b/docs/agent-intermediate-plan.md new file mode 100644 index 00000000..eec52fca --- /dev/null +++ b/docs/agent-intermediate-plan.md @@ -0,0 +1,52 @@ +# Agent acceptance preflight + +**Purpose:** make the first real SDK golden workday admissible without spending another full workday discovering a missing source, grant, guest image, or campaign authority. This is a temporary gate before returning to [`agent-acceptance.md`](./agent-acceptance.md), not a substitute acceptance campaign. Detailed defects and run evidence belong in Platform Issue #520 and owning-package tests/PRs. + +## Rules + +- Keep the six SDK work-item objectives, dependencies, review cycles, permissions, and acceptance criteria from `agent-acceptance.md` unchanged. Use one new canonical proposal ID because the specified ID is already superseded; record that one correction in the acceptance campaign freeze. Do not create another chain of diagnostic retry proposals. +- Use one published TreeDX source commit and explicit exact Book references; never infer an Architecture Book from a library root or a moving branch. +- Run focused tests and development-mode builds first. Do not cut an RC, run a full workday, or weaken a schema to pass preflight. +- Treat an intermediate pass as permission to *start* the SDK golden, not as evidence that any golden stage passed. + +## Gates + +### 1. Published content and immutable authority + +- [x] Publish the SDK Core Book and Core Objective in current schemas without losing the objective text. Read-back: SDK library `65106c908bca127ea45d11b3f6b54905878d191c`. +- [x] Read the SDK Architecture Book at the same published library commit. Its exact `books/architecture.md` content is available. +- [x] Freeze one replacement SDK proposal ID and exact proposal bytes. The original `golden-sdk-decision-governed-workday-intent` is superseded; the replacement retains the six fixed work items and adds exact Core and Architecture Book context, without changing their objectives or topology. Local freeze: `.treeseed/acceptance/agent-golden-20260921/sdk-intermediate-freeze.json`. +- [x] Validate the replacement proposal against the current schema and compare its fixed work-item fields to `agent-acceptance.md`. All six objectives match exactly; the governed draft is version 1 with content hash `7a781d0093e4485346d1454420c38fdc659428d158a06c27cc29cf96ad082836`. The local freeze records the source, Book digests, policy revision 1, and provider offer revision 1. + +### 2. Assignment and guest contract + +- [x] An Architect assignment with an exact Architecture Book receives it as a read grant and gets a valid `knowledge//.md` write target. Admission rejects a missing Book. API assignment-builder tests: 18 passing. +- [x] The guest constrains Knowledge output to the granted ID/slug and exact Book reference. The repaired schema passed a live Luna/low Kata assignment: Architect produced the granted SDK Architecture Knowledge page with the exact Book reference; focused Agent tests and type-check also pass. This is a guest-contract check, not golden acceptance. +- [x] Exercise the proposal → generated graph → immutable assignment → guest-context transformation in one local integration fixture, asserting exact published Book bytes, write target, timing budget, and no external mutation. The fixture produced 14 nodes, a 180-second Architect allocation, one exact Architecture Book context item, and a constrained Knowledge output at `knowledge/sdk-architecture/knowledge-bb1ba00e45b117114756c0d6.md`. +- [x] Confirm Researcher, Architect, and generated Reviewer output/grant contracts against the frozen proposal before a live workday. The cross-package fixture uses the actual published SDK role profiles, checks requested permissions against their activity ceilings, builds each role's grant, and verifies the Architect Knowledge output schema. This is local contract evidence, not an agent-execution result. + +### 3. Development runtime + +- [x] Replace the CLI's caller-owned `docker image save` path with a manager-owned import/export operation authorized for `treeseed-operators`. The local operator imported `treeseed/sandbox-codex:local` without sudo, `sg`, or Docker membership; manager read-back reports `sha256:2535021bfc679301a36675dbae543376039c7ea6dbdef63593a28788e6e68dee`. Kata guest readiness remains part of the next gate. +- [x] Rebuild and activate the final API service, Agent provider, and Agent sandbox in development mode once the focused changes are batched. Selected generations: API 699, provider 435, sandbox 214, TreeDX 266; all development selections ready. Host reconciliation plans noop and Kata sandbox is ready. The released-component TreeDX view flags `wrong-image` under the live selection; exact TreeDX reads succeed. +- [x] Check provider capability/model remaining supply, Identity authentication, TreeDX exact reads, and writable campaign-local custody immediately before starting the golden. Provider offer revision 1 is healthy with Sol/research 7,200s and Terra/implementation 28,800s ordinary daily caps; CLI authentication, exact Book read, and writable local freeze passed. The latest workday page had no active workday. + +### 4. Return to golden acceptance + +- [x] Update `agent-acceptance.md` only for the one canonical replacement ID and current frozen exact refs; preserve its objectives, stages, and pass criteria. +- [x] Record a passing intermediate preflight receipt in Platform Issue #520 with focused test results, runtime digests, exact refs, and an unchanged external-state baseline. The local freeze SHA-256 is `d38055c31a2a690b0c90186875e1dc613a4d7adf7906ff590210bd891b572419`. +- [x] Hand the frozen SDK proposal and a schema-valid, read-only `trsd workdays plan --plan` request back to Stage 0 of `agent-acceptance.md`. Starting and judging the SDK → API → joint workdays belongs exclusively to that acceptance plan, after its full campaign freeze; no golden checkbox is marked from this handoff. + +### 5. Mandatory executable regression gate + +- [x] Restore a package-owned scene/guarantee runner that fails closed on missing implementations, skipped/empty evidence, absent prerequisites, and uncovered required cases; retain exact local receipts in Platform #520. +- [x] Execute coded component scenes for SDK, API, Agent, Deployment isolation, and CLI operator boundaries; these are preflight evidence only, not a golden workday pass. +- [x] Enforce the package-owned component scenes in SDK, API, Agent and CLI Actions using the exact tested Reviewer Action. Deployment's scene gate is in its checked integration PR; an unrelated Identity runtime gate still prevents that PR's merge. Component coverage never attests the full golden or broad live guarantees. +- [ ] Reconcile every remaining stale catalog binding against current ownership and semantics; do not map a broad guarantee to an unrelated passing test or revive retired runtime paths. +- [ ] Prove the unchanged full SDK golden through the real graph, then proceed to API/joint acceptance under `agent-acceptance.md`. + +## Current frontier + +The guest-contract prerequisite is proven, but the executable regression gate remains open. Full acceptance remains governed exclusively by `agent-acceptance.md`; no golden pass is claimed. Detailed defects, component receipts, and remaining catalog gaps belong in Platform Issue #520. + +- Acceptance frontier (2026-10-01): Agent #296 is checked and active. EF completed five approved pairs and a genuine Tester correction/re-review; the release Actor passed release verification, packing and archive inspection. The final release Reviewer exhausted the original workday boundary with only 39 seconds available, so full SDK acceptance remains failed. Agent #298 / PR #299 removes redundant discovery of already-materialized exact context and separate builds already owned by aggregate verification; missing exact refs, required predecessor read-back, independent review and runner replay remain mandatory. Strict tests and the coded owner scene pass; checked staging and serial activation precede one fresh full SDK gate. Canonical objectives, one-hour/twenty-minute planning, concurrency five, model/cap policy and fresh review allowances stay unchanged. Historical failures remain immutable; no full SDK or API/joint promotion, manual seconds, schema or cap changes. Detailed evidence belongs in Platform #520; broad gates remain unchecked. diff --git a/docs/agent.schema.yml b/docs/agent.schema.yml new file mode 100644 index 00000000..7e364208 --- /dev/null +++ b/docs/agent.schema.yml @@ -0,0 +1,2557 @@ +# Canonical target contract for the agent execution system. +# +# This is JSON Schema 2020-12 written as YAML. It is intentionally strict: +# stored records reject unknown fields so architecture drift becomes a validation +# failure. Generate SDK types and validators from this file, or prove exact +# structural equivalence in CI. Do not copy these definitions into another +# handwritten schema. +# +# Storage boundary: +# - TreeDX stores governed content and its exact revision history. +# - PostgreSQL stores operational execution, capacity, and custody state. +# - Git stores source candidates; PostgreSQL results hold exact Git references. +# Package use: +# - SDK owns this portable contract and generated validators/types. +# - API validates content projections and owns PostgreSQL records/lifecycle. +# - Agent consumes immutable assignments and emits AssignmentResult. +# - Capacity providers exchange offers, assignments, leases, and results. +# - CLI renders and validates these same contracts without business-rule copies. +# +# Deliberately absent: +# architecture, review, workday-report, assignment_plan, assignment_status, +# assignment_summary, source-candidate, capacity-plan, and demand models. +# Architecture is a book/knowledge convention, review uses note/question/decision, +# and a workday report is a classified note. Assignment lifecycle belongs solely +# to the PostgreSQL records below. + +$schema: "https://json-schema.org/draft/2020-12/schema" +$id: "https://treeseed.ai/schema/agent-execution/v1" +title: TreeSeed agent execution object model +description: >- + The complete ideal object model from governed planning content through a living + execution graph, assignment execution, review, release or publication, workday + reporting, and usage settlement. +$comment: >- + The root union validates stored records. Runtime-only DTOs such as + AssignmentContext are addressable through $defs. SDK/API semantic validation + must additionally enforce ordered estimate bounds; unique work-item IDs; + local, acyclic dependencies; requested permissions within profile and policy + ceilings; exact current authority refs; deterministic node/edge identity; + one active assignment per node revision; repeated dependency-ordered planning cycles; the + parallel question-driven Researcher -> Reviewer and Architect -> Tester -> Engineer -> + Technical Writer -> Releaser branches; bounded review cycles; immutable assignment inputs; + and exactly-once settlement. + +# A document validated at the root must be exactly one stored record type. +oneOf: + - $ref: "#/$defs/AgentProfile" + - $ref: "#/$defs/Book" + - $ref: "#/$defs/Knowledge" + - $ref: "#/$defs/Objective" + - $ref: "#/$defs/Discussion" + - $ref: "#/$defs/DiscussionMessage" + - $ref: "#/$defs/Proposal" + - $ref: "#/$defs/Question" + - $ref: "#/$defs/Note" + - $ref: "#/$defs/Decision" + - $ref: "#/$defs/TreeDxWorkspace" + - $ref: "#/$defs/TreeDxWorkspaceReview" + - $ref: "#/$defs/TreeDxPublicationReceipt" + - $ref: "#/$defs/Team" + - $ref: "#/$defs/Project" + - $ref: "#/$defs/AgentRegistration" + - $ref: "#/$defs/WorkdayPolicy" + - $ref: "#/$defs/WorkdaySchedule" + - $ref: "#/$defs/ProviderOffer" + - $ref: "#/$defs/ProviderState" + - $ref: "#/$defs/Workday" + - $ref: "#/$defs/GraphRevision" + - $ref: "#/$defs/ExecutionNode" + - $ref: "#/$defs/ExecutionEdge" + - $ref: "#/$defs/AssignmentAttempt" + - $ref: "#/$defs/Lease" + - $ref: "#/$defs/Reservation" + - $ref: "#/$defs/AssignmentResult" + - $ref: "#/$defs/UsageSettlement" + +$defs: + # --------------------------------------------------------------------------- + # Shared scalar and reference contracts + # --------------------------------------------------------------------------- + + Identifier: + type: string + minLength: 1 + maxLength: 200 + pattern: "^[A-Za-z0-9][A-Za-z0-9._:/-]*$" + + Slug: + type: string + minLength: 1 + maxLength: 100 + pattern: "^[a-z0-9]+(?:[._/-][a-z0-9]+)*$" + + NonEmptyText: + type: string + minLength: 1 + + Timestamp: + type: string + format: date-time + + Sha256Digest: + type: string + pattern: "^sha256:[a-f0-9]{64}$" + + GitCommit: + type: string + pattern: "^[a-f0-9]{40}$" + + PositiveSeconds: + type: integer + minimum: 1 + + NonNegativeSeconds: + type: integer + minimum: 0 + + ContentModel: + # This is the entire core vocabulary available to profile permissions. + enum: + - agent + - book + - knowledge + - objective + - discussion + - discussion-message + - proposal + - question + - note + - decision + + DecisionClass: + # One decision model, with classes that select its governance semantics. + enum: [proposal, work-review, publication] + + DecisionDisposition: + enum: [approved, rejected, request-changes, deferred, superseded] + + DecisionPosition: + # Embedded signed position for approval or voting; it is not another model. + type: object + required: [actorRef, position, recordedAt] + properties: + actorRef: + $ref: "#/$defs/ExactEntityReference" + position: + enum: [approve, reject, abstain] + rationale: + type: string + recordedAt: + $ref: "#/$defs/Timestamp" + additionalProperties: false + + WorkspaceMode: + enum: [read-only, treedx, git] + + ActivityName: + enum: [planning, estimating, acting, reviewing, reporting, chat] + + ExecutionKind: + enum: [planning, estimating, acting, reviewing, reporting, communication, condition] + + AgentClass: + # Project-defined classes remain possible; first-party defaults use these IDs. + type: string + minLength: 1 + maxLength: 100 + pattern: "^[a-z][a-z0-9-]*$" + + ToolGroup: + # Profiles use stable groups, never provider-specific raw tool names. + enum: + - discussion + - source.read + - source.write + - verification + - release + + ExactEntityReference: + # Shared by notes, questions, decisions, assignment context, and reports. + # revision/digest pins TreeDX; commit pins Git or a TreeDX repository snapshot. + type: object + required: [store, model, id] + properties: + store: + enum: [treedx, postgresql, git, url] + model: + type: string + minLength: 1 + id: + $ref: "#/$defs/Identifier" + revision: + type: integer + minimum: 1 + digest: + $ref: "#/$defs/Sha256Digest" + repository: + type: string + minLength: 1 + commit: + $ref: "#/$defs/GitCommit" + path: + type: string + minLength: 1 + anchor: + type: string + minLength: 1 + startLine: + type: integer + minimum: 1 + endLine: + type: integer + minimum: 1 + url: + type: string + format: uri + allOf: + - if: + type: object + required: [endLine] + then: + type: object + required: [startLine] + - if: + type: object + properties: + store: + const: treedx + required: [store] + then: + type: object + anyOf: + - type: object + required: [revision, digest] + - type: object + required: [commit] + - if: + type: object + properties: + store: + const: git + required: [store] + then: + type: object + required: [repository, commit] + - if: + type: object + properties: + store: + const: url + required: [store] + then: + type: object + required: [url] + additionalProperties: false + + ExactWorkItemReference: + allOf: + - $ref: "#/$defs/ExactEntityReference" + - type: object + required: [store, model, id, revision, digest, repository, commit, path, anchor] + properties: + store: + const: treedx + model: + const: proposal + anchor: + type: string + pattern: "^work-item/[a-z0-9]+(?:-[a-z0-9]+)*$" + + GitReference: + type: object + required: [kind, repository, commit] + properties: + kind: + const: git + repository: + type: string + minLength: 1 + commit: + $ref: "#/$defs/GitCommit" + branch: + type: string + minLength: 1 + path: + type: string + minLength: 1 + additionalProperties: false + + TreeDxReference: + type: object + required: [kind, projectId, repository, commit, path] + properties: + kind: + const: treedx + projectId: + $ref: "#/$defs/Identifier" + repository: + type: string + minLength: 1 + commit: + $ref: "#/$defs/GitCommit" + path: + type: string + minLength: 1 + workspaceId: + $ref: "#/$defs/Identifier" + additionalProperties: false + + UrlReference: + type: object + required: [kind, url] + properties: + kind: + const: url + url: + type: string + format: uri + digest: + $ref: "#/$defs/Sha256Digest" + additionalProperties: false + + AssignmentReference: + oneOf: + - $ref: "#/$defs/GitReference" + - $ref: "#/$defs/TreeDxReference" + - $ref: "#/$defs/UrlReference" + + Estimate: + # expected <= maximum is enforced by semantic validation; neither is a minimum runtime. + type: object + required: [expectedSeconds, maximumSeconds] + properties: + expectedSeconds: + $ref: "#/$defs/PositiveSeconds" + maximumSeconds: + $ref: "#/$defs/PositiveSeconds" + rationale: + type: string + additionalProperties: false + + DependencySelectors: + # Human-authored standing dependencies never contain generated IDs. + type: object + minProperties: 1 + properties: + agents: + type: array + uniqueItems: true + items: + $ref: "#/$defs/AgentClass" + events: + type: array + uniqueItems: true + items: + enum: [workday-closing] + additionalProperties: false + + ContentPermissions: + type: object + required: [read, write] + properties: + read: + type: array + uniqueItems: true + items: + $ref: "#/$defs/ContentModel" + write: + type: array + uniqueItems: true + items: + $ref: "#/$defs/ContentModel" + additionalProperties: false + + PermissionSet: + # In a profile this is a ceiling; in a work item it is requested authority. + type: object + required: [content, tools] + properties: + content: + $ref: "#/$defs/ContentPermissions" + tools: + type: array + uniqueItems: true + items: + $ref: "#/$defs/ToolGroup" + additionalProperties: false + + ExactGrant: + # Assignment-time authority uses concrete refs and paths, not broad model groups. + type: object + required: [contentRead, contentWrite, sourceRead, sourceWrite, tools] + properties: + contentRead: + type: array + uniqueItems: true + items: + $ref: "#/$defs/ExactEntityReference" + contentWrite: + type: array + uniqueItems: true + items: + $ref: "#/$defs/ExactEntityReference" + sourceRead: + type: array + uniqueItems: true + items: + type: string + minLength: 1 + sourceWrite: + type: array + uniqueItems: true + items: + type: string + minLength: 1 + tools: + type: array + uniqueItems: true + items: + $ref: "#/$defs/ToolGroup" + additionalProperties: false + + Prompt: + type: object + required: [system] + properties: + system: + type: string + minLength: 20 + instructions: + type: array + items: + $ref: "#/$defs/NonEmptyText" + additionalProperties: false + + ActivityProfile: + type: object + required: [handler, permissions, prompt] + properties: + handler: + $ref: "#/$defs/Identifier" + dependsOn: + $ref: "#/$defs/DependencySelectors" + permissions: + $ref: "#/$defs/PermissionSet" + prompt: + $ref: "#/$defs/Prompt" + additionalContext: + type: array + uniqueItems: true + items: + $ref: "#/$defs/Identifier" + parameters: + # Handler-specific values are allowed only here and remain ordinary data. + type: object + additionalProperties: true + additionalProperties: false + + ActivityProfiles: + type: object + minProperties: 1 + properties: + planning: + $ref: "#/$defs/ActivityProfile" + estimating: + $ref: "#/$defs/ActivityProfile" + acting: + $ref: "#/$defs/ActivityProfile" + reviewing: + $ref: "#/$defs/ActivityProfile" + reporting: + $ref: "#/$defs/ActivityProfile" + chat: + $ref: "#/$defs/ActivityProfile" + additionalProperties: false + + WorkItem: + # Stable proposal-owned unit. Generated Reviewer nodes are not authored here. + type: object + required: + - id + - activity + - agentClass + - workspace + - review + - objective + - dependsOn + - requestedPermissions + - acceptanceCriteria + properties: + id: + $ref: "#/$defs/Slug" + activity: + enum: [acting] + agentClass: + $ref: "#/$defs/AgentClass" + workspace: + $ref: "#/$defs/WorkspaceMode" + review: + enum: [required, none] + objective: + $ref: "#/$defs/NonEmptyText" + priority: &canonicalWorkPriority + type: integer + minimum: -9007199254740991 + maximum: 9007199254740991 + description: >- + Governed work-item priority projected unchanged onto its Actor and + Reviewer nodes. Higher integers rank first only within the eligible + project and agent class selected by weighted fair admission. Omission + means zero; priority never bypasses readiness, permission, provider, + concurrency, or productive-window gates. + estimate: + $ref: "#/$defs/Estimate" + reviewEstimate: + $ref: "#/$defs/Estimate" + maximumReviewCycles: + type: integer + minimum: 1 + dependsOn: + type: array + uniqueItems: true + items: + $ref: "#/$defs/Slug" + requestedPermissions: + $ref: "#/$defs/PermissionSet" + requiredCapabilities: + type: array + uniqueItems: true + items: + $ref: "#/$defs/Identifier" + contextRefs: + type: array + uniqueItems: true + items: + $ref: "#/$defs/ExactEntityReference" + acceptanceCriteria: + type: array + minItems: 1 + items: + $ref: "#/$defs/NonEmptyText" + allOf: + - if: + type: object + properties: + review: + const: required + required: [review] + then: + type: object + required: [maximumReviewCycles] + - if: + type: object + properties: + review: + const: none + required: [review] + then: + type: object + not: + type: object + anyOf: + - type: object + required: [reviewEstimate] + - type: object + required: [maximumReviewCycles] + additionalProperties: false + + ExecutionPlan: + type: object + required: [workItems] + properties: + workItems: + type: array + minItems: 1 + items: + $ref: "#/$defs/WorkItem" + additionalProperties: false + + # --------------------------------------------------------------------------- + # Governed TreeDX content + # --------------------------------------------------------------------------- + + AgentProfile: + # Storage: TreeDX. Owner: SDK contract; authored as governed project content. + type: object + required: + - schemaVersion + - id + - name + - agentClass + - purpose + - responsibilities + - capabilities + - context + - activityProfiles + properties: + schemaVersion: + const: treeseed.agent/v1 + id: + $ref: "#/$defs/Identifier" + name: + $ref: "#/$defs/NonEmptyText" + agentClass: + $ref: "#/$defs/AgentClass" + purpose: + $ref: "#/$defs/NonEmptyText" + responsibilities: + type: array + minItems: 1 + items: + $ref: "#/$defs/NonEmptyText" + capabilities: + type: array + minItems: 1 + uniqueItems: true + items: + $ref: "#/$defs/Identifier" + context: + type: object + required: [include] + properties: + include: + type: array + minItems: 1 + uniqueItems: true + items: + $ref: "#/$defs/Identifier" + additionalProperties: false + activityProfiles: + $ref: "#/$defs/ActivityProfiles" + allOf: + # Reviewing is reserved for Reviewer by default. A future policy exception + # must change this canonical contract rather than bypass validation. + - if: + type: object + properties: + agentClass: + not: + const: reviewer + required: [agentClass] + then: + type: object + properties: + activityProfiles: + not: + type: object + required: [reviewing] + additionalProperties: false + + Book: + # Architecture is represented by a conventional " Architecture" book. + # Pages pin its content revision and digest, avoiding a same-commit hash cycle. + # Pages are discovered by bookRef, not copied into a reverse page list. + type: object + required: [schemaVersion, id, projectId, revision, slug, title, summary, status, visibility, order] + properties: + schemaVersion: + const: treeseed.book/v3 + id: + $ref: "#/$defs/Identifier" + projectId: + $ref: "#/$defs/Identifier" + revision: + type: integer + minimum: 1 + slug: + $ref: "#/$defs/Slug" + title: + $ref: "#/$defs/NonEmptyText" + summary: + $ref: "#/$defs/NonEmptyText" + description: + $ref: "#/$defs/NonEmptyText" + status: + enum: [draft, review, published, archived] + visibility: + enum: [public, authenticated, team, project, admin] + order: + type: integer + minimum: 0 + groupIds: + type: array + items: + $ref: "#/$defs/Identifier" + audience: + type: array + items: + $ref: "#/$defs/NonEmptyText" + relatedBookIds: + type: array + items: + $ref: "#/$defs/Identifier" + packPolicy: + enum: [allowed, restricted, disabled] + editorialCoreNoteId: + $ref: "#/$defs/Identifier" + cover: + type: object + properties: + image: + $ref: "#/$defs/NonEmptyText" + alt: + $ref: "#/$defs/NonEmptyText" + additionalProperties: false + additionalProperties: false + + Knowledge: + # Parsed Markdown document. `body` is its Markdown body, not a duplicated + # frontmatter field; `bookRef` pins the owning Book path, revision, and digest. + type: object + required: [schemaVersion, id, projectId, bookRef, slug, title, body, status, visibility] + properties: + schemaVersion: + const: treeseed.knowledge-page/v2 + id: + $ref: "#/$defs/Identifier" + projectId: + $ref: "#/$defs/Identifier" + bookRef: + $ref: "#/$defs/ExactEntityReference" + # Semantic validation requires store=treedx, model=book, and a + # nonempty path, revision, and digest. The path is within this project. + slug: + $ref: "#/$defs/Slug" + title: + $ref: "#/$defs/NonEmptyText" + description: + $ref: "#/$defs/NonEmptyText" + body: + $ref: "#/$defs/NonEmptyText" + summary: + $ref: "#/$defs/NonEmptyText" + status: + enum: [draft, review, published, archived] + visibility: + enum: [public, authenticated, team, project, admin] + order: + type: integer + minimum: 0 + relatedRefs: + type: array + uniqueItems: true + items: + $ref: "#/$defs/ExactEntityReference" + parentId: + $ref: "#/$defs/Identifier" + groupIds: + type: array + items: + $ref: "#/$defs/Identifier" + contributors: + type: array + items: + $ref: "#/$defs/Identifier" + relatedBookIds: + type: array + items: + $ref: "#/$defs/Identifier" + relatedKnowledgeIds: + type: array + items: + $ref: "#/$defs/Identifier" + relatedNoteIds: + type: array + items: + $ref: "#/$defs/Identifier" + relatedQuestionIds: + type: array + items: + $ref: "#/$defs/Identifier" + relatedObjectiveIds: + type: array + items: + $ref: "#/$defs/Identifier" + relatedProposalIds: + type: array + items: + $ref: "#/$defs/Identifier" + relatedDecisionIds: + type: array + items: + $ref: "#/$defs/Identifier" + guaranteeIds: + type: array + items: + $ref: "#/$defs/Identifier" + audiences: + type: object + properties: + primary: { type: array, items: { $ref: "#/$defs/NonEmptyText" } } + secondary: { type: array, items: { $ref: "#/$defs/NonEmptyText" } } + excluded: { type: array, items: { $ref: "#/$defs/NonEmptyText" } } + additionalProperties: false + capabilityIds: + type: array + items: + $ref: "#/$defs/Identifier" + routePatterns: + type: array + items: + $ref: "#/$defs/NonEmptyText" + resourceTypes: + type: array + items: + $ref: "#/$defs/Identifier" + actionIds: + type: array + items: + $ref: "#/$defs/Identifier" + keywords: + type: array + items: + $ref: "#/$defs/NonEmptyText" + documentationUrls: + type: array + items: + $ref: "#/$defs/NonEmptyText" + additionalProperties: false + + Objective: + # Durable outcome sought by a team or project; proposals may cite it. + type: object + required: [schemaVersion, id, projectId, title, outcome, status] + properties: + schemaVersion: + const: treeseed.objective/v1 + id: + $ref: "#/$defs/Identifier" + projectId: + $ref: "#/$defs/Identifier" + title: + $ref: "#/$defs/NonEmptyText" + outcome: + $ref: "#/$defs/NonEmptyText" + status: + enum: [active, achieved, abandoned] + evidenceRefs: + type: array + uniqueItems: true + items: + $ref: "#/$defs/ExactEntityReference" + additionalProperties: false + + Discussion: + # Thread metadata only; messages are independently revisioned content. + type: object + required: [schemaVersion, id, projectId, subjectRef, status, participantClasses, title, teamId, createdAt] + properties: + schemaVersion: + const: treeseed.discussion/v1 + id: + $ref: "#/$defs/Identifier" + projectId: + $ref: "#/$defs/Identifier" + subjectRef: + $ref: "#/$defs/ExactEntityReference" + status: + enum: [open, resolved, closed] + participantClasses: + type: array + uniqueItems: true + items: + $ref: "#/$defs/AgentClass" + title: { $ref: "#/$defs/NonEmptyText" } + teamId: { $ref: "#/$defs/Identifier" } + createdAt: { $ref: "#/$defs/Timestamp" } + topic: { $ref: "#/$defs/NonEmptyText" } + visibility: { enum: [public, authenticated, team, project, admin] } + participantIds: { type: array, items: { $ref: "#/$defs/Identifier" } } + agentIds: { type: array, items: { $ref: "#/$defs/Identifier" } } + groupIds: { type: array, items: { $ref: "#/$defs/Identifier" } } + parentWorkdayId: { $ref: "#/$defs/Identifier" } + updatedAt: { $ref: "#/$defs/Timestamp" } + additionalProperties: false + + DiscussionMessage: + # Parsed Markdown document: body is the Markdown body, not duplicated in frontmatter. + type: object + required: [schemaVersion, id, discussionRef, authorRef, body, createdAt] + properties: + schemaVersion: + const: treeseed.discussion-message/v1 + id: + $ref: "#/$defs/Identifier" + discussionRef: + $ref: "#/$defs/ExactEntityReference" + authorRef: + $ref: "#/$defs/ExactEntityReference" + body: + $ref: "#/$defs/NonEmptyText" + replyToRef: + $ref: "#/$defs/ExactEntityReference" + createdAt: + $ref: "#/$defs/Timestamp" + title: { $ref: "#/$defs/NonEmptyText" } + discussionId: { $ref: "#/$defs/Identifier" } + authorId: { $ref: "#/$defs/Identifier" } + authorType: { enum: [user, agent, system] } + intent: { enum: [discuss, propose] } + mentionedAgents: { type: array, items: { $ref: "#/$defs/Identifier" } } + recipientIds: { type: array, items: { $ref: "#/$defs/Identifier" } } + fileRefs: { type: array, items: { type: object } } + contextRefs: { type: array, items: { type: object } } + inboxIntent: { enum: [comment, answer, reply] } + sourceMessageRefs: { type: array, uniqueItems: true, items: { $ref: "#/$defs/ExactEntityReference" } } + authorAgentId: { $ref: "#/$defs/Identifier" } + handoffId: { $ref: "#/$defs/Identifier" } + parentWorkdayId: { $ref: "#/$defs/Identifier" } + resultingOperationId: { $ref: "#/$defs/Identifier" } + additionalProperties: false + + Proposal: + # The executable plan and accepted estimates live directly on this content. + type: object + required: + - schemaVersion + - id + - projectId + - title + - request + - status + properties: + schemaVersion: + const: treeseed.proposal/v1 + id: + $ref: "#/$defs/Identifier" + projectId: + $ref: "#/$defs/Identifier" + title: + $ref: "#/$defs/NonEmptyText" + request: + $ref: "#/$defs/NonEmptyText" + summary: + $ref: "#/$defs/NonEmptyText" + status: + enum: [draft, discussing, ready, decided, withdrawn] + objectiveRefs: + type: array + uniqueItems: true + items: + $ref: "#/$defs/ExactEntityReference" + evidenceRefs: + type: array + uniqueItems: true + items: + $ref: "#/$defs/ExactEntityReference" + discussionRef: + $ref: "#/$defs/ExactEntityReference" + executionPlan: + $ref: "#/$defs/ExecutionPlan" + allOf: + - if: + type: object + properties: + status: + enum: [ready, decided] + required: [status] + then: + type: object + required: [summary, executionPlan] + properties: + executionPlan: + type: object + properties: + workItems: + type: array + items: + type: object + required: [estimate] + allOf: + - if: + properties: + review: + const: required + required: [review] + then: + required: [reviewEstimate] + additionalProperties: false + + Question: + # Open questions become graph conditions until answered or withdrawn. + type: object + required: [schemaVersion, id, projectId, subjectRef, question, status, askedAt] + properties: + schemaVersion: + const: treeseed.question/v1 + id: + $ref: "#/$defs/Identifier" + projectId: + $ref: "#/$defs/Identifier" + subjectRef: + $ref: "#/$defs/ExactEntityReference" + question: + $ref: "#/$defs/NonEmptyText" + status: + enum: [open, answered, withdrawn] + addressedTo: + type: array + uniqueItems: true + items: + $ref: "#/$defs/AgentClass" + answer: + type: string + minLength: 1 + answerRefs: + type: array + uniqueItems: true + items: + $ref: "#/$defs/ExactEntityReference" + askedAt: + $ref: "#/$defs/Timestamp" + answeredAt: + $ref: "#/$defs/Timestamp" + allOf: + - if: + type: object + properties: + status: + const: answered + required: [status] + then: + type: object + anyOf: + - type: object + required: [answer] + - type: object + required: [answerRefs] + additionalProperties: false + + Note: + # Review findings and workday reports are classifications of this core model. + type: object + required: [schemaVersion, id, projectId, classification, subjectRefs, body, createdAt] + properties: + schemaVersion: + const: treeseed.note/v1 + id: + $ref: "#/$defs/Identifier" + projectId: + $ref: "#/$defs/Identifier" + classification: + enum: [general, feedback, research, workday-report] + subjectRefs: + type: array + minItems: 1 + uniqueItems: true + items: + $ref: "#/$defs/ExactEntityReference" + body: + $ref: "#/$defs/NonEmptyText" + links: + type: array + items: + type: object + required: [relation, from, to] + properties: + relation: + const: depends_on + from: + $ref: "#/$defs/ExactWorkItemReference" + to: + $ref: "#/$defs/ExactWorkItemReference" + additionalProperties: false + createdAt: + $ref: "#/$defs/Timestamp" + allOf: + # A workday report must cite its exact PostgreSQL workday record. Its other + # subject refs cite results, usage, releases, and publications summarized. + - if: + type: object + properties: + classification: + const: workday-report + required: [classification] + then: + type: object + properties: + subjectRefs: + type: array + contains: + type: object + required: [store, model] + properties: + store: + const: postgresql + model: + const: workday + additionalProperties: false + + Decision: + # Class selects governance; subjectRef binds disposition to exact evidence. + type: object + required: + - schemaVersion + - id + - projectId + - decisionClass + - decisionMethod + - subjectRef + - disposition + - rationale + - authorityRefs + - decidedByRefs + - decidedAt + properties: + schemaVersion: + const: treeseed.decision/v1 + id: + $ref: "#/$defs/Identifier" + projectId: + $ref: "#/$defs/Identifier" + decisionClass: + $ref: "#/$defs/DecisionClass" + decisionMethod: + # Classes define semantics; method records how authority was exercised. + enum: [authority, approval, vote] + subjectRef: + $ref: "#/$defs/ExactEntityReference" + disposition: + $ref: "#/$defs/DecisionDisposition" + rationale: + $ref: "#/$defs/NonEmptyText" + findingRefs: + type: array + uniqueItems: true + items: + $ref: "#/$defs/ExactEntityReference" + authorityRefs: + type: array + minItems: 1 + uniqueItems: true + items: + $ref: "#/$defs/ExactEntityReference" + decidedByRefs: + type: array + minItems: 1 + uniqueItems: true + items: + $ref: "#/$defs/ExactEntityReference" + positions: + type: array + minItems: 1 + items: + $ref: "#/$defs/DecisionPosition" + decidedAt: + $ref: "#/$defs/Timestamp" + allOf: + - if: + type: object + properties: + decisionMethod: + enum: [approval, vote] + required: [decisionMethod] + then: + type: object + required: [positions] + - if: + type: object + properties: + decisionClass: + const: work-review + required: [decisionClass] + then: + type: object + properties: + disposition: + enum: [approved, request-changes] + - if: + type: object + properties: + decisionClass: + const: proposal + required: [decisionClass] + then: + type: object + properties: + disposition: + enum: [approved, rejected, deferred, superseded] + - if: + type: object + properties: + decisionClass: + const: publication + required: [decisionClass] + then: + type: object + properties: + disposition: + enum: [approved, rejected, deferred, superseded] + additionalProperties: false + + # --------------------------------------------------------------------------- + # TreeDX service custody records + # --------------------------------------------------------------------------- + + TreeDxWorkspace: + # Storage: TreeDX service metadata. A governed mutable content workspace. + type: object + required: + - schemaVersion + - id + - teamId + - projectId + - repository + - baseCommit + - headCommit + - assignmentId + - status + - createdAt + properties: + schemaVersion: + const: treeseed.treedx-workspace/v1 + id: + $ref: "#/$defs/Identifier" + teamId: + $ref: "#/$defs/Identifier" + projectId: + $ref: "#/$defs/Identifier" + repository: + type: string + minLength: 1 + baseCommit: + $ref: "#/$defs/GitCommit" + headCommit: + $ref: "#/$defs/GitCommit" + assignmentId: + $ref: "#/$defs/Identifier" + status: + enum: [open, submitted, accepted, rejected, abandoned] + createdAt: + $ref: "#/$defs/Timestamp" + submittedAt: + $ref: "#/$defs/Timestamp" + closedAt: + $ref: "#/$defs/Timestamp" + additionalProperties: false + + TreeDxWorkspaceReview: + # Records governance over an exact TreeDX candidate; not a content model. + type: object + required: + - schemaVersion + - id + - workspaceId + - candidateCommit + - decisionRef + - status + - decidedAt + properties: + schemaVersion: + const: treeseed.treedx-workspace-review/v1 + id: + $ref: "#/$defs/Identifier" + workspaceId: + $ref: "#/$defs/Identifier" + candidateCommit: + $ref: "#/$defs/GitCommit" + decisionRef: + $ref: "#/$defs/ExactEntityReference" + status: + enum: [approved, request-changes] + decidedAt: + $ref: "#/$defs/Timestamp" + additionalProperties: false + + TreeDxPublicationReceipt: + # Exact read-back evidence after an approved publication operation. + type: object + required: + - schemaVersion + - id + - projectId + - repository + - sourceCommit + - publishedCommit + - destination + - decisionRef + - publishedAt + properties: + schemaVersion: + const: treeseed.treedx-publication-receipt/v1 + id: + $ref: "#/$defs/Identifier" + projectId: + $ref: "#/$defs/Identifier" + repository: + type: string + minLength: 1 + sourceCommit: + $ref: "#/$defs/GitCommit" + publishedCommit: + $ref: "#/$defs/GitCommit" + destination: + type: string + minLength: 1 + url: + type: string + format: uri + decisionRef: + $ref: "#/$defs/ExactEntityReference" + publishedAt: + $ref: "#/$defs/Timestamp" + additionalProperties: false + + # --------------------------------------------------------------------------- + # Shared operational value objects + # --------------------------------------------------------------------------- + + RepositoryBinding: + type: object + required: [repository, defaultBranch] + properties: + repository: + type: string + minLength: 1 + defaultBranch: + type: string + minLength: 1 + additionalProperties: false + + TreeDxBinding: + type: object + required: [repository, collection, protectedRef] + properties: + repository: + type: string + minLength: 1 + collection: + type: string + minLength: 1 + protectedRef: + type: string + minLength: 1 + additionalProperties: false + + WeightMap: + type: object + minProperties: 1 + additionalProperties: + type: integer + minimum: 1 + + ProjectWeight: + type: object + required: [projectId, weight] + properties: + projectId: + $ref: "#/$defs/Identifier" + weight: + type: integer + minimum: 1 + additionalProperties: false + + AgentClassWeight: + type: object + required: [agentClass, weight] + properties: + agentClass: + $ref: "#/$defs/AgentClass" + weight: + type: integer + minimum: 1 + additionalProperties: false + + WorkdayPolicyFields: + # Embedded in Workday as a snapshot so later policy edits cannot alter history. + type: object + required: + - durationSeconds + - maximumConcurrency + - planningPercent + - allocationWeight + - planningTurnMaximumSeconds + - communicationConcurrency + - projectPercentages + - agentClassPercentages + properties: + durationSeconds: + $ref: "#/$defs/PositiveSeconds" + maximumConcurrency: + type: integer + minimum: 1 + planningTurnMaximumSeconds: + $ref: "#/$defs/PositiveSeconds" + planningPercent: + type: number + minimum: 0 + maximum: 100 + default: 20 + allocationWeight: + type: number + exclusiveMinimum: 0 + default: 1 + communicationConcurrency: + type: integer + minimum: 1 + projectPercentages: + type: object + additionalProperties: + type: number + exclusiveMinimum: 0 + agentClassPercentages: + type: object + additionalProperties: + type: object + additionalProperties: + type: number + exclusiveMinimum: 0 + additionalProperties: false + + AvailabilityWindow: + type: object + required: [startsAt, endsAt] + properties: + startsAt: + $ref: "#/$defs/Timestamp" + endsAt: + $ref: "#/$defs/Timestamp" + additionalProperties: false + + NativeLimit: + # Provider-specific finite limits stay supply facts, not scheduling policy. + type: object + required: [name, unit, maximum] + properties: + name: + $ref: "#/$defs/Identifier" + unit: + $ref: "#/$defs/Identifier" + maximum: + type: number + exclusiveMinimum: 0 + additionalProperties: false + + PlanningRound: + type: object + required: [round, state, assignmentIds] + properties: + round: + type: integer + minimum: 1 + state: + enum: [pending, active, complete] + assignmentIds: + type: array + uniqueItems: true + items: + $ref: "#/$defs/Identifier" + startedAt: + $ref: "#/$defs/Timestamp" + completedAt: + $ref: "#/$defs/Timestamp" + additionalProperties: false + + GraphChangeSet: + # Compact audit summary; node and edge tables remain the state authority. + type: object + required: [added, changed, completed, blocked, stale, removedEdges, addedEdges] + properties: + added: + type: array + uniqueItems: true + items: + $ref: "#/$defs/Identifier" + changed: + type: array + uniqueItems: true + items: + $ref: "#/$defs/Identifier" + completed: + type: array + uniqueItems: true + items: + $ref: "#/$defs/Identifier" + blocked: + type: array + uniqueItems: true + items: + $ref: "#/$defs/Identifier" + stale: + type: array + uniqueItems: true + items: + $ref: "#/$defs/Identifier" + addedEdges: + type: array + uniqueItems: true + items: + $ref: "#/$defs/Identifier" + removedEdges: + type: array + uniqueItems: true + items: + $ref: "#/$defs/Identifier" + additionalProperties: false + + ReadOnlyWorkspace: + type: object + required: [mode] + properties: + mode: + const: read-only + additionalProperties: false + + TreeDxAssignmentWorkspace: + type: object + required: [mode, workspaceId, repository, baseCommit, writablePaths] + properties: + mode: + const: treedx + workspaceId: + $ref: "#/$defs/Identifier" + repository: + type: string + minLength: 1 + baseCommit: + $ref: "#/$defs/GitCommit" + writablePaths: + type: array + minItems: 1 + uniqueItems: true + items: + type: string + minLength: 1 + additionalProperties: false + + GitAssignmentWorkspace: + type: object + required: [mode, repository, baseCommit, branch, writablePaths] + properties: + mode: + const: git + repository: + type: string + minLength: 1 + baseCommit: + $ref: "#/$defs/GitCommit" + branch: + type: string + minLength: 1 + writablePaths: + type: array + minItems: 1 + uniqueItems: true + items: + type: string + minLength: 1 + additionalProperties: false + + AssignmentWorkspace: + oneOf: + - $ref: "#/$defs/ReadOnlyWorkspace" + - $ref: "#/$defs/TreeDxAssignmentWorkspace" + - $ref: "#/$defs/GitAssignmentWorkspace" + + AssignmentLimits: + type: object + required: [maximumSeconds, maximumContextBytes, maximumContextItems] + properties: + maximumSeconds: + $ref: "#/$defs/PositiveSeconds" + maximumContextBytes: + type: integer + minimum: 1 + maximumContextTokens: + type: integer + minimum: 1 + maximumContextItems: + type: integer + minimum: 1 + additionalProperties: false + + VerificationRecord: + type: object + required: [command, status, exitCode, outputDigest] + properties: + command: + $ref: "#/$defs/NonEmptyText" + status: + enum: [passed, failed, skipped] + exitCode: + type: integer + outputDigest: + $ref: "#/$defs/Sha256Digest" + durationSeconds: + $ref: "#/$defs/NonNegativeSeconds" + additionalProperties: false + + AssignmentTimingAwarenessReceipt: + type: object + required: [schemaVersion, requiredChecks, completedChecks, firstTool, + firstToolSucceeded, lastTool, lastToolSucceeded, firstToolCompliant, finalToolCompliant] + properties: + schemaVersion: {const: treeseed.assignment-timing-awareness/v1} + requiredChecks: {const: 2} + completedChecks: {type: integer, minimum: 2} + firstTool: {const: 'treedx:treeseed_time_status'} + firstToolSucceeded: {const: true} + lastTool: {const: 'treedx:treeseed_time_status'} + lastToolSucceeded: {const: true} + firstToolCompliant: {const: true} + finalToolCompliant: {const: true} + additionalProperties: false + + Usage: + # Attempt-local observed usage. Settlement is a separate exactly-once record. + type: object + required: [elapsedSeconds] + properties: + elapsedSeconds: + $ref: "#/$defs/NonNegativeSeconds" + modelInputTokens: + type: integer + minimum: 0 + modelOutputTokens: + type: integer + minimum: 0 + native: + type: object + additionalProperties: + type: number + minimum: 0 + additionalProperties: false + + Diagnostic: + type: object + required: [code, severity, message] + properties: + code: + $ref: "#/$defs/Identifier" + severity: + enum: [info, warning, error] + message: + $ref: "#/$defs/NonEmptyText" + ref: + $ref: "#/$defs/ExactEntityReference" + additionalProperties: false + + # --------------------------------------------------------------------------- + # PostgreSQL portfolio, provider, and workday records + # --------------------------------------------------------------------------- + + Team: + # Storage: PostgreSQL. Portfolio-level scheduling and isolation boundary. + type: object + required: [schemaVersion, id, slug, name, active] + properties: + schemaVersion: + const: treeseed.team/v1 + id: + $ref: "#/$defs/Identifier" + slug: + $ref: "#/$defs/Slug" + name: + $ref: "#/$defs/NonEmptyText" + active: + type: boolean + additionalProperties: false + + Project: + # Connects portfolio identity to exact Git and TreeDX custody boundaries. + type: object + required: [schemaVersion, id, teamId, slug, name, source, treeDx, active] + properties: + schemaVersion: + const: treeseed.project/v1 + id: + $ref: "#/$defs/Identifier" + teamId: + $ref: "#/$defs/Identifier" + slug: + $ref: "#/$defs/Slug" + name: + $ref: "#/$defs/NonEmptyText" + source: + $ref: "#/$defs/RepositoryBinding" + treeDx: + $ref: "#/$defs/TreeDxBinding" + active: + type: boolean + additionalProperties: false + + AgentRegistration: + # A team/project can schedule only an active, exact governed profile revision. + type: object + required: + - schemaVersion + - id + - teamId + - projectIds + - agentClass + - profileRef + - active + properties: + schemaVersion: + const: treeseed.agent-registration/v1 + id: + $ref: "#/$defs/Identifier" + teamId: + $ref: "#/$defs/Identifier" + projectIds: + type: array + minItems: 1 + uniqueItems: true + items: + $ref: "#/$defs/Identifier" + agentClass: + $ref: "#/$defs/AgentClass" + profileRef: + $ref: "#/$defs/ExactEntityReference" + active: + type: boolean + additionalProperties: false + + WorkdayIntent: + # Manual and recurring workdays use this one high-level input; resolved Workday owns mode and policy. + type: object + required: [schemaVersion, teamId, profileId, projects, startsAt] + allOf: + - if: {required: [continueFromWorkdayId]} + then: + required: [decisionIds] + not: + anyOf: + - required: [proposalIds] + - required: [planningOnly] + properties: {planningOnly: {const: true}} + properties: + schemaVersion: {const: treeseed.workday-intent/v1} + teamId: {$ref: "#/$defs/Identifier"} + profileId: {$ref: "#/$defs/Identifier"} + projects: + oneOf: + - {const: all} + - {type: array, minItems: 1, uniqueItems: true, items: {$ref: "#/$defs/Identifier"}} + executionMode: {enum: [simulation, production], default: simulation} + startsAt: {$ref: "#/$defs/Timestamp"} + endsAt: {$ref: "#/$defs/Timestamp"} + durationSeconds: {$ref: "#/$defs/PositiveSeconds"} + planningOnly: {type: boolean} + objectiveFilters: {type: array, items: {$ref: "#/$defs/Identifier"}} + proposalIds: {type: array, minItems: 1, maxItems: 64, uniqueItems: true, items: {$ref: "#/$defs/Identifier"}} + decisionIds: {type: array, minItems: 1, maxItems: 64, uniqueItems: true, items: {$ref: "#/$defs/Identifier"}} + continueFromWorkdayId: + type: string + minLength: 1 + maxLength: 128 + pattern: '\S' + description: Explicit settled workday lineage; same team, mode, provider and selected decisions. Fresh simulations omit this field and reset attempts. + allocation: + type: object + properties: + planningPercent: {$ref: "#/$defs/WorkdayPolicyFields/properties/planningPercent"} + allocationWeight: {$ref: "#/$defs/WorkdayPolicyFields/properties/allocationWeight"} + planningTurnMaximumSeconds: {$ref: "#/$defs/WorkdayPolicyFields/properties/planningTurnMaximumSeconds"} + projectPercentages: {$ref: "#/$defs/WorkdayPolicyFields/properties/projectPercentages"} + agentClassPercentages: {$ref: "#/$defs/WorkdayPolicyFields/properties/agentClassPercentages"} + additionalProperties: false + agentSelection: + type: object + anyOf: [{required: [agentSlugs]}, {required: [activityTypes]}, {required: [classIds]}, {required: [classSlugs]}] + properties: + agentSlugs: {type: array, minItems: 1, items: {$ref: "#/$defs/Identifier"}} + activityTypes: {type: array, minItems: 1, items: {enum: [planning, estimating, reviewing, reporting, chat]}} + classIds: {type: array, minItems: 1, items: {$ref: "#/$defs/Identifier"}} + classSlugs: {type: array, minItems: 1, items: {$ref: "#/$defs/Identifier"}} + mode: {const: intersection} + additionalProperties: false + operatorConstraints: + type: object + properties: + providerIds: {type: array, uniqueItems: true, items: {$ref: "#/$defs/Identifier"}} + maxConcurrency: {type: integer, minimum: 1} + additionalProperties: false + not: {required: [endsAt, durationSeconds]} + additionalProperties: false + + WorkdaySchedule: + # A recurrence stores canonical intent, never an alternate allocator or a manual reservation budget. + type: object + required: [id, teamId, status, purpose, cadenceSeconds, intent, lastRunId, nextRunAt, stateVersion, createdAt, updatedAt] + properties: + id: {$ref: "#/$defs/Identifier"} + teamId: {$ref: "#/$defs/Identifier"} + status: {enum: [active, paused, completed, failed]} + purpose: {type: string} + cadenceSeconds: {type: integer, minimum: 60} + intent: {$ref: "#/$defs/WorkdayIntent"} + lastRunId: {type: [string, "null"]} + nextRunAt: {$ref: "#/$defs/Timestamp"} + stateVersion: {type: integer, minimum: 1} + createdAt: {$ref: "#/$defs/Timestamp"} + updatedAt: {$ref: "#/$defs/Timestamp"} + additionalProperties: false + + WorkdayPolicy: + # The team's single default policy, stored with team metadata and snapshotted by workdays. + type: object + required: [id, teamId, revision, policy] + properties: + id: + const: default + teamId: + $ref: "#/$defs/Identifier" + revision: + type: integer + minimum: 1 + policy: + $ref: "#/$defs/WorkdayPolicyFields" + additionalProperties: false + + ProviderOffer: + # Versioned supply contract; providers describe runtime, not agent behavior. + type: object + required: + - schemaVersion + - id + - providerId + - revision + - runtimeBuild + - capabilities + - toolGroups + - maximumConcurrency + - availability + - nativeLimits + - validFrom + properties: + schemaVersion: + const: treeseed.provider-offer/v1 + id: + $ref: "#/$defs/Identifier" + providerId: + $ref: "#/$defs/Identifier" + revision: + type: integer + minimum: 1 + runtimeBuild: + $ref: "#/$defs/Sha256Digest" + capabilities: + type: array + uniqueItems: true + items: + $ref: "#/$defs/Identifier" + toolGroups: + type: array + uniqueItems: true + items: + $ref: "#/$defs/ToolGroup" + maximumConcurrency: + type: integer + minimum: 1 + availability: + type: array + minItems: 1 + items: + $ref: "#/$defs/AvailabilityWindow" + nativeLimits: + type: array + items: + $ref: "#/$defs/NativeLimit" + validFrom: + $ref: "#/$defs/Timestamp" + validUntil: + $ref: "#/$defs/Timestamp" + additionalProperties: false + + ProviderState: + # Mutable observed supply state, separate from the versioned offer. + type: object + required: + - schemaVersion + - providerId + - offerId + - healthy + - activeAssignmentIds + - observedNativeUsage + - observedAt + properties: + schemaVersion: + const: treeseed.provider-state/v1 + providerId: + $ref: "#/$defs/Identifier" + offerId: + $ref: "#/$defs/Identifier" + healthy: + type: boolean + activeAssignmentIds: + type: array + uniqueItems: true + items: + $ref: "#/$defs/Identifier" + observedNativeUsage: + type: object + additionalProperties: + type: number + minimum: 0 + observedAt: + $ref: "#/$defs/Timestamp" + additionalProperties: false + + Workday: + # Applied plan plus lifecycle; it is not a frozen work graph. + type: object + required: + - schemaVersion + - id + - teamId + - executionMode + - policyId + - policyRevision + - policySnapshot + - state + - startsAt + - endsAt + - planningRounds + - admittedSecondsByProject + - admittedSecondsByAgentClass + properties: + schemaVersion: + const: treeseed.workday/v1 + id: + $ref: "#/$defs/Identifier" + teamId: + $ref: "#/$defs/Identifier" + executionMode: + enum: [simulation, production] + policyId: + $ref: "#/$defs/Identifier" + policyRevision: + type: integer + minimum: 1 + policySnapshot: + $ref: "#/$defs/WorkdayPolicyFields" + state: + enum: [planned, active, closing, ended] + startsAt: + $ref: "#/$defs/Timestamp" + endsAt: + $ref: "#/$defs/Timestamp" + planningRounds: + type: array + items: + $ref: "#/$defs/PlanningRound" + admittedSecondsByProject: + type: object + additionalProperties: + $ref: "#/$defs/NonNegativeSeconds" + admittedSecondsByAgentClass: + type: object + additionalProperties: + $ref: "#/$defs/NonNegativeSeconds" + activatedAt: + $ref: "#/$defs/Timestamp" + closingAt: + $ref: "#/$defs/Timestamp" + endedAt: + $ref: "#/$defs/Timestamp" + reportRef: + # One exact committed closeout note, never a per-project report map. + $ref: "#/$defs/TreeDxReference" + allOf: + - if: + required: [state] + properties: + state: {const: ended} + then: + required: [reportRef] + additionalProperties: false + + # --------------------------------------------------------------------------- + # PostgreSQL living graph, assignments, and accounting + # --------------------------------------------------------------------------- + + ConditionDefinition: + # Conditions are deterministic projections of governed or lifecycle state. + type: object + required: [conditionType, subjectRef, expectedState] + properties: + conditionType: + enum: [question, external, authority, lifecycle] + subjectRef: + $ref: "#/$defs/ExactEntityReference" + expectedState: + $ref: "#/$defs/Identifier" + additionalProperties: false + + GraphRevision: + # Append-only revision, reconciliation receipt, audit summary, and watch cursor. + type: object + required: + - schemaVersion + - teamId + - revision + - ruleRevision + - changedSourceRefs + - graphDigest + - changes + - createdAt + properties: + schemaVersion: + const: treeseed.graph-revision/v1 + teamId: + $ref: "#/$defs/Identifier" + revision: + type: integer + minimum: 1 + ruleRevision: + type: integer + minimum: 1 + changedSourceRefs: + type: array + minItems: 1 + uniqueItems: true + items: + $ref: "#/$defs/ExactEntityReference" + graphDigest: + $ref: "#/$defs/Sha256Digest" + changes: + $ref: "#/$defs/GraphChangeSet" + createdAt: + $ref: "#/$defs/Timestamp" + additionalProperties: false + + ExecutionNode: + # Edges, active assignment IDs, and derived explanations are not duplicated here. + type: object + required: + - schemaVersion + - id + - teamId + - projectId + - kind + - pairRole + - sourceRef + - ruleRevision + - nodeRevision + - status + - graphRevisionCreated + - graphRevisionUpdated + properties: + schemaVersion: + const: treeseed.execution-node/v1 + id: + $ref: "#/$defs/Identifier" + teamId: + $ref: "#/$defs/Identifier" + projectId: + $ref: "#/$defs/Identifier" + workdayId: + $ref: "#/$defs/Identifier" + workItemId: + $ref: "#/$defs/Slug" + kind: + $ref: "#/$defs/ExecutionKind" + pairRole: + type: [string, "null"] + enum: [actor, reviewer, null] + sourceRef: + $ref: "#/$defs/ExactEntityReference" + authorityRefs: + type: array + uniqueItems: true + items: + $ref: "#/$defs/ExactEntityReference" + ruleRevision: + type: integer + minimum: 1 + nodeRevision: + type: integer + minimum: 1 + agentClass: + $ref: "#/$defs/AgentClass" + status: + enum: [proposed, blocked, ready, assigned, running, completed, failed, cancelled, stale] + estimate: + $ref: "#/$defs/Estimate" + requiredCapabilities: + type: array + uniqueItems: true + items: + $ref: "#/$defs/Identifier" + requestedPermissions: + $ref: "#/$defs/PermissionSet" + workspace: + $ref: "#/$defs/WorkspaceMode" + acceptanceCriteria: + type: array + minItems: 1 + items: + $ref: "#/$defs/NonEmptyText" + maximumReviewCycles: + type: integer + minimum: 1 + condition: + $ref: "#/$defs/ConditionDefinition" + graphRevisionCreated: + type: integer + minimum: 1 + graphRevisionUpdated: + type: integer + minimum: 1 + priority: *canonicalWorkPriority + allOf: + - if: + type: object + properties: + kind: + const: condition + required: [kind] + then: + type: object + required: [condition] + not: + type: object + anyOf: + - type: object + required: [agentClass] + - type: object + required: [estimate] + - type: object + required: [requestedPermissions] + - type: object + required: [workspace] + - if: + type: object + properties: + kind: + not: + const: condition + required: [kind] + then: + type: object + required: + - agentClass + - estimate + - requiredCapabilities + - requestedPermissions + - workspace + - if: + type: object + properties: + pairRole: + enum: [actor, reviewer] + required: [pairRole] + then: + type: object + required: [workItemId, maximumReviewCycles] + additionalProperties: false + + ExecutionEdge: + # Every dependency—profile, proposal, review pair, or condition—is one edge. + type: object + required: + - schemaVersion + - id + - teamId + - fromNodeId + - toNodeId + - provenance + - graphRevisionCreated + properties: + schemaVersion: + const: treeseed.execution-edge/v1 + id: + $ref: "#/$defs/Identifier" + teamId: + $ref: "#/$defs/Identifier" + fromNodeId: + $ref: "#/$defs/Identifier" + toNodeId: + $ref: "#/$defs/Identifier" + provenance: + enum: [profile-agent, profile-event, work-item, review-pair, governance, treedx-link] + sourceRef: + $ref: "#/$defs/ExactEntityReference" + graphRevisionCreated: + type: integer + minimum: 1 + graphRevisionRemoved: + type: integer + minimum: 1 + additionalProperties: false + + ProviderOfferSelection: + type: object + required: [providerId, offerId, executionProviderId, modelConfigurationId, executionCapabilityId, offerRevision, runtimeBuild] + properties: + providerId: + $ref: "#/$defs/Identifier" + offerId: + $ref: "#/$defs/Identifier" + executionProviderId: + $ref: "#/$defs/Identifier" + modelConfigurationId: + $ref: "#/$defs/Identifier" + executionCapabilityId: + $ref: "#/$defs/Identifier" + offerRevision: + type: integer + minimum: 1 + runtimeBuild: + $ref: "#/$defs/Sha256Digest" + additionalProperties: false + + EffectiveActivityProfile: + # Frozen resolved profile—not a second editable profile authority. + type: object + required: + - profileRef + - activity + - handler + - handlerOrigin + - prompt + - permissionCeiling + properties: + profileRef: + $ref: "#/$defs/ExactEntityReference" + activity: + $ref: "#/$defs/ActivityName" + handler: + $ref: "#/$defs/Identifier" + handlerOrigin: + enum: [agent-package, project-runtime] + prompt: + $ref: "#/$defs/Prompt" + permissionCeiling: + $ref: "#/$defs/PermissionSet" + additionalContext: + type: array + uniqueItems: true + items: + $ref: "#/$defs/Identifier" + parameters: + type: object + additionalProperties: true + additionalProperties: false + + AssignmentAttempt: + # Immutable execution snapshot. Lifecycle timestamps/status advance on this row; + # its authority, context, build, limits, and workspace never change. + type: object + required: + - schemaVersion + - id + - idempotencyKey + - teamId + - projectId + - workdayId + - nodeId + - agentClass + - nodeRevision + - graphRevision + - sourceRef + - authorityRefs + - effectiveProfile + - requiredCapabilities + - grant + - provider + - contextRefs + - predecessorResultIds + - workspace + - estimate + - limits + - deadline + - leaseId + - reservationId + - attempt + - status + - createdAt + properties: + schemaVersion: + const: treeseed.assignment-attempt/v1 + id: + $ref: "#/$defs/Identifier" + idempotencyKey: + $ref: "#/$defs/Identifier" + teamId: + $ref: "#/$defs/Identifier" + projectId: + $ref: "#/$defs/Identifier" + workdayId: + $ref: "#/$defs/Identifier" + nodeId: + $ref: "#/$defs/Identifier" + workItemId: + $ref: "#/$defs/Identifier" + agentClass: + type: string + pattern: "^[a-z][a-z0-9-]*$" + nodeRevision: + type: integer + minimum: 1 + graphRevision: + type: integer + minimum: 1 + sourceRef: + $ref: "#/$defs/ExactEntityReference" + authorityRefs: + type: array + minItems: 1 + uniqueItems: true + items: + $ref: "#/$defs/ExactEntityReference" + effectiveProfile: + $ref: "#/$defs/EffectiveActivityProfile" + requiredCapabilities: + type: array + uniqueItems: true + items: + $ref: "#/$defs/Identifier" + grant: + $ref: "#/$defs/ExactGrant" + provider: + $ref: "#/$defs/ProviderOfferSelection" + contextRefs: + type: array + uniqueItems: true + items: + $ref: "#/$defs/ExactEntityReference" + predecessorResultIds: + type: array + uniqueItems: true + items: + $ref: "#/$defs/Identifier" + acceptanceCriteria: + type: array + minItems: 1 + items: + $ref: "#/$defs/NonEmptyText" + workspace: + $ref: "#/$defs/AssignmentWorkspace" + estimate: + $ref: "#/$defs/Estimate" + limits: + $ref: "#/$defs/AssignmentLimits" + deadline: + $ref: "#/$defs/Timestamp" + leaseId: + $ref: "#/$defs/Identifier" + reservationId: + $ref: "#/$defs/Identifier" + attempt: + type: integer + minimum: 1 + status: + enum: [created, leased, running, completed, blocked, failed, cancelled, expired] + createdAt: + $ref: "#/$defs/Timestamp" + startedAt: + $ref: "#/$defs/Timestamp" + finishedAt: + $ref: "#/$defs/Timestamp" + additionalProperties: false + + AuthorizedContextItem: + # Runtime envelope. The referenced record is validated by its own model before + # materialization; value is intentionally opaque to this transport wrapper. + type: object + required: [ref, mediaType, digest, value] + properties: + ref: + $ref: "#/$defs/ExactEntityReference" + mediaType: + type: string + minLength: 1 + digest: + $ref: "#/$defs/Sha256Digest" + value: true + additionalProperties: false + + AssignmentContext: + # API/provider-to-AgentKernel DTO. It reuses the immutable assignment instead + # of restating identity, authority, workspace, prompt, limits, or deadline. + type: object + required: [assignment, context, predecessorResults] + properties: + assignment: + $ref: "#/$defs/AssignmentAttempt" + context: + type: array + items: + $ref: "#/$defs/AuthorizedContextItem" + predecessorResults: + type: array + items: + $ref: "#/$defs/AssignmentResult" + additionalProperties: false + + Lease: + # Exclusive, renewable claim over one assignment attempt. + type: object + required: + - schemaVersion + - id + - assignmentId + - providerId + - state + - acquiredAt + - expiresAt + - revision + properties: + schemaVersion: + const: treeseed.lease/v1 + id: + $ref: "#/$defs/Identifier" + assignmentId: + $ref: "#/$defs/Identifier" + providerId: + $ref: "#/$defs/Identifier" + state: + enum: [active, released, expired, revoked] + acquiredAt: + $ref: "#/$defs/Timestamp" + expiresAt: + $ref: "#/$defs/Timestamp" + releasedAt: + $ref: "#/$defs/Timestamp" + revision: + type: integer + minimum: 1 + additionalProperties: false + + Reservation: + # Capacity reservation for exactly one attempt and its accepted estimate. + type: object + required: + - schemaVersion + - id + - assignmentId + - workdayId + - providerId + - estimatedSeconds + - state + - reservedAt + properties: + schemaVersion: + const: treeseed.reservation/v1 + id: + $ref: "#/$defs/Identifier" + assignmentId: + $ref: "#/$defs/Identifier" + workdayId: + $ref: "#/$defs/Identifier" + providerId: + $ref: "#/$defs/Identifier" + estimatedSeconds: + $ref: "#/$defs/PositiveSeconds" + state: + enum: [held, consumed, released, expired] + reservedAt: + $ref: "#/$defs/Timestamp" + closedAt: + $ref: "#/$defs/Timestamp" + additionalProperties: false + + AssignmentResult: + # One result for every Handler. References carry products and handoffs. + type: object + required: + - schemaVersion + - id + - assignmentId + - status + - summary + - references + - verification + - usage + - diagnostics + - completedAt + properties: + schemaVersion: + const: treeseed.assignment-result/v1 + id: + $ref: "#/$defs/Identifier" + assignmentId: + $ref: "#/$defs/Identifier" + status: + enum: [completed, blocked, failed] + summary: + $ref: "#/$defs/NonEmptyText" + references: + type: array + uniqueItems: true + items: + $ref: "#/$defs/AssignmentReference" + verification: + type: array + items: + $ref: "#/$defs/VerificationRecord" + usage: + $ref: "#/$defs/Usage" + diagnostics: + type: array + items: + $ref: "#/$defs/Diagnostic" + timingAwareness: + $ref: "#/$defs/AssignmentTimingAwarenessReceipt" + completedAt: + $ref: "#/$defs/Timestamp" + additionalProperties: false + + UsageSettlement: + # Exactly-once accounting. Fairness uses actualSeconds; native usage remains + # distinct because providers expose different units and limits. + type: object + required: + - schemaVersion + - id + - idempotencyKey + - assignmentId + - reservationId + - workdayId + - teamId + - projectId + - agentClass + - providerId + - actualSeconds + - nativeUsage + - settledAt + properties: + schemaVersion: + const: treeseed.usage-settlement/v1 + id: + $ref: "#/$defs/Identifier" + idempotencyKey: + $ref: "#/$defs/Identifier" + assignmentId: + $ref: "#/$defs/Identifier" + reservationId: + $ref: "#/$defs/Identifier" + workdayId: + $ref: "#/$defs/Identifier" + teamId: + $ref: "#/$defs/Identifier" + projectId: + $ref: "#/$defs/Identifier" + agentClass: + $ref: "#/$defs/AgentClass" + providerId: + $ref: "#/$defs/Identifier" + actualSeconds: + $ref: "#/$defs/NonNegativeSeconds" + nativeUsage: + type: object + additionalProperties: + type: number + minimum: 0 + cost: + type: number + minimum: 0 + currency: + type: string + pattern: "^[A-Z]{3}$" + settledAt: + $ref: "#/$defs/Timestamp" + additionalProperties: false diff --git a/docs/dev-release.md b/docs/dev-release.md new file mode 100644 index 00000000..6ebf5faa --- /dev/null +++ b/docs/dev-release.md @@ -0,0 +1,736 @@ +# Development and Platform Release Architecture + +## Status and purpose + +This document defines the target architecture for fast local development, candidate verification, independent project release, Platform composition, and managed-host activation across TreeSeed projects. + +It complements [Standards-Based Independent Development](./standards-dev.md), [Reconciliation Platform](./reconciliation-platform.md), [Package Ownership](./package-ownership.md), and Deployment's [host architecture](../packages/deployment/docs/architecture.md). Where an older document requires Git-source staging, sibling source propagation, or a full published release before interactive testing, this document and `standards-dev.md` supersede that requirement. + +TreeSeed must support two needs without weakening either one: + +1. developers need a fast, real-time loop for API, UI, library, agent, and background-process work; and +2. operators need immutable, digest-bound releases that the Platform manager can verify, activate, repeat, roll back, and promote. + +The development system is therefore an input to the release system, not an alternative release system. A live development session may prove that an idea works. Only frozen candidate artifacts and an accepted Platform composition may prove that a release works. + +## Goals + +- Preserve independently owned repositories, contracts, versions, builds, tests, and releases. +- Allow UI changes to reach a browser in seconds without publishing npm packages or container images. +- Allow an API and its UI consumer to be developed together against real authentication, account, team, and application state. +- Allow agents and background processes to be compiled locally and exercised through safe drain, restart, and health boundaries. +- Keep stable hostnames, API connections, OAuth callbacks, cookies, Mailpit links, and managed service dependencies while selected components run from local source. +- Let SDK, UI, Core, and similar libraries update live consumers without treating incomplete build output as valid. +- Convert a successful development closure into immutable candidate packages and images without changing its source. +- Retain standards contract comparison, package acceptance, integrated guarantees, exact artifact selection, rollback, and promotion as release gates. +- Restore the last known-good managed composition automatically when a development session ends or fails. + +## Non-goals + +- Development mode is not production deployment or staging promotion. +- A source mount, workspace link, dirty worktree, hot reload, fixture, or successful process is not release evidence. +- The manager does not become the build or version owner for member projects. +- Platform does not fetch writable project source on behalf of a development session. +- Development Compose files do not replace packaged production Compose bundles. +- The development system does not bypass API authority, OAuth policy, database migration review, assignment leases, provider capacity, or branch protection. +- Not every project needs a development container. Libraries normally publish watched package output rather than run a service. +- Hot reload is not required or permitted for runtimes whose correctness depends on process initialization, leases, durable cursors, or native state. + +## Architectural principles + +1. **One manager, two evidence classes.** The manager may coordinate both development and release runtimes, but it records them as different kinds of state. +2. **Project-owned recipes.** Each repository declares how it builds, watches, reloads, restarts, verifies, freezes, and cleans its development targets. +3. **Stable integration boundaries.** Hostnames, service identities, ports, connection IDs, authentication behavior, and API authority remain stable while an implementation changes underneath them. +4. **Smallest affected closure.** A change reloads or rebuilds only declared consumers and dependencies. +5. **Explicit reaction semantics.** Dependency edges declare `reload`, `restart`, `rebuild`, `stale`, or `manual`; the manager never assumes all dependents must restart. +6. **State is protected separately from code.** Live code replacement never implies an automatic database migration, assignment cancellation, or durable-state reset. +7. **Source is exploratory; artifacts are admissible.** Linked output can accelerate development, but cross-project verification uses packed packages, built images, or other immutable candidate artifacts. +8. **Same-origin development by default.** The manager preserves canonical local hostnames so OAuth, cookies, redirects, CORS, and browser security behavior remain representative. +9. **Fail closed and restore.** An invalid recipe, incomplete output, failed health gate, expired session, or unsafe replacement restores or retains the known-good release. +10. **Promotion never rebuilds.** The artifacts accepted from the frozen candidate closure are the artifacts published and selected by Platform. + +## The two planes + +### Development plane + +The development plane operates on a named, time-bounded session associated with explicit local repository worktrees. It may use: + +- file watching and incremental compilation; +- local package output; +- development-only Compose `build` directives; +- source mounts or synchronized source; +- hot module replacement; +- bounded process restart; +- locally built container images; +- disposable or cloned development state; +- focused tests and browser scenes. + +Every development runtime is visibly marked non-promotable until it is frozen. The manager records the worktree identity, source commit, dirty-state digest, recipe digest, dependency closure, active modes, endpoints, and health observations. + +### Release plane + +The release plane consumes only immutable artifacts: + +- npm tarballs with exact versions, integrity, and SHA-256; +- OCI images with immutable multi-platform digests; +- local-tool archives with SHA-256; +- normalized contract bundles and compatibility attestations; +- component manifests and production Compose files by exact URL and digest; +- Platform integration releases with exact artifact and component selections; +- signed Deployment catalogs and Debian packages. + +Production Compose bundles continue to reject source mounts, `build` directives, mutable image references, undeclared ports, and missing health gates. A development feature must never relax those checks in the release path. + +## Runtime modes + +Each selected development target has exactly one active mode: + +| Mode | Source | Typical use | Promotion status | +| --- | --- | --- | --- | +| `released` | Platform-selected immutable artifact | Normal managed operation and comparison baseline | Admissible | +| `candidate` | Locally built immutable package, image, archive, or executable with digest | Integrated testing before publication | Admissible after verification | +| `live` | Watched local source or generated output | Interactive development and exploratory design | Never admissible directly | + +A host may mix modes. For example: + +```text +SDK live package build +UI live package build +Core live package build +Admin live Astro service +API live Node service +Agent candidate manager/runner images +TreeDX released service image +Postgres released managed state service +``` + +Mode selection is per target, not per host. Unaffected components remain on the exact known-good release. + +## Development runtime federation contract + +Projects opt in through a versioned `development` section in `treeseed.package.yaml`. The SDK owns the portable schema. The project owns the declared commands, Compose file, build outputs, health behavior, and verification entrypoints. Deployment and the manager consume the schema without embedding project-specific rules. + +An illustrative manifest is: + +```yaml +development: + schemaVersion: treeseed.development-runtime/v1 + targets: + - id: package + kind: package-watch + command: npm run build:watch + ready: + kind: marker + path: dist/.treeseed-build-complete.json + outputs: + - path: dist + mediaType: application/vnd.treeseed.node-package + freeze: + command: npm pack --json + artifact: "*.tgz" + consumers: + admin: reload + api: rebuild + agent: rebuild + + - id: service + kind: compose-service + composeFile: deploy/compose.development.yml + composeService: admin + buildTarget: development + endpoint: + id: http + port: 4322 + canonicalAlias: admin.treeseed.localhost + healthPath: /healthz + reaction: hot-reload + dependencies: + - id: api + capability: control-plane-api + locality: either + statePolicy: stateless + freeze: + kind: oci-image + dockerfile: Dockerfile + target: production +``` + +The final schema must support: + +- stable target ID and kind; +- supported platforms and runtime requirements; +- source roots and ignored paths; +- setup, watch, build, start, stop, freeze, verify, and cleanup operations; +- development Compose identity when applicable; +- atomic build-completion markers; +- endpoints, aliases, health gates, and connection requirements; +- dependency reactions; +- state and migration policy; +- secret and file bindings by reference, never value; +- shutdown, drain, cancellation, and replacement behavior; +- artifact outputs and digest algorithms; +- timeout and resource bounds; +- log and diagnostic locations; +- forbidden operations and promotion constraints. + +Unknown target kinds, undeclared commands, ambiguous outputs, unsafe paths, missing health gates, or unsupported manager capabilities fail before runtime mutation. + +## Development target kinds + +### Package watch + +`package-watch` is intended for SDK, UI, Core, and other libraries. It runs an atomic incremental build and publishes completed output into a session-owned package overlay. + +The manager must not expose a half-written `dist` tree. A package watcher writes into a temporary generation, verifies required exports and its completion marker, and atomically selects that generation. Consumers observe only completed generations. + +There are two consumption levels: + +1. **exploratory link:** a consumer resolves the session package overlay for rapid reload; this is non-admissible preview state; and +2. **packed candidate:** the project freezes an npm tarball, records integrity and SHA-256, and the consumer installs that immutable candidate for verification. + +The existing Core build-aware watcher is the reference behavior: dependency output completion invalidates the transformed client and SSR module graph only after the build is stable. + +### Live web service + +`live-web` runs an application server with browser-oriented hot reload. Admin and other Astro applications use this target. + +The manager: + +- stops or disconnects the released service instance for the selected component; +- preserves the component's canonical local hostname; +- routes edge traffic to the development service; +- injects manager-resolved service connections and public runtime configuration; +- verifies the same readiness path used by the released component; +- watches dependency output and reloads only after completed builds; +- records that responses come from a live source closure; +- restores the released service when the development lease ends. + +Keeping `admin.treeseed.localhost` stable preserves the exact `treeseed-admin` OAuth callback, secure cookies, same-origin return paths, device verification URLs, email-confirmation links, and browser security policy. Development does not introduce a generic OAuth redirect exception. + +### Live API service + +`live-api` runs an API from watched source with bounded restart semantics. API processes may use Node watch, an application-owned supervisor, or a development container, but the manager retains the canonical API hostname and health contract. + +An API change may regenerate OpenAPI and catalog output automatically. Admin and CLI can then exercise the new endpoint without publishing an API image. A restart is accepted only after readiness succeeds. If readiness fails, the manager retains logs, reports the candidate as degraded, and restores the released API unless the session explicitly requests a debugging hold. + +Database schema changes follow the state policies below and never apply merely because a migration file changed. + +### Rebuild-and-restart service + +`rebuild-restart` is intended for Agent, operations runners, TreeDX, AI runtimes, and other processes whose initialization or durable protocol state makes hot reload unsafe. + +On source change or explicit rebuild, the manager: + +1. builds a local image or executable in the owning repository; +2. records the exact source closure and artifact digest; +3. checks replacement preconditions; +4. drains or stops the old runtime through its declared protocol; +5. activates the candidate; +6. verifies health, registration, provider availability, and other declared postconditions; +7. retains the prior immutable runtime for restoration. + +Agent replacement blocks while assignments or leases are active unless they complete, are safely transferred by a declared protocol, or an authorized user explicitly cancels them. A process kill is not a substitute for API-owned lease and settlement behavior. + +### Local companion + +`local-companion` covers Reviewer and similar loopback-only applications. It binds only to loopback, receives no managed public route, and may consume released or candidate CLI/SDK/UI packages. The manager may supervise lifecycle and logs without turning the companion into a hosted component. + +## Development Compose contract + +A service project may own `deploy/compose.development.yml` or another path declared in its manifest. Unlike production Compose, the development file may contain: + +- `build` with a development target; +- source mounts or synchronized source; +- development commands; +- debug ports explicitly marked loopback-only; +- development-only caches and disposable volumes; +- file-watch rules that map to reload or rebuild behavior. + +It must not contain: + +- reusable credentials or secret values; +- an undeclared host-wide port; +- access to the manager or root-supervisor control socket; +- the host Docker socket inside a project container; +- broad home-directory, workspace-root, credential-directory, or unrelated repository mounts; +- mutable production state volumes without an explicit shared-state policy; +- production aliases not granted by the manager session; +- commands outside the owning project's declared development operations. + +The manager materializes a session-specific Compose overlay with resolved networks, dependency endpoints, secrets, source paths, labels, and resource limits. Project Compose does not choose global networks or canonical aliases directly. + +Libraries normally do not have a development Compose file. A container is added only when it supplies a real runtime boundary, not to make every package look uniform. + +## Dependency graph and reactions + +The manager compiles development dependencies from produced and consumed standards, package dependencies, runtime component dependencies, and the active session selection. Every edge declares one reaction: + +| Reaction | Meaning | +| --- | --- | +| `reload` | Consumer can reload completed dependency output without process replacement. | +| `restart` | Consumer process must restart against the new dependency generation. | +| `rebuild` | Consumer artifact must be rebuilt before it can use the dependency. | +| `stale` | Consumer may keep running, but verification is invalid until refreshed. | +| `manual` | Change may be incompatible or operationally costly; report it and await selection. | +| `none` | Dependency change does not affect the selected runtime target. | + +The reaction is directional. A UI build may reload Admin without affecting API. An SDK TypeScript-only change may rebuild CLI while leaving a running API untouched. An SDK wire-contract change may mark API, Admin, CLI, and Agent stale without automatically restarting all of them. + +Cycles in build-time development dependencies remain forbidden. A detected cycle is a contract-ownership defect, not permission for recursive rebuilding. + +## Development sessions and leases + +A development session is the unit of ownership and cleanup. It contains: + +- session ID, actor, host, and creation/expiry time; +- repository identities, worktree paths, commits, and dirty-state digests; +- selected targets and modes; +- resolved dependency graph and reactions; +- endpoint and route leases; +- state policies and migration decisions; +- secret references and connection bindings; +- current build generations and candidate digests; +- health, logs, warnings, blockers, and restoration state. + +Only one session may own a canonical hostname or managed component target at a time. Additional sessions use explicit session aliases such as `admin..treeseed.localhost`, or remain loopback-only. Canonical alias ownership is acquired atomically before a released route changes. + +Leases are time-bounded and renewable. Expiry initiates safe detach and restoration. An active debugging hold may delay automatic restoration of a failed live process but may not keep an expired route, secret, or state lease. + +The manager continuously reconciles released components that are not leased. For a leased target it verifies the development session contract instead of fighting the local process. A development lease never pauses host security updates, unrelated components, or the manager itself. + +## Command model + +The CLI should expose project-neutral commands backed by the SDK development-session contract. Illustrative commands are: + +```bash +trsd dev session start +trsd dev use sdk=live ui=live core=live admin=live api=live +trsd dev use agent=candidate +trsd dev rebuild agent +trsd dev status --all --json +trsd dev logs --target admin --follow +trsd dev plan --affected --json +trsd dev freeze +trsd dev verify +trsd dev session stop --restore +``` + +Existing `trsd dev start --web-runtime local` behavior should converge on this session model rather than remain a separate supervisor. Target filters must compile the smallest dependency closure. Known behavior where an app-only restart selects unrelated TreeDX or provider resources must be corrected and regression-tested before it is used as the general development control plane. + +Every mutation follows the normal lifecycle: + +```text +refresh -> plan -> validate -> apply -> refresh -> verify -> persist +``` + +Human-readable output is derived from the same versioned JSON result returned to automation. + +## Routing, connectivity, and service identity + +The manager-owned edge remains the only owner of canonical local ingress. Development services register endpoints; they do not edit Caddy directly. + +When a released service is replaced by a live or candidate target: + +1. validate the development target and health contract; +2. start it on a session-scoped internal or loopback endpoint; +3. verify readiness directly; +4. atomically switch the canonical edge route; +5. verify readiness through the canonical hostname; +6. retain the released service and route data for restoration. + +Connections continue to resolve through component capability and endpoint IDs. For example, Admin's `api` dependency still becomes `TREESEED_API_BASE_URL`, whether API is released, candidate, live, local, or remote. Consumers must not branch on implementation mode. + +Databases, workers, runners, raw inference services, and control sockets remain private unless their contract explicitly declares a host endpoint. Development mode is not permission to publish them. + +## State and migration policies + +Code mode and state mode are independent selections. Stateful development targets declare one of: + +| Policy | Behavior | +| --- | --- | +| `stateless` | Target owns no durable state. | +| `ephemeral` | Create disposable state and destroy it on cleanup. | +| `clone` | Create a bounded development copy from an approved source. | +| `shared-compatible` | Use managed development state only while schema and mutation policies remain compatible. | +| `isolated-persistent` | Retain a session-owned state volume for repeated development. | + +`ephemeral` is the default for incompatible API schema work. `clone` is preferred when realistic account/team data is needed without risking the managed development database. `shared-compatible` is opt-in and requires: + +- no destructive or backward-incompatible migration; +- a declared schema compatibility range; +- migration plan and postcondition checks; +- backup/restore policy where material; +- proof that the released runtime can resume against the resulting state. + +A changed migration file marks the target blocked or migration-pending. It does not auto-apply to shared state. Migration apply remains a distinct, reviewed manager operation. + +API remains the durable owner of identity, teams, permissions, sessions, tokens, audit, capacity, assignments, and workdays in every mode. UI or Agent development never substitutes local browser or worker state for API records. + +## Secrets, authority, and isolation + +- Manifests name secret references but never contain secret values. +- The manager injects only secrets required by the selected target and removes bindings on detach. +- Browser JavaScript never receives API access tokens, refresh tokens, provider credentials, or manager credentials. +- Development Admin retains the production-shaped HttpOnly cookie and CSRF boundary. +- Development API and Agent runtimes receive no broader authorization than their released counterparts. +- Agent tools remain assignment-scoped; a locally built runner receives the same frozen authority and cancellation boundary as a released runner. +- Source mounts are read-only unless the target explicitly owns generated output beneath that repository. +- A development runtime cannot mount another repository merely because it consumes that project's contract. +- Root operations remain behind the fixed Deployment supervisor protocol. Project development commands run unprivileged and cannot introduce arbitrary root commands. +- Logs, status, receipts, and errors redact declared secret and credential paths. + +## Source closure and build generations + +A live source closure records: + +- canonical repository identity; +- current commit and branch; +- dirty path list and content digest without recording secret content; +- development manifest and recipe digest; +- dependency source or artifact generations; +- toolchain and runtime versions; +- generated output marker and digest; +- selected configuration digest. + +Dirty worktrees are allowed in `live` mode and forbidden as release evidence. A file event does not become a generation until the owning build completes and its output passes structural checks. Failed or interrupted builds retain the prior completed generation. + +The manager does not infer semantic compatibility from timestamps. It reports which consumers are reloaded, rebuilt, stale, or blocked for each new generation. + +## Package-specific development profiles + +### SDK + +- Kind: `package-watch`. +- Produces compiled public entrypoints, schemas, catalog output, and contract tooling. +- Pure implementation changes reload compatible consumers only where supported. +- Public contract changes mark declared consumers stale until compatibility comparison runs. +- Freeze produces an npm tarball and normalized contract bundle. + +### UI + +- Kind: `package-watch` plus its package-owned sandbox. +- The sandbox is the fastest loop for components, tokens, responsive states, accessibility, forced colors, and interaction. +- Completed UI output reloads Admin and other web consumers. +- Fixtures are presentation evidence only; integrated journeys still require a real consumer. +- Freeze produces an npm tarball, public-export contract, and presentation catalog. + +### Core + +- Kind: `package-watch` and reusable web runtime development support. +- Owns stable build-aware reload coordination for web consumers. +- May run fixture applications, but does not take ownership of Admin behavior. +- Freeze produces an npm tarball and site/plugin/runtime contract bundle. + +### Admin + +- Kind: `live-web`, using the managed Node runtime target. +- Retains `admin.treeseed.localhost`, port `4322`, `/healthz`, and the configured API connection. +- Consumes live or candidate SDK/UI/Core packages through the session overlay. +- May use the real managed API, an API candidate, or a live API target without changing browser route contracts. +- Freeze builds the standalone application, npm artifact, production image, SBOM, and component release assets. + +### API + +- Kind: `live-api` and `rebuild-restart` for production-shaped image testing. +- Retains API hostname, OAuth issuer, PostgreSQL authority, operations-runner relationship, and readiness path. +- Supports ephemeral, cloned, or explicitly compatible shared database state. +- Freeze builds exact API and operations-runner images, OpenAPI/event bundles, SBOMs, and component release assets. + +### CLI + +- Kind: `package-watch` or direct executable rebuild. +- The installed `trsd` launcher automatically selects the completed local CLI generation recorded by `trsd dev use` and falls back to the released CLI when that selection is absent, expired, or unreadable. +- Machine JSON schemas, exit statuses, confirmation behavior, and stdout/stderr boundaries remain contract-tested. +- Freeze produces the npm tarball and later the Deployment-qualified Debian payload. + +### Agent and background providers + +- Kind: `rebuild-restart`. +- Produces local manager and runner images by digest. +- Replacement requires drain and lease checks; no runtime hot patching. +- Verification includes provider registration, availability, assignment execution, terminal state, usage, settlement, and cleanup. +- Freeze produces multi-platform images, service contracts, SBOMs, and component release assets. + +### TreeDX + +- Kind: normally `rebuild-restart`; released mode remains suitable for unrelated development. +- A local candidate must retain product-neutral OpenAPI, storage, Git, graph, search, and health contracts. +- State policy is explicit because index and repository stores may outlive a process. +- Freeze produces image and client artifacts plus normalized OpenAPI/service contracts. + +### Reviewer + +- Kind: `local-companion` with optional UI watch. +- Remains loopback-only and never receives a public managed route. +- Consumes released or candidate CLI/SDK/UI packages. +- Freeze produces an immutable local-tool archive and checksum. + +## The three primary workflows + +### API and UI co-development + +1. Start a session with Admin and API in `live` mode. +2. Keep PostgreSQL, TreeDX, Agent, Mailpit, and edge on released managed components unless affected. +3. Select an explicit API state policy. +4. Edit the API operation and regenerate its local catalog/OpenAPI output. +5. Edit the Admin consumer and UI presentation. +6. Exercise registration, confirmation, OAuth, account, team, and application behavior through canonical hostnames. +7. Run focused API contract and Admin browser tests. +8. Freeze API and Admin independently when the interaction stabilizes. + +The flow allows a new endpoint to be tested before either project publishes. It does not permit Admin to import API implementation or invent an uncatalogued authority path. + +### Exploratory UI development + +1. Develop reusable presentation in the UI sandbox with fixtures. +2. Run UI in `live` package mode and Admin in `live-web` mode. +3. Let completed UI/Core builds reload Admin through the dependency watcher. +4. Use real API-backed pages when interaction, authorization, or state matters. +5. Run responsive, accessibility, console-error, and route smoke checks locally. +6. Freeze UI/Core packages and rebuild Admin against their exact tarballs. +7. Run packed-install and integrated browser verification before RC publication. + +Spacing, typography, layout, color, iconography, and exploratory unavailable/error states do not require releases. Public component/API changes do require contract comparison before freezing. + +### Agent and background-process development + +1. Keep API and durable state managed. +2. Build a local Agent or worker candidate. +3. Verify no unsafe active lease or assignment blocks replacement. +4. Drain and activate the candidate through the manager. +5. Run focused provider, assignment, workday, communication, terminal-state, usage, and settlement scenarios. +6. Inspect evidence through Admin and Reviewer where applicable. +7. Restore the released runtime or freeze the candidate for release verification. + +The manager never treats a successful container start as proof of assignment correctness. + +## Freeze: from live source to immutable candidate + +`trsd dev freeze` creates a candidate closure without changing source: + +1. acquire a session freeze lock; +2. wait for all selected builds to reach completed generations; +3. reject missing, unstable, secret-bearing, or undeclared output; +4. record exact repository commits and require an explicit dirty-worktree policy; +5. pack libraries and local tools; +6. build service and worker images; +7. calculate integrity and SHA-256/OCI digests; +8. generate normalized contract bundles; +9. compare accepted baselines and calculate minimum semantic bumps; +10. rebuild consumers against packed candidates where required; +11. emit `treeseed.development-candidate/v1` binding source, contracts, artifacts, configuration, and dependency generations. + +A candidate created from a dirty worktree may be tested, but publication requires the identical source tree to be committed, reviewed, and read back from the owning repository. The candidate receipt must prove that the committed tree reproduces the candidate artifacts before release. + +## Verification ladder + +Verification escalates in cost and authority: + +1. **static feedback:** formatter, typecheck, lint, schema generation; +2. **package tests:** unit, contract, accessibility, and focused behavior; +3. **live development checks:** health, local routes, browser interaction, focused real service calls; +4. **candidate acceptance:** clean install, packed artifact or exact image, public exports, SBOM, source closure; +5. **compatibility:** normalized comparison, semantic bump sufficiency, consumer-driven cases; +6. **integrated candidate composition:** smallest affected exact candidate/released artifact set; +7. **active guarantees:** live required outcomes against one immutable generation; +8. **published readback:** registry, release assets, image digests, component manifests; +9. **managed staging activation:** install, readiness, edge routing, no-op reconciliation, rollback; +10. **promotion:** accepted composition selected without rebuild. + +Failure at one level does not erase useful diagnostics from cheaper levels, but cheaper evidence cannot satisfy a more authoritative gate. + +Platform plans active guarantees from the guarantee catalog contained in the exact selected Admin tarball. It merges verifier registries in catalog order so a reviewed composition registry can supersede historical source-test references. Every selected verifier must name an artifact or catalog operation, its owning package, case, and safe entrypoint; artifact owners must also be exact host payloads in that composition. Planning fails when any owner or immutable binding is absent. + +`npm run guarantees:run` materializes every selected payload by URL and SHA-256 into an isolated package graph, executes each unique verifier artifact once, and maps its case results back to the selected guarantee closure. Runtime verifiers may execute inside their declared managed component container while static package verifiers execute locally from the packed graph. The runner writes an atomic `.treeseed/guarantees/runs/` bundle containing `plan.json`, `report.json`, `report.md`, and redacted verifier evidence. Reviewer consumes that bundle; it does not reconstruct source tests or claim evidence from branch state. + +## Independent RC release workflow + +TreeSeed uses independently versioned release candidates cut from each project's protected staging branch. + +For each changed project: + +1. adopt the frozen source and candidate evidence on a reviewed branch; +2. merge through the project release gate into staging; +3. compute the version from contract comparison rather than dependency position; +4. tag the RC from the exact staging commit; +5. publish the already-verified artifact under a prerelease channel; +6. verify registry/release/image readback and source binding; +7. publish component manifests and production Compose assets where applicable; +8. notify Platform of exact artifact metadata. + +Unchanged projects do not receive releases. A compatible upstream patch does not require a consumer commit when its declared range and tests admit the new version. + +The normal dependency order is: + +```text +SDK contracts + -> UI + -> Core and API + -> Admin, CLI, Agent, and Reviewer as affected + -> component releases + -> Deployment + -> pinned Platform composition +``` + +This is an adoption order, not a global version train. + +## Platform composition and managed activation + +Platform creates a `treeseed.integration-release/v1` from exact published artifacts. It records: + +- artifact name and exact version; +- immutable download URL and SHA-256; +- image repository and OCI digest; +- contract bundle and compatibility evidence; +- component release manifest and Compose asset digests; +- exact Platform and Deployment commits/tags; +- generation and compatibility ID. + +Deployment consumes an immutable Platform commit URL, verifies every selected payload, and publishes its catalog and Debian packages. The manager then: + +1. refreshes signed stable and compatible development catalogs; +2. plans the exact package/component transition; +3. validates storage, secrets, dependencies, migration, and rollback prerequisites; +4. archives material state when required; +5. installs exact Debian payloads; +6. activates exact production Compose bundles; +7. verifies component and edge readiness; +8. records a known-good receipt; +9. proves repeated reconciliation is `noop`. + +Manager self-updates use a two-phase handoff. A running manager may refresh and install the exact core package set, but once any core package changes it must stop that reconciliation before loading the new catalog or composing components. It schedules a bounded restart and the upgraded process performs planning and activation from the beginning. The stale process must never interpret a newer catalog, schema, component type, or rollback set. + +Component packages remain installable across that handoff. Their package installation creates the manager-owned component configuration directory and a non-overwriting environment file before Compose can run; the upgraded manager then renders the authoritative connection environment. Production Compose joins only declared manager-owned external networks, publishes no application host ports, and relies on the edge network for public aliases and the private platform network for local component dependencies. The supervisor creates those networks before activation. Remote dependencies replace the injected connection URL without changing the component bundle. + +Development sessions are detached or explicitly excluded before a host composition is accepted. A host with a live overlay cannot claim that its released composition is fully active. + +## Promotion and production + +Production promotion selects an accepted immutable composition. It does not rebuild packages or images, publish mutable tags as identity, or infer compatibility from staging branch heads. + +Production remains unaffected by development-mode support: + +- no source mounts; +- no development Compose; +- no live package overlay; +- no session aliases; +- no dirty source closures; +- no automatic incompatible migration; +- no development credentials; +- no npm `latest` or production tag changes during RC development. + +## Failure, rollback, and cleanup + +Development failures are scoped to the leased targets. + +- An incomplete package build retains the prior completed generation. +- A failed live service health gate keeps or restores the released route. +- A failed candidate activation restores the prior image and runtime configuration. +- A migration failure restores from the policy's approved recovery point and blocks released-runtime reactivation when compatibility cannot be proven. +- A failed Agent candidate is drained and replaced without abandoning assignments or settlement. +- Session expiry removes routes, processes, networks, temporary volumes, generated secrets, package overlays, and candidate tags owned only by that session. + +Cleanup emits a receipt listing retained and removed resources. Durable evidence explicitly selected for review may remain; caches and incomplete artifacts are not silently treated as evidence. The manager reports any residue as a blocker rather than declaring the session stopped cleanly. + +Release rollback remains composition-based. It selects the prior immutable known-good composition and never rebuilds an old tag. + +## Observability and user experience + +`trsd dev status` and Admin's development diagnostics should show: + +- session and lease state; +- canonical and session aliases; +- released, candidate, or live mode per target; +- repository commit and dirty-state indicator; +- current completed build generation; +- dependency reactions and stale consumers; +- health and last restart/reload; +- state policy and pending migrations; +- exact candidate artifact digests; +- blockers, degraded capabilities, and restoration status. + +The browser must display a clear development-source indicator when a canonical application route is served by a live overlay. It must not expose secrets, internal filesystem paths, or tokens. + +Logs use stable target IDs, structured event envelopes, redaction rules, and bounded retention. A developer can follow one target without reading unrelated manager or provider logs. + +## Governance and evidence + +Development sessions may be created by an authorized human, Codex task, or governed agent assignment. The session does not broaden repository or runtime authority. It records the authority used to select source worktrees, targets, state, secrets, and mutations. + +An agent may operate only on assignment-scoped repositories and targets. Freezing, publishing, staging, promotion, destructive state changes, assignment cancellation, and production mutation retain their existing review and confirmation boundaries. + +GitHub issues, pull requests, reviews, checks, and release comments remain the project-local governance record. Manager receipts and Platform compositions complement that record; they do not replace protected repository review. + +## Adoption plan + +### Phase 1: portable contract + +- Add `treeseed.development-runtime/v1` and `treeseed.development-candidate/v1` to SDK. +- Extend `treeseed.package.yaml` validation and portfolio discovery. +- Define target kinds, reactions, state policies, receipts, and redaction behavior. +- Add negative schema and unsafe-path tests. + +### Phase 2: manager sessions and routing + +- Add session/lease storage, plan, status, logs, expiry, detach, and restoration. +- Add canonical edge-route switching after direct and routed health verification. +- Keep unrelated released reconciliation active. +- Prove crash and expired-session restoration. + +### Phase 3: UI stack + +- Declare SDK, UI, and Core package-watch targets. +- Declare Admin live-web target. +- Integrate Core's completed-build watcher with manager sessions. +- Prove same-origin OAuth, confirmation, account, team, and responsive UI development. +- Add packed-candidate freeze and Admin rebuild against exact tarballs. + +### Phase 4: API co-development + +- Add API live-service and production-image candidate targets. +- Add ephemeral, clone, and shared-compatible database policies. +- Regenerate and compare local catalog/OpenAPI output. +- Prove Admin and CLI against a live API without an API release. +- Prove released API restoration after failure. + +### Phase 5: Agent and background runtimes + +- Add Agent manager/runner rebuild-restart targets. +- Add drain, lease, active-assignment, availability, and settlement checks. +- Add operations-runner and applicable TreeDX/AI targets. +- Prove candidate failure restoration and zero abandoned work. + +### Phase 6: freeze-to-release + +- Emit exact candidate closures and semantic bump requirements. +- Reproduce candidates from reviewed commits. +- Publish RCs without rebuilding accepted artifacts. +- Compose exact Platform development generations. +- Run active guarantees, no-op reconciliation, rollback, and restoration. + +## Acceptance criteria + +The architecture is complete when: + +- every participating project can declare a validated development target without manager-specific project code; +- UI changes reach Admin through a completed build generation and browser reload without publishing a package; +- Admin and API can run live together through canonical hostnames and exact OAuth policy; +- SDK/UI/Core candidate packages can replace live links for cross-project verification without source imports; +- API state policies prevent automatic incompatible migration of shared data; +- Agent and background candidates rebuild, drain, restart, verify, and restore without abandoned leases or accounting residue; +- target selection restarts or rebuilds only the declared dependency closure; +- released components continue reconciling while selected targets are leased; +- session expiry and crash recovery restore the known-good routes and components; +- freeze produces immutable artifacts, digests, contract bundles, and compatibility attestations from one source closure; +- project RC publication reuses the accepted candidate artifacts; +- Platform pins exact artifacts and Deployment activates them through its normal signed catalog; +- a host with no development session repeatedly reconciles to `noop`; +- no live overlay, dirty source, development Compose file, or mutable tag can enter production evidence. + +## Summary + +TreeSeed's managed release architecture remains the authority for integration, rollback, and promotion. Its development architecture adds a faster, explicitly non-authoritative layer coordinated by the same manager and the same package/runtime graph. + +Libraries update completed package generations, UI applications hot reload, APIs restart behind stable routes, and agents or background services rebuild and drain safely. The manager preserves real connections and security behavior while isolating state and recording source closure. When work stabilizes, the session freezes exact candidate artifacts, runs standards and guarantee verification, publishes independent RCs, and lets Platform compose the immutable result. + +This separation provides real-time productivity without replacing release evidence with a development process. diff --git a/docs/hosted-deployment.md b/docs/hosted-deployment.md new file mode 100644 index 00000000..e406deb8 --- /dev/null +++ b/docs/hosted-deployment.md @@ -0,0 +1,50 @@ +# Hosted deployment + +Platform declares portable staging and production topology templates. Deployment owns the pinned OpenTofu modules and Cloudflare/Railway provider behavior; the API authorizes plans and mutations; `trsd` is the operator surface. Platform contains no provider account IDs, team IDs, credentials, host identities, or state. + +OpenTofu state is isolated by team, deployment, environment, and stack at: + +```text +teams//opentofu/v1/deployments//environments//stacks//terraform.tfstate +``` + +The R2 bucket and endpoint come from the active team's Cloudflare storage connection. State access uses a short-lived, team-scoped storage session and an independently scoped state-encryption key. Provider and state credentials are released only to the operations runner for one exact operation and never enter Platform Git, API records, plans, receipts, logs, or evidence. + +## Credential bootstrap + +Core OpenBao is a required private service alongside the control-plane API. Deployment owns its immutable image, TLS, persistent Raft storage, initialization, bounded AppRole sessions and OS-backed seal/recovery custody. It is not an optional external provider. API readiness fails closed when OpenBao is unavailable. + +A credential administrator creates a team service connection and enters its credential profiles in Admin or through `trsd services credentials`. The authenticated API authorizes the team, enabled capability, profile and environment before writing to OpenBao with an exact expected version. Only non-secret descriptors and authority versions enter PostgreSQL. There is no personal vault passphrase, browser key/grant/envelope, interactive runner delivery or environment-reference authority. + +The operations runner obtains a short-lived OpenBao session, reads only the operation's authorized scope, and revokes the session on completion or failure. State/backend/profile authority and current secret version are rechecked before use. An outage blocks credential-dependent work; it never enables a fallback vault. See [Secret custody](secret-custody.md) for bootstrap and recovery boundaries. + +Each `connectionRef` is a portable, provider-scoped reference. In Admin, set the service connection's **Connection reference** to that exact value; the API resolves it to the team-local immutable connection ID. Database IDs, account IDs, and credential material never belong in a Platform topology template. + +The staging topology requires these active, team-scoped connections: + +- `cloudflare-hosting-staging` for Pages, Workers, DNS, and TLS. +- `cloudflare-state-staging` for the R2 state bucket and endpoint, storage session, and separately authorized state-encryption key. +- `railway-hosting-staging` for the Railway workspace and staging project/environment. + +Their bootstrap profiles are exact: + +| Connection | Non-secret configuration | OpenBao profile and fields | Approved capabilities | +|---|---|---|---| +| `cloudflare-hosting-staging` | `deploymentEnvironment=staging`, account ID, zone ID | `cloudflare-runtime.apiToken`; `cloudflare-dns.apiToken` | `frontend-hosting`, `dns-management` | +| `cloudflare-state-staging` | `deploymentEnvironment=staging`, account ID, state bucket, HTTPS state endpoint, optional region, state-encryption key reference | `s3-state-session.accessKeyId`, `secretAccessKey`, optional `sessionToken`; `opentofu-state-encryption.stateEncryptionKey` | `object-storage`, `state-encryption` | +| `railway-hosting-staging` | `deploymentEnvironment=staging`, workspace ID, project ID, environment ID | `railway-workspace.apiToken` | `backend-hosting`, `database-hosting`, `private-knowledge-index-hosting` | + +Account, zone, workspace, project, environment, bucket, endpoint, and key references are installation-time connection metadata. Credential values remain in OpenBao and must not be committed here. Authorized agents can use the same capability-scoped connections without a separate human approval or personal unlock session. + +## Plan an environment + +Release automation produces an ignored `treeseed.hosted-topology-artifacts/v1` document containing exactly the Admin Pages archive, API-proxy Worker file, and immutable Railway OCI image identities required by the selected template. From a clean Platform commit: + +```text +trsd platform topology plan config/topologies/staging.yaml --artifacts .treeseed/topology-artifacts/staging.json --json +trsd platform topology plan config/topologies/production.yaml --artifacts .treeseed/topology-artifacts/production.json --json +``` + +The CLI binds the active authenticated team and exact current Platform commit. Credential resolution is server-side through core OpenBao; planning does not prompt for a personal vault passphrase. Template changes, extra or missing artifacts, mutable images, wrong artifact kinds, incomplete connection profiles, unavailable service connections, provider drift, expired custody sessions or stale credential versions, and cross-team state custody all fail closed. Apply requires authenticated `infrastructure.write` authority, the exact reviewed plan, its digest precondition, and `--yes`; no separate environment approval exists. Production is authorized only by human review of the exact Platform pull request targeting `main`, then proceeds through automated reconciliation without a second approval gate. + +Cloudflare owns the Admin Pages project, API-proxy Worker, DNS, and TLS policy. The target Railway composition must include PostgreSQL, core OpenBao, the control-plane API, operations runner, and TreeDX service. Cloud rollout remains blocked until Deployment has provisioned and accepted an independent cloud seal authority, private TLS, persistent storage and recovery; the older topology templates must not be applied without that closure. The three production capacity providers use the generic Debian installer on Ubuntu 26.04, generate identities locally, and require admin approval after registration; OpenTofu does not manage those physical hosts. diff --git a/docs/identity-authentication.md b/docs/identity-authentication.md new file mode 100644 index 00000000..39d87ac6 --- /dev/null +++ b/docs/identity-authentication.md @@ -0,0 +1,47 @@ +# Managed authentication + +Admin redirects to the independently managed Identity service. Keycloak supplies +the password, MFA, registration, and recovery flows; applications do not collect +passwords. Each application retains its own host-scoped session. + +The TreeSeed login theme belongs to Identity and reuses the UI package's logo, +design tokens, and authentication styles. Deployment installs those exact +published assets read-only. Platform does not build or implement the theme. +Light/dark appearance currently follows the operating-system preference; saved +cross-application theme preferences are not yet synchronized. + +## Registration and recovery policy + +The installation's managed host configuration selects public registration: + +```json +{ + "registrationAllowed": true, + "resetPasswordAllowed": true, + "mailTransport": "existing" +} +``` + +This is the Identity component's `configuration.authentication` value. The API's +`configuration.identityRuntime.registration.enabled` must match +`registrationAllowed`. Internal installations may set both registration flags +to false without disabling existing users' sign-in or password recovery. + +`existing` preserves the configured SMTP credentials and requires an existing +TLS-enabled email transport before enabling registration or recovery. Supply +that transport through managed installation authority, never Platform Git. + +For local staging only, `local-mailpit` selects the enabled Lab's mail capture +service. It does not deliver mail to a user's real inbox. Verification and reset +messages contain account-access links; treat the local mail viewer as privileged +test infrastructure. This transport is rejected for production. + +New registration requires verified email before the API provisions a local +principal. Identity is keyed by issuer and subject, not email. A matching email +does not merge accounts or confer team membership, ownership, or administrator +permissions. Existing principal mappings remain unchanged. + +Apply changes with `trsd host config plan` followed by `trsd host config apply`. +Registration is not activated merely by updating packages. Preserve the +coordinated application/database restore point; never restore an old +authentication writer onto incompatible migrated data. diff --git a/docs/kata-assignment-security.md b/docs/kata-assignment-security.md new file mode 100644 index 00000000..e81cb73b --- /dev/null +++ b/docs/kata-assignment-security.md @@ -0,0 +1,43 @@ +# Kata assignment security + +TreeSeed capacity providers use one Kata runtime-rs QEMU/KVM microVM for each assignment attempt. The provider container receives only the root-owned broker socket. It does not receive Docker, containerd, KVM, host filesystem, or upstream model credentials. + +## Trust boundary + +The provider signs a `treeseed.sandbox-assignment/v1` manifest. The broker validates its schema, provider signing key, immutable guest digest, limits, exact identity/context digests, network policy, and lease expiry before invoking containerd in the `treeseed-sandboxes` namespace. Guest input and output use separate mounts: verified input is read-only and the bounded output directory is writable. CPU, memory, wall-time, process, disk, and output limits are carried into the guest contract; the broker enforces the host-visible limits and the guest entrypoint enforces in-VM limits. + +The broker reports unavailable unless KVM, containerd, Kata, trusted provider keys, the guest entrypoint, and configured model authentication are all healthy. A v4 provider returns assignments when exact repository/TreeDX inputs have not been materialized. There is no fallback to process execution. + +Activity profiles request standardized capability contracts, never execution adapters, sandbox profiles, or image identities. The allocator matches those demands against public provider offers. Only after selection does the capacity provider privately map its opaque offer to an adapter, sandbox profile, and immutable image digest. The global trust catalog covers TreeSeed base and official images; provider-owned images remain private but must prove signed lineage from `treeseed/sandbox-base` or an approved descendant. Image identity is recorded in the post-selection environment receipt, not used as a market-matching input. + +## Host commands + +Read-only operations never require confirmation: + +```text +trsd host security plan +trsd host security status +trsd host security verify +trsd host sandbox status +trsd host sandbox doctor +trsd host security recovery verify --bundle /absolute/path/recovery.bundle +``` + +Initialization and rotation require explicit confirmation and hidden passphrase input: + +```text +trsd host security initialize --recovery-bundle /absolute/path/recovery.bundle --confirm +trsd host security rotate credentials --recovery-bundle /absolute/path/current.bundle --new-recovery-bundle /absolute/path/next.bundle --confirm +``` + +Initialization uses an existing `CODEX_HOME/auth.json` or `~/.codex/auth.json` ChatGPT subscription login when available and otherwise requests a hidden model-provider service API key. Either credential is encrypted into systemd credential custody. Subscription state is copied read-only by the root broker into one Kata assignment at a time and removed with the VM; Codex also runs in `workspace-write` sandbox mode over only the assignment's private project copy. Browser, apps, web search, and multi-agent capabilities are disabled, and collected output is rejected if it contains known token fingerprints. API-key mode continues to use the one-use host model gateway. + +The operation refuses an existing or partial volume, creates a LUKS2/Argon2id sparse image, adds independent runtime and recovery slots, uses TPM2 in production or an encrypted systemd credential on development hosts, formats ext4, copies state with metadata, retains the former plaintext directory as an offline rollback generation, and mounts with `nodev,nosuid,noexec`. The recovery bundle uses scrypt and AES-256-GCM, is written once with mode `0600`, and is only inventoried after authentication. + +## Application encryption + +`treeseed.encrypted-envelope/v1` uses a random 256-bit DEK for each record, AES-256-GCM for payload and DEK wrapping, independent nonces, canonical AAD, key generation metadata, and ciphertext digests. Provider `data://` credentials are encrypted at rest and legacy plaintext values are atomically migrated after a successful read. Protected communication trace payloads are stored only as envelopes for new writes; normal receipts never decrypt them, while authorized full diagnostics do. The database migration rejects new protected plaintext while a restartable, row-locked backfill encrypts historical rows. Manager generation backups use a separate authenticated backup KEK and persist only as `treeseed.encrypted-backup/v1`; their temporary plaintext tar exists only under `/run` and is removed before the operation returns. + +## Cutover gate + +Production capacity must remain unavailable until the security receipt is known-good, the v4 manifest contains only `microvm` adapters, exact input materialization and the model gateway are healthy, protected-diagnostic backfill is complete, and the encrypted restore drill passes. The encrypted volume and envelope formats are never rolled back to plaintext. diff --git a/docs/package-ownership.md b/docs/package-ownership.md index c05808bc..7c309330 100644 --- a/docs/package-ownership.md +++ b/docs/package-ownership.md @@ -217,9 +217,9 @@ Public npm package publish tokens belong in the package repository GitHub `produ The target ecommerce architecture is split by surface. Existing API/Admin commerce code is migration inventory, not target ownership: - `treeseed-ai/market` owns buyer-facing Market and ecosystem-governance presentation, including the extracted `/market` and `/app/market` families. -- private `treeseed-ai/market-api` owns vendors, products, offers, prices, ownership, stewardship, contributions, ecosystem-governance policies, orders, payment groups, subscriptions, entitlements, refunds, fulfillment, scoped services, capacity listings/inquiries, marketplace aggregation, seller monitoring, webhooks, and commercial-license entitlements under `/v1/market/**`. +- Public, AGPLv3-licensed `treeseed-ai/market-api` owns vendors, products, offers, prices, ownership, stewardship, contributions, ecosystem-governance policies, orders, payment groups, subscriptions, entitlements, refunds, fulfillment, scoped services, capacity listings/inquiries, marketplace aggregation, seller monitoring, webhooks, and commercial-license entitlements under `/v1/market/**`. - `@treeseed/api` owns hosted or sovereign Admin control-plane state only. Its complete versioned route descriptor is pinned by exact API ref and passed through the singleton gateway without transferring implementation ownership. The gateway admits only descriptor-declared method/path pairs; an arbitrary non-Market `/v1/**` prefix is not a pass-through contract. -- Singleton reconciliation owns only the declared gateway, descriptor, verification, and manifest overlay inside `treeseed-ai/market-api`. Private Market application files are repository-owned: the reconciler bootstraps the extension entrypoint once, preserves all paths outside its manifest, and blocks managed-file drift instead of replacing the private application tree. +- Singleton reconciliation owns only the declared gateway, descriptor, verification, and manifest overlay inside `treeseed-ai/market-api`. Market application files are repository-owned: the reconciler bootstraps the extension entrypoint once, preserves all paths outside its manifest, and blocks managed-file drift instead of replacing the application tree. - `@treeseed/admin` retains identity, teams, projects, project governance, knowledge, capacity/workday operations, services, secrets, audit, and control-plane administration. It contains no Market implementation after extraction. - `@treeseed/ui` owns reusable, Stripe-free, theme-native commerce and governance components. diff --git a/docs/production-readiness-migration-ledger.md b/docs/production-readiness-migration-ledger.md index 43031d65..f0a5b11b 100644 --- a/docs/production-readiness-migration-ledger.md +++ b/docs/production-readiness-migration-ledger.md @@ -443,7 +443,7 @@ The real TreeSeed team proved the new Designer against live TreeDX definitions r ### Repository-authored simulation reached the real team workday boundary -Simulation Bay committed its generated scene and seed through TreeDX and published exact GitHub content refs `aa5c57e0388a5c33b745dcb4fb6ff44b8b54a5d5` and `419a9769411981af0f64f85f8b3043c95cc81913`. This acceptance exposed four recovery defects instead of hiding them behind fixture aliases: remote fetch read-back checked a ref TreeDX does not expose; a fetched content ref could be current while graph/search state remained stale and the reconciler incorrectly planned `noop`; an immutable operation bundle was incorrectly treated as the live provider-runtime root; and the generated simulation invented a legacy `capacity-provider:treeseed/local` rather than resolving the active project grant's seed identity and execution-provider inventory. Fresh branch-ref verification, stale-index update planning, explicit `TREESEED_TENANT_ROOT`, and grant-derived provider references now own those boundaries. The resulting operation created and ticked real retained workday `agent-lab:27ab4e43-e1ca-4d39-b3c2-e2684aa7b755:cooperative-planning-demo` through the reconciled `capacity-provider:treeseed/agents` runtime. +Simulation Bay committed its generated scene and seed through TreeDX and published exact GitHub content refs `aa5c57e0388a5c33b745dcb4fb6ff44b8b54a5d5` and `419a9769411981af0f64f85f8b3043c95cc81913`. This acceptance exposed four recovery defects instead of hiding them behind fixture aliases: remote fetch read-back checked a ref TreeDX does not expose; a fetched content ref could be current while graph/search state remained stale and the reconciler incorrectly planned `noop`; an immutable operation bundle was incorrectly treated as the live provider-runtime root; and the generated simulation invented a fixed local provider identity rather than resolving the active project grant's seed identity and execution-provider inventory. Fresh branch-ref verification, stale-index update planning, explicit `TREESEED_TENANT_ROOT`, and grant-derived provider references now own those boundaries. The resulting operation created and ticked a retained cooperative-planning workday through the reconciled agent runtime. That live workday then exposed two content/forensic edge cases. SSE projection passed `null` URL filters into the Zod query contract and crashed the API; absent filters are now normalized before validation with a focused regression. The draft generator also selected the alphabetically first historical test even when its target agent was intentionally dormant. It now authors a Zod-validated project-inventory agent test from enabled durable agents and pins that test in the scene. A mixed create/update bundle additionally proved TreeDX batch reads fail atomically when one requested path is missing; authoring now observes each proposed path independently before building one atomic changeset. API lint/build and the focused workday-activity regression pass. The final inventory-test publication and completed Atlas return remain the current live gate; failed operations and reports are retained as forensic evidence. @@ -578,7 +578,7 @@ Authenticated scene `20260813t002808753z` then passed all 12 focus, vital-densit Canonical provider reconciliation rebuilt the absent Agent manager and runner images, restored both Agent and platform-operation Compose units, and fresh status now reports all six provider resources ready with no blockers. The first deliberately small planning selections exposed a plan/apply parity defect: CLI plan checked repository binding and class presence but did not compile the selected signal DAG or cooperative time budget, while API execution correctly rejected an invalid single-profile graph and an underfunded two-profile graph. Scheduling validation therefore remains an API-owned preflight gap; the CLI must consume that exact read-only result rather than duplicate the planning compiler. -Bounded acceptance run `bd79f131-3d3b-4e14-8801-db9ec9d39c82` proved a real two-profile chain. Audience Reviewer completed through Codex, committed `src/content/notes/editorial/books/treeseed-guide/reviews/core-objective-reader-journey-assessment.mdx` through TreeDX, and published the upstream signal that admitted Guide Steward. It also exposed two operator-boundary defects. First, the authenticated browser fixture belongs only to its isolated visual-audit team, so an internal TreeSeed-team run is correctly invisible in that session. The supported human path is the pending seed membership for `adrian.webb@treeseed.dev`, claimed when that verified account is created; automation must not weaken authorization by silently adding visual-test identities to the development team. Second, `workday-cancel` targets a project envelope while `workday-run` returns a parent coordination-run ID. Cancelling only the envelope left parent admission authority active. The CLI now exposes and documents `workday-run-cancel`, which transitions the API-owned parent and terminalizes remaining envelopes and assignments; its request compiler has focused coverage. +Bounded acceptance proved a real two-profile chain. Audience Reviewer completed through Codex, committed its assessment through TreeDX, and published the upstream signal that admitted Guide Steward. It also exposed two operator-boundary defects. First, the authenticated browser fixture belongs only to its isolated visual-audit team, so an internal team run is correctly invisible in that session. The supported human path is an installation-supplied pending membership claimed by its verified account; automation must not weaken authorization by silently adding visual-test identities to the development team. Second, `workday-cancel` targets a project envelope while `workday-run` returns a parent coordination-run ID. Cancelling only the envelope left parent admission authority active. The CLI now exposes and documents `workday-run-cancel`, which transitions the API-owned parent and terminalizes remaining envelopes and assignments; its request compiler has focused coverage. Fresh summary read-back proves the run closed without hidden work: the parent and Market envelope are cancelled, assignments total two with one completed and one failed, pending and leased counts are zero, mode runs are terminal, reservations total two, usage actuals total three, and ledger entries total two. One ledger entry is the normal Audience Reviewer provider settlement and one is explicit terminalization of Guide Steward. The focused CLI suite passes 5/5 and the CLI build passes. A broad standard clean plan was intentionally not applied because it would remove about 1.47 GB of retained scene evidence, including the accepted workspace-focus run; cleanup remains pending until the relevant evidence is bundled or a narrower supported cleanup scope exists. diff --git a/docs/project-architecture-migration.md b/docs/project-architecture-migration.md index 83956fb3..69e7506e 100644 --- a/docs/project-architecture-migration.md +++ b/docs/project-architecture-migration.md @@ -41,10 +41,10 @@ npx trsd platform workset --apply --yes --branch feature/assignment-change --ass The clone itself is initialized from one canonical Platform template. A Platform "profile" is not a second schema or runtime selector: it is the exact immutable template revision recorded in machine-local template state. The default TreeSeed development installation is created with: ```bash -npx trsd platform init /home/adrian/Projects/treeseed/platform \ +npx trsd platform init ./platform \ --repository treeseed-ai/platform --ref staging \ --template platform-local-managed-codex --team treeseed --plan --json -npx trsd platform init /home/adrian/Projects/treeseed/platform \ +npx trsd platform init ./platform \ --repository treeseed-ai/platform --ref staging \ --template platform-local-managed-codex --team treeseed --apply --yes --json ``` diff --git a/docs/sdk-first-cutover-implementation-plan.md b/docs/sdk-first-cutover-implementation-plan.md index a7cf824d..4bb50982 100644 --- a/docs/sdk-first-cutover-implementation-plan.md +++ b/docs/sdk-first-cutover-implementation-plan.md @@ -12,6 +12,7 @@ Hosted deployment, unscoped `trsd release`, and production promotion remain fail ## Current checkpoint +Full SDK acceptance remains unpassed. Agent #296 is checked and active; EF proved five approved pairs, a genuine Tester correction/re-review and the release Actor's full verifier, packing and archive checks. Final release review exhausted the unchanged workday boundary with only 39 seconds available. Agent #298 / PR #299 removes duplicate materialized-context discovery and aggregate-owned builds in the existing canonical prompt, preserving missing exact-ref reads, required predecessor read-back, independent review and runner replay. Strict tests and the coded owner scene pass; checked staging and serial activation precede one fresh full SDK gate. Canonical objectives, one-hour/twenty-minute planning, concurrency five, model/cap policy and fresh review allowances stay unchanged. Historical failures remain immutable; full SDK, historical allocation and API/joint gates remain open. Detailed evidence belongs in Platform #520. - Updated: 2026-08-23 - Active gate: Gate 2 prerequisite — Unified seed and capacity-provider battery cutover - State: `in_progress` @@ -23,7 +24,7 @@ Hosted deployment, unscoped `trsd release`, and production promotion remain fail - Active repositories: SDK staging `548c13ac8bf156361c0329fd4117e266bc541d41` / immutable `0.13.0-rc.25`; API staging `819dbcd3aa24661ceab98df4e1413853a0166548` / tag `0.8.0-rc.7`; CLI staging `de880f4e6abeba8b9e484f80486d595f76ef73fa` / immutable `0.13.0-rc.11`; Agent staging `dfdda15d9aa72d14cb88186965c3bb5bf3b60c6c` / immutable `0.13.0-rc.9`; TreeDX staging `557c41f8e631cb440f21512cc5f182195805c9b9` / immutable `0.3.0-rc.4`; Platform readiness staging `85e5b51061df7c2102a97f06ec6709d446de1dc6`. The first live communication send remains the explicit next boundary. - Completed bootstrap repositories: `treeseed-ai/cli`, `treeseed-ai/platform`, and the SDK source canary - Next action: run the first live, single-recipient SDK communication through `trsd send`, observe the communication assignment through the live provider runner, verify the TreeDX response, exact settlement, human Markdown panel, and zero execution residue, then repeat as the clean-repeat scene. Platform and workday adapters remain explicitly unavailable and outside this first communication run. -- Unified seed and capacity-provider battery checkpoint: `in_progress`. Audit found the canonical seed omits Market and Market API, uses stale owner email and removed `agentLabServicePrincipals`, and declares separate platform/agent providers. Accepted SDK still exposes `treeseed.capacity-provider/v2` with `agent | platform-operation`; API seed apply plans but does not reconcile provider prerequisites; Agent selects only its default executor and ignores declared lanes; CLI provider leaves are not fully bound. Target is one approved local provider with shared communication/platform/workday capacity, reserved-borrowable communication admission, an isolated platform executor, owner memberships for `adrian.webb@knowledge.coop` and a non-login automation service principal, and exact grants across fifteen projects. Live agents, workdays, repository mutation, and TreeDX mutation remain fail-closed. +- Unified seed and capacity-provider battery checkpoint: `in_progress`. Audit found the canonical seed omitted Market and Market API, used a host-specific owner identity, and declared separate platform/agent providers. The target is an approved provider with shared communication/platform/workday capacity, reserved-borrowable communication admission, an isolated platform executor, installation-supplied membership, and exact project grants. Live agents, workdays, repository mutation, and TreeDX mutation remain fail-closed. - Derived virtual-knowledge-repository checkpoint: root projects are the only seed-declared ownership resources. Each root project automatically owns one TreeDX virtual knowledge repository exposed through file, blob, search, graph, context, and artifact operations and backed by the selected TreeDX storage profile (local now; R2-capable binding later). These are not GitHub repositories and have no checkout, branch, PR, Actions, or package-release policy. Platform Issue #33 / PR #34 removed the fifteen false Git content bindings and merged as staging `3c7052f`; digest changed from `sha256:4277f55449ed1d0a6e4d21f4d3e356890006a5383bdf0aa520a8a4121dd1bbb0` to `sha256:5c2ca42c74e21523940cf576fb08f4513eb6c21a49ccf23d8b573d945a577b0c`, leaving fifteen projects, sixteen real source/support repositories, and fifteen derived TreeDX virtual knowledge repositories. API bootstrap and content-only adoption are accepted at `5756f27aedc55af24dfc300f3f9f28d94628f61c`. SDK Issue #64 / PR #65 merged as `2b45313f66efe58fc85a873ff4fac5e89eba4c8d`; immutable RC21 publish/verify runs `32624069609`, `32624069556`, and `32624067909` passed, with npm integrity `sha512-f0qYE6uyI3qWx3F9XE3g1F0q/9CIRp7QvEvcvta+s9I2fxuwmr0Aj8BewdwZi6kbPpBH6Ng9dnhs5m0MoGtMJA==` and shasum `8b119de604d371bee9e428abae3a29b1a0dc1b5f`. TreeDX Issue #16 / PR #17 adds authoritative `retireRepository`, tombstones repository/name/placement records, moves managed storage into recoverable retired custody, and updates OpenAPI `0.11.1` plus all four generated clients for `0.3.0-rc.4`; focused store, API, OpenAPI, and SDK coverage checks pass. Remaining work: hosted acceptance and immutable TreeDX publication, then SDK/API proxy mapping and project-deletion adoption. - Unified battery SDK contract checkpoint: Issue #62 / PR #63 exact head `182b05dd8415e7d45f5934f450fda8bf9702ca5d` passed local architecture/build, deterministic standards and packed acceptance, 20 modern files/98 tests, and hosted Verify `32619054665`/`32619062873`. It merged/read back as staging `974bf855b57eac8e30250f4e3dcade2c8a4baa18`; post-merge Verify `32619090785`, tag Verify `32619118808`, and publish/read-back `32619118800` passed. Immutable npm `@treeseed/sdk@0.13.0-rc.20` has integrity `sha512-XM2ewAUACIO/umqZEsKlfdJxaDZW8IyMnH5pSoS7vcySKbMb/2bGPwJpfIIuNui9vMAkQ7KwkoIEV5fHXiFUvQ==`, shasum `6b207fd37378703a4501852cce895a667fe35a8f`, `rc=0.13.0-rc.20`, and unchanged `latest=0.12.62`. The accepted catalog contains 306 operations, 123 MCP tools, and 56 MCP resources. Next: pin API to RC20 and implement portable seed application, service-principal ownership, provider enrollment/reconciliation, and shared lane admission. - Unified battery API checkpoint: Issue #23 / PR #24 implementation `f1dfbc14c26ab7e234757f068e671b66435ba035` and follow-up Issue #25 / PR #26 merged/read back as staging `0982d41dc64f6c9c6903bc147b81e76004124ec1`. API `0.8.0-rc.3` consumes and persists uploaded bundles, owns non-login service principals, provider enrollment/approval/grants, provider-wide three-lane admission, and portable verification. Focused seed/provider/capacity tests, catalog completeness, build, hosted Verify, authorization, disposable PostgreSQL proof, and retained development database migration/read-back passed. @@ -33,7 +34,7 @@ Hosted deployment, unscoped `trsd release`, and production promotion remain fail - Canonical portfolio checkpoint: Platform seed digest is `sha256:4277f55449ed1d0a6e4d21f4d3e356890006a5383bdf0aa520a8a4121dd1bbb0`; unified provider manifest SHA-256 is `9b3f675f40a7f23d66cc7429600d68438cb28ba866ebe4ce8688e240a4fa482c`. SDK validation reads 1 team, 2 owners, 15 projects, 31 repositories, and a provider prerequisite spanning all 15 projects with zero diagnostics. All four installer templates now use only this seed and the v3 manifest. Platform `verify:local` passes. Market PR #2 removes its competing legacy seeds without adding AGPL enforcement. Market API PR #2 makes that repository explicitly AGPL-3.0-only, adds the one-time username allowlist, moves gateway behavior out of SDK ownership, removes its Git SDK dependency, and passes build plus 3 files/6 tests. - Retained database checkpoint: before applying the v3 provider/service-principal migration, the healthy PostgreSQL 16 `treeseed_api` database read back at 637 MB. Owner-only custom-format backup `.treeseed/backups/api-control-plane/2026-08-23-pre-capacity-battery/treeseed-api-pre-capacity-battery.dump` is 149,140,950 bytes, mode `0600`, SHA-256 `b5c2717ec4ce0322035c0b0c0ff0b7fbdfc6dfb501d03624e188407b2e74db94`, and `pg_restore --list` succeeds inside the pinned PostgreSQL container. It remains retained pending explicit human deletion approval. - Unified battery composition checkpoint: `docs/evidence/unified-capacity-battery-composition.json` binds the accepted TreeDX, SDK, API, CLI, Agent, Market, Market API, and Platform staging refs; SDK/npm, CLI/npm, Agent/npm, OpenAPI, MCP, command-tree, seed, provider-manifest, hosted-run, and backup receipts. All seven GitHub repositories have zero open PRs and only `main`/`staging` branches after deleting seven Market branch pointers whose tips were already ancestors of staging. Runtime closure remains `waiting_human_authentication`; the composition explicitly keeps live agent execution false. -- Human checkpoint — local CLI OAuth device approval: the new `--server` custody intentionally has no session because legacy Market custody was not migrated. The owner must run `TREESEED_API_BASE_URL=http://127.0.0.1:3002 node packages/cli/dist/cli/main.js auth login --server local`, open the displayed local verification URL, authenticate as `adrian.webb@knowledge.coop`, and approve the device request. Passwords, device codes, OAuth tokens, custody keys, and `~/.config/treeseed` contents must not be pasted into chat. Success is an encrypted session whose read-only status resolves Adrian Webb; expiry, denial, or another principal fails. Seed/provider runtime closure proceeds immediately after read-back. +- Human checkpoint — local CLI OAuth device approval: the new `--server` custody intentionally has no session because legacy custody was not migrated. The installation owner must run `trsd auth login --server local`, open the displayed local verification URL, authenticate, and approve the device request. Passwords, device codes, OAuth tokens, and custody keys must not be pasted into chat. Success is an encrypted session whose read-only status resolves the approved principal; expiry, denial, or another principal fails. - Device-approval correction: the first human attempt proved GET `/auth/device/approve` returned a JSON instruction while POST required the bearer credential the device flow was intended to issue. API Issue #27 / PR #28 fixes the circular bootstrap with an HTML form that authenticates the existing human credential server-side, approves only the pending code, returns no OAuth credential to the browser, and preserves the bearer/JSON path. Focused OAuth protocol/custody passed 11/11, the distribution build passed, contributor authorization and both hosted Verify jobs passed, and staging reads back at `84e4ea1d9f697de91b2012f1e7dfcbdafcce5418`. The restarted local API serves the form with `no-store`, CSP, and anti-framing headers. - TreeDX control-plane proxy cutover: `verified`. TreeDX remains the independent wire authority; SDK owns the TreeSeed semantic proxy facade and mapping; API is the sole TreeSeed credential, authorization, binding, delegation, REST, OpenAPI, and MCP proxy boundary. CLI and Agent consume catalog operations without TreeDX endpoints or credentials. Exact artifacts, hosted checks, focused modern verification, Platform composition, authoritative read-back, and final PR/branch/worktree residue checks pass. Production, npm `latest`, and live agent/workday execution were not changed by this prerequisite. - TreeDX authoritative-contract checkpoint: Issue [#1](https://github.com/treeseed-ai/treedx/issues/1) / PR [#2](https://github.com/treeseed-ai/treedx/pull/2) started from exact staging `25e5ac36abd273994af8cab35c3bcbb679e6ab2b`; reviewed head `52cde66008195c329a9231cf5c58506645fe6eb7` merged and reads back as staging `ca3fbdf79f28c82060387f14887c99c44eb9a8cf`. The candidate publishes service `0.3.0-rc.1`, OpenAPI `0.11.0`, 119 operation IDs, raw OpenAPI and typed contract exports, and OpenAPI digest `sha256:52ed190300922c388b115981e60635c306c643d48a3308ef9f79975510ae1926`. Four SDK omissions are explicit all-language exceptions; any new unclassified public operation fails. The TypeScript transport propagates request ID, trace context, idempotency key, timeout, and cancellation; independent review found the pre-aborted-signal edge, fixed at the reviewed head with a regression test. TreeDX no longer depends on `@treeseed/sdk` or its deleted content publisher. Local router/OpenAPI 4/4, TypeScript 35/35, Python 32 passed/one optional live skipped, Rust 42/42, Elixir 32/32, SDK-spec, generated-freshness, and packed-package checks pass. Exact-head PR runs `32593810903` and `32593814202` passed; staging release gate `32594038645` is active. No package publication or TreeDX mutation occurred. @@ -235,7 +236,7 @@ Hosted deployment, unscoped `trsd release`, and production promotion remain fail - State: `verified` - Why human authority is required: only the human may see the password-reset email, choose the new password, and establish the accountable human session used to approve SDK project contribution authority. The agent must not see or enter those secrets. - Surface: local Mailpit `http://127.0.0.1:8025`, trusted local API `http://127.0.0.1:3002`, and the locally built CLI candidate at `.treeseed/definition-cutover-worktrees/cli/dist/cli/main.js`. -- Human action: open the newest password-reset message in Mailpit. From `/home/adrian/Projects/treeseed/platform`, run `TREESEED_CONTROL_PLANE_MODE=managed TREESEED_API_BASE_URL=http://127.0.0.1:3002 node .treeseed/definition-cutover-worktrees/cli/dist/cli/main.js auth password-reset complete --market local`. Paste the complete reset link into the silent prompt, enter and confirm a new password, then run the same command prefix with `auth login --market local` and finally `auth whoami --market local`. +- Human action: open the newest password-reset message in Mailpit. From the Platform checkout root, run `TREESEED_CONTROL_PLANE_MODE=managed TREESEED_API_BASE_URL=http://127.0.0.1:3002 node .treeseed/definition-cutover-worktrees/cli/dist/cli/main.js auth password-reset complete --market local`. Paste the complete reset link into the silent prompt, enter and confirm a new password, then run the same command prefix with `auth login --market local` and finally `auth whoami --market local`. - Safe output: reset reports completion without echoing the link/token/password; login reports the principal display name/ID and local market; `whoami` reports the human principal and teams but no access or refresh token. - Redaction: do not paste the reset link, token, password, session file, cookies, or command output containing private account data into chat. Password and token values must never be command options. - Success criteria: reset completes, password login succeeds, and authoritative `whoami` returns human principal `edc6ce32-8e6e-4dbe-b085-6e077a24ce93` with TreeSeed team-owner access. diff --git a/docs/secret-custody.md b/docs/secret-custody.md new file mode 100644 index 00000000..b612155a --- /dev/null +++ b/docs/secret-custody.md @@ -0,0 +1,41 @@ +# Secret custody + +TreeSeed has two custody implementations. Platform declares composition and ownership; it does not implement a vault. + +| Custody | Owns | Access | +|---|---|---| +| Core OpenBao | Team service/provider credentials and OpenTofu encryption keys | API-authorized team, project, environment and purpose; versioned writes; short-lived trusted-service sessions | +| OS-backed local custody | Host bootstrap/seal/recovery roots, CLI OAuth sessions and provider-owned credentials | Deployment implementation, private OS credentials and scoped authenticated local records; provider environment files remain inside the OS-encrypted provider volume | + +Cryptographic envelopes for protected diagnostics, native GitHub App token exchange and GitHub Actions sealed uploads are protocols/data encryption, not additional credential stores. Runtime environment variables are an injection transport, not an alternative team-vault authority. Bootstrap inputs must come from protected installation custody; never commit their values or persist plaintext key fallbacks. + +## Team connections + +Sign in to Admin, select the team, open Services and configure the connection's non-secret target and enabled capabilities. On that connection, save each required credential profile. Admin sends the value over HTTPS to the authenticated API and clears secret fields. Read-back returns configured field names and version, never values. No personal passphrase or team-vault initialization wizard exists. + +The corresponding CLI surface is: + +```text +trsd services credentials show --team --json +trsd services credentials put --team --expected-version +trsd services credentials validate --team --expected-version --json +trsd services credentials delete --team --expected-version --json +``` + +Use hidden prompts or `--stdin` for a JSON field object; never place values in arguments or shell history. Version zero creates a new profile. Inspect the current version before replacement or deletion. R2 validation is read-only; encryption-key validation checks key format, not remote resource readiness. Neither substitutes for hosted plan/apply/read-back acceptance. + +## Local custody and bootstrap + +CLI sessions use OS-sealed local custody. `trsd secrets lock` prevents decryption across CLI invocations; `trsd secrets unlock` asks the OS to unlock the key. There is no plaintext CLI keyring or fake key rotation command. OAuth reauthentication replaces session credentials. + +The host manager prepares OpenBao's TLS and static-seal material outside its Raft volume. A one-shot initializer configures KV/AppRole authority and revokes initialization root authority. The API and runner receive only private client identity mounts. Do not mount these into provider assignments or custom applications. + +Provider identities and membership credentials use the shared Deployment local store with an OS-injected key. Provider secrets stay on the provider; arbitrary host environment inheritance is denied. Existing retired files, missing keys, unsafe paths and invalid ciphertext fail closed. No plaintext import, compatibility reader or automatic identity regeneration is allowed. An uncertain identity rotation retains its encrypted pending transaction for recovery. + +Recovery-bundle passphrases still protect offline host recovery. They are distinct from the removed personal service-vault passphrase. Preserve an independently accessible encrypted recovery bundle and test restoration before replacing OS seal authority. + +## Release boundary + +The consumer refactor must ship as one exact composition. Do not mix a new Admin/CLI with an old API or activate a new API without its Deployment/OpenBao bootstrap closure. Repository tests and staging PR merges are not evidence of managed-host or Railway acceptance. + +Cloud rollout additionally requires an independently provisioned seal authority and private, persistent OpenBao service. Neither its seal key nor its only recovery copy may live in the state it unlocks. Until Deployment's hosted closure and restore tests pass, cloud apply remains fail-closed. Production promotion requires human review of the exact Platform PR to `main`; staging work has no human-only approval gate. diff --git a/package.json b/package.json deleted file mode 100644 index f23079e8..00000000 --- a/package.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "name": "@treeseed/platform", - "version": "0.2.0-rc.1", - "private": true, - "license": "Apache-2.0", - "type": "module", - "packageManager": "npm@11.7.0", - "engines": { - "node": ">=22" - }, - "scripts": { - "verify": "node scripts/verify-platform.mjs", - "verify:local": "node scripts/verify-platform.mjs" - } -} diff --git a/packages/market-guarantee-catalog/guarantees/agent/system/guide-golden.guarantee.yaml b/packages/market-guarantee-catalog/guarantees/agent/system/guide-golden.guarantee.yaml deleted file mode 100644 index dadc93e0..00000000 --- a/packages/market-guarantee-catalog/guarantees/agent/system/guide-golden.guarantee.yaml +++ /dev/null @@ -1,68 +0,0 @@ -schemaVersion: treeseed.guarantee/v2 -id: guarantee.agent.system.guide-golden.918 -journeyIndex: 918 -type: agent -subtype: system -journey: Prove editorial Guide development end to end -ownerPackage: "@treeseed/market" -surface: cli -summary: Editorial agents improve canonical Guide content through the governed lifecycle with semantic target-ref read-back and zero residue. -status: planned -capabilityId: agent.system.guide-golden -catalog: agent.system -activation: - minimumConsecutivePasses: 3 - requiredVariants: [baseline, clean-repeat, interruption-resume] - invalidateOnSourceChange: true - distinctEntityRefs: - - subject: ephemeralProject - variants: [baseline, interruption-resume] -proof: - requiredCommands: [projects.list, capacity.context-query-checks, governance.proposal-show, capacity.decision-planning, capacity.capacity-plan, capacity.assignment, capacity.workday-summary, capacity.treedx-proxy-audit, platform.status] - minimumRepositoryPostconditions: 1 - outcomePredicates: - guide.editorial-lifecycle: [guide.dynamic-context, guide.proposal, guide.simulated-human-decision, guide.estimate, guide.writing, guide.editorial-review, guide.technical-review, guide.reporting, guide.settlement, guide.cleanup] - guide.semantic-content-outcome: [guide.pages, guide.required-claims, guide.relationships, guide.navigation, guide.receipts, guide.signals, guide.target-ref-read-back] - guide.ephemeral-baseline: [guide.ephemeral-project, guide.isolated-project] - guide.canonical-integration: [guide.canonical-project, guide.target-ref-read-back] - guide.ephemeral-interruption: [guide.ephemeral-project, guide.interruption-resume, guide.zero-residue] -outcomes: - - id: guide.editorial-lifecycle - kind: required - description: Dynamic context, proposal, decision, estimate, writing, independent editorial and technical review, reporting, settlement, and cleanup are exact and governed. - evidenceKinds: [redacted_cli_transcript, workflow_graph, treedx_read_back] - authoritativeSubjects: [proposalRevision, decision, workday, summaryRef] - - id: guide.semantic-content-outcome - kind: required - description: Intended Guide pages, claims, relationships, navigation placement, receipts, and signals exist at the observed target ref. - evidenceKinds: [semantic_content_assertions, mutation_receipt, repository_read_back] - authoritativeSubjects: [contentArtifacts, integratedRef, targetRef] - - id: guide.ephemeral-baseline - kind: required - variants: [baseline] - description: The baseline run uses one isolated ephemeral Guide project. - evidenceKinds: [project_inventory, cleanup] - authoritativeSubjects: [ephemeralProject, targetRef] - - id: guide.canonical-integration - kind: required - variants: [clean-repeat] - description: The clean repeat integrates the intended outcome into the canonical Guide project. - evidenceKinds: [project_inventory, repository_read_back] - authoritativeSubjects: [canonicalProject, targetRef] - - id: guide.ephemeral-interruption - kind: required - variants: [interruption-resume] - description: The interruption run uses a second isolated ephemeral Guide project and resumes without residue. - evidenceKinds: [project_inventory, replay_trace, cleanup] - authoritativeSubjects: [ephemeralProject, targetRef] -dependencies: { journeys: [], guarantees: [guarantee.agent.portability.project-fork.920] } -actors: { allowed: [capacity_operator, simulated_human], forbidden: [anonymous_user, unauthorized_user] } -devices: { required: [] } -gates: [core] -preconditions: { fixtures: [ephemeral_guide_project, canonical_guide_project] } -api: { required: true, verifierRefs: [market.agent-catalog.golden-live-proof] } -content: { required: true, verifierRefs: [] } -audit: { required: true, verifierRefs: [] } -negativeCases: [] -evidence: { required: [verifier_evidence, redacted_cli_transcript] } -notes: ["Operational readiness begins only when this capability reaches active status."] diff --git a/packages/market-guarantee-catalog/guarantees/agent/system/source-golden.guarantee.yaml b/packages/market-guarantee-catalog/guarantees/agent/system/source-golden.guarantee.yaml deleted file mode 100644 index f7402527..00000000 --- a/packages/market-guarantee-catalog/guarantees/agent/system/source-golden.guarantee.yaml +++ /dev/null @@ -1,48 +0,0 @@ -schemaVersion: treeseed.guarantee/v2 -id: guarantee.agent.system.source-golden.917 -journeyIndex: 917 -type: agent -subtype: system -journey: Prove bounded source development end to end -ownerPackage: "@treeseed/market" -surface: cli -summary: Authenticated CLI orchestration drives all six profiles through exact-ref source work, independent review, revision, integration, settlement, and cleanup. -status: planned -capabilityId: agent.system.source-golden -catalog: agent.system -activation: { minimumConsecutivePasses: 3, requiredVariants: [baseline, clean-repeat, interruption-resume], invalidateOnSourceChange: true } -proof: - requiredCommands: [governance.proposal-show, capacity.decision-planning, capacity.capacity-plan, capacity.assignment, capacity.checkpoint-integrate, capacity.workday-summary, platform.status] - minimumRepositoryPostconditions: 1 - outcomePredicates: - source.complete-governed-lifecycle: [source.planning, source.chat, source.estimating, source.acting, source.reviewing, source.reporting, source.simulated-human-transcript, source.settlement] - source.semantic-repository-outcome: [source.exact-local-ref, source.exact-remote-ref, source.behavior, source.verification, source.receipt, source.review, source.integration, source.zero-residue] - source.rejection-revision: [source.fixture-provenance, source.initial-rejection, source.real-codex-revision, source.distinct-final-reviewer, source.exact-revision-approval] -outcomes: - - id: source.complete-governed-lifecycle - kind: required - description: Proposal, simulated-human decision, estimate, accepted plan, acting, review, report, and settlement use exact refs and authenticated CLI operations. - evidenceKinds: [redacted_cli_transcript, workflow_graph] - authoritativeSubjects: [proposalRevision, decision, capacityPlan, workday, targetRef] - - id: source.semantic-repository-outcome - kind: required - description: Required behavior exists at exact local and remote refs with verification, receipts, review, integration, and zero residue. - evidenceKinds: [git_read_back, verification, mutation_receipt, cleanup] - authoritativeSubjects: [checkpointRef, reviewedRef, integratedRef, remoteRef] - - id: source.rejection-revision - kind: required - variants: [interruption-resume] - description: The interruption variant rejects a pre-seeded deficient checkpoint, real Codex revises it, and a distinct reviewer approves the revision. - evidenceKinds: [fixture_provenance, review_read_back, revised_diff] - authoritativeSubjects: [deficientCheckpointRef, rejectionRef, revisedCheckpointRef, approvalRef] -dependencies: { journeys: [], guarantees: [guarantee.agent.lifecycle.simulation-upstream-isolation.919] } -actors: { allowed: [capacity_operator, simulated_human], forbidden: [anonymous_user, unauthorized_user] } -devices: { required: [] } -gates: [core] -preconditions: { fixtures: [bounded_source_project] } -api: { required: true, verifierRefs: [market.agent-catalog.golden-live-proof] } -content: { required: true, verifierRefs: [] } -audit: { required: true, verifierRefs: [] } -negativeCases: [] -evidence: { required: [verifier_evidence, redacted_cli_transcript] } -notes: ["The deficient checkpoint is fixture evidence and is never attributed to an agent."] diff --git a/packages/market-guarantee-catalog/guarantees/capacity/research/verify-autonomous-cited-research-starter.guarantee.yaml b/packages/market-guarantee-catalog/guarantees/capacity/research/verify-autonomous-cited-research-starter.guarantee.yaml deleted file mode 100644 index 4a913839..00000000 --- a/packages/market-guarantee-catalog/guarantees/capacity/research/verify-autonomous-cited-research-starter.guarantee.yaml +++ /dev/null @@ -1,65 +0,0 @@ -schemaVersion: treeseed.guarantee/v2 -id: guarantee.capacity.research.verify-autonomous-cited-research-starter.510 -journeyIndex: 510 -type: capacity -subtype: research -journey: Verify Autonomous Cited Research Starter -ownerPackage: "@treeseed/market" -surface: agent-runtime -summary: "Prove the reconciled research starter autonomously decomposes a question, applies source policy, gathers independent evidence, rejects an unsupported claim, revises it, preserves contradiction, publishes cited knowledge, reports the workday, settles usage, and cleans up." -status: planned -capabilityId: agent.system.research-golden -catalog: agent.system -activation: { minimumConsecutivePasses: 3, requiredVariants: [baseline, clean-repeat, interruption-resume], invalidateOnSourceChange: true } -proof: - requiredCommands: [governance.proposal-show, capacity.decision-planning, capacity.capacity-plan, capacity.assignment, capacity.workday-summary, platform.status] - minimumRepositoryPostconditions: 1 - outcomePredicates: - research.governed-synthesis: [research.dynamic-context, research.two-independent-sources, research.claim-synthesis, research.source-policy, research.unsupported-claim-denial] - research.review-and-publication: [research.initial-rejection, research.semantic-revision, research.independent-approval, research.cited-output, research.reporting, research.settlement, research.cleanup] -outcomes: - - id: research.governed-synthesis - kind: required - description: Real governed retrieval supplies at least two independent cited sources and unsupported claims are denied. - evidenceKinds: [retrieval_receipt, citation_read_back, execution_trace] - authoritativeSubjects: [sourceRefs, claimArtifact] - - id: research.review-and-publication - kind: required - description: Rejection, semantic revision, independent approval, cited knowledge output, reporting, settlement, and cleanup use exact refs. - evidenceKinds: [review_read_back, repository_read_back, cleanup] - authoritativeSubjects: [rejectedCheckpointRef, approvedCheckpointRef, targetRef] -dependencies: { journeys: [], guarantees: [guarantee.agent.system.source-golden.917] } -actors: - allowed: [team_owner, capacity_provider, capacity_operator] - forbidden: [unapproved_capacity_provider, revoked_capacity_provider] -gates: [future] -preconditions: - fixtures: [integrated_treeseed_project] - notes: - - "The canonical local development stack and reconciled research starter TreeDX repository must be ready." -scene: - required: false -api: - required: true - verifierRefs: [market.agent-catalog.golden-live-proof] -content: - required: true - verifierRefs: [market.agent-catalog.golden-live-proof] -audit: - required: true - verifierRefs: [market.agent-catalog.golden-live-proof] -negativeCases: - - id: unsupported-material-claim-cannot-pass-review - actor: capacity_provider - verifierRefs: [market.agent-catalog.golden-live-proof] - - id: research-cannot-bypass-source-policy - actor: capacity_provider - verifierRefs: [market.agent-catalog.golden-live-proof] -evidence: - required: [guarantee_report, verifier_evidence, api_verification_log, audit_event_id] -notes: - - "Reopened on 2026-07-20: scripted source and execution evidence was withdrawn. Reactivate only after governed real-source collection and the complete real-provider revision workflow pass." - - "The verifier requires all four starter roles, every canonical stage with one settled assignment per attempt, two independent citations with hashes and retrieval metadata, rejection and at least one revision, repeated revision/review when approval is withheld, cited publication only after approval, Reporter completion, continuous access-token refresh, and terminal cleanup." -run: - timeoutSeconds: 14400 - requiredForRelease: false diff --git a/packages/market-guarantee-catalog/guarantees/verifiers/service-workflows.verifiers.yaml b/packages/market-guarantee-catalog/guarantees/verifiers/service-workflows.verifiers.yaml deleted file mode 100644 index 4abea416..00000000 --- a/packages/market-guarantee-catalog/guarantees/verifiers/service-workflows.verifiers.yaml +++ /dev/null @@ -1,70 +0,0 @@ -schemaVersion: treeseed.guarantee-verifiers/v1 -ownerPackage: "@treeseed/market" -verifiers: - market.portfolio.licensing: - kind: vitestCase - ownerPackage: "@treeseed/market" - testFile: tests/contract/architecture/portfolio-licensing.test.ts - timeoutSeconds: 60 - market.gateway.admin-route-inventory: - kind: vitestCase - ownerPackage: "@treeseed/sdk" - testFile: tests/unit/gateway/admin-passthrough.test.ts - timeoutSeconds: 60 - market.gateway.private-workspace-overlay: - kind: vitestCase - ownerPackage: "@treeseed/sdk" - testFile: tests/unit/seeds/managed-workspace-overlay.test.ts - timeoutSeconds: 60 - market.capacity.sdk-operator-contract: - kind: vitestCase - ownerPackage: "@treeseed/sdk" - testFile: tests/unit/agent-capacity/capacity-operator-surface.test.ts - timeoutSeconds: 60 - market.capacity.sdk-configuration-contract: - kind: vitestCase - ownerPackage: "@treeseed/sdk" - testFile: tests/contract/agent-capacity/capacity-configuration.test.ts - timeoutSeconds: 60 - market.capacity.api-operator-contract: - kind: vitestCase - ownerPackage: "@treeseed/api" - testFile: tests/integration/repositories/capacity-operator-routes.test.ts - timeoutSeconds: 120 - market.capacity.api-descriptor-contract: - kind: vitestCase - ownerPackage: "@treeseed/api" - testFile: tests/contract/api/api-route-descriptors.test.ts - timeoutSeconds: 120 - market.capacity.cli-operator-contract: - kind: nodeScript - ownerPackage: "@treeseed/cli" - command: packages/cli/tests/contract/capacity/operator-parity.test.ts - timeoutSeconds: 120 - market.capacity.cli-secret-contract: - kind: nodeScript - ownerPackage: "@treeseed/cli" - command: packages/cli/tests/contract/capacity/output-security.test.ts - timeoutSeconds: 120 - market.capacity.full-local-lifecycle: - kind: packageScript - ownerPackage: "@treeseed/market" - command: guarantee:capacity-local-acceptance - timeoutSeconds: 7200 - market.capacity.failure-concurrency-matrix: - kind: vitestCase - ownerPackage: "@treeseed/market" - testFile: tests/integration/capacity/capacity-failure-concurrency-service-workflow.test.ts - testName: recovers interruption, fences stale leases, limits cross-project pressure, and preserves human policy - timeoutSeconds: 60 - market.agent-testing.production-lab-content: - kind: vitestCase - ownerPackage: "@treeseed/sdk" - testFile: tests/unit/scenes/agent-lab/agent-lab-contract.test.ts - timeoutSeconds: 120 - market.agent-catalog.golden-live-proof: - kind: nodeScript - ownerPackage: "@treeseed/market" - command: scripts/guarantees/verify-agent-capability.ts - timeoutSeconds: 7200 - resultSchema: treeseed.guarantee-verifier-result/v1 diff --git a/profiles/capacity-provider.yaml b/profiles/capacity-provider.yaml new file mode 100644 index 00000000..ac97bfce --- /dev/null +++ b/profiles/capacity-provider.yaml @@ -0,0 +1,5 @@ +schemaVersion: treeseed.platform-profile/v1 +id: capacity-provider +extends: [] +sources: { projects: [sdk, cli, agent, deployment] } +runtime: { targets: [capacity-provider.agent, capacity-provider.sandbox] } diff --git a/profiles/control-plane.yaml b/profiles/control-plane.yaml new file mode 100644 index 00000000..4322a4e9 --- /dev/null +++ b/profiles/control-plane.yaml @@ -0,0 +1,6 @@ +schemaVersion: treeseed.platform-profile/v1 +id: control-plane +extends: [] +sources: { projects: [sdk, cli, ui, core, identity, admin, api, reviewer, treedx, deployment] } +runtime: + targets: [control-plane.identity, control-plane.api, control-plane.postgres, control-plane.operations, control-plane.admin, control-plane.treedx, development.lab] diff --git a/profiles/core.yaml b/profiles/core.yaml new file mode 100644 index 00000000..497c7fe5 --- /dev/null +++ b/profiles/core.yaml @@ -0,0 +1,6 @@ +schemaVersion: treeseed.platform-profile/v1 +id: core +extends: [] +sources: + projects: [platform, deployment, api, treedx, sdk, ui, cli, core, admin, agent, reviewer, template-engineering, template-research, market, market-api, skill, identity] +runtime: { targets: [released.all] } diff --git a/profiles/treeai.yaml b/profiles/treeai.yaml new file mode 100644 index 00000000..99f005d8 --- /dev/null +++ b/profiles/treeai.yaml @@ -0,0 +1,7 @@ +schemaVersion: treeseed.platform-profile/v1 +id: treeai +extends: [] +sources: { projects: [sdk, cli, identity, api, admin, agent, reviewer, treedx, deployment] } +runtime: + targets: [treeai.inference, treeai.training, treeai.lab] + defaultEnabled: false diff --git a/scenes/team-project-portfolio-demo.yaml b/scenes/team-project-portfolio-demo.yaml deleted file mode 100644 index 47793867..00000000 --- a/scenes/team-project-portfolio-demo.yaml +++ /dev/null @@ -1,731 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: team-project-portfolio-demo -title: Team Project Portfolio Demo -description: >- - Register a user, create the TreeSeed team, and prepare portfolio projects for research and engineering work. This scene is intentionally practical: it should expose real admin-flow, project-launch, Mailpit, recording, rendering, and training-output gaps while serving as a central TreeSeed acceptance test harness and demo / educational video generator scenario. -audience: - - evaluator - - operator - - trainee - -mode: - test: false - demo: true - training: true - -runtime: - mode: training - timeouts: - sceneSeconds: 1800 - chapterSeconds: 600 - stepSeconds: 120 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: true - -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 - -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false - browserFrame: - enabled: false - title: Team Project Portfolio Demo - chrome: desktop - - id: tablet - title: Tablet - orientation: landscape - viewport: - width: 1024 - height: 768 - video: - width: 1024 - height: 768 - output: - width: 1440 - height: 1080 - deviceScaleFactor: 1 - isMobile: true - hasTouch: true - browserFrame: - enabled: false - title: Team Project Portfolio Demo - chrome: tablet - - id: mobile - title: Mobile - orientation: portrait - viewport: - width: 390 - height: 844 - video: - width: 390 - height: 844 - output: - width: 1080 - height: 1920 - deviceScaleFactor: 2 - isMobile: true - hasTouch: true - browserFrame: - enabled: false - title: Team Project Portfolio Demo - chrome: mobile - -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true - -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true - -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser - browserFrame: - enabled: false - title: Team Project Portfolio Demo - -chapters: - - id: registration - title: Register a portfolio owner - startsAt: open-register - - id: email-confirmation - title: Confirm the account through Mailpit - startsAt: open-mailpit - - id: team-setup - title: Create the TreeSeed team - startsAt: verify-admin-home - - id: portfolio-projects - title: Prepare portfolio projects - startsAt: open-new-project-bylaws - - id: gap-review - title: Capture linked project gaps - startsAt: open-new-project-sdk - -overlays: - - id: scenario-purpose - at: open-register - renderer: remotion - type: callout - variant: panel - region: top-right - style: - tone: brand - shadow: medium - radius: 8 - motion: - keyframes: - - at: 0 - unit: progress - opacity: 0 - position: - x: 100 - y: 10 - unit: percent - - at: 0.18 - unit: progress - opacity: 1 - position: - x: 82 - y: 10 - unit: percent - - at: 1 - unit: progress - opacity: 1 - position: - x: 82 - y: 10 - unit: percent - objects: - - id: acceptance-pulse - type: circle - position: - x: 8 - y: 22 - size: - width: 14 - height: 14 - style: - tone: success - opacity: 0.82 - motion: - keyframes: - - at: 0 - unit: progress - scale: 0.8 - opacity: 0.45 - - at: 0.5 - unit: progress - scale: 1.28 - opacity: 1 - - at: 1 - unit: progress - scale: 0.8 - opacity: 0.45 - text: This demo doubles as a product acceptance probe and an educational video source. - - id: mailpit-selector-risk - at: open-mailpit - renderer: remotion - type: callout - text: Mailpit confirmation is attempted through the browser so local email and auth gaps are visible in the run artifacts. - - id: team-portfolio-context - at: open-new-team - renderer: remotion - type: callout - text: The TreeSeed team will own a portfolio of research and engineering projects. - - id: bylaws-project-context - at: open-new-project-bylaws - renderer: remotion - type: callout - text: Bylaws is expected to be a new research-template project with no upstream remote. - - id: sdk-linked-project-gap - at: capture-sdk-linking-gap - renderer: remotion - type: callout - text: >- - Expected: link github.com/treeseed-ai/sdk and request a docs repository. Current gap: this linked-project operation is not exposed by the scene runtime or obvious project UI. - - id: final-gap-summary - at: review-gap-summary - renderer: remotion - type: callout - text: Review the screenshots, timeline, captions, transcript, and evidence bundle to prioritize product and selector hardening. - -diagrams: - - id: local-runtime-topology - renderer: remotion - component: DevRuntimeTopologyDiagram - at: open-mailpit - placement: overlay - durationSeconds: 12 - style: - tone: info - shadow: medium - motion: - keyframes: - - at: 0 - unit: progress - opacity: 0 - scale: 0.96 - - at: 0.2 - unit: progress - opacity: 1 - scale: 1 - - at: 1 - unit: progress - opacity: 1 - scale: 1 - objects: - - id: mail-flow-cursor - type: arrow - from: - x: 18 - y: 80 - unit: percent - to: - x: 84 - y: 80 - unit: percent - style: - tone: brand - opacity: 0.78 - motion: - keyframes: - - at: 0 - unit: progress - opacity: 0.2 - - at: 0.6 - unit: progress - opacity: 1 - - at: 1 - unit: progress - opacity: 0.7 - props: - title: Local demo runtime - surfaces: - - id: browser - label: Browser scene - kind: playwright - - id: web - label: Local web app - kind: astro - - id: api - label: Local API - kind: treeseed-api - - id: mailpit - label: Mailpit - kind: email - links: - - from: browser - to: web - label: drives UI - - from: web - to: api - label: auth and project calls - - from: api - to: mailpit - label: confirmation email - - id: project-launch-lifecycle - renderer: remotion - component: OperationLifecycleDiagram - at: submit-bylaws-project - placement: overlay - durationSeconds: 12 - props: - title: Project launch lifecycle - states: - - form-ready - - submitted - - queued - - deploying - - review - activeState: review - - id: scene-timeline-review - renderer: remotion - component: SceneExecutionTimelineDiagram - at: review-gap-summary - placement: overlay - durationSeconds: 10 - props: - title: Portfolio demo execution timeline - showCheckpoints: true - showSegments: true - -training: - enabled: true - captions: - enabled: true - formats: - - vtt - - srt - maxCueSeconds: 6 - renderInTrainingVideo: true - transcript: - enabled: true - formats: - - json - - markdown - narration: - enabled: true - style: instructional - includeDiagnostics: true - glossary: - enabled: true - terms: - - term: team - definition: A TreeSeed ownership boundary for projects, hosts, work, and knowledge. - sourceStep: open-new-team - groupIds: - - portfolio - - term: project - definition: A managed TreeSeed work surface that can own content, repositories, hosting, and launch evidence. - sourceStep: open-new-project-bylaws - groupIds: - - portfolio - - term: research template - definition: The starter used for research and knowledge-oriented projects such as Bylaws. - sourceStep: choose-research-template - groupIds: - - template - - term: linked repository - definition: An existing upstream repository that should be connected to a TreeSeed project instead of creating a new source repository. - sourceStep: capture-sdk-linking-gap - groupIds: - - gap - - term: docs repository - definition: A documentation repository expected for the linked SDK software project. - sourceStep: capture-sdk-linking-gap - groupIds: - - gap - - term: Mailpit - definition: The local email inbox used to confirm registration during the demo. - sourceStep: open-mailpit - groupIds: - - local-dev - - term: checkpoint - definition: A resumable scene runtime marker that helps diagnose and continue long workflows. - sourceStep: review-gap-summary - groupIds: - - scene-runtime - chapterClips: - enabled: true - format: manifest - -workflow: - - id: open-register - title: Open registration for a normal user - action: - goto: /auth/register?returnTo=/app - expect: - visible: - - role: heading - name: Create account - - - id: fill-first-name - title: Enter the user's first name - action: - fill: - css: input[name="firstName"] - internal: true - value: Test - expect: - visible: - - css: input[name="firstName"] - internal: true - - - id: fill-last-name - title: Enter the user's last name - action: - fill: - css: input[name="lastName"] - internal: true - value: Portfolio - expect: - visible: - - css: input[name="lastName"] - internal: true - - - id: fill-username - title: Choose a unique username - action: - fill: - css: input[name="username"] - internal: true - value: __PORTFOLIO_USERNAME__ - expect: - visible: - - css: input[name="username"] - internal: true - - - id: fill-email - title: Enter the generated local email address - action: - fill: - css: input[name="email"] - internal: true - value: __PORTFOLIO_EMAIL__ - expect: - visible: - - css: input[name="email"] - internal: true - - - id: fill-password - title: Enter a strong generated password - action: - fill: - css: input[name="password"] - internal: true - value: __PORTFOLIO_PASSWORD__ - expect: - visible: - - css: input[name="password"] - internal: true - - - id: fill-confirm-password - title: Confirm the generated password - action: - fill: - css: input[name="confirmPassword"] - internal: true - value: __PORTFOLIO_PASSWORD__ - expect: - visible: - - css: input[name="confirmPassword"] - internal: true - - - id: submit-registration - title: Submit the registration form - action: - click: - role: button - name: Create account - expect: - text: Check your email - checkpoint: - resumable: true - - - id: open-mailpit - title: Open the local Mailpit inbox - action: - goto: __PORTFOLIO_MAILPIT_URL__ - demoOnly: true - checkpoint: - resumable: true - - - id: open-confirmation-email - title: Open the newest confirmation email - action: - click: - css: a[href^="/view/"]:has-text("__PORTFOLIO_EMAIL__") - brittle: true - demoOnly: true - continueOnFailure: true - checkpoint: - resumable: true - - - id: open-confirmation-link - title: Open the email confirmation link - action: - mailpitConfirmLatest: - mailpitUrl: __PORTFOLIO_MAILPIT_URL__ - email: __PORTFOLIO_EMAIL__ - subjectIncludes: Confirm - expect: - urlIncludes: /app - demoOnly: true - continueOnFailure: true - checkpoint: - resumable: true - - - id: verify-admin-home - title: Confirm the user can see the admin homepage - action: - goto: /app - expect: - visible: - - role: heading - name: Start - continueOnFailure: true - checkpoint: - resumable: true - - - id: open-new-team - title: Open the new team screen - action: - goto: /app/teams/new - expect: - visible: - - role: heading - name: Create team - continueOnFailure: true - - - id: fill-team-slug - title: Enter the TreeSeed team slug - action: - fill: - css: input[name="name"] - internal: true - value: treeseed - expect: - visible: - - css: input[name="name"] - internal: true - continueOnFailure: true - - - id: fill-team-display-name - title: Enter the TreeSeed team display name - action: - fill: - css: input[name="displayName"] - internal: true - value: TreeSeed - expect: - visible: - - css: input[name="displayName"] - internal: true - continueOnFailure: true - - - id: fill-team-summary - title: Describe the team project portfolio - action: - fill: - css: textarea[name="profileSummary"] - internal: true - value: TreeSeed owns a portfolio of research and engineering projects, including governance research and software platform work. - expect: - visible: - - css: textarea[name="profileSummary"] - internal: true - continueOnFailure: true - - - id: submit-team - title: Create the TreeSeed team - action: - click: - role: button - name: Create team - expect: - urlIncludes: /app/teams - continueOnFailure: true - checkpoint: - resumable: true - - - id: open-new-project-bylaws - title: Open the new project screen for Bylaws - action: - goto: /app/projects/new - expect: - text: Create hosted project - continueOnFailure: true - - - id: fill-bylaws-name - title: Enter the Bylaws project name - action: - fill: - css: input[name="name"] - internal: true - value: Bylaws - expect: - visible: - - css: input[name="name"] - internal: true - continueOnFailure: true - - - id: fill-bylaws-slug - title: Enter the Bylaws project slug - action: - fill: - css: input[name="slug"] - internal: true - value: bylaws - expect: - visible: - - css: input[name="slug"] - internal: true - continueOnFailure: true - - - id: choose-research-template - title: Choose the research template - action: - click: - css: label[for="template-research"] - internal: true - expect: - visible: - - css: label[for="template-research"] - internal: true - continueOnFailure: true - - - id: fill-bylaws-objective - title: Describe the Bylaws research objective - action: - fill: - css: textarea[name="coreObjective"] - internal: true - value: Build a research project for organizing TreeSeed bylaws, governance notes, decision records, and portfolio policy. - expect: - visible: - - css: textarea[name="coreObjective"] - internal: true - continueOnFailure: true - - - id: submit-bylaws-project - title: Submit the Bylaws project launch - action: - click: - role: button - name: Create project - expect: - visible: - - css: "body" - internal: true - continueOnFailure: true - checkpoint: - resumable: true - - - id: open-new-project-sdk - title: Open the new project screen for SDK - action: - goto: /app/projects/new - expect: - text: Create hosted project - continueOnFailure: true - - - id: fill-sdk-name - title: Enter the SDK project name - action: - fill: - css: input[name="name"] - internal: true - value: SDK - expect: - visible: - - css: input[name="name"] - internal: true - continueOnFailure: true - - - id: fill-sdk-slug - title: Enter the SDK project slug - action: - fill: - css: input[name="slug"] - internal: true - value: sdk - expect: - visible: - - css: input[name="slug"] - internal: true - continueOnFailure: true - - - id: capture-sdk-linking-gap - title: Capture the linked SDK project gap - action: - pause: - mode: timed - durationSeconds: 6 - prompt: >- - Expected linked software project: public GitHub repository github.com/treeseed-ai/sdk with a docs repository request. Current gap: this operation is not exposed by the scene runtime or obvious project UI. - demoOnly: true - continueOnFailure: true - checkpoint: - resumable: true - - - id: review-gap-summary - title: Review portfolio demo evidence and gaps - action: - goto: /app/projects - expect: - visible: - - css: "body" - internal: true - continueOnFailure: true - checkpoint: - resumable: true diff --git a/scripts/guarantees/agent-catalog/cli-runtime.ts b/scripts/guarantees/agent-catalog/cli-runtime.ts deleted file mode 100644 index 7dd0482c..00000000 --- a/scripts/guarantees/agent-catalog/cli-runtime.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { spawnSync } from 'node:child_process'; -import { resolve } from 'node:path'; - -export type ProofCommandResult = { - id:string;args:string[];exitCode:number;payload:Record;stdout:string;stderr:string; -}; - -export function runProofCli(workspaceRoot:string,id:string,args:string[]):ProofCommandResult { - const result=spawnSync(process.execPath,[resolve(workspaceRoot,'packages/cli/dist/cli/main.js'),...args,'--json'],{ - cwd:workspaceRoot,env:process.env,encoding:'utf8',maxBuffer:20*1024*1024, - }); - let payload:Record={}; - try { const start=result.stdout.indexOf('{'); payload=JSON.parse(result.stdout.slice(start)) as Record; } catch { /* raw output remains evidence */ } - return {id,args,exitCode:result.status??1,payload,stdout:result.stdout,stderr:result.stderr}; -} - -export function redactProofValue(value:unknown):unknown { - if(Array.isArray(value)) return value.map(redactProofValue); - if(value&&typeof value==='object') return Object.fromEntries(Object.entries(value as Record).map(([key,entry])=>[ - key,/secret|token|password|authorization|cookie|private.?key/iu.test(key)?'':redactProofValue(entry), - ])); - if(typeof value==='string') return value.replace(/Bearer\s+[^\s"']+/giu,'Bearer '); - return value; -} - -export function redactProofArgs(args:string[]) { - let redactNext=false; - return args.map((value)=>{ - if(redactNext) { redactNext=false; return ''; } - if(/^--(?:document|password|secret|token|authorization|private-key)$/iu.test(value)) redactNext=true; - return value; - }); -} diff --git a/scripts/guarantees/agent-catalog/json-evidence.ts b/scripts/guarantees/agent-catalog/json-evidence.ts deleted file mode 100644 index aa15fe78..00000000 --- a/scripts/guarantees/agent-catalog/json-evidence.ts +++ /dev/null @@ -1,43 +0,0 @@ -import type { AgentGuaranteeProofPredicate,AgentGuaranteeProofValueRef } from '../../../packages/sdk/src/guarantees/contracts/agent-guarantee-contracts.ts'; -import type { ProofCommandResult } from './cli-runtime.ts'; - -function children(value:unknown,token:string):unknown[] { - const wildcard=token.endsWith('[*]'); const key=wildcard?token.slice(0,-3):token; - const indexed=wildcard?null:key.match(/^(.*)\[(\d+)\]$/u); - if(indexed) { - const selected=indexed[1] ? (value&&typeof value==='object'&&!Array.isArray(value)?(value as Record)[indexed[1]]:undefined) : value; - return Array.isArray(selected)?[selected[Number(indexed[2])]]:[]; - } - const selected=key ? (value&&typeof value==='object'&&!Array.isArray(value)?(value as Record)[key]:undefined) : value; - return wildcard ? (Array.isArray(selected)?selected:[]) : [selected]; -} - -export function evidenceValues(results:Map,ref:AgentGuaranteeProofValueRef):unknown[] { - let values:unknown[]=[results.get(ref.commandId)?.payload]; - for(const token of ref.path.split('.').filter(Boolean)) values=values.flatMap((value)=>children(value,token)); - return values.filter((value)=>value!==undefined); -} - -function normalized(value:unknown){ return JSON.stringify(value); } -function expectedValue(results:Map,predicate:AgentGuaranteeProofPredicate):unknown { - if(predicate.expectedRef) { const values=evidenceValues(results,predicate.expectedRef); return values.length===1?values[0]:values; } - return predicate.expected; -} - -export function evaluatePredicate(results:Map,predicate:AgentGuaranteeProofPredicate) { - const values=evidenceValues(results,predicate); const expected=expectedValue(results,predicate); - let passed=false; - if(predicate.operator==='exists') passed=values.some((value)=>value!==null&&value!==''&&(!Array.isArray(value)||value.length>0)); - if(predicate.operator==='equals') passed=values.length>0&&values.every((value)=>normalized(value)===normalized(expected)); - if(predicate.operator==='not-equals') passed=values.length>0&&values.every((value)=>normalized(value)!==normalized(expected)); - if(predicate.operator==='includes') passed=values.length>0&&values.every((value)=>typeof value==='string'?value.includes(String(expected)):Array.isArray(value)&&value.some((entry)=>normalized(entry)===normalized(expected))); - if(predicate.operator==='matches') { try { const pattern=new RegExp(String(expected),'u'); passed=values.length>0&&values.every((value)=>pattern.test(String(value))); } catch { passed=false; } } - if(predicate.operator==='length-at-least') passed=values.length>0&&values.every((value)=>(typeof value==='string'||Array.isArray(value))&&value.length>=Number(expected)); - if(predicate.operator==='distinct') { const flattened=values.flatMap((value)=>Array.isArray(value)?value:[value]).filter((value)=>value!==null&&value!==''); passed=flattened.length>=2&&new Set(flattened.map(normalized)).size===flattened.length; } - return {passed,diagnostic:passed?'':`${predicate.id} failed: ${predicate.path} ${predicate.operator} ${normalized(expected)}; observed ${normalized(values)}.`}; -} - -export function scalarEvidence(results:Map,ref:AgentGuaranteeProofValueRef) { - const values=evidenceValues(results,ref).flatMap((value)=>Array.isArray(value)?value:[value]).filter((value)=>value!==undefined&&value!==null&&value!==''); - return values.length===1?String(values[0]):values.map(String).join(','); -} diff --git a/scripts/guarantees/agent-catalog/proof-executor.ts b/scripts/guarantees/agent-catalog/proof-executor.ts deleted file mode 100644 index 516cfbee..00000000 --- a/scripts/guarantees/agent-catalog/proof-executor.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { mkdirSync,writeFileSync } from 'node:fs'; -import { relative,resolve } from 'node:path'; -import type { AgentGuaranteeProofInput,GuaranteeVerifierResult } from '../../../packages/sdk/src/guarantees/contracts/agent-guarantee-contracts.ts'; -import { redactProofArgs,redactProofValue,runProofCli,type ProofCommandResult } from './cli-runtime.ts'; -import { evidenceValues,evaluatePredicate,scalarEvidence } from './json-evidence.ts'; - -const numberEvidence=(results:Map,ref:Parameters[1])=>Number(evidenceValues(results,ref)[0]??Number.NaN); -const booleanEvidence=(results:Map,ref:Parameters[1])=>evidenceValues(results,ref)[0]===true; - -export function executeProof(input:{workspaceRoot:string;outputRoot:string;guaranteeId:string;sourceGeneration:string;proof:AgentGuaranteeProofInput}) : GuaranteeVerifierResult { - const evidenceRoot=resolve(input.outputRoot,'agent-catalog',input.proof.capabilityId.replaceAll('.','-')); - mkdirSync(evidenceRoot,{recursive:true}); - const results=new Map(); const evidenceByCommand=new Map(); - for(const command of input.proof.commands) { - const result=runProofCli(input.workspaceRoot,command.id,command.args); results.set(command.id,result); - const path=resolve(evidenceRoot,`${command.id}.json`); - writeFileSync(path,`${JSON.stringify(redactProofValue({command:['trsd',...redactProofArgs(command.args)],expectedExitCode:command.expectedExitCode,exitCode:result.exitCode,payload:result.payload}),null,2)}\n`); - evidenceByCommand.set(command.id,relative(input.workspaceRoot,path).replaceAll('\\','/')); - } - const assertions=input.proof.outcomes.map((outcome)=>{ - const commandFailures=outcome.evidenceCommands.filter((id)=>{ - const command=input.proof.commands.find((entry)=>entry.id===id); return !command||results.get(id)?.exitCode!==command.expectedExitCode; - }); - const predicateResults=outcome.predicates.map((predicate)=>evaluatePredicate(results,predicate)); - const diagnostics=[...commandFailures.map((id)=>`Command ${id} did not return its declared exit code.`),...predicateResults.filter((entry)=>!entry.passed).map((entry)=>entry.diagnostic)]; - return {id:outcome.outcomeId,status:diagnostics.length?'failed' as const:'passed' as const,evidence:outcome.evidenceCommands.map((id)=>evidenceByCommand.get(id)!).filter(Boolean),entityRefs:Object.fromEntries(Object.entries(outcome.entityRefs).map(([key,value])=>[key,scalarEvidence(results,value)])),diagnostics}; - }); - const repositoryPostconditions=input.proof.repositoryPostconditions.map((entry)=>({ - repository:entry.repository,baseRef:scalarEvidence(results,entry.baseRef),effectiveRef:scalarEvidence(results,entry.effectiveRef),...(entry.targetRef?{targetRef:scalarEvidence(results,entry.targetRef)}:{}),changedPaths:evidenceValues(results,entry.changedPaths).flatMap((value)=>Array.isArray(value)?value:[value]).map(String),readBackVerified:booleanEvidence(results,entry.readBackVerified), - })); - const cleanup=input.proof.cleanup; - return {schemaVersion:'treeseed.guarantee-verifier-result/v1',guaranteeId:input.guaranteeId,capabilityId:input.proof.capabilityId,variant:input.proof.variant,sourceGeneration:input.sourceGeneration,assertions,repositoryPostconditions,cleanup:{verified:booleanEvidence(results,cleanup.verified),activeAssignments:numberEvidence(results,cleanup.activeAssignments),activeLeases:numberEvidence(results,cleanup.activeLeases),activeReservations:numberEvidence(results,cleanup.activeReservations),activeDemands:numberEvidence(results,cleanup.activeDemands),activeWorkspaces:numberEvidence(results,cleanup.activeWorkspaces),activeWorktrees:numberEvidence(results,cleanup.activeWorktrees),unpublishedBranches:numberEvidence(results,cleanup.unpublishedBranches),staleAuthorities:numberEvidence(results,cleanup.staleAuthorities)},evidence:[...evidenceByCommand.values()]}; -} diff --git a/scripts/guarantees/agent-catalog/proof-input.ts b/scripts/guarantees/agent-catalog/proof-input.ts deleted file mode 100644 index 6f5c47cf..00000000 --- a/scripts/guarantees/agent-catalog/proof-input.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { existsSync,readFileSync } from 'node:fs'; -import { isAbsolute,relative,resolve } from 'node:path'; -import type { GuaranteeCatalogContract } from '../../../packages/sdk/src/guarantees/contracts/agent-guarantee-contracts.ts'; -import { parseAgentGuaranteeProofInput } from '../../../packages/sdk/src/guarantees/contracts/parse-agent-guarantee-proof.ts'; - -export function loadProofInput(input:{workspaceRoot:string;contract:GuaranteeCatalogContract;variant:string;sourceGeneration:string}) { - let state:Record={}; - try { state=JSON.parse(process.env.TREESEED_GUARANTEE_RUN_STATE??'{}') as Record; } catch { /* diagnosed below */ } - const configured=typeof state.agentProofInput==='string'?state.agentProofInput.trim():''; - if(!configured) return {ok:false as const,issues:['This capability requires --proof-input .']}; - const path=resolve(input.workspaceRoot,configured); const traversal=relative(input.workspaceRoot,path); - if(isAbsolute(configured)||traversal.startsWith('..')||isAbsolute(traversal)) return {ok:false as const,issues:['Proof input must be workspace-relative.']}; - if(!existsSync(path)) return {ok:false as const,issues:[`Proof input ${configured} does not exist.`]}; - let parsed:unknown; - try { parsed=JSON.parse(readFileSync(path,'utf8')); } catch(error) { return {ok:false as const,issues:[`Proof input is not valid JSON: ${error instanceof Error?error.message:String(error)}`]}; } - const result=parseAgentGuaranteeProofInput(parsed,input.contract,input.variant,input.sourceGeneration); - return result.ok?{ok:true as const,proof:result.proof,path}:{ok:false as const,issues:result.issues}; -} diff --git a/scripts/guarantees/verify-agent-capability.ts b/scripts/guarantees/verify-agent-capability.ts deleted file mode 100644 index 2bdec377..00000000 --- a/scripts/guarantees/verify-agent-capability.ts +++ /dev/null @@ -1,119 +0,0 @@ -import { resolve } from 'node:path'; -import { spawnSync } from 'node:child_process'; -import { mkdirSync,writeFileSync } from 'node:fs'; -import { relative } from 'node:path'; -import { discoverGuarantees } from '../../packages/sdk/src/guarantees/index/parse-verifier-registry.ts'; -import { executeProof } from './agent-catalog/proof-executor.ts'; -import { loadProofInput } from './agent-catalog/proof-input.ts'; - -const workspaceRoot = resolve(process.cwd()); -const guaranteeId = process.env.TREESEED_GUARANTEE_ID?.trim() ?? ''; -const capabilityId = process.env.TREESEED_GUARANTEE_CAPABILITY_ID?.trim() ?? ''; -const sourceGeneration = process.env.TREESEED_GUARANTEE_SOURCE_GENERATION?.trim() ?? ''; -const variant = process.env.TREESEED_GUARANTEE_VARIANT?.trim() ?? ''; -const registry = discoverGuarantees({ workspaceRoot, filter: { ids: guaranteeId ? [guaranteeId] : [] } }); -const guarantee = registry.guarantees.find((entry) => entry.manifest?.id === guaranteeId)?.manifest; -if (!guarantee?.catalogContract || guarantee.catalogContract.capabilityId !== capabilityId) { - throw new Error('The requested canonical agent capability does not resolve to its exact v2 guarantee contract.'); -} - -function cli(args:string[]) { - const result=spawnSync(process.execPath,[resolve(workspaceRoot,'packages/cli/dist/cli/main.js'),...args,'--json'],{cwd:workspaceRoot,env:process.env,encoding:'utf8',maxBuffer:10*1024*1024,timeout:180_000,killSignal:'SIGTERM'}); - let payload:Record={}; - try { payload=JSON.parse(result.stdout.slice(result.stdout.indexOf('{'))) as Record; } catch { /* captured below */ } - return {args,exitCode:result.status??1,payload,stdout:result.stdout,stderr:`${result.stderr}${result.error?`\n${result.error.message}`:''}`,required:true}; -} - -function contextChecksReady(probe:ReturnType) { - return probe.exitCode===0&&/^[a-f0-9]{40}$/u.test(String(probe.payload.definitionCommit??'')) - &&Array.isArray(probe.payload.tests)&&probe.payload.tests.length>0 - &&Array.isArray(probe.payload.definitions)&&probe.payload.definitions.length>0 - &&Array.isArray(probe.payload.unpublishedAuthoring); -} - -function stableContextChecks(transcript:Array>,args:string[],minimumStableMs=0) { - const startedAt=Date.now(); let consecutive=0; let last:ReturnType|null=null; - for(let attempt=0;attempt<40;attempt+=1) { - const probe=cli(args); - last=probe; consecutive=contextChecksReady(probe)?consecutive+1:0; - const stable=Date.now()-startedAt>=minimumStableMs&&consecutive>=3; - const terminal=stable||attempt===39; - transcript.push({...probe,required:terminal,recoveryProbe:true,attempt:attempt+1}); - if(stable) return probe; - Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,750); - } - return last!; -} - -function containsResultPayload(value:unknown):boolean { - if(Array.isArray(value)) return value.some(containsResultPayload); - if(!value||typeof value!=='object') return false; - return Object.entries(value as Record).some(([key,entry])=>key==='result'||containsResultPayload(entry)); -} - -function redact(value:unknown):unknown { - if(Array.isArray(value)) return value.map(redact); - if(value&&typeof value==='object') return Object.fromEntries(Object.entries(value as Record).map(([key,entry])=>[/secret|token|password|authorization|cookie/iu.test(key)?key:key,/secret|token|password|authorization|cookie/iu.test(key)?'':redact(entry)])); - if(typeof value==='string') return value.replace(/Bearer\s+[^\s"']+/giu,'Bearer '); - return value; -} - -function contextReadinessProof() { - const team=process.env.TREESEED_AGENT_GUARANTEE_TEAM?.trim()||'treeseed'; - const market=process.env.TREESEED_AGENT_GUARANTEE_MARKET?.trim()||'local'; - const projectSelector=process.env.TREESEED_AGENT_GUARANTEE_PROJECT?.trim()||'market'; - const transcript:Array>=[]; - const projects=cli(['projects','list','--market',market]); transcript.push(projects); - const projectRows=Array.isArray(projects.payload.projects)?projects.payload.projects.filter((entry):entry is Record=>Boolean(entry&&typeof entry==='object')):[]; - const selectedProject=projectRows.find((entry)=>entry.id===projectSelector||entry.slug===projectSelector); - const project=String(selectedProject?.id??''); - const exactTeam=String(selectedProject?.teamId??team); - const checksArgs=['capacity','context-query-checks','--market',market,'--team',exactTeam,'--project',project]; - const before=project?stableContextChecks(transcript,checksArgs):{args:['capacity','context-query-checks'],exitCode:1,payload:{},stdout:'',stderr:`Project ${projectSelector} was not found.`,required:true}; - if(!project) transcript.push(before); - const tests=Array.isArray(before.payload.tests)?before.payload.tests.filter((entry):entry is Record=>Boolean(entry&&typeof entry==='object'&&Array.isArray((entry as Record).requiredBy)&&((entry as Record).requiredBy as unknown[]).length>0)):[]; - for(const [index,test] of tests.entries()) { - const id=String(test.id??''); if(!id) continue; - transcript.push(cli(['capacity','context-query-test','--market',market,'--team',exactTeam,'--project',project,'--agent-test',id,'--idempotency-key',`guarantee:${sourceGeneration}:${variant}:${id}`])); - if(variant==='interruption-resume'&&index===0) { - transcript.push(cli(['dev','restart','--app','api'])); - stableContextChecks(transcript,checksArgs,15_000); - } - } - const after=project?stableContextChecks(transcript,checksArgs):before; - const outputRoot=resolve(process.env.TREESEED_GUARANTEE_OUTPUT_ROOT||'.treeseed/guarantees/unscoped'); - mkdirSync(resolve(outputRoot,'agent-catalog'),{recursive:true}); - const transcriptPath=resolve(outputRoot,'agent-catalog','dynamic-context-transcript.json'); - writeFileSync(transcriptPath,`${JSON.stringify(redact(transcript.map(({args,exitCode,payload,stderr,required,recoveryProbe,attempt})=>({command:['trsd',...(args as string[])],exitCode,payload,stderr,required,recoveryProbe,attempt}))),null,2)}\n`); - const evidencePath=relative(workspaceRoot,transcriptPath).replaceAll('\\','/'); - const requiredTests=Array.isArray(after.payload.tests)?after.payload.tests.filter((entry)=>Array.isArray((entry as Record)?.requiredBy)&&((entry as {requiredBy:unknown[]}).requiredBy.length>0)):[]; - const passingTests=requiredTests.length>0&&requiredTests.every((entry)=>Boolean((entry as Record)?.readiness&&((entry as {readiness?:{selectable?:unknown}}).readiness?.selectable===true))); - const requiredDefinitions=Array.isArray(after.payload.definitions)?after.payload.definitions.filter((entry)=>Array.isArray((entry as Record)?.requiredBy)&&((entry as {requiredBy:unknown[]}).requiredBy.length>0)):[]; - const selectableDefinitions=requiredDefinitions.length>0&&requiredDefinitions.every((entry)=>((entry as {readiness?:{selectable?:unknown}}).readiness?.selectable===true)); - const commandsPassed=transcript.filter((entry)=>entry.required!==false).every((entry)=>entry.exitCode===0); - const noResultsPersisted=!transcript.filter((entry)=>entry.args[0]==='capacity'&&String(entry.args[1]).startsWith('context-query')).some((entry)=>containsResultPayload(entry.payload)); - const definitionCommit=String(after.payload.definitionCommit??''); - const authoringIdentity=(entry:unknown)=>entry&&typeof entry==='object'?`${String((entry as Record).commitSha??'')}:${String((entry as Record).ref??'')}`:''; - const afterAuthoring=Array.isArray(after.payload.unpublishedAuthoring)?after.payload.unpublishedAuthoring.map(authoringIdentity).filter(Boolean):[]; - return { - schemaVersion:'treeseed.guarantee-verifier-result/v1',guaranteeId,capabilityId,variant,sourceGeneration, - assertions:[ - {id:'context.current-results',status:commandsPassed&&passingTests&&selectableDefinitions?'passed':'failed',evidence:[evidencePath],entityRefs:{queryRevision:tests.map((test)=>`${String(test.definitionId)}@${String(test.definitionRevision)}`).join(','),observedSourceRef:definitionCommit},diagnostics:commandsPassed?[]:['One or more authenticated CLI query checks failed.']}, - {id:'context.results-not-persisted',status:noResultsPersisted?'passed':'failed',evidence:[evidencePath],entityRefs:{checkRecord:(Array.isArray(after.payload.items)?after.payload.items:[]).map((item)=>String((item as Record).id??'')).filter(Boolean).join(',')}}, - ],repositoryPostconditions:[], - cleanup:{verified:commandsPassed&&afterAuthoring.length===0,activeAssignments:0,activeLeases:0,activeReservations:0,activeDemands:0,activeWorkspaces:0,activeWorktrees:0,unpublishedBranches:afterAuthoring.length,staleAuthorities:0}, - evidence:[evidencePath], - }; -} - -if(capabilityId==='agent.context.dynamic-readiness') { - process.stdout.write(`${JSON.stringify(contextReadinessProof(),null,2)}\n`); - process.exit(0); -} - -const loaded=loadProofInput({workspaceRoot,contract:guarantee.catalogContract,variant,sourceGeneration}); -if(!loaded.ok) { - process.stdout.write(`${JSON.stringify({schemaVersion:'treeseed.guarantee-verifier-result/v1',guaranteeId,capabilityId,variant,sourceGeneration,assertions:guarantee.catalogContract.outcomes.map((outcome)=>({id:outcome.id,status:'blocked',evidence:[],diagnostics:loaded.issues})),repositoryPostconditions:[],cleanup:{verified:false,activeAssignments:-1,activeLeases:-1,activeReservations:-1,activeDemands:-1,activeWorkspaces:-1,activeWorktrees:-1,unpublishedBranches:-1,staleAuthorities:-1},evidence:[]},null,2)}\n`); - process.exit(0); -} -process.stdout.write(`${JSON.stringify(executeProof({workspaceRoot,outputRoot:resolve(process.env.TREESEED_GUARANTEE_OUTPUT_ROOT||'.treeseed/guarantees/unscoped'),guaranteeId,sourceGeneration,proof:loaded.proof}),null,2)}\n`); diff --git a/scripts/verify-local-workset-inventory.mjs b/scripts/verify-local-workset-inventory.mjs deleted file mode 100644 index 45560d9b..00000000 --- a/scripts/verify-local-workset-inventory.mjs +++ /dev/null @@ -1,74 +0,0 @@ -import { createHash } from 'node:crypto'; -import { readFileSync } from 'node:fs'; -import { resolve } from 'node:path'; - -const root = resolve(import.meta.dirname, '..'); -const baseUrl = process.env.TREESEED_API_BASE_URL?.trim() || 'http://127.0.0.1:3000'; -const token = process.env.TREESEED_LOCAL_OPERATOR_TOKEN?.trim(); -if (!/^http:\/\/(?:127\.0\.0\.1|localhost)(?::\d+)?$/u.test(baseUrl)) throw new Error('Local inventory verification requires a loopback API URL.'); -if (!token) throw new Error('TREESEED_LOCAL_OPERATOR_TOKEN is required; never pass it as a command argument or print it.'); - -const request = async (path) => { - const response = await fetch(`${baseUrl}${path}`, { headers: { authorization: `Bearer ${token}` } }); - const body = await response.json(); - if (!response.ok || body.ok === false) throw new Error(`Local inventory request failed at ${path} with status ${response.status}.`); - return body.payload; -}; -const text = (value) => typeof value === 'string' && value.trim() ? value.trim() : null; -const record = (value) => value && typeof value === 'object' && !Array.isArray(value) ? value : {}; -const repositoryIdentity = (value) => String(value).replace(/^https:\/\/github\.com\//u, '').replace(/\.git$/u, ''); -const expectedRepositories = [ - 'treeseed-ai/admin', 'treeseed-ai/agent', 'treeseed-ai/ai', 'treeseed-ai/api', 'treeseed-ai/cli', 'treeseed-ai/core', - 'treeseed-ai/fixtures', 'treeseed-ai/reviewer', 'treeseed-ai/sdk', 'treeseed-ai/template-engineering', - 'treeseed-ai/template-research', 'treeseed-ai/treedx', 'treeseed-ai/ui', -].sort(); -const profile = await request('/v1/teams/by-name/treeseed/profile'); -const teamId = text(record(profile.team).id); -if (!teamId) throw new Error('Local TreeSeed team profile has no id.'); -const payload = await request(`/v1/teams/${encodeURIComponent(teamId)}/project-inventory`); -const inventory = []; -const excludedExternalProjects = new Set(); -for (const project of Array.isArray(payload.projects) ? payload.projects : []) { - const metadata = record(project.metadata); - const configured = record(metadata.repository); - for (const repository of Array.isArray(project.repositories) ? project.repositories : []) { - const role = text(repository.role); - const owner = text(repository.owner); - const name = text(repository.name); - if (!['primary', 'fixture'].includes(role) || !owner || !name) continue; - if (['market', 'market-api'].includes(name)) { - excludedExternalProjects.add(`${owner}/${name}`); - continue; - } - if (name === 'platform' || name.endsWith('-content')) continue; - const policy = record(configured.repositoryPolicy); - const path = text(repository.submodulePath) || text(configured.checkoutPath); - if (!path || name === 'platform') continue; - const branch = role === 'primary' - ? text(repository.currentBranch) || text(policy.stagingBranch) || text(repository.defaultBranch) - : text(repository.currentBranch) || text(repository.defaultBranch); - if (!branch) throw new Error(`API inventory entry ${owner}/${name} is missing its observable branch.`); - inventory.push({ repository: `${owner}/${name}`, role, path, branch }); - } -} -inventory.sort((left, right) => JSON.stringify(left).localeCompare(JSON.stringify(right))); -const repositoryIdentities = inventory.map((entry) => repositoryIdentity(entry.repository)).sort(); -if (inventory.length !== 13 || JSON.stringify(repositoryIdentities) !== JSON.stringify(expectedRepositories)) { - throw new Error(`Local API inventory is not the canonical 13-repository Platform workset: ${repositoryIdentities.join(', ')}.`); -} -const receipt = JSON.parse(readFileSync(resolve(root, '.treeseed/worksets/platform/latest.json'), 'utf8')); -if (receipt.status !== 'verified') throw new Error('Platform workset receipt is not verified.'); -const observed = receipt.completed.map((action) => ({ repository: repositoryIdentity(action.repository), role: action.role, path: action.path, branch: action.sourceBranch })) - .sort((left, right) => JSON.stringify(left).localeCompare(JSON.stringify(right))); -const forbiddenObserved = observed.filter((entry) => ['treeseed-ai/market', 'treeseed-ai/market-api'].includes(entry.repository)); -if (forbiddenObserved.length > 0) throw new Error(`Platform workset contains forbidden custody: ${forbiddenObserved.map((entry) => entry.repository).join(', ')}.`); -if (JSON.stringify(inventory) !== JSON.stringify(observed)) throw new Error('Local API inventory does not equal the materialized workset receipt.'); -const digest = createHash('sha256').update(JSON.stringify(inventory)).digest('hex'); -console.log(JSON.stringify({ - ok: true, - teamId, - count: inventory.length, - inventoryDigest: `sha256:${digest}`, - receiptStatus: receipt.status, - excludedExternalProjects: [...excludedExternalProjects].sort(), -})); diff --git a/scripts/verify-platform.mjs b/scripts/verify-platform.mjs deleted file mode 100644 index b4d16e8a..00000000 --- a/scripts/verify-platform.mjs +++ /dev/null @@ -1,130 +0,0 @@ -import { execFileSync } from 'node:child_process'; -import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs'; -import { basename, resolve } from 'node:path'; - -const root = resolve(import.meta.dirname, '..'); -const fail = (message) => { throw new Error(message); }; -const read = (path) => readFileSync(resolve(root, path), 'utf8'); -const requireFile = (path) => { if (!existsSync(resolve(root, path))) fail(`Platform is missing ${path}.`); }; - -const rootPackage = JSON.parse(read('package.json')); -if ('workspaces' in rootPackage) fail('Platform must not treat independent project repositories as npm workspaces.'); -if (existsSync(resolve(root, 'package-lock.json'))) fail('Platform must not create a root package lock; each project repository owns its lock independently.'); -execFileSync(process.execPath, [resolve(root, 'scripts/verify-treeseed-skill.mjs')], { cwd: root, stdio: 'inherit' }); -if (existsSync(resolve(root, '.gitmodules'))) fail('Platform must not encode team inventory as gitlinks.'); -if (existsSync(resolve(root, 'treeseed.portfolio.json'))) fail('Platform must read live team inventory from its portable seed bundle.'); -const index = execFileSync('git', ['ls-files', '--stage'], { cwd: root, encoding: 'utf8' }); -const gitlinks = index.split('\n').filter((line) => line.startsWith('160000 ')); -if (gitlinks.length) fail(`Platform contains forbidden gitlinks: ${gitlinks.join(', ')}`); - -for (const path of ['seeds/treeseed.yaml', 'treeseed.capacity-provider.yaml', 'deployment/host-configs/development-workstation.json', 'deployment/host-configs/capacity-provider-development.json', 'deployment/integration-releases/stable.json', 'deployment/integration-releases/development.json', 'docs/multi-host-deployment.md']) requireFile(path); -for (const path of ['seeds/agents.yaml', 'seeds/platform.yaml', 'treeseed.agents-capacity-provider.yaml', 'treeseed.platform-capacity-provider.yaml']) { - if (existsSync(resolve(root, path))) fail(`Platform retains obsolete split-provider input ${path}.`); -} - -const seed = read('seeds/treeseed.yaml'); -for (const required of ['schemaVersion: treeseed.seed-bundle/v3', 'adrian.webb@knowledge.coop', 'service-principal:treeseed/automation', 'interactiveLogin: false', 'capacity-provider:treeseed/local', 'requiredLanePurposes: [communication, platform, workday]']) { - if (!seed.includes(required)) fail(`Canonical seed is missing required contract text: ${required}`); -} -for (const forbidden of ['agentLabServicePrincipals', 'providerClass:', 'adrian.webb@treeseed.dev', 'registrationKey', 'privateKey']) { - if (seed.includes(forbidden)) fail(`Canonical seed retains forbidden legacy or secret field: ${forbidden}`); -} -const projects = [...seed.matchAll(/key: ['"]?(project:treeseed\/[a-z0-9-]+)/gu)].map((match) => match[1]); -if (new Set(projects).size !== 16) fail(`Canonical seed must contain 16 unique primary projects; found ${new Set(projects).size}.`); -for (const project of ['project:treeseed/market', 'project:treeseed/market-api']) if (!projects.includes(project)) fail(`Canonical seed is missing ${project}.`); -if (!projects.includes('project:treeseed/deployment')) fail('Canonical seed is missing the shared Deployment project.'); -const repositories = [...seed.matchAll(/key: ['"]?(repository:treeseed\/[a-z0-9-]+)/gu)].map((match) => match[1]); -if (new Set(repositories).size !== 33) fail(`Canonical seed must contain 16 primary repositories, 16 libraries, and one fixture repository; found ${new Set(repositories).size}.`); -if (!/repository:treeseed\/deployment[^\n]+checkoutPath: packages\/deployment[^\n]+repositoryPolicy:/u.test(seed)) fail('Deployment must be a first-party checkout without a gitlink.'); -if (/repository:treeseed\/deployment[^\n]+submodulePath:/u.test(seed)) fail('Deployment must not be declared as a submodule.'); -if (/role: content(?:[,}\s]|$)/u.test(seed)) fail('Legacy content repository roles must not remain in the v3 seed.'); -if ((seed.match(/role: library/gmu) ?? []).length !== 16 || (seed.match(/libraryRepository:/gmu) ?? []).length !== 16) fail('Every seeded project must declare exactly one repository-backed library.'); -if (!/digest: sha256:[a-f0-9]{64}/u.test(seed)) fail('Canonical seed is not digest-bound.'); - -const provider = read('treeseed.capacity-provider.yaml'); -for (const required of ['schemaVersion: 3', 'purpose: communication', 'purpose: platform', 'purpose: workday', 'reclaimPolicy: admission', 'isolation: process']) { - if (!provider.includes(required)) fail(`Unified provider manifest is missing ${required}.`); -} -for (const forbidden of ['providerClass:', 'registrationKeyRef:', 'membershipCredentialRef:']) if (provider.includes(forbidden)) fail(`Unified provider manifest retains ${forbidden}.`); - -const host = JSON.parse(read('deployment/host-configs/development-workstation.json')); -if (host.schemaVersion !== 'treeseed.host/v1' || host.configurationId !== 'development-workstation' || host.host?.role !== 'integrated' || host.runtime?.management !== 'managed' || host.runtime?.environment !== 'development' || !host.runtime?.dataRoot?.endsWith('/platform/.treeseed/data')) fail('Development workstation must use the current integrated managed-host contract and workspace-visible data root.'); -if (host.updates?.defaultTrack !== 'development' || host.updates?.stable?.maintenanceWindow?.weekday !== 'sunday' || host.updates?.stable?.maintenanceWindow?.localTime !== '03:00') fail('Development workstation must poll development while preserving the stable weekly activation policy.'); -for (const componentId of ['api', 'agent', 'treedx', 'lab']) if (!host.components?.[componentId]?.enabled || host.components[componentId].track !== 'development') fail(`Development workstation must select the development ${componentId} release.`); -const aliases = [host.network?.manager?.aliases ?? [], ...Object.values(host.components ?? {}).flatMap((component) => Object.values(component.aliases ?? {}))].flat(); -if (aliases.length !== new Set(aliases).size || aliases.some((alias) => !/^[a-z0-9.-]+\.localhost$/u.test(alias))) fail('Local aliases must be unique and remain in the .localhost namespace.'); -const overrideKeys = Object.values(host.components ?? {}).flatMap((component) => Object.keys(component.aliases ?? {})); -if (overrideKeys.some((key) => !/^[a-z][a-z0-9.-]+\.[a-z][a-z0-9.-]+\.[a-z][a-z0-9.-]+$/u.test(key))) fail('Alias overrides must use full component.service.endpoint identities.'); -if (!host.secrets?.['agent-codex-auth'] || JSON.stringify(host).includes('auth.json')) fail('Codex custody must use the named manager secret rather than an embedded login cache.'); -if (host.generation !== 10) fail('Development workstation must use configuration generation 10.'); -if (host.components?.api?.configuration?.environment?.TREESEED_API_BASE_URL !== 'https://api.treeseed.localhost') fail('The API and managed providers must use the canonical API audience.'); -if (host.components?.api?.configuration?.environment?.TREESEED_TREEDX_URL !== 'http://treedx:4000') fail('The integrated API must use the manager-owned TreeDX service over the private platform network.'); -if (host.components?.api?.configuration?.environment?.TREESEED_API_BOOTSTRAP_ADMIN_ALLOWLIST !== 'adrian.webb@knowledge.coop') fail('A fresh workstation must assign its configured initial account through the API bootstrap-admin allowlist.'); -if (host.components?.api?.configuration?.environment?.TREESEED_SITE_URL !== 'https://api.treeseed.localhost' - || host.components?.api?.configuration?.environment?.TREESEED_MAILPIT_SMTP_HOST !== 'mailpit' - || host.components?.api?.configuration?.environment?.TREESEED_MAILPIT_SMTP_PORT !== '1025') fail('A fresh workstation must route account confirmation through the managed Lab Mailpit service.'); -const brokerSecret = 'treedx-credential-broker-assertion'; -if (host.components?.api?.configuration?.secretEnvironment?.TREESEED_TREEDX_CREDENTIAL_BROKER_ASSERTION !== brokerSecret - || host.components?.treedx?.configuration?.secretEnvironment?.TREEDX_REMOTE_CREDENTIAL_BROKER_ASSERTION !== brokerSecret - || !host.secrets?.[brokerSecret]) fail('API and TreeDX must share one manager-custodied credential-broker assertion.'); -if (host.components?.api?.configuration?.secretEnvironment?.TREESEED_GITHUB_TOKEN !== 'github-repository-token' - || host.secrets?.['github-repository-token']?.reference !== '/etc/treeseed/credentials/github-repository-token') fail('Library reconciliation requires a manager-custodied GitHub repository token outside the development data root.'); -if (host.components?.treedx?.configuration?.environment?.TREEDX_REMOTE_CREDENTIAL_BROKER_SERVICE_ID !== 'node_local' - || host.components?.treedx?.configuration?.environment?.TREEDX_GIT_EXTERNAL_TRANSPORT_ENABLED !== 'true' - || host.components?.treedx?.configuration?.environment?.TREEDX_GIT_ALLOWED_HOSTS !== 'github.com' - || host.components?.treedx?.configuration?.environment?.TREEDX_BOOTSTRAP_TRUST_ACTOR_ID !== 'treeseed-api' - || host.components?.treedx?.configuration?.environment?.TREEDX_BOOTSTRAP_TRUST_TENANT_ID !== 'treeseed-control-plane') fail('TreeDX must declare its broker identity, bounded Git hosts, and API delegation trust identity.'); -const treeDxIssuer = 'https://api.treeseed.localhost/treedx'; -const treeDxAudience = 'treedx'; -if (host.components?.api?.configuration?.environment?.TREESEED_TREEDX_JWT_ISSUER !== treeDxIssuer - || host.components?.api?.configuration?.environment?.TREESEED_TREEDX_JWT_AUDIENCE !== treeDxAudience - || host.components?.treedx?.configuration?.environment?.TREEDX_JWT_ISSUER !== treeDxIssuer - || host.components?.treedx?.configuration?.environment?.TREEDX_JWT_AUDIENCE !== treeDxAudience - || host.components?.treedx?.configuration?.environment?.TREEDX_JWT_ALLOWED_ALGS !== 'RS256') fail('API and TreeDX must share the generation 7 RS256 issuer, audience, and private JWKS discovery contract.'); -if (host.components?.agent?.connections?.['control-plane']?.kind !== 'local' || host.components?.treedx?.connections?.['control-plane']?.kind !== 'local') fail('Integrated Agent and TreeDX components require explicit local control-plane connections.'); -if (JSON.stringify(aliases.sort()) !== JSON.stringify(['api.treeseed.localhost', 'lab.treeseed.localhost', 'mail.treeseed.localhost', 'manager.treeseed.localhost', 'treedx.treeseed.localhost'])) fail('Development workstation must use only the canonical local aliases.'); -const providerHost = JSON.parse(read('deployment/host-configs/capacity-provider-development.json')); -if (providerHost.host?.role !== 'capacity-provider' || Object.keys(providerHost.components ?? {}).join(',') !== 'agent' || providerHost.components.agent?.connections?.['control-plane']?.kind !== 'remote') fail('Capacity-provider fixture must select only Agent with an explicit remote control plane.'); -if ((providerHost.network?.manager?.aliases ?? []).length || Object.values(providerHost.components.agent?.aliases ?? {}).length) fail('Private capacity-provider fixture must remain edge-free.'); - -const stableIntegration = JSON.parse(read('deployment/integration-releases/stable.json')); -const developmentIntegration = JSON.parse(read('deployment/integration-releases/development.json')); -if (stableIntegration.schemaVersion !== 'treeseed.integration-release/v1' || stableIntegration.track !== 'stable' || stableIntegration.components?.length !== 0) fail('Preproduction stable integration must remain an explicit empty base.'); -if (developmentIntegration.schemaVersion !== 'treeseed.integration-release/v1' || developmentIntegration.track !== 'development') fail('Development integration lock must use the current SDK-owned contract.'); -if (developmentIntegration.platform?.commit !== stableIntegration.platform?.commit || developmentIntegration.deployment?.commit !== stableIntegration.deployment?.commit) fail('Stable and development locks must identify the same reviewed Platform and Deployment sources.'); -if (JSON.stringify(developmentIntegration.components?.map(({ componentId }) => componentId).sort()) !== JSON.stringify(['agent', 'api', 'lab', 'treedx'])) fail('Development integration must select the exact API, Agent, TreeDX, and Lab component set.'); -for (const integration of [stableIntegration, developmentIntegration]) for (const payload of integration.hostPayloads ?? []) if (!/^https:\/\//u.test(payload.artifact?.url) || !/^[a-f0-9]{64}$/u.test(payload.artifact?.sha256 ?? '')) fail(`Integration payload ${payload.id} lacks an immutable artifact identity.`); -for (const component of developmentIntegration.components ?? []) { - if (!/^[a-f0-9]{64}$/u.test(component.manifest?.sha256 ?? '') || component.files?.some(({ artifact }) => !/^[a-f0-9]{64}$/u.test(artifact?.sha256 ?? ''))) fail(`Component ${component.componentId} is not fully digest locked.`); -} - -const config = read('treeseed.site.yaml'); -const requiredConfig = [/^authority: \{ kind: customer-platform \}\s*$/mu, /^controlPlane: \{ mode: managed \}\s*$/mu, /^\s*inventory: \{ source: seed, path: seeds\/treeseed\.yaml \}\s*$/mu, /^processing: \{ mode: local, providerRef: codex-sub \}\s*$/mu]; -if (requiredConfig.some((pattern) => !pattern.test(config))) fail('Platform configuration does not use the canonical managed local inventory.'); - -const templateIds = ['platform-local-managed-codex', 'platform-local-managed-ai', 'platform-market-codex', 'platform-external-codex']; -for (const templateId of templateIds) { - const templateRoot = resolve(root, 'templates', templateId); - const manifest = JSON.parse(readFileSync(resolve(templateRoot, 'template.config.json'), 'utf8')); - if (manifest.templateVersion !== '3.0.0') fail(`${templateId} must use unified seed template version 3.0.0.`); - for (const path of ['seeds/treeseed.yaml', 'treeseed.capacity-provider.yaml']) { - if (!manifest.managedSurface?.coreManaged?.includes(path) || !manifest.managedSurface?.validatedOnly?.includes(path)) fail(`${templateId} does not manage and validate ${path}.`); - } - if (JSON.stringify(manifest.platform?.seeds) !== JSON.stringify(['seeds/treeseed.yaml'])) fail(`${templateId} must instantiate only the canonical seed.`); - if (readFileSync(resolve(templateRoot, 'template/seeds/treeseed.yaml'), 'utf8') !== seed) fail(`${templateId} seed has drifted from the canonical bundle.`); - if (readFileSync(resolve(templateRoot, 'template/treeseed.capacity-provider.yaml'), 'utf8') !== provider) fail(`${templateId} provider manifest has drifted from the unified battery.`); - for (const legacy of ['template/seeds/agents.yaml', 'template/seeds/platform.yaml']) if (existsSync(resolve(templateRoot, legacy))) fail(`${templateId} retains ${legacy}.`); -} - -const repositoryRoots = ['packages', 'templates', '.fixtures', 'starters', 'products', 'services'].flatMap((directory) => { - const absolute = resolve(root, directory); - if (!existsSync(absolute) || !statSync(absolute).isDirectory()) return []; - return readdirSync(absolute, { withFileTypes: true }).filter((entry) => entry.isDirectory() && existsSync(resolve(absolute, entry.name, '.git'))).map((entry) => resolve(absolute, entry.name)); -}); -const marketRoots = repositoryRoots.filter((path) => ['market', 'market-api'].includes(basename(path))); -if (marketRoots.length > 2) fail(`Platform contains duplicate Market worksets: ${marketRoots.join(', ')}`); - -for (const path of ['packages/market-guarantee-catalog/guarantees/agent/system/guide-golden.guarantee.yaml', 'packages/market-guarantee-catalog/guarantees/agent/system/source-golden.guarantee.yaml', 'scripts/guarantees/verify-agent-capability.ts']) requireFile(path); -const agentGuaranteeDefinitions = readdirSync(resolve(root, 'packages/market-guarantee-catalog/guarantees'), { recursive: true }).filter((path) => typeof path === 'string' && path.endsWith('.guarantee.yaml')).length; - -console.log(JSON.stringify({ ok: true, inventoryAuthority: 'portable-seed-bundle', projects: 16, primaryRepositories: 16, projectLibraries: 16, fixtureRepositories: 1, owners: 2, providerModel: 'unified-battery-v3', lanes: ['communication', 'platform', 'workday'], gitlinks: 0, marketCheckouts: marketRoots.length, agentGuaranteeDefinitions, hostedDeployment: false })); diff --git a/scripts/verify-treeseed-skill.mjs b/scripts/verify-treeseed-skill.mjs deleted file mode 100644 index a9f8f604..00000000 --- a/scripts/verify-treeseed-skill.mjs +++ /dev/null @@ -1,37 +0,0 @@ -import { existsSync, readFileSync } from 'node:fs'; -import { resolve } from 'node:path'; - -const root = resolve(import.meta.dirname, '..'); -const skillRoot = resolve(root, 'skills/treeseed'); -const skill = readFileSync(resolve(skillRoot, 'SKILL.md'), 'utf8'); -const receipt = JSON.parse(readFileSync(resolve(skillRoot, 'catalog-receipt.json'), 'utf8')); -const composition = JSON.parse(readFileSync(resolve(root, 'docs/evidence/unified-capacity-battery-composition.json'), 'utf8')); -const fail = (message) => { throw new Error(message); }; -const categories = ['knowledge', 'governance', 'projects', 'execution', 'mcp']; - -if (!/^name: treeseed$/mu.test(skill)) fail('TreeSeed Skill name is not canonical.'); -if (!/^ protocol: "2026-07-28"$/mu.test(skill)) fail('TreeSeed Skill does not declare the accepted MCP protocol.'); -if (receipt.schemaVersion !== 'treeseed.skill-catalog-receipt/v1' || receipt.protocolVersion !== '2026-07-28') fail('TreeSeed Skill receipt version is unsupported.'); -if (JSON.stringify(receipt.categories) !== JSON.stringify(categories)) fail('TreeSeed Skill categories drifted from the accepted set.'); -if (!/^sha256:[0-9a-f]{64}$/u.test(receipt.sdk.operationCatalogDigest) || !/^sha256:[0-9a-f]{64}$/u.test(receipt.sdk.mcpInputDigest) || !/^sha256:[0-9a-f]{64}$/u.test(receipt.api.mcpCatalogDigest)) fail('TreeSeed Skill receipt contains an invalid catalog digest.'); -if (composition.schemaVersion !== 'treeseed.platform-composition-evidence/v1' || composition.status !== 'staging_accepted') fail('TreeSeed capacity-battery composition evidence is not accepted.'); -const sdk = composition.members?.sdk; -const api = composition.members?.api; -if (receipt.sdk.version !== sdk?.version || receipt.sdk.stagingCommit !== sdk?.sourceCommit - || receipt.sdk.operationCatalogDigest !== `sha256:${sdk?.operationCatalogSha256}` - || receipt.sdk.mcpInputDigest !== `sha256:${sdk?.mcpInputSha256}`) fail('TreeSeed Skill SDK receipt drifted from the accepted composition.'); -if (receipt.api.stagingCommit !== api?.sourceCommit || receipt.api.openApiDigest !== `sha256:${api?.openApiSha256}` - || receipt.api.mcpCatalogDigest !== `sha256:${api?.mcpCatalogSha256}`) fail('TreeSeed Skill API receipt drifted from the accepted composition.'); -for (const field of ['tools', 'resources', 'resourceTemplates', 'prompts']) { - if (receipt.mcpSurface[field] !== api?.mcp?.[field]) fail(`TreeSeed Skill MCP ${field} receipt drifted from the accepted composition.`); -} - -for (const category of categories) { - const reference = `references/${category}.md`; - if (!skill.includes(`](${reference})`) || !existsSync(resolve(skillRoot, reference))) fail(`TreeSeed Skill is missing its ${category} reference.`); -} - -for (const forbidden of ['/v1/', 'tools/call', 'MarketClient', '--market']) if (skill.includes(forbidden)) fail(`TreeSeed Skill hard-codes forbidden transport detail: ${forbidden}`); -if (!/Discover its current MCP tools, resources, templates, prompts, schemas, and capability annotations/u.test(skill)) fail('TreeSeed Skill does not require runtime capability discovery.'); - -console.log(JSON.stringify({ ok: true, skill: 'treeseed', protocolVersion: receipt.protocolVersion, categories, sdkVersion: receipt.sdk.version, apiStaging: receipt.api.stagingCommit, mcpCatalogDigest: receipt.api.mcpCatalogDigest })); diff --git a/seeds/README.md b/seeds/README.md index 66d32cb7..3b394006 100644 --- a/seeds/README.md +++ b/seeds/README.md @@ -13,7 +13,11 @@ trsd seeds apply seeds/treeseed.yaml trsd seeds verify treeseed ``` -The seed declares one local `treeseed.capacity-provider/v3` battery with -communication, platform, and workday lanes. Enrollment and owner approval are -runtime operations; no token, key, membership credential, or interactive -service-principal credential belongs in either YAML file. +The authenticated user applying a local seed becomes an owner of every team +created by that seed. The bundle therefore contains no personal membership or +email bootstrap. + +Capacity-provider identity, capacity, enrollment, environment grants, and +owner approval are runtime operations. No token, key, host capacity, provider +identity, membership credential, or interactive service-principal credential +belongs in the portable seed. diff --git a/seeds/treeseed.yaml b/seeds/treeseed.yaml index fac2b439..8d3933fa 100644 --- a/seeds/treeseed.yaml +++ b/seeds/treeseed.yaml @@ -1,55 +1,57 @@ schemaVersion: treeseed.seed-bundle/v3 name: treeseed -version: 4 -description: Reproducible local TreeSeed portfolio with one unified capacity-provider battery. -environments: [local, staging, prod] -digest: sha256:e983c02364fb1e292018acf264c447da697d3fc106608ba76ce8d9656671c116 +version: 11 +description: Portable first-party source and library inventory for integrated and selective development. +environments: [local] +digest: sha256:8a71ce152df9fdb9696855c48da28f77a8755635a380caecc0386c6310c6ec60 resources: teams: - { key: 'team:treeseed', slug: treeseed, name: treeseed, displayName: TreeSeed, profileSummary: 'TreeSeed platform, packages, products, and agent operations.' } - memberships: - - { key: 'membership:treeseed/adrian-webb', team: 'team:treeseed', principal: { kind: user, email: 'adrian.webb@knowledge.coop' }, roles: [team_owner], missingUser: reject } - - key: membership:treeseed/automation - team: team:treeseed - principal: { kind: service-principal, key: 'service-principal:treeseed/automation', displayName: TreeSeed Automation, interactiveLogin: false } - roles: [team_owner] + # The authenticated local seed actor becomes a team owner at apply time. Keep + # personal identities and host-specific membership bootstrap out of Platform. + memberships: [] projects: + - { key: 'project:treeseed/identity', team: 'team:treeseed', slug: identity, name: TreeSeed Identity, description: Sovereign identity and session integration., kind: package, primaryRepository: 'repository:treeseed/identity', libraryRepository: 'repository:treeseed/identity-library', metadata: { packageId: '@treeseed/identity' } } + - { key: 'project:treeseed/team', team: 'team:treeseed', slug: team, name: Team Library, description: Shared TreeSeed team knowledge and context., kind: content, libraryRepository: 'repository:treeseed/team-library' } - { key: 'project:treeseed/platform', team: 'team:treeseed', slug: platform, name: TreeSeed Platform, description: Public installer and portfolio integration workspace., kind: platform, primaryRepository: 'repository:treeseed/platform', libraryRepository: 'repository:treeseed/platform-library' } - - { key: 'project:treeseed/deployment', team: 'team:treeseed', slug: deployment, name: TreeSeed Deployment, description: Shared Debian bootstrap, host manager, edge, and component integration system., kind: platform, primaryRepository: 'repository:treeseed/deployment', libraryRepository: 'repository:treeseed/deployment-library' } + - { key: 'project:treeseed/deployment', team: 'team:treeseed', slug: deployment, name: TreeSeed Deployment, description: Debian bootstrap and host-manager integration system., kind: platform, primaryRepository: 'repository:treeseed/deployment', libraryRepository: 'repository:treeseed/deployment-library' } - { key: 'project:treeseed/api', team: 'team:treeseed', slug: api, name: TreeSeed API, description: Authoritative TreeSeed control plane., kind: package, primaryRepository: 'repository:treeseed/api', libraryRepository: 'repository:treeseed/api-library', metadata: { packageId: '@treeseed/api' } } - { key: 'project:treeseed/treedx', team: 'team:treeseed', slug: treedx, name: TreeDX, description: Independent content and knowledge service., kind: service, primaryRepository: 'repository:treeseed/treedx', libraryRepository: 'repository:treeseed/treedx-library' } - { key: 'project:treeseed/sdk', team: 'team:treeseed', slug: sdk, name: TreeSeed SDK, description: Portable contracts and remote clients., kind: package, primaryRepository: 'repository:treeseed/sdk', libraryRepository: 'repository:treeseed/sdk-library', metadata: { packageId: '@treeseed/sdk' } } - - { key: 'project:treeseed/ui', team: 'team:treeseed', slug: ui, name: TreeSeed UI, description: TreeSeed user-interface package., kind: package, primaryRepository: 'repository:treeseed/ui', libraryRepository: 'repository:treeseed/ui-library', metadata: { packageId: '@treeseed/ui' } } + - { key: 'project:treeseed/ui', team: 'team:treeseed', slug: ui, name: TreeSeed UI, description: Shared TreeSeed user-interface package., kind: package, primaryRepository: 'repository:treeseed/ui', libraryRepository: 'repository:treeseed/ui-library', metadata: { packageId: '@treeseed/ui' } } - { key: 'project:treeseed/cli', team: 'team:treeseed', slug: cli, name: TreeSeed CLI, description: Human-centered TreeSeed command-line interface., kind: package, primaryRepository: 'repository:treeseed/cli', libraryRepository: 'repository:treeseed/cli-library', metadata: { packageId: '@treeseed/cli' } } - { key: 'project:treeseed/core', team: 'team:treeseed', slug: core, name: TreeSeed Core, description: Core TreeSeed package., kind: package, primaryRepository: 'repository:treeseed/core', libraryRepository: 'repository:treeseed/core-library', metadata: { packageId: '@treeseed/core' } } - { key: 'project:treeseed/admin', team: 'team:treeseed', slug: admin, name: TreeSeed Admin, description: TreeSeed administration interface., kind: package, primaryRepository: 'repository:treeseed/admin', libraryRepository: 'repository:treeseed/admin-library', metadata: { packageId: '@treeseed/admin' } } - - { key: 'project:treeseed/agent', team: 'team:treeseed', slug: agent, name: TreeSeed Agent, description: Unified capacity-provider and agent execution runtime., kind: package, primaryRepository: 'repository:treeseed/agent', libraryRepository: 'repository:treeseed/agent-library', metadata: { packageId: '@treeseed/agent' } } + - { key: 'project:treeseed/agent', team: 'team:treeseed', slug: agent, name: TreeSeed Agent, description: Capacity-provider and agent execution runtime., kind: package, primaryRepository: 'repository:treeseed/agent', libraryRepository: 'repository:treeseed/agent-library', metadata: { packageId: '@treeseed/agent' } } - { key: 'project:treeseed/reviewer', team: 'team:treeseed', slug: reviewer, name: TreeSeed Reviewer, description: Independent review package., kind: package, primaryRepository: 'repository:treeseed/reviewer', libraryRepository: 'repository:treeseed/reviewer-library', metadata: { packageId: '@treeseed/reviewer' } } - - { key: 'project:treeseed/ai', team: 'team:treeseed', slug: ai, name: TreeSeed AI, description: AI integration package., kind: package, primaryRepository: 'repository:treeseed/ai', libraryRepository: 'repository:treeseed/ai-library', metadata: { packageId: '@treeseed/ai' } } - { key: 'project:treeseed/template-engineering', team: 'team:treeseed', slug: template-engineering, name: Engineering Template, description: Engineering project template., kind: template, primaryRepository: 'repository:treeseed/template-engineering', libraryRepository: 'repository:treeseed/template-engineering-library' } - { key: 'project:treeseed/template-research', team: 'team:treeseed', slug: template-research, name: Research Template, description: Research project template., kind: template, primaryRepository: 'repository:treeseed/template-research', libraryRepository: 'repository:treeseed/template-research-library' } - - { key: 'project:treeseed/market', team: 'team:treeseed', slug: market, name: TreeSeed Market, description: First-party portfolio product managed independently from Platform deployment., kind: product, primaryRepository: 'repository:treeseed/market', libraryRepository: 'repository:treeseed/market-library' } - - { key: 'project:treeseed/market-api', team: 'team:treeseed', slug: market-api, name: TreeSeed Market API, description: First-party Market service managed independently from Platform deployment., kind: service, primaryRepository: 'repository:treeseed/market-api', libraryRepository: 'repository:treeseed/market-api-library' } + - { key: 'project:treeseed/market', team: 'team:treeseed', slug: market, name: TreeSeed Market, description: First-party portfolio product with independent hosted-deployment authority., kind: product, primaryRepository: 'repository:treeseed/market', libraryRepository: 'repository:treeseed/market-library' } + - { key: 'project:treeseed/market-api', team: 'team:treeseed', slug: market-api, name: TreeSeed Market API, description: First-party Market service with independent hosted-deployment authority., kind: service, primaryRepository: 'repository:treeseed/market-api', libraryRepository: 'repository:treeseed/market-api-library' } + - { key: 'project:treeseed/skill', team: 'team:treeseed', slug: skill, name: TreeSeed Skill, description: Versioned agent skill for operating the TreeSeed ecosystem., kind: skill, primaryRepository: 'repository:treeseed/skill', libraryRepository: 'repository:treeseed/skill-library' } repositories: - - &platform_repo { key: 'repository:treeseed/platform', project: 'project:treeseed/platform', role: primary, provider: github, owner: treeseed-ai, name: platform, gitUrl: 'git@github.com:treeseed-ai/platform.git', defaultBranch: main, checkoutPath: '.', repositoryPolicy: &public_repo { visibility: public, lifecycle: create-or-adopt, deletionPolicy: retain, defaultBranch: main, stagingBranch: staging, issues: true, actions: true, workflows: [verify.yml] } } - - { key: 'repository:treeseed/deployment', project: 'project:treeseed/deployment', role: primary, provider: github, owner: treeseed-ai, name: deployment, gitUrl: 'git@github.com:treeseed-ai/deployment.git', defaultBranch: main, checkoutPath: packages/deployment, repositoryPolicy: *public_repo, metadata: { deploymentAuthority: host-manager } } - - { key: 'repository:treeseed/api', project: 'project:treeseed/api', role: primary, provider: github, owner: treeseed-ai, name: api, gitUrl: 'git@github.com:treeseed-ai/api.git', defaultBranch: main, checkoutPath: packages/api, submodulePath: packages/api, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/treedx', project: 'project:treeseed/treedx', role: primary, provider: github, owner: treeseed-ai, name: treedx, gitUrl: 'git@github.com:treeseed-ai/treedx.git', defaultBranch: main, checkoutPath: packages/treedx, submodulePath: packages/treedx, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/sdk', project: 'project:treeseed/sdk', role: primary, provider: github, owner: treeseed-ai, name: sdk, gitUrl: 'git@github.com:treeseed-ai/sdk.git', defaultBranch: main, checkoutPath: packages/sdk, submodulePath: packages/sdk, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/ui', project: 'project:treeseed/ui', role: primary, provider: github, owner: treeseed-ai, name: ui, gitUrl: 'git@github.com:treeseed-ai/ui.git', defaultBranch: main, checkoutPath: packages/ui, submodulePath: packages/ui, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/cli', project: 'project:treeseed/cli', role: primary, provider: github, owner: treeseed-ai, name: cli, gitUrl: 'git@github.com:treeseed-ai/cli.git', defaultBranch: main, checkoutPath: packages/cli, submodulePath: packages/cli, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/core', project: 'project:treeseed/core', role: primary, provider: github, owner: treeseed-ai, name: core, gitUrl: 'git@github.com:treeseed-ai/core.git', defaultBranch: main, checkoutPath: packages/core, submodulePath: packages/core, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/admin', project: 'project:treeseed/admin', role: primary, provider: github, owner: treeseed-ai, name: admin, gitUrl: 'git@github.com:treeseed-ai/admin.git', defaultBranch: main, checkoutPath: packages/admin, submodulePath: packages/admin, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/agent', project: 'project:treeseed/agent', role: primary, provider: github, owner: treeseed-ai, name: agent, gitUrl: 'git@github.com:treeseed-ai/agent.git', defaultBranch: main, checkoutPath: packages/agent, submodulePath: packages/agent, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/reviewer', project: 'project:treeseed/reviewer', role: primary, provider: github, owner: treeseed-ai, name: reviewer, gitUrl: 'git@github.com:treeseed-ai/reviewer.git', defaultBranch: main, checkoutPath: packages/reviewer, submodulePath: packages/reviewer, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/ai', project: 'project:treeseed/ai', role: primary, provider: github, owner: treeseed-ai, name: ai, gitUrl: 'git@github.com:treeseed-ai/ai.git', defaultBranch: main, checkoutPath: packages/ai, submodulePath: packages/ai, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/template-engineering', project: 'project:treeseed/template-engineering', role: primary, provider: github, owner: treeseed-ai, name: template-engineering, gitUrl: 'git@github.com:treeseed-ai/template-engineering.git', defaultBranch: main, checkoutPath: templates/engineering, submodulePath: templates/engineering, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/template-research', project: 'project:treeseed/template-research', role: primary, provider: github, owner: treeseed-ai, name: template-research, gitUrl: 'git@github.com:treeseed-ai/template-research.git', defaultBranch: main, checkoutPath: templates/research, submodulePath: templates/research, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/market', project: 'project:treeseed/market', role: primary, provider: github, owner: treeseed-ai, name: market, gitUrl: 'git@github.com:treeseed-ai/market.git', defaultBranch: main, checkoutPath: products/market, repositoryPolicy: *public_repo, metadata: { platformCustody: portfolio-only, deployableByPlatform: false } } - - { key: 'repository:treeseed/market-api', project: 'project:treeseed/market-api', role: primary, provider: github, owner: treeseed-ai, name: market-api, gitUrl: 'git@github.com:treeseed-ai/market-api.git', defaultBranch: main, checkoutPath: services/market-api, repositoryPolicy: &private_repo { visibility: private, lifecycle: create-or-adopt, deletionPolicy: retain, defaultBranch: main, stagingBranch: staging, issues: true, actions: true, workflows: [verify.yml] }, metadata: { platformCustody: portfolio-only, deployableByPlatform: false } } + - { key: 'repository:treeseed/team-library', project: 'project:treeseed/team', role: library, provider: github, owner: treeseed-ai, name: team-library, gitUrl: 'https://github.com/treeseed-ai/team-library.git', defaultBranch: main, repositoryPolicy: { visibility: public, lifecycle: adopt, deletionPolicy: retain, defaultBranch: main, stagingBranch: staging, issues: true, actions: true, workflows: [] }, metadata: { libraryRoot: '.', synchronizedRefs: [main, staging] } } + - { key: 'repository:treeseed/platform', project: 'project:treeseed/platform', role: primary, provider: github, owner: treeseed-ai, name: platform, gitUrl: 'https://github.com/treeseed-ai/platform.git', defaultBranch: main, checkoutPath: '.', repositoryPolicy: &public_repo { visibility: public, lifecycle: create-or-adopt, deletionPolicy: retain, defaultBranch: main, stagingBranch: staging, issues: true, actions: true, workflows: [verify.yml] } } + - { key: 'repository:treeseed/deployment', project: 'project:treeseed/deployment', role: primary, provider: github, owner: treeseed-ai, name: deployment, gitUrl: 'https://github.com/treeseed-ai/deployment.git', defaultBranch: main, checkoutPath: packages/deployment, repositoryPolicy: *public_repo, metadata: { deploymentAuthority: host-manager } } + - { key: 'repository:treeseed/api', project: 'project:treeseed/api', role: primary, provider: github, owner: treeseed-ai, name: api, gitUrl: 'https://github.com/treeseed-ai/api.git', defaultBranch: main, checkoutPath: packages/api, repositoryPolicy: *public_repo } + - { key: 'repository:treeseed/identity', project: 'project:treeseed/identity', role: primary, provider: github, owner: treeseed-ai, name: identity, gitUrl: 'https://github.com/treeseed-ai/identity.git', defaultBranch: main, checkoutPath: packages/identity, repositoryPolicy: *public_repo } + - { key: 'repository:treeseed/treedx', project: 'project:treeseed/treedx', role: primary, provider: github, owner: treeseed-ai, name: treedx, gitUrl: 'https://github.com/treeseed-ai/treedx.git', defaultBranch: main, checkoutPath: packages/treedx, repositoryPolicy: *public_repo } + - { key: 'repository:treeseed/sdk', project: 'project:treeseed/sdk', role: primary, provider: github, owner: treeseed-ai, name: sdk, gitUrl: 'https://github.com/treeseed-ai/sdk.git', defaultBranch: main, checkoutPath: packages/sdk, repositoryPolicy: *public_repo } + - { key: 'repository:treeseed/ui', project: 'project:treeseed/ui', role: primary, provider: github, owner: treeseed-ai, name: ui, gitUrl: 'https://github.com/treeseed-ai/ui.git', defaultBranch: main, checkoutPath: packages/ui, repositoryPolicy: *public_repo } + - { key: 'repository:treeseed/cli', project: 'project:treeseed/cli', role: primary, provider: github, owner: treeseed-ai, name: cli, gitUrl: 'https://github.com/treeseed-ai/cli.git', defaultBranch: main, checkoutPath: packages/cli, repositoryPolicy: *public_repo } + - { key: 'repository:treeseed/core', project: 'project:treeseed/core', role: primary, provider: github, owner: treeseed-ai, name: core, gitUrl: 'https://github.com/treeseed-ai/core.git', defaultBranch: main, checkoutPath: packages/core, repositoryPolicy: *public_repo } + - { key: 'repository:treeseed/admin', project: 'project:treeseed/admin', role: primary, provider: github, owner: treeseed-ai, name: admin, gitUrl: 'https://github.com/treeseed-ai/admin.git', defaultBranch: main, checkoutPath: packages/admin, repositoryPolicy: *public_repo } + - { key: 'repository:treeseed/agent', project: 'project:treeseed/agent', role: primary, provider: github, owner: treeseed-ai, name: agent, gitUrl: 'https://github.com/treeseed-ai/agent.git', defaultBranch: main, checkoutPath: packages/agent, repositoryPolicy: *public_repo } + - { key: 'repository:treeseed/reviewer', project: 'project:treeseed/reviewer', role: primary, provider: github, owner: treeseed-ai, name: reviewer, gitUrl: 'https://github.com/treeseed-ai/reviewer.git', defaultBranch: main, checkoutPath: packages/reviewer, repositoryPolicy: *public_repo } + - { key: 'repository:treeseed/template-engineering', project: 'project:treeseed/template-engineering', role: primary, provider: github, owner: treeseed-ai, name: template-engineering, gitUrl: 'https://github.com/treeseed-ai/template-engineering.git', defaultBranch: main, checkoutPath: packages/template-engineering, repositoryPolicy: *public_repo } + - { key: 'repository:treeseed/template-research', project: 'project:treeseed/template-research', role: primary, provider: github, owner: treeseed-ai, name: template-research, gitUrl: 'https://github.com/treeseed-ai/template-research.git', defaultBranch: main, checkoutPath: packages/template-research, repositoryPolicy: *public_repo } + - { key: 'repository:treeseed/market', project: 'project:treeseed/market', role: primary, provider: github, owner: treeseed-ai, name: market, gitUrl: 'https://github.com/treeseed-ai/market.git', defaultBranch: main, checkoutPath: packages/market, repositoryPolicy: *public_repo, metadata: { hostedDeploymentAuthority: external } } + - { key: 'repository:treeseed/market-api', project: 'project:treeseed/market-api', role: primary, provider: github, owner: treeseed-ai, name: market-api, gitUrl: 'https://github.com/treeseed-ai/market-api.git', defaultBranch: main, checkoutPath: packages/market-api, repositoryPolicy: *public_repo, metadata: { hostedDeploymentAuthority: external } } + - { key: 'repository:treeseed/skill', project: 'project:treeseed/skill', role: primary, provider: github, owner: treeseed-ai, name: skill, gitUrl: 'https://github.com/treeseed-ai/skill.git', defaultBranch: main, checkoutPath: packages/skill, repositoryPolicy: *public_repo } - { key: 'repository:treeseed/platform-library', project: 'project:treeseed/platform', role: library, provider: github, owner: treeseed-ai, name: platform-library, gitUrl: 'https://github.com/treeseed-ai/platform-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: &library_metadata { libraryRoot: '.', synchronizedRefs: [main, staging] } } - { key: 'repository:treeseed/deployment-library', project: 'project:treeseed/deployment', role: library, provider: github, owner: treeseed-ai, name: deployment-library, gitUrl: 'https://github.com/treeseed-ai/deployment-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - { key: 'repository:treeseed/api-library', project: 'project:treeseed/api', role: library, provider: github, owner: treeseed-ai, name: api-library, gitUrl: 'https://github.com/treeseed-ai/api-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } + - { key: 'repository:treeseed/identity-library', project: 'project:treeseed/identity', role: library, provider: github, owner: treeseed-ai, name: identity-library, gitUrl: 'https://github.com/treeseed-ai/identity-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - { key: 'repository:treeseed/treedx-library', project: 'project:treeseed/treedx', role: library, provider: github, owner: treeseed-ai, name: treedx-library, gitUrl: 'https://github.com/treeseed-ai/treedx-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - { key: 'repository:treeseed/sdk-library', project: 'project:treeseed/sdk', role: library, provider: github, owner: treeseed-ai, name: sdk-library, gitUrl: 'https://github.com/treeseed-ai/sdk-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - { key: 'repository:treeseed/ui-library', project: 'project:treeseed/ui', role: library, provider: github, owner: treeseed-ai, name: ui-library, gitUrl: 'https://github.com/treeseed-ai/ui-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } @@ -58,20 +60,40 @@ resources: - { key: 'repository:treeseed/admin-library', project: 'project:treeseed/admin', role: library, provider: github, owner: treeseed-ai, name: admin-library, gitUrl: 'https://github.com/treeseed-ai/admin-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - { key: 'repository:treeseed/agent-library', project: 'project:treeseed/agent', role: library, provider: github, owner: treeseed-ai, name: agent-library, gitUrl: 'https://github.com/treeseed-ai/agent-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - { key: 'repository:treeseed/reviewer-library', project: 'project:treeseed/reviewer', role: library, provider: github, owner: treeseed-ai, name: reviewer-library, gitUrl: 'https://github.com/treeseed-ai/reviewer-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/ai-library', project: 'project:treeseed/ai', role: library, provider: github, owner: treeseed-ai, name: ai-library, gitUrl: 'https://github.com/treeseed-ai/ai-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - { key: 'repository:treeseed/template-engineering-library', project: 'project:treeseed/template-engineering', role: library, provider: github, owner: treeseed-ai, name: template-engineering-library, gitUrl: 'https://github.com/treeseed-ai/template-engineering-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - { key: 'repository:treeseed/template-research-library', project: 'project:treeseed/template-research', role: library, provider: github, owner: treeseed-ai, name: template-research-library, gitUrl: 'https://github.com/treeseed-ai/template-research-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - { key: 'repository:treeseed/market-library', project: 'project:treeseed/market', role: library, provider: github, owner: treeseed-ai, name: market-library, gitUrl: 'https://github.com/treeseed-ai/market-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/market-api-library', project: 'project:treeseed/market-api', role: library, provider: github, owner: treeseed-ai, name: market-api-library, gitUrl: 'https://github.com/treeseed-ai/market-api-library.git', defaultBranch: main, repositoryPolicy: *private_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/fixtures', project: 'project:treeseed/platform', role: fixture, provider: github, owner: treeseed-ai, name: fixtures, gitUrl: 'git@github.com:treeseed-ai/fixtures.git', defaultBranch: main, checkoutPath: fixtures, submodulePath: fixtures, repositoryPolicy: { visibility: public, lifecycle: create-or-adopt, deletionPolicy: retain, defaultBranch: main, stagingBranch: staging, issues: true, actions: false, workflows: [] } } + - { key: 'repository:treeseed/market-api-library', project: 'project:treeseed/market-api', role: library, provider: github, owner: treeseed-ai, name: market-api-library, gitUrl: 'https://github.com/treeseed-ai/market-api-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } + - { key: 'repository:treeseed/skill-library', project: 'project:treeseed/skill', role: library, provider: github, owner: treeseed-ai, name: skill-library, gitUrl: 'https://github.com/treeseed-ai/skill-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } + - { key: 'repository:treeseed/fixtures', project: 'project:treeseed/platform', role: fixture, provider: github, owner: treeseed-ai, name: fixtures, gitUrl: 'https://github.com/treeseed-ai/fixtures.git', defaultBranch: main, checkoutPath: .fixtures, repositoryPolicy: { visibility: public, lifecycle: create-or-adopt, deletionPolicy: retain, defaultBranch: main, stagingBranch: staging, issues: true, actions: false, workflows: [] } } runtime: + # Local development adopts the approved provider or uses protected local + # enrollment. Identity, machine capacity and credentials remain runtime inputs. + # This local-only seed does not authorize production provider enrollment. capacityProviders: - key: capacity-provider:treeseed/local team: team:treeseed environments: [local] - manifestDigest: sha256:9b3f675f40a7f23d66cc7429600d68438cb28ba866ebe4ce8688e240a4fa482c - manifestRef: treeseed.capacity-provider.yaml approval: trusted-local-owner - projects: ['project:treeseed/platform', 'project:treeseed/deployment', 'project:treeseed/api', 'project:treeseed/treedx', 'project:treeseed/sdk', 'project:treeseed/ui', 'project:treeseed/cli', 'project:treeseed/core', 'project:treeseed/admin', 'project:treeseed/agent', 'project:treeseed/reviewer', 'project:treeseed/ai', 'project:treeseed/template-engineering', 'project:treeseed/template-research', 'project:treeseed/market', 'project:treeseed/market-api'] - allowedModes: [planning, acting] + manifestRef: https://github.com/treeseed-ai/agent/releases/download/0.13.0-rc.45/component-release.json + manifestDigest: sha256:ec93a341addcecc3dee9b7010a2f4d5923a326c36a91b120b729c9acab9ff514 requiredLanePurposes: [communication, platform, workday] + allowedModes: [planning, acting] + projects: + - project:treeseed/platform + - project:treeseed/deployment + - project:treeseed/api + - project:treeseed/identity + - project:treeseed/treedx + - project:treeseed/sdk + - project:treeseed/ui + - project:treeseed/cli + - project:treeseed/core + - project:treeseed/admin + - project:treeseed/agent + - project:treeseed/reviewer + - project:treeseed/template-engineering + - project:treeseed/template-research + - project:treeseed/market + - project:treeseed/market-api + - project:treeseed/skill diff --git a/skills-lock.json b/skills-lock.json new file mode 100644 index 00000000..8ae1e95c --- /dev/null +++ b/skills-lock.json @@ -0,0 +1,12 @@ +{ + "version": 1, + "skills": { + "treeseed": { + "source": "treeseed-ai/skill", + "ref": "0.1.0-rc.1", + "sourceType": "github", + "skillPath": "SKILL.md", + "computedHash": "9f7ee249da009916505cf5d4ca9ad1091080221ae5f17577f17d824a1ec710f6" + } + } +} diff --git a/skills/treeseed/SKILL.md b/skills/treeseed/SKILL.md deleted file mode 100644 index 936aa570..00000000 --- a/skills/treeseed/SKILL.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -name: treeseed -description: Operate a TreeSeed control plane through its current MCP capabilities for project, knowledge, governance, and execution work. Use when a task targets TreeSeed records or governed project-agent chat; do not use it as authority to run agents or mutate repositories. -metadata: - protocol: "2026-07-28" - catalog-receipt: "catalog-receipt.json" - categories: "knowledge,governance,projects,execution,mcp" ---- - -# TreeSeed - -Treat the connected TreeSeed server as the authority for identity, access, governance, scheduling, and receipts. Discover its current MCP tools, resources, templates, prompts, schemas, and capability annotations before choosing an operation. Do not rely on a remembered tool list or construct REST paths. - -## Operating boundary - -- Act as the authenticated external principal. Do not claim project-agent identity unless an explicit, authorized project-agent chat operation returns that delegation. -- Read current state before a consequential mutation. Follow returned blockers, concurrency tokens, confirmation requests, resource links, and next actions. -- Use server-provided structured input and output schemas. Never place credentials, session material, private keys, or bearer tokens in tool arguments or model-visible content. -- Treat `input_required` as a signed, exact-argument confirmation checkpoint. Ask the human when required; never alter, reuse, or synthesize confirmation state. -- Follow durable `treeseed://` resource links for asynchronous work. Use progress, cancellation, completion, and subscriptions when advertised instead of polling invented endpoints. -- Do not invoke or emulate `save`, `stage`, or `release` until the server advertises their accepted governed operations. -- For repository-backed project knowledge, use the `trsd library` workflow in `references/knowledge.md`; never assume an unbound virtual repository or a `src/content` library root. - -## Choose the relevant guidance - -- For questions, research, knowledge, or TreeDX projections, read [references/knowledge.md](references/knowledge.md). -- For proposals, decisions, estimates, reviews, or discussions, read [references/governance.md](references/governance.md). -- For teams, projects, repositories, or provider bindings, read [references/projects.md](references/projects.md). -- For agents, providers, capacity, plans, workdays, assignments, or explicit project-agent chat, read [references/execution.md](references/execution.md). -- For connection discovery, protocol behavior, errors, subscriptions, or confirmations, read [references/mcp.md](references/mcp.md). - -## Distribution - -Install this directory as one skill named `treeseed`, preserving `SKILL.md`, `catalog-receipt.json`, and `references/`. The receipt pins the accepted source and catalog evidence for this published copy; runtime discovery remains authoritative when a connected server advertises a newer compatible catalog. diff --git a/skills/treeseed/catalog-receipt.json b/skills/treeseed/catalog-receipt.json deleted file mode 100644 index a00bc093..00000000 --- a/skills/treeseed/catalog-receipt.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "schemaVersion": "treeseed.skill-catalog-receipt/v1", - "protocolVersion": "2026-07-28", - "categories": [ - "knowledge", - "governance", - "projects", - "execution", - "mcp" - ], - "sdk": { - "version": "0.13.0-rc.25", - "stagingCommit": "548c13ac8bf156361c0329fd4117e266bc541d41", - "operationCatalogDigest": "sha256:e1d3ba43af80ed5978b22b86e8e0c43894fd27ddb48434940bac4659e391ce0f", - "mcpInputDigest": "sha256:cf9c77d9f81234b4fd123de68a197d8e32a8555c4534aa8b51fe36e384c8367f" - }, - "api": { - "stagingCommit": "819dbcd3aa24661ceab98df4e1413853a0166548", - "mcpCatalogDigest": "sha256:556297ce4e293df6e1446d5f081eeef6bc43ec76bbc6c59795a7d0414bd27d3a", - "openApiDigest": "sha256:8679239462624d57bdc285d6727042944081ac8b6c9c8eadd96e6fb76a2df0c2" - }, - "mcpSurface": { - "tools": 123, - "resources": 5, - "resourceTemplates": 51, - "prompts": 5, - "capabilities": [ - "completion", - "progress", - "cancellation", - "input_required", - "resource_subscriptions" - ] - } -} diff --git a/skills/treeseed/references/execution.md b/skills/treeseed/references/execution.md deleted file mode 100644 index a9f98a66..00000000 --- a/skills/treeseed/references/execution.md +++ /dev/null @@ -1,10 +0,0 @@ -# Execution work - -Use execution resources to understand agents, provider connections, capacity, API-derived plans, time-based workdays, assignments, and durable operation status. External assistants remain external principals. - -- Inspect capacity and plan explanations; do not author derived capacity plans, reservations, leases, or settlements. -- Plan a workday from high-level intent. Start only the exact fresh preflight receipt returned by the API, and accept stale-plan rejection rather than silently recalculating. -- Follow assignment and workday resource links for progress, cancellation, interruption, return, and settlement. -- Invoke project-agent chat only through the explicit governed chat capability. The returned actor chain and invocation record determine whether delegation occurred. -- Never pass provider credentials, GitHub credentials, host authority, repository write credentials, or TreeDX secrets into an agent workspace. -- If the server does not advertise an operation, it is unavailable. Do not emulate it with raw REST, Git, database, or provider calls. diff --git a/skills/treeseed/references/governance.md b/skills/treeseed/references/governance.md deleted file mode 100644 index 94a1401e..00000000 --- a/skills/treeseed/references/governance.md +++ /dev/null @@ -1,9 +0,0 @@ -# Governance work - -Use the server's current semantic resources for questions, objectives, proposals, decisions, discussions, estimates, reviews, and findings. Do not infer approval from comments, labels, reactions, or an external host's state. - -- Read the proposal, its evidence, current revision, and decision state before commenting or reviewing. -- Keep plans, estimates, findings, and summaries attached to the returned governed lineage. -- Acting work requires the API's accepted decision and execution evidence. Planning or research may be admitted under a workday profile, but it does not mint acting authority. -- Treat a merge, provider receipt, or external PR as observed evidence until TreeSeed adopts it through an authoritative operation. -- For high-risk decisions, pass the server's exact confirmation request back to the accountable human without rewriting its arguments. diff --git a/skills/treeseed/references/knowledge.md b/skills/treeseed/references/knowledge.md deleted file mode 100644 index fe1199ca..00000000 --- a/skills/treeseed/references/knowledge.md +++ /dev/null @@ -1,53 +0,0 @@ -# Knowledge work - -Start by discovering the connected server's current knowledge and question resources. Prefer resource reads and search over broad mutation tools, and preserve project/team scope in every request. - -- Questions drive research; knowledge records and TreeDX projections hold the durable result. -- Fetch the current record and its revision before updating it. Preserve citations, provenance, project scope, and returned concurrency evidence. -- Use subscriptions for changing discussions or knowledge projections when advertised. -- TreeDX remains canonical for content. A control-plane projection or receipt is not permission to bypass TreeDX custody or write directly to its storage. -- If research should become governed work, hand it into the proposal/decision lifecycle described in [governance.md](governance.md). - -## Query a project library with `trsd` - -Resolve the project binding before relying on results: - -```sh -trsd library show --json -trsd library status --json -``` - -`` may be an unambiguous project slug or UUID. Status must report a bound repository and healthy search index. Treat missing bindings, unavailable indexes, moved refs, and empty error responses as failures. - -Discover and read repository-root collections: - -```sh -trsd library paths --prefix agents --ref --json -trsd library search "release policy" --path knowledge --ref --json -trsd library read agents/engineer.mdx --ref --json -trsd library query "active agents" --model agent --ref --json -trsd library context "what governs this change?" --ref --max-items 20 --max-tokens 8000 --json -``` - -Prefer the exact `resolvedRef` returned by TreeDX for subsequent calls. Libraries use top-level paths such as `agents/`, `books/`, `knowledge/`, `notes/`, and `questions/`; never prepend `src/content`. - -## Organize and save knowledge - -All changes use governed TreeDX workspaces: - -```sh -trsd library workspace create --json -trsd library workspace read --json -trsd library workspace write --input draft.yaml --json -trsd library workspace diff --json -trsd library workspace submit --version --message "Describe the knowledge change" --json -trsd library reviews list --team --json -trsd library reviews decide --input decision.yaml --json -trsd library reviews publish --input publication.yaml --json -``` - -Use `workspace abandon --version ` only for an unsubmitted draft. Mutation input belongs in files or stdin-capable clients, never in arguments when it contains document bodies or sensitive material. Publication must verify the reviewed commit at the upstream exact ref. - -## Local diagnosis - -Development state is mounted beneath the Platform workspace at `.treeseed/data`. It is visible for diagnostics only. Use TreeDX, control-plane, MCP, or `trsd` APIs for every read that informs work and every mutation; never repair repositories, refs, indexes, databases, or credentials by editing mounted files. diff --git a/skills/treeseed/references/mcp.md b/skills/treeseed/references/mcp.md deleted file mode 100644 index 87dc3a21..00000000 --- a/skills/treeseed/references/mcp.md +++ /dev/null @@ -1,10 +0,0 @@ -# MCP connection behavior - -The accepted server speaks stateless Streamable HTTP MCP `2026-07-28`. Begin with server discovery, then list the capabilities relevant to the task. Runtime discovery is authoritative over the pinned receipt when the server presents a newer compatible catalog. - -- Use advertised input/output schemas, semantic annotations, and OAuth scope challenges. -- Follow `treeseed://` resources and templates instead of inventing REST paths. Use completion for resource or prompt arguments when available. -- Use resource subscriptions/listen for durable changes and honor cancellation and progress notifications. -- An `input_required` response contains signed, expiring, single-use state bound to the principal, OAuth client, operation, and exact arguments. Never decode it into authority, replay it, or transplant it between clients. -- Treat RFC 9457 problems and TreeSeed blockers as typed outcomes. Preserve request and trace identifiers when reporting failures. -- Do not request legacy initialization, session, roots, sampling, or MCP logging behavior. Do not expose credentials in prompts, content, resources, logs, or tool results. diff --git a/skills/treeseed/references/projects.md b/skills/treeseed/references/projects.md deleted file mode 100644 index fbea962d..00000000 --- a/skills/treeseed/references/projects.md +++ /dev/null @@ -1,9 +0,0 @@ -# Project and repository work - -Resolve team and project context from visible resources rather than guessing identifiers. When names are ambiguous, fetch the candidates and ask the user to choose. - -- Read project access, current revision, repository topology, and provider status before mutation. -- Use catalogued provider and repository operations. Never construct GitHub API calls, raw control-plane URLs, commit-authority fields, or integration receipts on TreeSeed's behalf. -- Git commits remain native Git objects. Issues and pull requests are provider projections bound to governed work; they do not independently grant TreeSeed authority. -- Archive, withdraw, or supersede when the server offers those lifecycle operations. Treat deletion, credential changes, authority expansion, and production changes as confirmation-bearing work. -- Market and Market API are external projects and never Platform-custodied repositories or deployment resources. diff --git a/templates/engineering.yaml b/templates/engineering.yaml new file mode 100644 index 00000000..dc11b163 --- /dev/null +++ b/templates/engineering.yaml @@ -0,0 +1,11 @@ +schemaVersion: treeseed.platform-template-lock/v1 +id: engineering +version: 1.0.0-rc.5 +repository: treeseed-ai/template-engineering +commit: 1ea645d4825aa6bb9bb6b371696fbab70b611ae3 +tag: template/1.0.0-rc.5 +artifact: + url: https://github.com/treeseed-ai/template-engineering/releases/download/template%2F1.0.0-rc.5/engineering-template.tgz + digest: sha256:bd0307d90291cb5bc4e6c63c2344cf18dd62173b5a9ba265a20ca117d61fa37b +contract: + digest: sha256:230ea6a6e0412f29530f1d980d4bd101662bde20bdd3f47dc51edb56622602e7 diff --git a/templates/platform-external-codex/template.config.json b/templates/platform-external-codex/template.config.json deleted file mode 100644 index 1c4b45b6..00000000 --- a/templates/platform-external-codex/template.config.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "schemaVersion": 2, - "id": "platform-external-codex", - "displayName": "External-control-plane Platform with Codex", - "description": "A TreeSeed Platform using an explicit Admin API endpoint and external Codex execution.", - "category": "platform", - "tags": ["platform", "external", "codex"], - "templateVersion": "3.0.0", - "templateApiVersion": 2, - "minCliVersion": "0.12.0", - "variables": [ - { "name": "Control-plane URL", "token": "__CONTROL_PLANE_BASE_URL__", "deriveFrom": "controlPlaneBaseUrl", "required": true }, - { "name": "Runtime portfolio username", "token": "__PORTFOLIO_USERNAME__", "deriveFrom": "runtime" }, - { "name": "Runtime portfolio email", "token": "__PORTFOLIO_EMAIL__", "deriveFrom": "runtime" }, - { "name": "Runtime portfolio password", "token": "__PORTFOLIO_PASSWORD__", "deriveFrom": "runtime" }, - { "name": "Runtime Mailpit URL", "token": "__PORTFOLIO_MAILPIT_URL__", "deriveFrom": "runtime" } - ], - "managedSurface": { - "coreManaged": ["treeseed.site.yaml", "seeds/treeseed.yaml", "treeseed.capacity-provider.yaml", "scenes/team-project-portfolio-demo.yaml"], - "validatedOnly": ["treeseed.site.yaml", "seeds/treeseed.yaml", "treeseed.capacity-provider.yaml", "scenes/team-project-portfolio-demo.yaml"] - }, - "platform": { - "controlPlane": { "mode": "external", "baseUrl": "__CONTROL_PLANE_BASE_URL__" }, - "processing": { "mode": "team-owned" }, - "admin": { "enabled": true }, - "executionProvider": "codex", - "aiAppliance": false, - "services": ["admin", "agentProvider"], - "seeds": ["seeds/treeseed.yaml"], - "scenes": ["scenes/team-project-portfolio-demo.yaml"] - }, - "testing": { "smokeCommand": "npx trsd platform status --json", "buildCommand": "npm run verify" } -} diff --git a/templates/platform-external-codex/template/scenes/team-project-portfolio-demo.yaml b/templates/platform-external-codex/template/scenes/team-project-portfolio-demo.yaml deleted file mode 100644 index 47793867..00000000 --- a/templates/platform-external-codex/template/scenes/team-project-portfolio-demo.yaml +++ /dev/null @@ -1,731 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: team-project-portfolio-demo -title: Team Project Portfolio Demo -description: >- - Register a user, create the TreeSeed team, and prepare portfolio projects for research and engineering work. This scene is intentionally practical: it should expose real admin-flow, project-launch, Mailpit, recording, rendering, and training-output gaps while serving as a central TreeSeed acceptance test harness and demo / educational video generator scenario. -audience: - - evaluator - - operator - - trainee - -mode: - test: false - demo: true - training: true - -runtime: - mode: training - timeouts: - sceneSeconds: 1800 - chapterSeconds: 600 - stepSeconds: 120 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: true - -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 - -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false - browserFrame: - enabled: false - title: Team Project Portfolio Demo - chrome: desktop - - id: tablet - title: Tablet - orientation: landscape - viewport: - width: 1024 - height: 768 - video: - width: 1024 - height: 768 - output: - width: 1440 - height: 1080 - deviceScaleFactor: 1 - isMobile: true - hasTouch: true - browserFrame: - enabled: false - title: Team Project Portfolio Demo - chrome: tablet - - id: mobile - title: Mobile - orientation: portrait - viewport: - width: 390 - height: 844 - video: - width: 390 - height: 844 - output: - width: 1080 - height: 1920 - deviceScaleFactor: 2 - isMobile: true - hasTouch: true - browserFrame: - enabled: false - title: Team Project Portfolio Demo - chrome: mobile - -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true - -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true - -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser - browserFrame: - enabled: false - title: Team Project Portfolio Demo - -chapters: - - id: registration - title: Register a portfolio owner - startsAt: open-register - - id: email-confirmation - title: Confirm the account through Mailpit - startsAt: open-mailpit - - id: team-setup - title: Create the TreeSeed team - startsAt: verify-admin-home - - id: portfolio-projects - title: Prepare portfolio projects - startsAt: open-new-project-bylaws - - id: gap-review - title: Capture linked project gaps - startsAt: open-new-project-sdk - -overlays: - - id: scenario-purpose - at: open-register - renderer: remotion - type: callout - variant: panel - region: top-right - style: - tone: brand - shadow: medium - radius: 8 - motion: - keyframes: - - at: 0 - unit: progress - opacity: 0 - position: - x: 100 - y: 10 - unit: percent - - at: 0.18 - unit: progress - opacity: 1 - position: - x: 82 - y: 10 - unit: percent - - at: 1 - unit: progress - opacity: 1 - position: - x: 82 - y: 10 - unit: percent - objects: - - id: acceptance-pulse - type: circle - position: - x: 8 - y: 22 - size: - width: 14 - height: 14 - style: - tone: success - opacity: 0.82 - motion: - keyframes: - - at: 0 - unit: progress - scale: 0.8 - opacity: 0.45 - - at: 0.5 - unit: progress - scale: 1.28 - opacity: 1 - - at: 1 - unit: progress - scale: 0.8 - opacity: 0.45 - text: This demo doubles as a product acceptance probe and an educational video source. - - id: mailpit-selector-risk - at: open-mailpit - renderer: remotion - type: callout - text: Mailpit confirmation is attempted through the browser so local email and auth gaps are visible in the run artifacts. - - id: team-portfolio-context - at: open-new-team - renderer: remotion - type: callout - text: The TreeSeed team will own a portfolio of research and engineering projects. - - id: bylaws-project-context - at: open-new-project-bylaws - renderer: remotion - type: callout - text: Bylaws is expected to be a new research-template project with no upstream remote. - - id: sdk-linked-project-gap - at: capture-sdk-linking-gap - renderer: remotion - type: callout - text: >- - Expected: link github.com/treeseed-ai/sdk and request a docs repository. Current gap: this linked-project operation is not exposed by the scene runtime or obvious project UI. - - id: final-gap-summary - at: review-gap-summary - renderer: remotion - type: callout - text: Review the screenshots, timeline, captions, transcript, and evidence bundle to prioritize product and selector hardening. - -diagrams: - - id: local-runtime-topology - renderer: remotion - component: DevRuntimeTopologyDiagram - at: open-mailpit - placement: overlay - durationSeconds: 12 - style: - tone: info - shadow: medium - motion: - keyframes: - - at: 0 - unit: progress - opacity: 0 - scale: 0.96 - - at: 0.2 - unit: progress - opacity: 1 - scale: 1 - - at: 1 - unit: progress - opacity: 1 - scale: 1 - objects: - - id: mail-flow-cursor - type: arrow - from: - x: 18 - y: 80 - unit: percent - to: - x: 84 - y: 80 - unit: percent - style: - tone: brand - opacity: 0.78 - motion: - keyframes: - - at: 0 - unit: progress - opacity: 0.2 - - at: 0.6 - unit: progress - opacity: 1 - - at: 1 - unit: progress - opacity: 0.7 - props: - title: Local demo runtime - surfaces: - - id: browser - label: Browser scene - kind: playwright - - id: web - label: Local web app - kind: astro - - id: api - label: Local API - kind: treeseed-api - - id: mailpit - label: Mailpit - kind: email - links: - - from: browser - to: web - label: drives UI - - from: web - to: api - label: auth and project calls - - from: api - to: mailpit - label: confirmation email - - id: project-launch-lifecycle - renderer: remotion - component: OperationLifecycleDiagram - at: submit-bylaws-project - placement: overlay - durationSeconds: 12 - props: - title: Project launch lifecycle - states: - - form-ready - - submitted - - queued - - deploying - - review - activeState: review - - id: scene-timeline-review - renderer: remotion - component: SceneExecutionTimelineDiagram - at: review-gap-summary - placement: overlay - durationSeconds: 10 - props: - title: Portfolio demo execution timeline - showCheckpoints: true - showSegments: true - -training: - enabled: true - captions: - enabled: true - formats: - - vtt - - srt - maxCueSeconds: 6 - renderInTrainingVideo: true - transcript: - enabled: true - formats: - - json - - markdown - narration: - enabled: true - style: instructional - includeDiagnostics: true - glossary: - enabled: true - terms: - - term: team - definition: A TreeSeed ownership boundary for projects, hosts, work, and knowledge. - sourceStep: open-new-team - groupIds: - - portfolio - - term: project - definition: A managed TreeSeed work surface that can own content, repositories, hosting, and launch evidence. - sourceStep: open-new-project-bylaws - groupIds: - - portfolio - - term: research template - definition: The starter used for research and knowledge-oriented projects such as Bylaws. - sourceStep: choose-research-template - groupIds: - - template - - term: linked repository - definition: An existing upstream repository that should be connected to a TreeSeed project instead of creating a new source repository. - sourceStep: capture-sdk-linking-gap - groupIds: - - gap - - term: docs repository - definition: A documentation repository expected for the linked SDK software project. - sourceStep: capture-sdk-linking-gap - groupIds: - - gap - - term: Mailpit - definition: The local email inbox used to confirm registration during the demo. - sourceStep: open-mailpit - groupIds: - - local-dev - - term: checkpoint - definition: A resumable scene runtime marker that helps diagnose and continue long workflows. - sourceStep: review-gap-summary - groupIds: - - scene-runtime - chapterClips: - enabled: true - format: manifest - -workflow: - - id: open-register - title: Open registration for a normal user - action: - goto: /auth/register?returnTo=/app - expect: - visible: - - role: heading - name: Create account - - - id: fill-first-name - title: Enter the user's first name - action: - fill: - css: input[name="firstName"] - internal: true - value: Test - expect: - visible: - - css: input[name="firstName"] - internal: true - - - id: fill-last-name - title: Enter the user's last name - action: - fill: - css: input[name="lastName"] - internal: true - value: Portfolio - expect: - visible: - - css: input[name="lastName"] - internal: true - - - id: fill-username - title: Choose a unique username - action: - fill: - css: input[name="username"] - internal: true - value: __PORTFOLIO_USERNAME__ - expect: - visible: - - css: input[name="username"] - internal: true - - - id: fill-email - title: Enter the generated local email address - action: - fill: - css: input[name="email"] - internal: true - value: __PORTFOLIO_EMAIL__ - expect: - visible: - - css: input[name="email"] - internal: true - - - id: fill-password - title: Enter a strong generated password - action: - fill: - css: input[name="password"] - internal: true - value: __PORTFOLIO_PASSWORD__ - expect: - visible: - - css: input[name="password"] - internal: true - - - id: fill-confirm-password - title: Confirm the generated password - action: - fill: - css: input[name="confirmPassword"] - internal: true - value: __PORTFOLIO_PASSWORD__ - expect: - visible: - - css: input[name="confirmPassword"] - internal: true - - - id: submit-registration - title: Submit the registration form - action: - click: - role: button - name: Create account - expect: - text: Check your email - checkpoint: - resumable: true - - - id: open-mailpit - title: Open the local Mailpit inbox - action: - goto: __PORTFOLIO_MAILPIT_URL__ - demoOnly: true - checkpoint: - resumable: true - - - id: open-confirmation-email - title: Open the newest confirmation email - action: - click: - css: a[href^="/view/"]:has-text("__PORTFOLIO_EMAIL__") - brittle: true - demoOnly: true - continueOnFailure: true - checkpoint: - resumable: true - - - id: open-confirmation-link - title: Open the email confirmation link - action: - mailpitConfirmLatest: - mailpitUrl: __PORTFOLIO_MAILPIT_URL__ - email: __PORTFOLIO_EMAIL__ - subjectIncludes: Confirm - expect: - urlIncludes: /app - demoOnly: true - continueOnFailure: true - checkpoint: - resumable: true - - - id: verify-admin-home - title: Confirm the user can see the admin homepage - action: - goto: /app - expect: - visible: - - role: heading - name: Start - continueOnFailure: true - checkpoint: - resumable: true - - - id: open-new-team - title: Open the new team screen - action: - goto: /app/teams/new - expect: - visible: - - role: heading - name: Create team - continueOnFailure: true - - - id: fill-team-slug - title: Enter the TreeSeed team slug - action: - fill: - css: input[name="name"] - internal: true - value: treeseed - expect: - visible: - - css: input[name="name"] - internal: true - continueOnFailure: true - - - id: fill-team-display-name - title: Enter the TreeSeed team display name - action: - fill: - css: input[name="displayName"] - internal: true - value: TreeSeed - expect: - visible: - - css: input[name="displayName"] - internal: true - continueOnFailure: true - - - id: fill-team-summary - title: Describe the team project portfolio - action: - fill: - css: textarea[name="profileSummary"] - internal: true - value: TreeSeed owns a portfolio of research and engineering projects, including governance research and software platform work. - expect: - visible: - - css: textarea[name="profileSummary"] - internal: true - continueOnFailure: true - - - id: submit-team - title: Create the TreeSeed team - action: - click: - role: button - name: Create team - expect: - urlIncludes: /app/teams - continueOnFailure: true - checkpoint: - resumable: true - - - id: open-new-project-bylaws - title: Open the new project screen for Bylaws - action: - goto: /app/projects/new - expect: - text: Create hosted project - continueOnFailure: true - - - id: fill-bylaws-name - title: Enter the Bylaws project name - action: - fill: - css: input[name="name"] - internal: true - value: Bylaws - expect: - visible: - - css: input[name="name"] - internal: true - continueOnFailure: true - - - id: fill-bylaws-slug - title: Enter the Bylaws project slug - action: - fill: - css: input[name="slug"] - internal: true - value: bylaws - expect: - visible: - - css: input[name="slug"] - internal: true - continueOnFailure: true - - - id: choose-research-template - title: Choose the research template - action: - click: - css: label[for="template-research"] - internal: true - expect: - visible: - - css: label[for="template-research"] - internal: true - continueOnFailure: true - - - id: fill-bylaws-objective - title: Describe the Bylaws research objective - action: - fill: - css: textarea[name="coreObjective"] - internal: true - value: Build a research project for organizing TreeSeed bylaws, governance notes, decision records, and portfolio policy. - expect: - visible: - - css: textarea[name="coreObjective"] - internal: true - continueOnFailure: true - - - id: submit-bylaws-project - title: Submit the Bylaws project launch - action: - click: - role: button - name: Create project - expect: - visible: - - css: "body" - internal: true - continueOnFailure: true - checkpoint: - resumable: true - - - id: open-new-project-sdk - title: Open the new project screen for SDK - action: - goto: /app/projects/new - expect: - text: Create hosted project - continueOnFailure: true - - - id: fill-sdk-name - title: Enter the SDK project name - action: - fill: - css: input[name="name"] - internal: true - value: SDK - expect: - visible: - - css: input[name="name"] - internal: true - continueOnFailure: true - - - id: fill-sdk-slug - title: Enter the SDK project slug - action: - fill: - css: input[name="slug"] - internal: true - value: sdk - expect: - visible: - - css: input[name="slug"] - internal: true - continueOnFailure: true - - - id: capture-sdk-linking-gap - title: Capture the linked SDK project gap - action: - pause: - mode: timed - durationSeconds: 6 - prompt: >- - Expected linked software project: public GitHub repository github.com/treeseed-ai/sdk with a docs repository request. Current gap: this operation is not exposed by the scene runtime or obvious project UI. - demoOnly: true - continueOnFailure: true - checkpoint: - resumable: true - - - id: review-gap-summary - title: Review portfolio demo evidence and gaps - action: - goto: /app/projects - expect: - visible: - - css: "body" - internal: true - continueOnFailure: true - checkpoint: - resumable: true diff --git a/templates/platform-external-codex/template/seeds/treeseed.yaml b/templates/platform-external-codex/template/seeds/treeseed.yaml deleted file mode 100644 index fac2b439..00000000 --- a/templates/platform-external-codex/template/seeds/treeseed.yaml +++ /dev/null @@ -1,77 +0,0 @@ -schemaVersion: treeseed.seed-bundle/v3 -name: treeseed -version: 4 -description: Reproducible local TreeSeed portfolio with one unified capacity-provider battery. -environments: [local, staging, prod] -digest: sha256:e983c02364fb1e292018acf264c447da697d3fc106608ba76ce8d9656671c116 -resources: - teams: - - { key: 'team:treeseed', slug: treeseed, name: treeseed, displayName: TreeSeed, profileSummary: 'TreeSeed platform, packages, products, and agent operations.' } - memberships: - - { key: 'membership:treeseed/adrian-webb', team: 'team:treeseed', principal: { kind: user, email: 'adrian.webb@knowledge.coop' }, roles: [team_owner], missingUser: reject } - - key: membership:treeseed/automation - team: team:treeseed - principal: { kind: service-principal, key: 'service-principal:treeseed/automation', displayName: TreeSeed Automation, interactiveLogin: false } - roles: [team_owner] - projects: - - { key: 'project:treeseed/platform', team: 'team:treeseed', slug: platform, name: TreeSeed Platform, description: Public installer and portfolio integration workspace., kind: platform, primaryRepository: 'repository:treeseed/platform', libraryRepository: 'repository:treeseed/platform-library' } - - { key: 'project:treeseed/deployment', team: 'team:treeseed', slug: deployment, name: TreeSeed Deployment, description: Shared Debian bootstrap, host manager, edge, and component integration system., kind: platform, primaryRepository: 'repository:treeseed/deployment', libraryRepository: 'repository:treeseed/deployment-library' } - - { key: 'project:treeseed/api', team: 'team:treeseed', slug: api, name: TreeSeed API, description: Authoritative TreeSeed control plane., kind: package, primaryRepository: 'repository:treeseed/api', libraryRepository: 'repository:treeseed/api-library', metadata: { packageId: '@treeseed/api' } } - - { key: 'project:treeseed/treedx', team: 'team:treeseed', slug: treedx, name: TreeDX, description: Independent content and knowledge service., kind: service, primaryRepository: 'repository:treeseed/treedx', libraryRepository: 'repository:treeseed/treedx-library' } - - { key: 'project:treeseed/sdk', team: 'team:treeseed', slug: sdk, name: TreeSeed SDK, description: Portable contracts and remote clients., kind: package, primaryRepository: 'repository:treeseed/sdk', libraryRepository: 'repository:treeseed/sdk-library', metadata: { packageId: '@treeseed/sdk' } } - - { key: 'project:treeseed/ui', team: 'team:treeseed', slug: ui, name: TreeSeed UI, description: TreeSeed user-interface package., kind: package, primaryRepository: 'repository:treeseed/ui', libraryRepository: 'repository:treeseed/ui-library', metadata: { packageId: '@treeseed/ui' } } - - { key: 'project:treeseed/cli', team: 'team:treeseed', slug: cli, name: TreeSeed CLI, description: Human-centered TreeSeed command-line interface., kind: package, primaryRepository: 'repository:treeseed/cli', libraryRepository: 'repository:treeseed/cli-library', metadata: { packageId: '@treeseed/cli' } } - - { key: 'project:treeseed/core', team: 'team:treeseed', slug: core, name: TreeSeed Core, description: Core TreeSeed package., kind: package, primaryRepository: 'repository:treeseed/core', libraryRepository: 'repository:treeseed/core-library', metadata: { packageId: '@treeseed/core' } } - - { key: 'project:treeseed/admin', team: 'team:treeseed', slug: admin, name: TreeSeed Admin, description: TreeSeed administration interface., kind: package, primaryRepository: 'repository:treeseed/admin', libraryRepository: 'repository:treeseed/admin-library', metadata: { packageId: '@treeseed/admin' } } - - { key: 'project:treeseed/agent', team: 'team:treeseed', slug: agent, name: TreeSeed Agent, description: Unified capacity-provider and agent execution runtime., kind: package, primaryRepository: 'repository:treeseed/agent', libraryRepository: 'repository:treeseed/agent-library', metadata: { packageId: '@treeseed/agent' } } - - { key: 'project:treeseed/reviewer', team: 'team:treeseed', slug: reviewer, name: TreeSeed Reviewer, description: Independent review package., kind: package, primaryRepository: 'repository:treeseed/reviewer', libraryRepository: 'repository:treeseed/reviewer-library', metadata: { packageId: '@treeseed/reviewer' } } - - { key: 'project:treeseed/ai', team: 'team:treeseed', slug: ai, name: TreeSeed AI, description: AI integration package., kind: package, primaryRepository: 'repository:treeseed/ai', libraryRepository: 'repository:treeseed/ai-library', metadata: { packageId: '@treeseed/ai' } } - - { key: 'project:treeseed/template-engineering', team: 'team:treeseed', slug: template-engineering, name: Engineering Template, description: Engineering project template., kind: template, primaryRepository: 'repository:treeseed/template-engineering', libraryRepository: 'repository:treeseed/template-engineering-library' } - - { key: 'project:treeseed/template-research', team: 'team:treeseed', slug: template-research, name: Research Template, description: Research project template., kind: template, primaryRepository: 'repository:treeseed/template-research', libraryRepository: 'repository:treeseed/template-research-library' } - - { key: 'project:treeseed/market', team: 'team:treeseed', slug: market, name: TreeSeed Market, description: First-party portfolio product managed independently from Platform deployment., kind: product, primaryRepository: 'repository:treeseed/market', libraryRepository: 'repository:treeseed/market-library' } - - { key: 'project:treeseed/market-api', team: 'team:treeseed', slug: market-api, name: TreeSeed Market API, description: First-party Market service managed independently from Platform deployment., kind: service, primaryRepository: 'repository:treeseed/market-api', libraryRepository: 'repository:treeseed/market-api-library' } - repositories: - - &platform_repo { key: 'repository:treeseed/platform', project: 'project:treeseed/platform', role: primary, provider: github, owner: treeseed-ai, name: platform, gitUrl: 'git@github.com:treeseed-ai/platform.git', defaultBranch: main, checkoutPath: '.', repositoryPolicy: &public_repo { visibility: public, lifecycle: create-or-adopt, deletionPolicy: retain, defaultBranch: main, stagingBranch: staging, issues: true, actions: true, workflows: [verify.yml] } } - - { key: 'repository:treeseed/deployment', project: 'project:treeseed/deployment', role: primary, provider: github, owner: treeseed-ai, name: deployment, gitUrl: 'git@github.com:treeseed-ai/deployment.git', defaultBranch: main, checkoutPath: packages/deployment, repositoryPolicy: *public_repo, metadata: { deploymentAuthority: host-manager } } - - { key: 'repository:treeseed/api', project: 'project:treeseed/api', role: primary, provider: github, owner: treeseed-ai, name: api, gitUrl: 'git@github.com:treeseed-ai/api.git', defaultBranch: main, checkoutPath: packages/api, submodulePath: packages/api, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/treedx', project: 'project:treeseed/treedx', role: primary, provider: github, owner: treeseed-ai, name: treedx, gitUrl: 'git@github.com:treeseed-ai/treedx.git', defaultBranch: main, checkoutPath: packages/treedx, submodulePath: packages/treedx, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/sdk', project: 'project:treeseed/sdk', role: primary, provider: github, owner: treeseed-ai, name: sdk, gitUrl: 'git@github.com:treeseed-ai/sdk.git', defaultBranch: main, checkoutPath: packages/sdk, submodulePath: packages/sdk, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/ui', project: 'project:treeseed/ui', role: primary, provider: github, owner: treeseed-ai, name: ui, gitUrl: 'git@github.com:treeseed-ai/ui.git', defaultBranch: main, checkoutPath: packages/ui, submodulePath: packages/ui, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/cli', project: 'project:treeseed/cli', role: primary, provider: github, owner: treeseed-ai, name: cli, gitUrl: 'git@github.com:treeseed-ai/cli.git', defaultBranch: main, checkoutPath: packages/cli, submodulePath: packages/cli, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/core', project: 'project:treeseed/core', role: primary, provider: github, owner: treeseed-ai, name: core, gitUrl: 'git@github.com:treeseed-ai/core.git', defaultBranch: main, checkoutPath: packages/core, submodulePath: packages/core, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/admin', project: 'project:treeseed/admin', role: primary, provider: github, owner: treeseed-ai, name: admin, gitUrl: 'git@github.com:treeseed-ai/admin.git', defaultBranch: main, checkoutPath: packages/admin, submodulePath: packages/admin, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/agent', project: 'project:treeseed/agent', role: primary, provider: github, owner: treeseed-ai, name: agent, gitUrl: 'git@github.com:treeseed-ai/agent.git', defaultBranch: main, checkoutPath: packages/agent, submodulePath: packages/agent, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/reviewer', project: 'project:treeseed/reviewer', role: primary, provider: github, owner: treeseed-ai, name: reviewer, gitUrl: 'git@github.com:treeseed-ai/reviewer.git', defaultBranch: main, checkoutPath: packages/reviewer, submodulePath: packages/reviewer, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/ai', project: 'project:treeseed/ai', role: primary, provider: github, owner: treeseed-ai, name: ai, gitUrl: 'git@github.com:treeseed-ai/ai.git', defaultBranch: main, checkoutPath: packages/ai, submodulePath: packages/ai, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/template-engineering', project: 'project:treeseed/template-engineering', role: primary, provider: github, owner: treeseed-ai, name: template-engineering, gitUrl: 'git@github.com:treeseed-ai/template-engineering.git', defaultBranch: main, checkoutPath: templates/engineering, submodulePath: templates/engineering, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/template-research', project: 'project:treeseed/template-research', role: primary, provider: github, owner: treeseed-ai, name: template-research, gitUrl: 'git@github.com:treeseed-ai/template-research.git', defaultBranch: main, checkoutPath: templates/research, submodulePath: templates/research, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/market', project: 'project:treeseed/market', role: primary, provider: github, owner: treeseed-ai, name: market, gitUrl: 'git@github.com:treeseed-ai/market.git', defaultBranch: main, checkoutPath: products/market, repositoryPolicy: *public_repo, metadata: { platformCustody: portfolio-only, deployableByPlatform: false } } - - { key: 'repository:treeseed/market-api', project: 'project:treeseed/market-api', role: primary, provider: github, owner: treeseed-ai, name: market-api, gitUrl: 'git@github.com:treeseed-ai/market-api.git', defaultBranch: main, checkoutPath: services/market-api, repositoryPolicy: &private_repo { visibility: private, lifecycle: create-or-adopt, deletionPolicy: retain, defaultBranch: main, stagingBranch: staging, issues: true, actions: true, workflows: [verify.yml] }, metadata: { platformCustody: portfolio-only, deployableByPlatform: false } } - - { key: 'repository:treeseed/platform-library', project: 'project:treeseed/platform', role: library, provider: github, owner: treeseed-ai, name: platform-library, gitUrl: 'https://github.com/treeseed-ai/platform-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: &library_metadata { libraryRoot: '.', synchronizedRefs: [main, staging] } } - - { key: 'repository:treeseed/deployment-library', project: 'project:treeseed/deployment', role: library, provider: github, owner: treeseed-ai, name: deployment-library, gitUrl: 'https://github.com/treeseed-ai/deployment-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/api-library', project: 'project:treeseed/api', role: library, provider: github, owner: treeseed-ai, name: api-library, gitUrl: 'https://github.com/treeseed-ai/api-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/treedx-library', project: 'project:treeseed/treedx', role: library, provider: github, owner: treeseed-ai, name: treedx-library, gitUrl: 'https://github.com/treeseed-ai/treedx-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/sdk-library', project: 'project:treeseed/sdk', role: library, provider: github, owner: treeseed-ai, name: sdk-library, gitUrl: 'https://github.com/treeseed-ai/sdk-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/ui-library', project: 'project:treeseed/ui', role: library, provider: github, owner: treeseed-ai, name: ui-library, gitUrl: 'https://github.com/treeseed-ai/ui-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/cli-library', project: 'project:treeseed/cli', role: library, provider: github, owner: treeseed-ai, name: cli-library, gitUrl: 'https://github.com/treeseed-ai/cli-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/core-library', project: 'project:treeseed/core', role: library, provider: github, owner: treeseed-ai, name: core-library, gitUrl: 'https://github.com/treeseed-ai/core-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/admin-library', project: 'project:treeseed/admin', role: library, provider: github, owner: treeseed-ai, name: admin-library, gitUrl: 'https://github.com/treeseed-ai/admin-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/agent-library', project: 'project:treeseed/agent', role: library, provider: github, owner: treeseed-ai, name: agent-library, gitUrl: 'https://github.com/treeseed-ai/agent-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/reviewer-library', project: 'project:treeseed/reviewer', role: library, provider: github, owner: treeseed-ai, name: reviewer-library, gitUrl: 'https://github.com/treeseed-ai/reviewer-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/ai-library', project: 'project:treeseed/ai', role: library, provider: github, owner: treeseed-ai, name: ai-library, gitUrl: 'https://github.com/treeseed-ai/ai-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/template-engineering-library', project: 'project:treeseed/template-engineering', role: library, provider: github, owner: treeseed-ai, name: template-engineering-library, gitUrl: 'https://github.com/treeseed-ai/template-engineering-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/template-research-library', project: 'project:treeseed/template-research', role: library, provider: github, owner: treeseed-ai, name: template-research-library, gitUrl: 'https://github.com/treeseed-ai/template-research-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/market-library', project: 'project:treeseed/market', role: library, provider: github, owner: treeseed-ai, name: market-library, gitUrl: 'https://github.com/treeseed-ai/market-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/market-api-library', project: 'project:treeseed/market-api', role: library, provider: github, owner: treeseed-ai, name: market-api-library, gitUrl: 'https://github.com/treeseed-ai/market-api-library.git', defaultBranch: main, repositoryPolicy: *private_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/fixtures', project: 'project:treeseed/platform', role: fixture, provider: github, owner: treeseed-ai, name: fixtures, gitUrl: 'git@github.com:treeseed-ai/fixtures.git', defaultBranch: main, checkoutPath: fixtures, submodulePath: fixtures, repositoryPolicy: { visibility: public, lifecycle: create-or-adopt, deletionPolicy: retain, defaultBranch: main, stagingBranch: staging, issues: true, actions: false, workflows: [] } } -runtime: - capacityProviders: - - key: capacity-provider:treeseed/local - team: team:treeseed - environments: [local] - manifestDigest: sha256:9b3f675f40a7f23d66cc7429600d68438cb28ba866ebe4ce8688e240a4fa482c - manifestRef: treeseed.capacity-provider.yaml - approval: trusted-local-owner - projects: ['project:treeseed/platform', 'project:treeseed/deployment', 'project:treeseed/api', 'project:treeseed/treedx', 'project:treeseed/sdk', 'project:treeseed/ui', 'project:treeseed/cli', 'project:treeseed/core', 'project:treeseed/admin', 'project:treeseed/agent', 'project:treeseed/reviewer', 'project:treeseed/ai', 'project:treeseed/template-engineering', 'project:treeseed/template-research', 'project:treeseed/market', 'project:treeseed/market-api'] - allowedModes: [planning, acting] - requiredLanePurposes: [communication, platform, workday] diff --git a/templates/platform-external-codex/template/treeseed.capacity-provider.yaml b/templates/platform-external-codex/template/treeseed.capacity-provider.yaml deleted file mode 100644 index f240e115..00000000 --- a/templates/platform-external-codex/template/treeseed.capacity-provider.yaml +++ /dev/null @@ -1,84 +0,0 @@ -schemaVersion: 3 -ownership: - type: team - teamId: team:treeseed -configuration: - generation: local-battery-v2 -identity: - privateKeyRef: data://identity-v3.json - displayName: TreeSeed local capacity battery -capacity: - maxConcurrentWorkers: 4 - cpuCores: 8 - memoryBytes: 17179869184 - maxActiveSeconds: 28800 - maxInputTokens: 4000000 - maxOutputTokens: 1000000 - maxCost: 100 - currency: USD - maxAttempts: 3 -credentialProfiles: - - { id: codex-auth, source: process-environment, reference: TREESEED_CODEX_AUTH_FILE, required: true } - - { id: codex-executable, source: process-environment, reference: TREESEED_CODEX_EXECUTABLE, required: true } - - { id: platform-github, source: process-environment, reference: TREESEED_GITHUB_TOKEN, required: false } - - { id: platform-cloudflare, source: process-environment, reference: TREESEED_CLOUDFLARE_API_TOKEN, required: false } -lanes: - - id: communication - purpose: communication - priority: 100 - reservedConcurrentWorkers: 1 - maxConcurrentWorkers: 2 - borrowWhenIdle: true - lendWhenIdle: true - reclaimPolicy: admission - queueLimit: 100 - timeoutSeconds: 120 - capabilities: [communication, agent-execution, research, planning] - - id: platform - purpose: platform - priority: 70 - reservedConcurrentWorkers: 0 - maxConcurrentWorkers: 2 - borrowWhenIdle: true - lendWhenIdle: true - reclaimPolicy: admission - queueLimit: 25 - timeoutSeconds: 900 - capabilities: [platform_operation, infrastructure_reconciliation, repository_reconciliation] - - id: workday - purpose: workday - priority: 50 - reservedConcurrentWorkers: 0 - maxConcurrentWorkers: 4 - borrowWhenIdle: true - lendWhenIdle: true - reclaimPolicy: admission - queueLimit: 100 - timeoutSeconds: 900 - minimumAssignmentDuration: { amount: 600, unit: seconds } - capabilities: [agent-execution, engineering, research, planning, acting, verification, repository_work] -adapters: - - id: codex-local - adapter: codex - isolation: process - module: module:codex-chat - profile: subscription - protocol: responses - credentialProfiles: [codex-auth, codex-executable] - laneIds: [communication] - maxConcurrentWorkers: 2 - minimumAssignmentDuration: { amount: 600, unit: seconds } - nativeLimits: { availableAgentSeconds: 28800 } - capabilities: [communication, agent-execution] - - id: platform-local - adapter: platform-operation - isolation: process - credentialProfiles: [platform-github, platform-cloudflare] - laneIds: [platform] - maxConcurrentWorkers: 2 - nativeLimits: { availableAgentSeconds: 14400 } - capabilities: [platform_operation, infrastructure_reconciliation, repository_reconciliation] -connections: [] -metadata: - custody: local-only - sharedBattery: true diff --git a/templates/platform-external-codex/template/treeseed.site.yaml b/templates/platform-external-codex/template/treeseed.site.yaml deleted file mode 100644 index 2659b73c..00000000 --- a/templates/platform-external-codex/template/treeseed.site.yaml +++ /dev/null @@ -1,14 +0,0 @@ -name: TreeSeed Platform -slug: treeseed-platform -siteUrl: https://treeseed.dev/platform -contactEmail: hello@treeseed.email -authority: { kind: customer-platform } -market: { profile: treeseed } -controlPlane: { mode: external, baseUrl: __CONTROL_PLANE_BASE_URL__ } -hub: { mode: customer_hosted } -runtime: { mode: byo_attached, registration: optional } -processing: { mode: team-owned, providerRef: codex-sub } -surfaces: { web: { enabled: true }, admin: { enabled: true }, api: { enabled: false } } -services: - admin: { enabled: true, provider: local } - agentProvider: { enabled: true, provider: local } diff --git a/templates/platform-local-managed-ai/template.config.json b/templates/platform-local-managed-ai/template.config.json deleted file mode 100644 index dec73a69..00000000 --- a/templates/platform-local-managed-ai/template.config.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "schemaVersion": 2, - "id": "platform-local-managed-ai", - "displayName": "Local managed Platform with TreeSeed AI", - "description": "A sovereign local TreeSeed control plane with the optional TreeSeed AI appliance.", - "category": "platform", - "tags": ["platform", "local", "managed", "ai"], - "templateVersion": "3.0.0", - "templateApiVersion": 2, - "minCliVersion": "0.12.59", - "variables": [ - { "name": "Runtime portfolio username", "token": "__PORTFOLIO_USERNAME__", "deriveFrom": "runtime" }, - { "name": "Runtime portfolio email", "token": "__PORTFOLIO_EMAIL__", "deriveFrom": "runtime" }, - { "name": "Runtime portfolio password", "token": "__PORTFOLIO_PASSWORD__", "deriveFrom": "runtime" }, - { "name": "Runtime Mailpit URL", "token": "__PORTFOLIO_MAILPIT_URL__", "deriveFrom": "runtime" } - ], - "managedSurface": { - "coreManaged": ["treeseed.site.yaml", "seeds/treeseed.yaml", "treeseed.capacity-provider.yaml", "scenes/team-project-portfolio-demo.yaml"], - "validatedOnly": ["treeseed.site.yaml", "seeds/treeseed.yaml", "treeseed.capacity-provider.yaml", "scenes/team-project-portfolio-demo.yaml"] - }, - "platform": { - "controlPlane": { "mode": "managed" }, - "processing": { "mode": "local" }, - "admin": { "enabled": false }, - "executionProvider": "treeseed-ai", - "aiAppliance": true, - "services": ["api", "treeseedDatabase", "operationsRunner", "treedx", "agentProvider", "aiAppliance"], - "seeds": ["seeds/treeseed.yaml"], - "scenes": ["scenes/team-project-portfolio-demo.yaml"] - }, - "testing": { "smokeCommand": "npx trsd platform status --json", "buildCommand": "npm run verify" } -} diff --git a/templates/platform-local-managed-ai/template/scenes/team-project-portfolio-demo.yaml b/templates/platform-local-managed-ai/template/scenes/team-project-portfolio-demo.yaml deleted file mode 100644 index 47793867..00000000 --- a/templates/platform-local-managed-ai/template/scenes/team-project-portfolio-demo.yaml +++ /dev/null @@ -1,731 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: team-project-portfolio-demo -title: Team Project Portfolio Demo -description: >- - Register a user, create the TreeSeed team, and prepare portfolio projects for research and engineering work. This scene is intentionally practical: it should expose real admin-flow, project-launch, Mailpit, recording, rendering, and training-output gaps while serving as a central TreeSeed acceptance test harness and demo / educational video generator scenario. -audience: - - evaluator - - operator - - trainee - -mode: - test: false - demo: true - training: true - -runtime: - mode: training - timeouts: - sceneSeconds: 1800 - chapterSeconds: 600 - stepSeconds: 120 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: true - -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 - -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false - browserFrame: - enabled: false - title: Team Project Portfolio Demo - chrome: desktop - - id: tablet - title: Tablet - orientation: landscape - viewport: - width: 1024 - height: 768 - video: - width: 1024 - height: 768 - output: - width: 1440 - height: 1080 - deviceScaleFactor: 1 - isMobile: true - hasTouch: true - browserFrame: - enabled: false - title: Team Project Portfolio Demo - chrome: tablet - - id: mobile - title: Mobile - orientation: portrait - viewport: - width: 390 - height: 844 - video: - width: 390 - height: 844 - output: - width: 1080 - height: 1920 - deviceScaleFactor: 2 - isMobile: true - hasTouch: true - browserFrame: - enabled: false - title: Team Project Portfolio Demo - chrome: mobile - -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true - -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true - -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser - browserFrame: - enabled: false - title: Team Project Portfolio Demo - -chapters: - - id: registration - title: Register a portfolio owner - startsAt: open-register - - id: email-confirmation - title: Confirm the account through Mailpit - startsAt: open-mailpit - - id: team-setup - title: Create the TreeSeed team - startsAt: verify-admin-home - - id: portfolio-projects - title: Prepare portfolio projects - startsAt: open-new-project-bylaws - - id: gap-review - title: Capture linked project gaps - startsAt: open-new-project-sdk - -overlays: - - id: scenario-purpose - at: open-register - renderer: remotion - type: callout - variant: panel - region: top-right - style: - tone: brand - shadow: medium - radius: 8 - motion: - keyframes: - - at: 0 - unit: progress - opacity: 0 - position: - x: 100 - y: 10 - unit: percent - - at: 0.18 - unit: progress - opacity: 1 - position: - x: 82 - y: 10 - unit: percent - - at: 1 - unit: progress - opacity: 1 - position: - x: 82 - y: 10 - unit: percent - objects: - - id: acceptance-pulse - type: circle - position: - x: 8 - y: 22 - size: - width: 14 - height: 14 - style: - tone: success - opacity: 0.82 - motion: - keyframes: - - at: 0 - unit: progress - scale: 0.8 - opacity: 0.45 - - at: 0.5 - unit: progress - scale: 1.28 - opacity: 1 - - at: 1 - unit: progress - scale: 0.8 - opacity: 0.45 - text: This demo doubles as a product acceptance probe and an educational video source. - - id: mailpit-selector-risk - at: open-mailpit - renderer: remotion - type: callout - text: Mailpit confirmation is attempted through the browser so local email and auth gaps are visible in the run artifacts. - - id: team-portfolio-context - at: open-new-team - renderer: remotion - type: callout - text: The TreeSeed team will own a portfolio of research and engineering projects. - - id: bylaws-project-context - at: open-new-project-bylaws - renderer: remotion - type: callout - text: Bylaws is expected to be a new research-template project with no upstream remote. - - id: sdk-linked-project-gap - at: capture-sdk-linking-gap - renderer: remotion - type: callout - text: >- - Expected: link github.com/treeseed-ai/sdk and request a docs repository. Current gap: this linked-project operation is not exposed by the scene runtime or obvious project UI. - - id: final-gap-summary - at: review-gap-summary - renderer: remotion - type: callout - text: Review the screenshots, timeline, captions, transcript, and evidence bundle to prioritize product and selector hardening. - -diagrams: - - id: local-runtime-topology - renderer: remotion - component: DevRuntimeTopologyDiagram - at: open-mailpit - placement: overlay - durationSeconds: 12 - style: - tone: info - shadow: medium - motion: - keyframes: - - at: 0 - unit: progress - opacity: 0 - scale: 0.96 - - at: 0.2 - unit: progress - opacity: 1 - scale: 1 - - at: 1 - unit: progress - opacity: 1 - scale: 1 - objects: - - id: mail-flow-cursor - type: arrow - from: - x: 18 - y: 80 - unit: percent - to: - x: 84 - y: 80 - unit: percent - style: - tone: brand - opacity: 0.78 - motion: - keyframes: - - at: 0 - unit: progress - opacity: 0.2 - - at: 0.6 - unit: progress - opacity: 1 - - at: 1 - unit: progress - opacity: 0.7 - props: - title: Local demo runtime - surfaces: - - id: browser - label: Browser scene - kind: playwright - - id: web - label: Local web app - kind: astro - - id: api - label: Local API - kind: treeseed-api - - id: mailpit - label: Mailpit - kind: email - links: - - from: browser - to: web - label: drives UI - - from: web - to: api - label: auth and project calls - - from: api - to: mailpit - label: confirmation email - - id: project-launch-lifecycle - renderer: remotion - component: OperationLifecycleDiagram - at: submit-bylaws-project - placement: overlay - durationSeconds: 12 - props: - title: Project launch lifecycle - states: - - form-ready - - submitted - - queued - - deploying - - review - activeState: review - - id: scene-timeline-review - renderer: remotion - component: SceneExecutionTimelineDiagram - at: review-gap-summary - placement: overlay - durationSeconds: 10 - props: - title: Portfolio demo execution timeline - showCheckpoints: true - showSegments: true - -training: - enabled: true - captions: - enabled: true - formats: - - vtt - - srt - maxCueSeconds: 6 - renderInTrainingVideo: true - transcript: - enabled: true - formats: - - json - - markdown - narration: - enabled: true - style: instructional - includeDiagnostics: true - glossary: - enabled: true - terms: - - term: team - definition: A TreeSeed ownership boundary for projects, hosts, work, and knowledge. - sourceStep: open-new-team - groupIds: - - portfolio - - term: project - definition: A managed TreeSeed work surface that can own content, repositories, hosting, and launch evidence. - sourceStep: open-new-project-bylaws - groupIds: - - portfolio - - term: research template - definition: The starter used for research and knowledge-oriented projects such as Bylaws. - sourceStep: choose-research-template - groupIds: - - template - - term: linked repository - definition: An existing upstream repository that should be connected to a TreeSeed project instead of creating a new source repository. - sourceStep: capture-sdk-linking-gap - groupIds: - - gap - - term: docs repository - definition: A documentation repository expected for the linked SDK software project. - sourceStep: capture-sdk-linking-gap - groupIds: - - gap - - term: Mailpit - definition: The local email inbox used to confirm registration during the demo. - sourceStep: open-mailpit - groupIds: - - local-dev - - term: checkpoint - definition: A resumable scene runtime marker that helps diagnose and continue long workflows. - sourceStep: review-gap-summary - groupIds: - - scene-runtime - chapterClips: - enabled: true - format: manifest - -workflow: - - id: open-register - title: Open registration for a normal user - action: - goto: /auth/register?returnTo=/app - expect: - visible: - - role: heading - name: Create account - - - id: fill-first-name - title: Enter the user's first name - action: - fill: - css: input[name="firstName"] - internal: true - value: Test - expect: - visible: - - css: input[name="firstName"] - internal: true - - - id: fill-last-name - title: Enter the user's last name - action: - fill: - css: input[name="lastName"] - internal: true - value: Portfolio - expect: - visible: - - css: input[name="lastName"] - internal: true - - - id: fill-username - title: Choose a unique username - action: - fill: - css: input[name="username"] - internal: true - value: __PORTFOLIO_USERNAME__ - expect: - visible: - - css: input[name="username"] - internal: true - - - id: fill-email - title: Enter the generated local email address - action: - fill: - css: input[name="email"] - internal: true - value: __PORTFOLIO_EMAIL__ - expect: - visible: - - css: input[name="email"] - internal: true - - - id: fill-password - title: Enter a strong generated password - action: - fill: - css: input[name="password"] - internal: true - value: __PORTFOLIO_PASSWORD__ - expect: - visible: - - css: input[name="password"] - internal: true - - - id: fill-confirm-password - title: Confirm the generated password - action: - fill: - css: input[name="confirmPassword"] - internal: true - value: __PORTFOLIO_PASSWORD__ - expect: - visible: - - css: input[name="confirmPassword"] - internal: true - - - id: submit-registration - title: Submit the registration form - action: - click: - role: button - name: Create account - expect: - text: Check your email - checkpoint: - resumable: true - - - id: open-mailpit - title: Open the local Mailpit inbox - action: - goto: __PORTFOLIO_MAILPIT_URL__ - demoOnly: true - checkpoint: - resumable: true - - - id: open-confirmation-email - title: Open the newest confirmation email - action: - click: - css: a[href^="/view/"]:has-text("__PORTFOLIO_EMAIL__") - brittle: true - demoOnly: true - continueOnFailure: true - checkpoint: - resumable: true - - - id: open-confirmation-link - title: Open the email confirmation link - action: - mailpitConfirmLatest: - mailpitUrl: __PORTFOLIO_MAILPIT_URL__ - email: __PORTFOLIO_EMAIL__ - subjectIncludes: Confirm - expect: - urlIncludes: /app - demoOnly: true - continueOnFailure: true - checkpoint: - resumable: true - - - id: verify-admin-home - title: Confirm the user can see the admin homepage - action: - goto: /app - expect: - visible: - - role: heading - name: Start - continueOnFailure: true - checkpoint: - resumable: true - - - id: open-new-team - title: Open the new team screen - action: - goto: /app/teams/new - expect: - visible: - - role: heading - name: Create team - continueOnFailure: true - - - id: fill-team-slug - title: Enter the TreeSeed team slug - action: - fill: - css: input[name="name"] - internal: true - value: treeseed - expect: - visible: - - css: input[name="name"] - internal: true - continueOnFailure: true - - - id: fill-team-display-name - title: Enter the TreeSeed team display name - action: - fill: - css: input[name="displayName"] - internal: true - value: TreeSeed - expect: - visible: - - css: input[name="displayName"] - internal: true - continueOnFailure: true - - - id: fill-team-summary - title: Describe the team project portfolio - action: - fill: - css: textarea[name="profileSummary"] - internal: true - value: TreeSeed owns a portfolio of research and engineering projects, including governance research and software platform work. - expect: - visible: - - css: textarea[name="profileSummary"] - internal: true - continueOnFailure: true - - - id: submit-team - title: Create the TreeSeed team - action: - click: - role: button - name: Create team - expect: - urlIncludes: /app/teams - continueOnFailure: true - checkpoint: - resumable: true - - - id: open-new-project-bylaws - title: Open the new project screen for Bylaws - action: - goto: /app/projects/new - expect: - text: Create hosted project - continueOnFailure: true - - - id: fill-bylaws-name - title: Enter the Bylaws project name - action: - fill: - css: input[name="name"] - internal: true - value: Bylaws - expect: - visible: - - css: input[name="name"] - internal: true - continueOnFailure: true - - - id: fill-bylaws-slug - title: Enter the Bylaws project slug - action: - fill: - css: input[name="slug"] - internal: true - value: bylaws - expect: - visible: - - css: input[name="slug"] - internal: true - continueOnFailure: true - - - id: choose-research-template - title: Choose the research template - action: - click: - css: label[for="template-research"] - internal: true - expect: - visible: - - css: label[for="template-research"] - internal: true - continueOnFailure: true - - - id: fill-bylaws-objective - title: Describe the Bylaws research objective - action: - fill: - css: textarea[name="coreObjective"] - internal: true - value: Build a research project for organizing TreeSeed bylaws, governance notes, decision records, and portfolio policy. - expect: - visible: - - css: textarea[name="coreObjective"] - internal: true - continueOnFailure: true - - - id: submit-bylaws-project - title: Submit the Bylaws project launch - action: - click: - role: button - name: Create project - expect: - visible: - - css: "body" - internal: true - continueOnFailure: true - checkpoint: - resumable: true - - - id: open-new-project-sdk - title: Open the new project screen for SDK - action: - goto: /app/projects/new - expect: - text: Create hosted project - continueOnFailure: true - - - id: fill-sdk-name - title: Enter the SDK project name - action: - fill: - css: input[name="name"] - internal: true - value: SDK - expect: - visible: - - css: input[name="name"] - internal: true - continueOnFailure: true - - - id: fill-sdk-slug - title: Enter the SDK project slug - action: - fill: - css: input[name="slug"] - internal: true - value: sdk - expect: - visible: - - css: input[name="slug"] - internal: true - continueOnFailure: true - - - id: capture-sdk-linking-gap - title: Capture the linked SDK project gap - action: - pause: - mode: timed - durationSeconds: 6 - prompt: >- - Expected linked software project: public GitHub repository github.com/treeseed-ai/sdk with a docs repository request. Current gap: this operation is not exposed by the scene runtime or obvious project UI. - demoOnly: true - continueOnFailure: true - checkpoint: - resumable: true - - - id: review-gap-summary - title: Review portfolio demo evidence and gaps - action: - goto: /app/projects - expect: - visible: - - css: "body" - internal: true - continueOnFailure: true - checkpoint: - resumable: true diff --git a/templates/platform-local-managed-ai/template/seeds/treeseed.yaml b/templates/platform-local-managed-ai/template/seeds/treeseed.yaml deleted file mode 100644 index fac2b439..00000000 --- a/templates/platform-local-managed-ai/template/seeds/treeseed.yaml +++ /dev/null @@ -1,77 +0,0 @@ -schemaVersion: treeseed.seed-bundle/v3 -name: treeseed -version: 4 -description: Reproducible local TreeSeed portfolio with one unified capacity-provider battery. -environments: [local, staging, prod] -digest: sha256:e983c02364fb1e292018acf264c447da697d3fc106608ba76ce8d9656671c116 -resources: - teams: - - { key: 'team:treeseed', slug: treeseed, name: treeseed, displayName: TreeSeed, profileSummary: 'TreeSeed platform, packages, products, and agent operations.' } - memberships: - - { key: 'membership:treeseed/adrian-webb', team: 'team:treeseed', principal: { kind: user, email: 'adrian.webb@knowledge.coop' }, roles: [team_owner], missingUser: reject } - - key: membership:treeseed/automation - team: team:treeseed - principal: { kind: service-principal, key: 'service-principal:treeseed/automation', displayName: TreeSeed Automation, interactiveLogin: false } - roles: [team_owner] - projects: - - { key: 'project:treeseed/platform', team: 'team:treeseed', slug: platform, name: TreeSeed Platform, description: Public installer and portfolio integration workspace., kind: platform, primaryRepository: 'repository:treeseed/platform', libraryRepository: 'repository:treeseed/platform-library' } - - { key: 'project:treeseed/deployment', team: 'team:treeseed', slug: deployment, name: TreeSeed Deployment, description: Shared Debian bootstrap, host manager, edge, and component integration system., kind: platform, primaryRepository: 'repository:treeseed/deployment', libraryRepository: 'repository:treeseed/deployment-library' } - - { key: 'project:treeseed/api', team: 'team:treeseed', slug: api, name: TreeSeed API, description: Authoritative TreeSeed control plane., kind: package, primaryRepository: 'repository:treeseed/api', libraryRepository: 'repository:treeseed/api-library', metadata: { packageId: '@treeseed/api' } } - - { key: 'project:treeseed/treedx', team: 'team:treeseed', slug: treedx, name: TreeDX, description: Independent content and knowledge service., kind: service, primaryRepository: 'repository:treeseed/treedx', libraryRepository: 'repository:treeseed/treedx-library' } - - { key: 'project:treeseed/sdk', team: 'team:treeseed', slug: sdk, name: TreeSeed SDK, description: Portable contracts and remote clients., kind: package, primaryRepository: 'repository:treeseed/sdk', libraryRepository: 'repository:treeseed/sdk-library', metadata: { packageId: '@treeseed/sdk' } } - - { key: 'project:treeseed/ui', team: 'team:treeseed', slug: ui, name: TreeSeed UI, description: TreeSeed user-interface package., kind: package, primaryRepository: 'repository:treeseed/ui', libraryRepository: 'repository:treeseed/ui-library', metadata: { packageId: '@treeseed/ui' } } - - { key: 'project:treeseed/cli', team: 'team:treeseed', slug: cli, name: TreeSeed CLI, description: Human-centered TreeSeed command-line interface., kind: package, primaryRepository: 'repository:treeseed/cli', libraryRepository: 'repository:treeseed/cli-library', metadata: { packageId: '@treeseed/cli' } } - - { key: 'project:treeseed/core', team: 'team:treeseed', slug: core, name: TreeSeed Core, description: Core TreeSeed package., kind: package, primaryRepository: 'repository:treeseed/core', libraryRepository: 'repository:treeseed/core-library', metadata: { packageId: '@treeseed/core' } } - - { key: 'project:treeseed/admin', team: 'team:treeseed', slug: admin, name: TreeSeed Admin, description: TreeSeed administration interface., kind: package, primaryRepository: 'repository:treeseed/admin', libraryRepository: 'repository:treeseed/admin-library', metadata: { packageId: '@treeseed/admin' } } - - { key: 'project:treeseed/agent', team: 'team:treeseed', slug: agent, name: TreeSeed Agent, description: Unified capacity-provider and agent execution runtime., kind: package, primaryRepository: 'repository:treeseed/agent', libraryRepository: 'repository:treeseed/agent-library', metadata: { packageId: '@treeseed/agent' } } - - { key: 'project:treeseed/reviewer', team: 'team:treeseed', slug: reviewer, name: TreeSeed Reviewer, description: Independent review package., kind: package, primaryRepository: 'repository:treeseed/reviewer', libraryRepository: 'repository:treeseed/reviewer-library', metadata: { packageId: '@treeseed/reviewer' } } - - { key: 'project:treeseed/ai', team: 'team:treeseed', slug: ai, name: TreeSeed AI, description: AI integration package., kind: package, primaryRepository: 'repository:treeseed/ai', libraryRepository: 'repository:treeseed/ai-library', metadata: { packageId: '@treeseed/ai' } } - - { key: 'project:treeseed/template-engineering', team: 'team:treeseed', slug: template-engineering, name: Engineering Template, description: Engineering project template., kind: template, primaryRepository: 'repository:treeseed/template-engineering', libraryRepository: 'repository:treeseed/template-engineering-library' } - - { key: 'project:treeseed/template-research', team: 'team:treeseed', slug: template-research, name: Research Template, description: Research project template., kind: template, primaryRepository: 'repository:treeseed/template-research', libraryRepository: 'repository:treeseed/template-research-library' } - - { key: 'project:treeseed/market', team: 'team:treeseed', slug: market, name: TreeSeed Market, description: First-party portfolio product managed independently from Platform deployment., kind: product, primaryRepository: 'repository:treeseed/market', libraryRepository: 'repository:treeseed/market-library' } - - { key: 'project:treeseed/market-api', team: 'team:treeseed', slug: market-api, name: TreeSeed Market API, description: First-party Market service managed independently from Platform deployment., kind: service, primaryRepository: 'repository:treeseed/market-api', libraryRepository: 'repository:treeseed/market-api-library' } - repositories: - - &platform_repo { key: 'repository:treeseed/platform', project: 'project:treeseed/platform', role: primary, provider: github, owner: treeseed-ai, name: platform, gitUrl: 'git@github.com:treeseed-ai/platform.git', defaultBranch: main, checkoutPath: '.', repositoryPolicy: &public_repo { visibility: public, lifecycle: create-or-adopt, deletionPolicy: retain, defaultBranch: main, stagingBranch: staging, issues: true, actions: true, workflows: [verify.yml] } } - - { key: 'repository:treeseed/deployment', project: 'project:treeseed/deployment', role: primary, provider: github, owner: treeseed-ai, name: deployment, gitUrl: 'git@github.com:treeseed-ai/deployment.git', defaultBranch: main, checkoutPath: packages/deployment, repositoryPolicy: *public_repo, metadata: { deploymentAuthority: host-manager } } - - { key: 'repository:treeseed/api', project: 'project:treeseed/api', role: primary, provider: github, owner: treeseed-ai, name: api, gitUrl: 'git@github.com:treeseed-ai/api.git', defaultBranch: main, checkoutPath: packages/api, submodulePath: packages/api, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/treedx', project: 'project:treeseed/treedx', role: primary, provider: github, owner: treeseed-ai, name: treedx, gitUrl: 'git@github.com:treeseed-ai/treedx.git', defaultBranch: main, checkoutPath: packages/treedx, submodulePath: packages/treedx, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/sdk', project: 'project:treeseed/sdk', role: primary, provider: github, owner: treeseed-ai, name: sdk, gitUrl: 'git@github.com:treeseed-ai/sdk.git', defaultBranch: main, checkoutPath: packages/sdk, submodulePath: packages/sdk, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/ui', project: 'project:treeseed/ui', role: primary, provider: github, owner: treeseed-ai, name: ui, gitUrl: 'git@github.com:treeseed-ai/ui.git', defaultBranch: main, checkoutPath: packages/ui, submodulePath: packages/ui, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/cli', project: 'project:treeseed/cli', role: primary, provider: github, owner: treeseed-ai, name: cli, gitUrl: 'git@github.com:treeseed-ai/cli.git', defaultBranch: main, checkoutPath: packages/cli, submodulePath: packages/cli, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/core', project: 'project:treeseed/core', role: primary, provider: github, owner: treeseed-ai, name: core, gitUrl: 'git@github.com:treeseed-ai/core.git', defaultBranch: main, checkoutPath: packages/core, submodulePath: packages/core, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/admin', project: 'project:treeseed/admin', role: primary, provider: github, owner: treeseed-ai, name: admin, gitUrl: 'git@github.com:treeseed-ai/admin.git', defaultBranch: main, checkoutPath: packages/admin, submodulePath: packages/admin, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/agent', project: 'project:treeseed/agent', role: primary, provider: github, owner: treeseed-ai, name: agent, gitUrl: 'git@github.com:treeseed-ai/agent.git', defaultBranch: main, checkoutPath: packages/agent, submodulePath: packages/agent, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/reviewer', project: 'project:treeseed/reviewer', role: primary, provider: github, owner: treeseed-ai, name: reviewer, gitUrl: 'git@github.com:treeseed-ai/reviewer.git', defaultBranch: main, checkoutPath: packages/reviewer, submodulePath: packages/reviewer, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/ai', project: 'project:treeseed/ai', role: primary, provider: github, owner: treeseed-ai, name: ai, gitUrl: 'git@github.com:treeseed-ai/ai.git', defaultBranch: main, checkoutPath: packages/ai, submodulePath: packages/ai, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/template-engineering', project: 'project:treeseed/template-engineering', role: primary, provider: github, owner: treeseed-ai, name: template-engineering, gitUrl: 'git@github.com:treeseed-ai/template-engineering.git', defaultBranch: main, checkoutPath: templates/engineering, submodulePath: templates/engineering, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/template-research', project: 'project:treeseed/template-research', role: primary, provider: github, owner: treeseed-ai, name: template-research, gitUrl: 'git@github.com:treeseed-ai/template-research.git', defaultBranch: main, checkoutPath: templates/research, submodulePath: templates/research, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/market', project: 'project:treeseed/market', role: primary, provider: github, owner: treeseed-ai, name: market, gitUrl: 'git@github.com:treeseed-ai/market.git', defaultBranch: main, checkoutPath: products/market, repositoryPolicy: *public_repo, metadata: { platformCustody: portfolio-only, deployableByPlatform: false } } - - { key: 'repository:treeseed/market-api', project: 'project:treeseed/market-api', role: primary, provider: github, owner: treeseed-ai, name: market-api, gitUrl: 'git@github.com:treeseed-ai/market-api.git', defaultBranch: main, checkoutPath: services/market-api, repositoryPolicy: &private_repo { visibility: private, lifecycle: create-or-adopt, deletionPolicy: retain, defaultBranch: main, stagingBranch: staging, issues: true, actions: true, workflows: [verify.yml] }, metadata: { platformCustody: portfolio-only, deployableByPlatform: false } } - - { key: 'repository:treeseed/platform-library', project: 'project:treeseed/platform', role: library, provider: github, owner: treeseed-ai, name: platform-library, gitUrl: 'https://github.com/treeseed-ai/platform-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: &library_metadata { libraryRoot: '.', synchronizedRefs: [main, staging] } } - - { key: 'repository:treeseed/deployment-library', project: 'project:treeseed/deployment', role: library, provider: github, owner: treeseed-ai, name: deployment-library, gitUrl: 'https://github.com/treeseed-ai/deployment-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/api-library', project: 'project:treeseed/api', role: library, provider: github, owner: treeseed-ai, name: api-library, gitUrl: 'https://github.com/treeseed-ai/api-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/treedx-library', project: 'project:treeseed/treedx', role: library, provider: github, owner: treeseed-ai, name: treedx-library, gitUrl: 'https://github.com/treeseed-ai/treedx-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/sdk-library', project: 'project:treeseed/sdk', role: library, provider: github, owner: treeseed-ai, name: sdk-library, gitUrl: 'https://github.com/treeseed-ai/sdk-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/ui-library', project: 'project:treeseed/ui', role: library, provider: github, owner: treeseed-ai, name: ui-library, gitUrl: 'https://github.com/treeseed-ai/ui-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/cli-library', project: 'project:treeseed/cli', role: library, provider: github, owner: treeseed-ai, name: cli-library, gitUrl: 'https://github.com/treeseed-ai/cli-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/core-library', project: 'project:treeseed/core', role: library, provider: github, owner: treeseed-ai, name: core-library, gitUrl: 'https://github.com/treeseed-ai/core-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/admin-library', project: 'project:treeseed/admin', role: library, provider: github, owner: treeseed-ai, name: admin-library, gitUrl: 'https://github.com/treeseed-ai/admin-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/agent-library', project: 'project:treeseed/agent', role: library, provider: github, owner: treeseed-ai, name: agent-library, gitUrl: 'https://github.com/treeseed-ai/agent-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/reviewer-library', project: 'project:treeseed/reviewer', role: library, provider: github, owner: treeseed-ai, name: reviewer-library, gitUrl: 'https://github.com/treeseed-ai/reviewer-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/ai-library', project: 'project:treeseed/ai', role: library, provider: github, owner: treeseed-ai, name: ai-library, gitUrl: 'https://github.com/treeseed-ai/ai-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/template-engineering-library', project: 'project:treeseed/template-engineering', role: library, provider: github, owner: treeseed-ai, name: template-engineering-library, gitUrl: 'https://github.com/treeseed-ai/template-engineering-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/template-research-library', project: 'project:treeseed/template-research', role: library, provider: github, owner: treeseed-ai, name: template-research-library, gitUrl: 'https://github.com/treeseed-ai/template-research-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/market-library', project: 'project:treeseed/market', role: library, provider: github, owner: treeseed-ai, name: market-library, gitUrl: 'https://github.com/treeseed-ai/market-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/market-api-library', project: 'project:treeseed/market-api', role: library, provider: github, owner: treeseed-ai, name: market-api-library, gitUrl: 'https://github.com/treeseed-ai/market-api-library.git', defaultBranch: main, repositoryPolicy: *private_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/fixtures', project: 'project:treeseed/platform', role: fixture, provider: github, owner: treeseed-ai, name: fixtures, gitUrl: 'git@github.com:treeseed-ai/fixtures.git', defaultBranch: main, checkoutPath: fixtures, submodulePath: fixtures, repositoryPolicy: { visibility: public, lifecycle: create-or-adopt, deletionPolicy: retain, defaultBranch: main, stagingBranch: staging, issues: true, actions: false, workflows: [] } } -runtime: - capacityProviders: - - key: capacity-provider:treeseed/local - team: team:treeseed - environments: [local] - manifestDigest: sha256:9b3f675f40a7f23d66cc7429600d68438cb28ba866ebe4ce8688e240a4fa482c - manifestRef: treeseed.capacity-provider.yaml - approval: trusted-local-owner - projects: ['project:treeseed/platform', 'project:treeseed/deployment', 'project:treeseed/api', 'project:treeseed/treedx', 'project:treeseed/sdk', 'project:treeseed/ui', 'project:treeseed/cli', 'project:treeseed/core', 'project:treeseed/admin', 'project:treeseed/agent', 'project:treeseed/reviewer', 'project:treeseed/ai', 'project:treeseed/template-engineering', 'project:treeseed/template-research', 'project:treeseed/market', 'project:treeseed/market-api'] - allowedModes: [planning, acting] - requiredLanePurposes: [communication, platform, workday] diff --git a/templates/platform-local-managed-ai/template/treeseed.capacity-provider.yaml b/templates/platform-local-managed-ai/template/treeseed.capacity-provider.yaml deleted file mode 100644 index f240e115..00000000 --- a/templates/platform-local-managed-ai/template/treeseed.capacity-provider.yaml +++ /dev/null @@ -1,84 +0,0 @@ -schemaVersion: 3 -ownership: - type: team - teamId: team:treeseed -configuration: - generation: local-battery-v2 -identity: - privateKeyRef: data://identity-v3.json - displayName: TreeSeed local capacity battery -capacity: - maxConcurrentWorkers: 4 - cpuCores: 8 - memoryBytes: 17179869184 - maxActiveSeconds: 28800 - maxInputTokens: 4000000 - maxOutputTokens: 1000000 - maxCost: 100 - currency: USD - maxAttempts: 3 -credentialProfiles: - - { id: codex-auth, source: process-environment, reference: TREESEED_CODEX_AUTH_FILE, required: true } - - { id: codex-executable, source: process-environment, reference: TREESEED_CODEX_EXECUTABLE, required: true } - - { id: platform-github, source: process-environment, reference: TREESEED_GITHUB_TOKEN, required: false } - - { id: platform-cloudflare, source: process-environment, reference: TREESEED_CLOUDFLARE_API_TOKEN, required: false } -lanes: - - id: communication - purpose: communication - priority: 100 - reservedConcurrentWorkers: 1 - maxConcurrentWorkers: 2 - borrowWhenIdle: true - lendWhenIdle: true - reclaimPolicy: admission - queueLimit: 100 - timeoutSeconds: 120 - capabilities: [communication, agent-execution, research, planning] - - id: platform - purpose: platform - priority: 70 - reservedConcurrentWorkers: 0 - maxConcurrentWorkers: 2 - borrowWhenIdle: true - lendWhenIdle: true - reclaimPolicy: admission - queueLimit: 25 - timeoutSeconds: 900 - capabilities: [platform_operation, infrastructure_reconciliation, repository_reconciliation] - - id: workday - purpose: workday - priority: 50 - reservedConcurrentWorkers: 0 - maxConcurrentWorkers: 4 - borrowWhenIdle: true - lendWhenIdle: true - reclaimPolicy: admission - queueLimit: 100 - timeoutSeconds: 900 - minimumAssignmentDuration: { amount: 600, unit: seconds } - capabilities: [agent-execution, engineering, research, planning, acting, verification, repository_work] -adapters: - - id: codex-local - adapter: codex - isolation: process - module: module:codex-chat - profile: subscription - protocol: responses - credentialProfiles: [codex-auth, codex-executable] - laneIds: [communication] - maxConcurrentWorkers: 2 - minimumAssignmentDuration: { amount: 600, unit: seconds } - nativeLimits: { availableAgentSeconds: 28800 } - capabilities: [communication, agent-execution] - - id: platform-local - adapter: platform-operation - isolation: process - credentialProfiles: [platform-github, platform-cloudflare] - laneIds: [platform] - maxConcurrentWorkers: 2 - nativeLimits: { availableAgentSeconds: 14400 } - capabilities: [platform_operation, infrastructure_reconciliation, repository_reconciliation] -connections: [] -metadata: - custody: local-only - sharedBattery: true diff --git a/templates/platform-local-managed-ai/template/treeseed.site.yaml b/templates/platform-local-managed-ai/template/treeseed.site.yaml deleted file mode 100644 index 45089450..00000000 --- a/templates/platform-local-managed-ai/template/treeseed.site.yaml +++ /dev/null @@ -1,23 +0,0 @@ -name: TreeSeed Platform -slug: treeseed-platform -siteUrl: https://treeseed.dev/platform -contactEmail: hello@treeseed.email -authority: { kind: customer-platform } -market: { profile: treeseed } -controlPlane: { mode: managed } -development: - local: - marketConnectivity: disabled - inventory: { source: seed, path: seeds/treeseed.yaml } -hub: { mode: customer_hosted } -runtime: { mode: none, registration: none } -processing: { mode: local, providerRef: codex-treeseed } -surfaces: { web: { enabled: false }, admin: { enabled: false }, api: { enabled: true } } -services: - api: { enabled: true, provider: local } - treeseedDatabase: { enabled: true, provider: local } - operationsRunner: { enabled: true, provider: local } - treedx: { enabled: true, provider: local } - agentProvider: { enabled: true, provider: local } - aiAppliance: { enabled: true, provider: local } -publicTreeDxFederation: {} diff --git a/templates/platform-local-managed-codex/template.config.json b/templates/platform-local-managed-codex/template.config.json deleted file mode 100644 index a77dc8bb..00000000 --- a/templates/platform-local-managed-codex/template.config.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "schemaVersion": 2, - "id": "platform-local-managed-codex", - "displayName": "Local managed Platform with Codex", - "description": "A sovereign local TreeSeed control plane with external Codex execution.", - "category": "platform", - "tags": ["platform", "local", "managed", "codex"], - "templateVersion": "3.0.0", - "templateApiVersion": 2, - "minCliVersion": "0.12.59", - "variables": [ - { "name": "Runtime portfolio username", "token": "__PORTFOLIO_USERNAME__", "deriveFrom": "runtime" }, - { "name": "Runtime portfolio email", "token": "__PORTFOLIO_EMAIL__", "deriveFrom": "runtime" }, - { "name": "Runtime portfolio password", "token": "__PORTFOLIO_PASSWORD__", "deriveFrom": "runtime" }, - { "name": "Runtime Mailpit URL", "token": "__PORTFOLIO_MAILPIT_URL__", "deriveFrom": "runtime" } - ], - "managedSurface": { - "coreManaged": ["treeseed.site.yaml", "seeds/treeseed.yaml", "treeseed.capacity-provider.yaml", "scenes/team-project-portfolio-demo.yaml"], - "validatedOnly": ["treeseed.site.yaml", "seeds/treeseed.yaml", "treeseed.capacity-provider.yaml", "scenes/team-project-portfolio-demo.yaml"] - }, - "platform": { - "controlPlane": { "mode": "managed" }, - "processing": { "mode": "local" }, - "admin": { "enabled": false }, - "executionProvider": "codex", - "aiAppliance": false, - "services": ["api", "treeseedDatabase", "operationsRunner", "treedx", "agentProvider"], - "seeds": ["seeds/treeseed.yaml"], - "scenes": ["scenes/team-project-portfolio-demo.yaml"] - }, - "testing": { "smokeCommand": "npx trsd platform status --json", "buildCommand": "npm run verify" } -} diff --git a/templates/platform-local-managed-codex/template/scenes/team-project-portfolio-demo.yaml b/templates/platform-local-managed-codex/template/scenes/team-project-portfolio-demo.yaml deleted file mode 100644 index 47793867..00000000 --- a/templates/platform-local-managed-codex/template/scenes/team-project-portfolio-demo.yaml +++ /dev/null @@ -1,731 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: team-project-portfolio-demo -title: Team Project Portfolio Demo -description: >- - Register a user, create the TreeSeed team, and prepare portfolio projects for research and engineering work. This scene is intentionally practical: it should expose real admin-flow, project-launch, Mailpit, recording, rendering, and training-output gaps while serving as a central TreeSeed acceptance test harness and demo / educational video generator scenario. -audience: - - evaluator - - operator - - trainee - -mode: - test: false - demo: true - training: true - -runtime: - mode: training - timeouts: - sceneSeconds: 1800 - chapterSeconds: 600 - stepSeconds: 120 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: true - -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 - -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false - browserFrame: - enabled: false - title: Team Project Portfolio Demo - chrome: desktop - - id: tablet - title: Tablet - orientation: landscape - viewport: - width: 1024 - height: 768 - video: - width: 1024 - height: 768 - output: - width: 1440 - height: 1080 - deviceScaleFactor: 1 - isMobile: true - hasTouch: true - browserFrame: - enabled: false - title: Team Project Portfolio Demo - chrome: tablet - - id: mobile - title: Mobile - orientation: portrait - viewport: - width: 390 - height: 844 - video: - width: 390 - height: 844 - output: - width: 1080 - height: 1920 - deviceScaleFactor: 2 - isMobile: true - hasTouch: true - browserFrame: - enabled: false - title: Team Project Portfolio Demo - chrome: mobile - -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true - -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true - -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser - browserFrame: - enabled: false - title: Team Project Portfolio Demo - -chapters: - - id: registration - title: Register a portfolio owner - startsAt: open-register - - id: email-confirmation - title: Confirm the account through Mailpit - startsAt: open-mailpit - - id: team-setup - title: Create the TreeSeed team - startsAt: verify-admin-home - - id: portfolio-projects - title: Prepare portfolio projects - startsAt: open-new-project-bylaws - - id: gap-review - title: Capture linked project gaps - startsAt: open-new-project-sdk - -overlays: - - id: scenario-purpose - at: open-register - renderer: remotion - type: callout - variant: panel - region: top-right - style: - tone: brand - shadow: medium - radius: 8 - motion: - keyframes: - - at: 0 - unit: progress - opacity: 0 - position: - x: 100 - y: 10 - unit: percent - - at: 0.18 - unit: progress - opacity: 1 - position: - x: 82 - y: 10 - unit: percent - - at: 1 - unit: progress - opacity: 1 - position: - x: 82 - y: 10 - unit: percent - objects: - - id: acceptance-pulse - type: circle - position: - x: 8 - y: 22 - size: - width: 14 - height: 14 - style: - tone: success - opacity: 0.82 - motion: - keyframes: - - at: 0 - unit: progress - scale: 0.8 - opacity: 0.45 - - at: 0.5 - unit: progress - scale: 1.28 - opacity: 1 - - at: 1 - unit: progress - scale: 0.8 - opacity: 0.45 - text: This demo doubles as a product acceptance probe and an educational video source. - - id: mailpit-selector-risk - at: open-mailpit - renderer: remotion - type: callout - text: Mailpit confirmation is attempted through the browser so local email and auth gaps are visible in the run artifacts. - - id: team-portfolio-context - at: open-new-team - renderer: remotion - type: callout - text: The TreeSeed team will own a portfolio of research and engineering projects. - - id: bylaws-project-context - at: open-new-project-bylaws - renderer: remotion - type: callout - text: Bylaws is expected to be a new research-template project with no upstream remote. - - id: sdk-linked-project-gap - at: capture-sdk-linking-gap - renderer: remotion - type: callout - text: >- - Expected: link github.com/treeseed-ai/sdk and request a docs repository. Current gap: this linked-project operation is not exposed by the scene runtime or obvious project UI. - - id: final-gap-summary - at: review-gap-summary - renderer: remotion - type: callout - text: Review the screenshots, timeline, captions, transcript, and evidence bundle to prioritize product and selector hardening. - -diagrams: - - id: local-runtime-topology - renderer: remotion - component: DevRuntimeTopologyDiagram - at: open-mailpit - placement: overlay - durationSeconds: 12 - style: - tone: info - shadow: medium - motion: - keyframes: - - at: 0 - unit: progress - opacity: 0 - scale: 0.96 - - at: 0.2 - unit: progress - opacity: 1 - scale: 1 - - at: 1 - unit: progress - opacity: 1 - scale: 1 - objects: - - id: mail-flow-cursor - type: arrow - from: - x: 18 - y: 80 - unit: percent - to: - x: 84 - y: 80 - unit: percent - style: - tone: brand - opacity: 0.78 - motion: - keyframes: - - at: 0 - unit: progress - opacity: 0.2 - - at: 0.6 - unit: progress - opacity: 1 - - at: 1 - unit: progress - opacity: 0.7 - props: - title: Local demo runtime - surfaces: - - id: browser - label: Browser scene - kind: playwright - - id: web - label: Local web app - kind: astro - - id: api - label: Local API - kind: treeseed-api - - id: mailpit - label: Mailpit - kind: email - links: - - from: browser - to: web - label: drives UI - - from: web - to: api - label: auth and project calls - - from: api - to: mailpit - label: confirmation email - - id: project-launch-lifecycle - renderer: remotion - component: OperationLifecycleDiagram - at: submit-bylaws-project - placement: overlay - durationSeconds: 12 - props: - title: Project launch lifecycle - states: - - form-ready - - submitted - - queued - - deploying - - review - activeState: review - - id: scene-timeline-review - renderer: remotion - component: SceneExecutionTimelineDiagram - at: review-gap-summary - placement: overlay - durationSeconds: 10 - props: - title: Portfolio demo execution timeline - showCheckpoints: true - showSegments: true - -training: - enabled: true - captions: - enabled: true - formats: - - vtt - - srt - maxCueSeconds: 6 - renderInTrainingVideo: true - transcript: - enabled: true - formats: - - json - - markdown - narration: - enabled: true - style: instructional - includeDiagnostics: true - glossary: - enabled: true - terms: - - term: team - definition: A TreeSeed ownership boundary for projects, hosts, work, and knowledge. - sourceStep: open-new-team - groupIds: - - portfolio - - term: project - definition: A managed TreeSeed work surface that can own content, repositories, hosting, and launch evidence. - sourceStep: open-new-project-bylaws - groupIds: - - portfolio - - term: research template - definition: The starter used for research and knowledge-oriented projects such as Bylaws. - sourceStep: choose-research-template - groupIds: - - template - - term: linked repository - definition: An existing upstream repository that should be connected to a TreeSeed project instead of creating a new source repository. - sourceStep: capture-sdk-linking-gap - groupIds: - - gap - - term: docs repository - definition: A documentation repository expected for the linked SDK software project. - sourceStep: capture-sdk-linking-gap - groupIds: - - gap - - term: Mailpit - definition: The local email inbox used to confirm registration during the demo. - sourceStep: open-mailpit - groupIds: - - local-dev - - term: checkpoint - definition: A resumable scene runtime marker that helps diagnose and continue long workflows. - sourceStep: review-gap-summary - groupIds: - - scene-runtime - chapterClips: - enabled: true - format: manifest - -workflow: - - id: open-register - title: Open registration for a normal user - action: - goto: /auth/register?returnTo=/app - expect: - visible: - - role: heading - name: Create account - - - id: fill-first-name - title: Enter the user's first name - action: - fill: - css: input[name="firstName"] - internal: true - value: Test - expect: - visible: - - css: input[name="firstName"] - internal: true - - - id: fill-last-name - title: Enter the user's last name - action: - fill: - css: input[name="lastName"] - internal: true - value: Portfolio - expect: - visible: - - css: input[name="lastName"] - internal: true - - - id: fill-username - title: Choose a unique username - action: - fill: - css: input[name="username"] - internal: true - value: __PORTFOLIO_USERNAME__ - expect: - visible: - - css: input[name="username"] - internal: true - - - id: fill-email - title: Enter the generated local email address - action: - fill: - css: input[name="email"] - internal: true - value: __PORTFOLIO_EMAIL__ - expect: - visible: - - css: input[name="email"] - internal: true - - - id: fill-password - title: Enter a strong generated password - action: - fill: - css: input[name="password"] - internal: true - value: __PORTFOLIO_PASSWORD__ - expect: - visible: - - css: input[name="password"] - internal: true - - - id: fill-confirm-password - title: Confirm the generated password - action: - fill: - css: input[name="confirmPassword"] - internal: true - value: __PORTFOLIO_PASSWORD__ - expect: - visible: - - css: input[name="confirmPassword"] - internal: true - - - id: submit-registration - title: Submit the registration form - action: - click: - role: button - name: Create account - expect: - text: Check your email - checkpoint: - resumable: true - - - id: open-mailpit - title: Open the local Mailpit inbox - action: - goto: __PORTFOLIO_MAILPIT_URL__ - demoOnly: true - checkpoint: - resumable: true - - - id: open-confirmation-email - title: Open the newest confirmation email - action: - click: - css: a[href^="/view/"]:has-text("__PORTFOLIO_EMAIL__") - brittle: true - demoOnly: true - continueOnFailure: true - checkpoint: - resumable: true - - - id: open-confirmation-link - title: Open the email confirmation link - action: - mailpitConfirmLatest: - mailpitUrl: __PORTFOLIO_MAILPIT_URL__ - email: __PORTFOLIO_EMAIL__ - subjectIncludes: Confirm - expect: - urlIncludes: /app - demoOnly: true - continueOnFailure: true - checkpoint: - resumable: true - - - id: verify-admin-home - title: Confirm the user can see the admin homepage - action: - goto: /app - expect: - visible: - - role: heading - name: Start - continueOnFailure: true - checkpoint: - resumable: true - - - id: open-new-team - title: Open the new team screen - action: - goto: /app/teams/new - expect: - visible: - - role: heading - name: Create team - continueOnFailure: true - - - id: fill-team-slug - title: Enter the TreeSeed team slug - action: - fill: - css: input[name="name"] - internal: true - value: treeseed - expect: - visible: - - css: input[name="name"] - internal: true - continueOnFailure: true - - - id: fill-team-display-name - title: Enter the TreeSeed team display name - action: - fill: - css: input[name="displayName"] - internal: true - value: TreeSeed - expect: - visible: - - css: input[name="displayName"] - internal: true - continueOnFailure: true - - - id: fill-team-summary - title: Describe the team project portfolio - action: - fill: - css: textarea[name="profileSummary"] - internal: true - value: TreeSeed owns a portfolio of research and engineering projects, including governance research and software platform work. - expect: - visible: - - css: textarea[name="profileSummary"] - internal: true - continueOnFailure: true - - - id: submit-team - title: Create the TreeSeed team - action: - click: - role: button - name: Create team - expect: - urlIncludes: /app/teams - continueOnFailure: true - checkpoint: - resumable: true - - - id: open-new-project-bylaws - title: Open the new project screen for Bylaws - action: - goto: /app/projects/new - expect: - text: Create hosted project - continueOnFailure: true - - - id: fill-bylaws-name - title: Enter the Bylaws project name - action: - fill: - css: input[name="name"] - internal: true - value: Bylaws - expect: - visible: - - css: input[name="name"] - internal: true - continueOnFailure: true - - - id: fill-bylaws-slug - title: Enter the Bylaws project slug - action: - fill: - css: input[name="slug"] - internal: true - value: bylaws - expect: - visible: - - css: input[name="slug"] - internal: true - continueOnFailure: true - - - id: choose-research-template - title: Choose the research template - action: - click: - css: label[for="template-research"] - internal: true - expect: - visible: - - css: label[for="template-research"] - internal: true - continueOnFailure: true - - - id: fill-bylaws-objective - title: Describe the Bylaws research objective - action: - fill: - css: textarea[name="coreObjective"] - internal: true - value: Build a research project for organizing TreeSeed bylaws, governance notes, decision records, and portfolio policy. - expect: - visible: - - css: textarea[name="coreObjective"] - internal: true - continueOnFailure: true - - - id: submit-bylaws-project - title: Submit the Bylaws project launch - action: - click: - role: button - name: Create project - expect: - visible: - - css: "body" - internal: true - continueOnFailure: true - checkpoint: - resumable: true - - - id: open-new-project-sdk - title: Open the new project screen for SDK - action: - goto: /app/projects/new - expect: - text: Create hosted project - continueOnFailure: true - - - id: fill-sdk-name - title: Enter the SDK project name - action: - fill: - css: input[name="name"] - internal: true - value: SDK - expect: - visible: - - css: input[name="name"] - internal: true - continueOnFailure: true - - - id: fill-sdk-slug - title: Enter the SDK project slug - action: - fill: - css: input[name="slug"] - internal: true - value: sdk - expect: - visible: - - css: input[name="slug"] - internal: true - continueOnFailure: true - - - id: capture-sdk-linking-gap - title: Capture the linked SDK project gap - action: - pause: - mode: timed - durationSeconds: 6 - prompt: >- - Expected linked software project: public GitHub repository github.com/treeseed-ai/sdk with a docs repository request. Current gap: this operation is not exposed by the scene runtime or obvious project UI. - demoOnly: true - continueOnFailure: true - checkpoint: - resumable: true - - - id: review-gap-summary - title: Review portfolio demo evidence and gaps - action: - goto: /app/projects - expect: - visible: - - css: "body" - internal: true - continueOnFailure: true - checkpoint: - resumable: true diff --git a/templates/platform-local-managed-codex/template/seeds/treeseed.yaml b/templates/platform-local-managed-codex/template/seeds/treeseed.yaml deleted file mode 100644 index fac2b439..00000000 --- a/templates/platform-local-managed-codex/template/seeds/treeseed.yaml +++ /dev/null @@ -1,77 +0,0 @@ -schemaVersion: treeseed.seed-bundle/v3 -name: treeseed -version: 4 -description: Reproducible local TreeSeed portfolio with one unified capacity-provider battery. -environments: [local, staging, prod] -digest: sha256:e983c02364fb1e292018acf264c447da697d3fc106608ba76ce8d9656671c116 -resources: - teams: - - { key: 'team:treeseed', slug: treeseed, name: treeseed, displayName: TreeSeed, profileSummary: 'TreeSeed platform, packages, products, and agent operations.' } - memberships: - - { key: 'membership:treeseed/adrian-webb', team: 'team:treeseed', principal: { kind: user, email: 'adrian.webb@knowledge.coop' }, roles: [team_owner], missingUser: reject } - - key: membership:treeseed/automation - team: team:treeseed - principal: { kind: service-principal, key: 'service-principal:treeseed/automation', displayName: TreeSeed Automation, interactiveLogin: false } - roles: [team_owner] - projects: - - { key: 'project:treeseed/platform', team: 'team:treeseed', slug: platform, name: TreeSeed Platform, description: Public installer and portfolio integration workspace., kind: platform, primaryRepository: 'repository:treeseed/platform', libraryRepository: 'repository:treeseed/platform-library' } - - { key: 'project:treeseed/deployment', team: 'team:treeseed', slug: deployment, name: TreeSeed Deployment, description: Shared Debian bootstrap, host manager, edge, and component integration system., kind: platform, primaryRepository: 'repository:treeseed/deployment', libraryRepository: 'repository:treeseed/deployment-library' } - - { key: 'project:treeseed/api', team: 'team:treeseed', slug: api, name: TreeSeed API, description: Authoritative TreeSeed control plane., kind: package, primaryRepository: 'repository:treeseed/api', libraryRepository: 'repository:treeseed/api-library', metadata: { packageId: '@treeseed/api' } } - - { key: 'project:treeseed/treedx', team: 'team:treeseed', slug: treedx, name: TreeDX, description: Independent content and knowledge service., kind: service, primaryRepository: 'repository:treeseed/treedx', libraryRepository: 'repository:treeseed/treedx-library' } - - { key: 'project:treeseed/sdk', team: 'team:treeseed', slug: sdk, name: TreeSeed SDK, description: Portable contracts and remote clients., kind: package, primaryRepository: 'repository:treeseed/sdk', libraryRepository: 'repository:treeseed/sdk-library', metadata: { packageId: '@treeseed/sdk' } } - - { key: 'project:treeseed/ui', team: 'team:treeseed', slug: ui, name: TreeSeed UI, description: TreeSeed user-interface package., kind: package, primaryRepository: 'repository:treeseed/ui', libraryRepository: 'repository:treeseed/ui-library', metadata: { packageId: '@treeseed/ui' } } - - { key: 'project:treeseed/cli', team: 'team:treeseed', slug: cli, name: TreeSeed CLI, description: Human-centered TreeSeed command-line interface., kind: package, primaryRepository: 'repository:treeseed/cli', libraryRepository: 'repository:treeseed/cli-library', metadata: { packageId: '@treeseed/cli' } } - - { key: 'project:treeseed/core', team: 'team:treeseed', slug: core, name: TreeSeed Core, description: Core TreeSeed package., kind: package, primaryRepository: 'repository:treeseed/core', libraryRepository: 'repository:treeseed/core-library', metadata: { packageId: '@treeseed/core' } } - - { key: 'project:treeseed/admin', team: 'team:treeseed', slug: admin, name: TreeSeed Admin, description: TreeSeed administration interface., kind: package, primaryRepository: 'repository:treeseed/admin', libraryRepository: 'repository:treeseed/admin-library', metadata: { packageId: '@treeseed/admin' } } - - { key: 'project:treeseed/agent', team: 'team:treeseed', slug: agent, name: TreeSeed Agent, description: Unified capacity-provider and agent execution runtime., kind: package, primaryRepository: 'repository:treeseed/agent', libraryRepository: 'repository:treeseed/agent-library', metadata: { packageId: '@treeseed/agent' } } - - { key: 'project:treeseed/reviewer', team: 'team:treeseed', slug: reviewer, name: TreeSeed Reviewer, description: Independent review package., kind: package, primaryRepository: 'repository:treeseed/reviewer', libraryRepository: 'repository:treeseed/reviewer-library', metadata: { packageId: '@treeseed/reviewer' } } - - { key: 'project:treeseed/ai', team: 'team:treeseed', slug: ai, name: TreeSeed AI, description: AI integration package., kind: package, primaryRepository: 'repository:treeseed/ai', libraryRepository: 'repository:treeseed/ai-library', metadata: { packageId: '@treeseed/ai' } } - - { key: 'project:treeseed/template-engineering', team: 'team:treeseed', slug: template-engineering, name: Engineering Template, description: Engineering project template., kind: template, primaryRepository: 'repository:treeseed/template-engineering', libraryRepository: 'repository:treeseed/template-engineering-library' } - - { key: 'project:treeseed/template-research', team: 'team:treeseed', slug: template-research, name: Research Template, description: Research project template., kind: template, primaryRepository: 'repository:treeseed/template-research', libraryRepository: 'repository:treeseed/template-research-library' } - - { key: 'project:treeseed/market', team: 'team:treeseed', slug: market, name: TreeSeed Market, description: First-party portfolio product managed independently from Platform deployment., kind: product, primaryRepository: 'repository:treeseed/market', libraryRepository: 'repository:treeseed/market-library' } - - { key: 'project:treeseed/market-api', team: 'team:treeseed', slug: market-api, name: TreeSeed Market API, description: First-party Market service managed independently from Platform deployment., kind: service, primaryRepository: 'repository:treeseed/market-api', libraryRepository: 'repository:treeseed/market-api-library' } - repositories: - - &platform_repo { key: 'repository:treeseed/platform', project: 'project:treeseed/platform', role: primary, provider: github, owner: treeseed-ai, name: platform, gitUrl: 'git@github.com:treeseed-ai/platform.git', defaultBranch: main, checkoutPath: '.', repositoryPolicy: &public_repo { visibility: public, lifecycle: create-or-adopt, deletionPolicy: retain, defaultBranch: main, stagingBranch: staging, issues: true, actions: true, workflows: [verify.yml] } } - - { key: 'repository:treeseed/deployment', project: 'project:treeseed/deployment', role: primary, provider: github, owner: treeseed-ai, name: deployment, gitUrl: 'git@github.com:treeseed-ai/deployment.git', defaultBranch: main, checkoutPath: packages/deployment, repositoryPolicy: *public_repo, metadata: { deploymentAuthority: host-manager } } - - { key: 'repository:treeseed/api', project: 'project:treeseed/api', role: primary, provider: github, owner: treeseed-ai, name: api, gitUrl: 'git@github.com:treeseed-ai/api.git', defaultBranch: main, checkoutPath: packages/api, submodulePath: packages/api, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/treedx', project: 'project:treeseed/treedx', role: primary, provider: github, owner: treeseed-ai, name: treedx, gitUrl: 'git@github.com:treeseed-ai/treedx.git', defaultBranch: main, checkoutPath: packages/treedx, submodulePath: packages/treedx, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/sdk', project: 'project:treeseed/sdk', role: primary, provider: github, owner: treeseed-ai, name: sdk, gitUrl: 'git@github.com:treeseed-ai/sdk.git', defaultBranch: main, checkoutPath: packages/sdk, submodulePath: packages/sdk, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/ui', project: 'project:treeseed/ui', role: primary, provider: github, owner: treeseed-ai, name: ui, gitUrl: 'git@github.com:treeseed-ai/ui.git', defaultBranch: main, checkoutPath: packages/ui, submodulePath: packages/ui, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/cli', project: 'project:treeseed/cli', role: primary, provider: github, owner: treeseed-ai, name: cli, gitUrl: 'git@github.com:treeseed-ai/cli.git', defaultBranch: main, checkoutPath: packages/cli, submodulePath: packages/cli, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/core', project: 'project:treeseed/core', role: primary, provider: github, owner: treeseed-ai, name: core, gitUrl: 'git@github.com:treeseed-ai/core.git', defaultBranch: main, checkoutPath: packages/core, submodulePath: packages/core, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/admin', project: 'project:treeseed/admin', role: primary, provider: github, owner: treeseed-ai, name: admin, gitUrl: 'git@github.com:treeseed-ai/admin.git', defaultBranch: main, checkoutPath: packages/admin, submodulePath: packages/admin, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/agent', project: 'project:treeseed/agent', role: primary, provider: github, owner: treeseed-ai, name: agent, gitUrl: 'git@github.com:treeseed-ai/agent.git', defaultBranch: main, checkoutPath: packages/agent, submodulePath: packages/agent, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/reviewer', project: 'project:treeseed/reviewer', role: primary, provider: github, owner: treeseed-ai, name: reviewer, gitUrl: 'git@github.com:treeseed-ai/reviewer.git', defaultBranch: main, checkoutPath: packages/reviewer, submodulePath: packages/reviewer, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/ai', project: 'project:treeseed/ai', role: primary, provider: github, owner: treeseed-ai, name: ai, gitUrl: 'git@github.com:treeseed-ai/ai.git', defaultBranch: main, checkoutPath: packages/ai, submodulePath: packages/ai, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/template-engineering', project: 'project:treeseed/template-engineering', role: primary, provider: github, owner: treeseed-ai, name: template-engineering, gitUrl: 'git@github.com:treeseed-ai/template-engineering.git', defaultBranch: main, checkoutPath: templates/engineering, submodulePath: templates/engineering, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/template-research', project: 'project:treeseed/template-research', role: primary, provider: github, owner: treeseed-ai, name: template-research, gitUrl: 'git@github.com:treeseed-ai/template-research.git', defaultBranch: main, checkoutPath: templates/research, submodulePath: templates/research, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/market', project: 'project:treeseed/market', role: primary, provider: github, owner: treeseed-ai, name: market, gitUrl: 'git@github.com:treeseed-ai/market.git', defaultBranch: main, checkoutPath: products/market, repositoryPolicy: *public_repo, metadata: { platformCustody: portfolio-only, deployableByPlatform: false } } - - { key: 'repository:treeseed/market-api', project: 'project:treeseed/market-api', role: primary, provider: github, owner: treeseed-ai, name: market-api, gitUrl: 'git@github.com:treeseed-ai/market-api.git', defaultBranch: main, checkoutPath: services/market-api, repositoryPolicy: &private_repo { visibility: private, lifecycle: create-or-adopt, deletionPolicy: retain, defaultBranch: main, stagingBranch: staging, issues: true, actions: true, workflows: [verify.yml] }, metadata: { platformCustody: portfolio-only, deployableByPlatform: false } } - - { key: 'repository:treeseed/platform-library', project: 'project:treeseed/platform', role: library, provider: github, owner: treeseed-ai, name: platform-library, gitUrl: 'https://github.com/treeseed-ai/platform-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: &library_metadata { libraryRoot: '.', synchronizedRefs: [main, staging] } } - - { key: 'repository:treeseed/deployment-library', project: 'project:treeseed/deployment', role: library, provider: github, owner: treeseed-ai, name: deployment-library, gitUrl: 'https://github.com/treeseed-ai/deployment-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/api-library', project: 'project:treeseed/api', role: library, provider: github, owner: treeseed-ai, name: api-library, gitUrl: 'https://github.com/treeseed-ai/api-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/treedx-library', project: 'project:treeseed/treedx', role: library, provider: github, owner: treeseed-ai, name: treedx-library, gitUrl: 'https://github.com/treeseed-ai/treedx-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/sdk-library', project: 'project:treeseed/sdk', role: library, provider: github, owner: treeseed-ai, name: sdk-library, gitUrl: 'https://github.com/treeseed-ai/sdk-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/ui-library', project: 'project:treeseed/ui', role: library, provider: github, owner: treeseed-ai, name: ui-library, gitUrl: 'https://github.com/treeseed-ai/ui-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/cli-library', project: 'project:treeseed/cli', role: library, provider: github, owner: treeseed-ai, name: cli-library, gitUrl: 'https://github.com/treeseed-ai/cli-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/core-library', project: 'project:treeseed/core', role: library, provider: github, owner: treeseed-ai, name: core-library, gitUrl: 'https://github.com/treeseed-ai/core-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/admin-library', project: 'project:treeseed/admin', role: library, provider: github, owner: treeseed-ai, name: admin-library, gitUrl: 'https://github.com/treeseed-ai/admin-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/agent-library', project: 'project:treeseed/agent', role: library, provider: github, owner: treeseed-ai, name: agent-library, gitUrl: 'https://github.com/treeseed-ai/agent-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/reviewer-library', project: 'project:treeseed/reviewer', role: library, provider: github, owner: treeseed-ai, name: reviewer-library, gitUrl: 'https://github.com/treeseed-ai/reviewer-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/ai-library', project: 'project:treeseed/ai', role: library, provider: github, owner: treeseed-ai, name: ai-library, gitUrl: 'https://github.com/treeseed-ai/ai-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/template-engineering-library', project: 'project:treeseed/template-engineering', role: library, provider: github, owner: treeseed-ai, name: template-engineering-library, gitUrl: 'https://github.com/treeseed-ai/template-engineering-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/template-research-library', project: 'project:treeseed/template-research', role: library, provider: github, owner: treeseed-ai, name: template-research-library, gitUrl: 'https://github.com/treeseed-ai/template-research-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/market-library', project: 'project:treeseed/market', role: library, provider: github, owner: treeseed-ai, name: market-library, gitUrl: 'https://github.com/treeseed-ai/market-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/market-api-library', project: 'project:treeseed/market-api', role: library, provider: github, owner: treeseed-ai, name: market-api-library, gitUrl: 'https://github.com/treeseed-ai/market-api-library.git', defaultBranch: main, repositoryPolicy: *private_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/fixtures', project: 'project:treeseed/platform', role: fixture, provider: github, owner: treeseed-ai, name: fixtures, gitUrl: 'git@github.com:treeseed-ai/fixtures.git', defaultBranch: main, checkoutPath: fixtures, submodulePath: fixtures, repositoryPolicy: { visibility: public, lifecycle: create-or-adopt, deletionPolicy: retain, defaultBranch: main, stagingBranch: staging, issues: true, actions: false, workflows: [] } } -runtime: - capacityProviders: - - key: capacity-provider:treeseed/local - team: team:treeseed - environments: [local] - manifestDigest: sha256:9b3f675f40a7f23d66cc7429600d68438cb28ba866ebe4ce8688e240a4fa482c - manifestRef: treeseed.capacity-provider.yaml - approval: trusted-local-owner - projects: ['project:treeseed/platform', 'project:treeseed/deployment', 'project:treeseed/api', 'project:treeseed/treedx', 'project:treeseed/sdk', 'project:treeseed/ui', 'project:treeseed/cli', 'project:treeseed/core', 'project:treeseed/admin', 'project:treeseed/agent', 'project:treeseed/reviewer', 'project:treeseed/ai', 'project:treeseed/template-engineering', 'project:treeseed/template-research', 'project:treeseed/market', 'project:treeseed/market-api'] - allowedModes: [planning, acting] - requiredLanePurposes: [communication, platform, workday] diff --git a/templates/platform-local-managed-codex/template/treeseed.capacity-provider.yaml b/templates/platform-local-managed-codex/template/treeseed.capacity-provider.yaml deleted file mode 100644 index f240e115..00000000 --- a/templates/platform-local-managed-codex/template/treeseed.capacity-provider.yaml +++ /dev/null @@ -1,84 +0,0 @@ -schemaVersion: 3 -ownership: - type: team - teamId: team:treeseed -configuration: - generation: local-battery-v2 -identity: - privateKeyRef: data://identity-v3.json - displayName: TreeSeed local capacity battery -capacity: - maxConcurrentWorkers: 4 - cpuCores: 8 - memoryBytes: 17179869184 - maxActiveSeconds: 28800 - maxInputTokens: 4000000 - maxOutputTokens: 1000000 - maxCost: 100 - currency: USD - maxAttempts: 3 -credentialProfiles: - - { id: codex-auth, source: process-environment, reference: TREESEED_CODEX_AUTH_FILE, required: true } - - { id: codex-executable, source: process-environment, reference: TREESEED_CODEX_EXECUTABLE, required: true } - - { id: platform-github, source: process-environment, reference: TREESEED_GITHUB_TOKEN, required: false } - - { id: platform-cloudflare, source: process-environment, reference: TREESEED_CLOUDFLARE_API_TOKEN, required: false } -lanes: - - id: communication - purpose: communication - priority: 100 - reservedConcurrentWorkers: 1 - maxConcurrentWorkers: 2 - borrowWhenIdle: true - lendWhenIdle: true - reclaimPolicy: admission - queueLimit: 100 - timeoutSeconds: 120 - capabilities: [communication, agent-execution, research, planning] - - id: platform - purpose: platform - priority: 70 - reservedConcurrentWorkers: 0 - maxConcurrentWorkers: 2 - borrowWhenIdle: true - lendWhenIdle: true - reclaimPolicy: admission - queueLimit: 25 - timeoutSeconds: 900 - capabilities: [platform_operation, infrastructure_reconciliation, repository_reconciliation] - - id: workday - purpose: workday - priority: 50 - reservedConcurrentWorkers: 0 - maxConcurrentWorkers: 4 - borrowWhenIdle: true - lendWhenIdle: true - reclaimPolicy: admission - queueLimit: 100 - timeoutSeconds: 900 - minimumAssignmentDuration: { amount: 600, unit: seconds } - capabilities: [agent-execution, engineering, research, planning, acting, verification, repository_work] -adapters: - - id: codex-local - adapter: codex - isolation: process - module: module:codex-chat - profile: subscription - protocol: responses - credentialProfiles: [codex-auth, codex-executable] - laneIds: [communication] - maxConcurrentWorkers: 2 - minimumAssignmentDuration: { amount: 600, unit: seconds } - nativeLimits: { availableAgentSeconds: 28800 } - capabilities: [communication, agent-execution] - - id: platform-local - adapter: platform-operation - isolation: process - credentialProfiles: [platform-github, platform-cloudflare] - laneIds: [platform] - maxConcurrentWorkers: 2 - nativeLimits: { availableAgentSeconds: 14400 } - capabilities: [platform_operation, infrastructure_reconciliation, repository_reconciliation] -connections: [] -metadata: - custody: local-only - sharedBattery: true diff --git a/templates/platform-local-managed-codex/template/treeseed.site.yaml b/templates/platform-local-managed-codex/template/treeseed.site.yaml deleted file mode 100644 index 3751753f..00000000 --- a/templates/platform-local-managed-codex/template/treeseed.site.yaml +++ /dev/null @@ -1,22 +0,0 @@ -name: TreeSeed Platform -slug: treeseed-platform -siteUrl: https://treeseed.dev/platform -contactEmail: hello@treeseed.email -authority: { kind: customer-platform } -market: { profile: treeseed } -controlPlane: { mode: managed } -development: - local: - marketConnectivity: disabled - inventory: { source: seed, path: seeds/treeseed.yaml } -hub: { mode: customer_hosted } -runtime: { mode: none, registration: none } -processing: { mode: local, providerRef: codex-sub } -surfaces: { web: { enabled: false }, admin: { enabled: false }, api: { enabled: true } } -services: - api: { enabled: true, provider: local } - treeseedDatabase: { enabled: true, provider: local } - operationsRunner: { enabled: true, provider: local } - treedx: { enabled: true, provider: local } - agentProvider: { enabled: true, provider: local } -publicTreeDxFederation: {} diff --git a/templates/platform-market-codex/template.config.json b/templates/platform-market-codex/template.config.json deleted file mode 100644 index beb944b0..00000000 --- a/templates/platform-market-codex/template.config.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "schemaVersion": 2, - "id": "platform-market-codex", - "displayName": "Market-connected Platform with Codex", - "description": "A TreeSeed Platform using the immutable Market gateway and external Codex execution.", - "category": "platform", - "tags": ["platform", "market", "codex"], - "templateVersion": "3.0.0", - "templateApiVersion": 2, - "minCliVersion": "0.12.0", - "variables": [ - { "name": "Runtime portfolio username", "token": "__PORTFOLIO_USERNAME__", "deriveFrom": "runtime" }, - { "name": "Runtime portfolio email", "token": "__PORTFOLIO_EMAIL__", "deriveFrom": "runtime" }, - { "name": "Runtime portfolio password", "token": "__PORTFOLIO_PASSWORD__", "deriveFrom": "runtime" }, - { "name": "Runtime Mailpit URL", "token": "__PORTFOLIO_MAILPIT_URL__", "deriveFrom": "runtime" } - ], - "managedSurface": { - "coreManaged": ["treeseed.site.yaml", "seeds/treeseed.yaml", "treeseed.capacity-provider.yaml", "scenes/team-project-portfolio-demo.yaml"], - "validatedOnly": ["treeseed.site.yaml", "seeds/treeseed.yaml", "treeseed.capacity-provider.yaml", "scenes/team-project-portfolio-demo.yaml"] - }, - "platform": { - "controlPlane": { "mode": "market-passthrough" }, - "processing": { "mode": "market-assigned" }, - "admin": { "enabled": true }, - "executionProvider": "codex", - "aiAppliance": false, - "services": ["admin"], - "seeds": ["seeds/treeseed.yaml"], - "scenes": ["scenes/team-project-portfolio-demo.yaml"] - }, - "testing": { "smokeCommand": "npx trsd platform status --json", "buildCommand": "npm run verify" } -} diff --git a/templates/platform-market-codex/template/scenes/team-project-portfolio-demo.yaml b/templates/platform-market-codex/template/scenes/team-project-portfolio-demo.yaml deleted file mode 100644 index 47793867..00000000 --- a/templates/platform-market-codex/template/scenes/team-project-portfolio-demo.yaml +++ /dev/null @@ -1,731 +0,0 @@ -schemaVersion: treeseed.scene/v1 -id: team-project-portfolio-demo -title: Team Project Portfolio Demo -description: >- - Register a user, create the TreeSeed team, and prepare portfolio projects for research and engineering work. This scene is intentionally practical: it should expose real admin-flow, project-launch, Mailpit, recording, rendering, and training-output gaps while serving as a central TreeSeed acceptance test harness and demo / educational video generator scenario. -audience: - - evaluator - - operator - - trainee - -mode: - test: false - demo: true - training: true - -runtime: - mode: training - timeouts: - sceneSeconds: 1800 - chapterSeconds: 600 - stepSeconds: 120 - checkpoints: - enabled: true - defaultResumable: true - everyStep: true - progress: - heartbeatSeconds: 15 - failure: - continueOnFailure: true - -target: - app: market - environment: local - baseUrl: auto - browser: chromium - viewport: - width: 1600 - height: 900 - -devices: - defaultProfile: desktop - profiles: - - id: desktop - title: Desktop - orientation: landscape - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - output: - width: 1920 - height: 1080 - deviceScaleFactor: 1 - isMobile: false - hasTouch: false - browserFrame: - enabled: false - title: Team Project Portfolio Demo - chrome: desktop - - id: tablet - title: Tablet - orientation: landscape - viewport: - width: 1024 - height: 768 - video: - width: 1024 - height: 768 - output: - width: 1440 - height: 1080 - deviceScaleFactor: 1 - isMobile: true - hasTouch: true - browserFrame: - enabled: false - title: Team Project Portfolio Demo - chrome: tablet - - id: mobile - title: Mobile - orientation: portrait - viewport: - width: 390 - height: 844 - video: - width: 390 - height: 844 - output: - width: 1080 - height: 1920 - deviceScaleFactor: 2 - isMobile: true - hasTouch: true - browserFrame: - enabled: false - title: Team Project Portfolio Demo - chrome: mobile - -setup: - dev: - required: true - command: trsd dev start --web-runtime local --json - reuseExisting: true - -artifacts: - trace: true - video: true - screenshots: true - console: true - network: true - timeline: true - appLogs: true - -render: - remotion: - composition: treeseed-training-default - output: - format: mp4 - fps: 30 - resolution: - width: 1920 - height: 1080 - capture: - viewport: - width: 1600 - height: 900 - video: - width: 1600 - height: 900 - evidenceFit: fixed-browser - browserFrame: - enabled: false - title: Team Project Portfolio Demo - -chapters: - - id: registration - title: Register a portfolio owner - startsAt: open-register - - id: email-confirmation - title: Confirm the account through Mailpit - startsAt: open-mailpit - - id: team-setup - title: Create the TreeSeed team - startsAt: verify-admin-home - - id: portfolio-projects - title: Prepare portfolio projects - startsAt: open-new-project-bylaws - - id: gap-review - title: Capture linked project gaps - startsAt: open-new-project-sdk - -overlays: - - id: scenario-purpose - at: open-register - renderer: remotion - type: callout - variant: panel - region: top-right - style: - tone: brand - shadow: medium - radius: 8 - motion: - keyframes: - - at: 0 - unit: progress - opacity: 0 - position: - x: 100 - y: 10 - unit: percent - - at: 0.18 - unit: progress - opacity: 1 - position: - x: 82 - y: 10 - unit: percent - - at: 1 - unit: progress - opacity: 1 - position: - x: 82 - y: 10 - unit: percent - objects: - - id: acceptance-pulse - type: circle - position: - x: 8 - y: 22 - size: - width: 14 - height: 14 - style: - tone: success - opacity: 0.82 - motion: - keyframes: - - at: 0 - unit: progress - scale: 0.8 - opacity: 0.45 - - at: 0.5 - unit: progress - scale: 1.28 - opacity: 1 - - at: 1 - unit: progress - scale: 0.8 - opacity: 0.45 - text: This demo doubles as a product acceptance probe and an educational video source. - - id: mailpit-selector-risk - at: open-mailpit - renderer: remotion - type: callout - text: Mailpit confirmation is attempted through the browser so local email and auth gaps are visible in the run artifacts. - - id: team-portfolio-context - at: open-new-team - renderer: remotion - type: callout - text: The TreeSeed team will own a portfolio of research and engineering projects. - - id: bylaws-project-context - at: open-new-project-bylaws - renderer: remotion - type: callout - text: Bylaws is expected to be a new research-template project with no upstream remote. - - id: sdk-linked-project-gap - at: capture-sdk-linking-gap - renderer: remotion - type: callout - text: >- - Expected: link github.com/treeseed-ai/sdk and request a docs repository. Current gap: this linked-project operation is not exposed by the scene runtime or obvious project UI. - - id: final-gap-summary - at: review-gap-summary - renderer: remotion - type: callout - text: Review the screenshots, timeline, captions, transcript, and evidence bundle to prioritize product and selector hardening. - -diagrams: - - id: local-runtime-topology - renderer: remotion - component: DevRuntimeTopologyDiagram - at: open-mailpit - placement: overlay - durationSeconds: 12 - style: - tone: info - shadow: medium - motion: - keyframes: - - at: 0 - unit: progress - opacity: 0 - scale: 0.96 - - at: 0.2 - unit: progress - opacity: 1 - scale: 1 - - at: 1 - unit: progress - opacity: 1 - scale: 1 - objects: - - id: mail-flow-cursor - type: arrow - from: - x: 18 - y: 80 - unit: percent - to: - x: 84 - y: 80 - unit: percent - style: - tone: brand - opacity: 0.78 - motion: - keyframes: - - at: 0 - unit: progress - opacity: 0.2 - - at: 0.6 - unit: progress - opacity: 1 - - at: 1 - unit: progress - opacity: 0.7 - props: - title: Local demo runtime - surfaces: - - id: browser - label: Browser scene - kind: playwright - - id: web - label: Local web app - kind: astro - - id: api - label: Local API - kind: treeseed-api - - id: mailpit - label: Mailpit - kind: email - links: - - from: browser - to: web - label: drives UI - - from: web - to: api - label: auth and project calls - - from: api - to: mailpit - label: confirmation email - - id: project-launch-lifecycle - renderer: remotion - component: OperationLifecycleDiagram - at: submit-bylaws-project - placement: overlay - durationSeconds: 12 - props: - title: Project launch lifecycle - states: - - form-ready - - submitted - - queued - - deploying - - review - activeState: review - - id: scene-timeline-review - renderer: remotion - component: SceneExecutionTimelineDiagram - at: review-gap-summary - placement: overlay - durationSeconds: 10 - props: - title: Portfolio demo execution timeline - showCheckpoints: true - showSegments: true - -training: - enabled: true - captions: - enabled: true - formats: - - vtt - - srt - maxCueSeconds: 6 - renderInTrainingVideo: true - transcript: - enabled: true - formats: - - json - - markdown - narration: - enabled: true - style: instructional - includeDiagnostics: true - glossary: - enabled: true - terms: - - term: team - definition: A TreeSeed ownership boundary for projects, hosts, work, and knowledge. - sourceStep: open-new-team - groupIds: - - portfolio - - term: project - definition: A managed TreeSeed work surface that can own content, repositories, hosting, and launch evidence. - sourceStep: open-new-project-bylaws - groupIds: - - portfolio - - term: research template - definition: The starter used for research and knowledge-oriented projects such as Bylaws. - sourceStep: choose-research-template - groupIds: - - template - - term: linked repository - definition: An existing upstream repository that should be connected to a TreeSeed project instead of creating a new source repository. - sourceStep: capture-sdk-linking-gap - groupIds: - - gap - - term: docs repository - definition: A documentation repository expected for the linked SDK software project. - sourceStep: capture-sdk-linking-gap - groupIds: - - gap - - term: Mailpit - definition: The local email inbox used to confirm registration during the demo. - sourceStep: open-mailpit - groupIds: - - local-dev - - term: checkpoint - definition: A resumable scene runtime marker that helps diagnose and continue long workflows. - sourceStep: review-gap-summary - groupIds: - - scene-runtime - chapterClips: - enabled: true - format: manifest - -workflow: - - id: open-register - title: Open registration for a normal user - action: - goto: /auth/register?returnTo=/app - expect: - visible: - - role: heading - name: Create account - - - id: fill-first-name - title: Enter the user's first name - action: - fill: - css: input[name="firstName"] - internal: true - value: Test - expect: - visible: - - css: input[name="firstName"] - internal: true - - - id: fill-last-name - title: Enter the user's last name - action: - fill: - css: input[name="lastName"] - internal: true - value: Portfolio - expect: - visible: - - css: input[name="lastName"] - internal: true - - - id: fill-username - title: Choose a unique username - action: - fill: - css: input[name="username"] - internal: true - value: __PORTFOLIO_USERNAME__ - expect: - visible: - - css: input[name="username"] - internal: true - - - id: fill-email - title: Enter the generated local email address - action: - fill: - css: input[name="email"] - internal: true - value: __PORTFOLIO_EMAIL__ - expect: - visible: - - css: input[name="email"] - internal: true - - - id: fill-password - title: Enter a strong generated password - action: - fill: - css: input[name="password"] - internal: true - value: __PORTFOLIO_PASSWORD__ - expect: - visible: - - css: input[name="password"] - internal: true - - - id: fill-confirm-password - title: Confirm the generated password - action: - fill: - css: input[name="confirmPassword"] - internal: true - value: __PORTFOLIO_PASSWORD__ - expect: - visible: - - css: input[name="confirmPassword"] - internal: true - - - id: submit-registration - title: Submit the registration form - action: - click: - role: button - name: Create account - expect: - text: Check your email - checkpoint: - resumable: true - - - id: open-mailpit - title: Open the local Mailpit inbox - action: - goto: __PORTFOLIO_MAILPIT_URL__ - demoOnly: true - checkpoint: - resumable: true - - - id: open-confirmation-email - title: Open the newest confirmation email - action: - click: - css: a[href^="/view/"]:has-text("__PORTFOLIO_EMAIL__") - brittle: true - demoOnly: true - continueOnFailure: true - checkpoint: - resumable: true - - - id: open-confirmation-link - title: Open the email confirmation link - action: - mailpitConfirmLatest: - mailpitUrl: __PORTFOLIO_MAILPIT_URL__ - email: __PORTFOLIO_EMAIL__ - subjectIncludes: Confirm - expect: - urlIncludes: /app - demoOnly: true - continueOnFailure: true - checkpoint: - resumable: true - - - id: verify-admin-home - title: Confirm the user can see the admin homepage - action: - goto: /app - expect: - visible: - - role: heading - name: Start - continueOnFailure: true - checkpoint: - resumable: true - - - id: open-new-team - title: Open the new team screen - action: - goto: /app/teams/new - expect: - visible: - - role: heading - name: Create team - continueOnFailure: true - - - id: fill-team-slug - title: Enter the TreeSeed team slug - action: - fill: - css: input[name="name"] - internal: true - value: treeseed - expect: - visible: - - css: input[name="name"] - internal: true - continueOnFailure: true - - - id: fill-team-display-name - title: Enter the TreeSeed team display name - action: - fill: - css: input[name="displayName"] - internal: true - value: TreeSeed - expect: - visible: - - css: input[name="displayName"] - internal: true - continueOnFailure: true - - - id: fill-team-summary - title: Describe the team project portfolio - action: - fill: - css: textarea[name="profileSummary"] - internal: true - value: TreeSeed owns a portfolio of research and engineering projects, including governance research and software platform work. - expect: - visible: - - css: textarea[name="profileSummary"] - internal: true - continueOnFailure: true - - - id: submit-team - title: Create the TreeSeed team - action: - click: - role: button - name: Create team - expect: - urlIncludes: /app/teams - continueOnFailure: true - checkpoint: - resumable: true - - - id: open-new-project-bylaws - title: Open the new project screen for Bylaws - action: - goto: /app/projects/new - expect: - text: Create hosted project - continueOnFailure: true - - - id: fill-bylaws-name - title: Enter the Bylaws project name - action: - fill: - css: input[name="name"] - internal: true - value: Bylaws - expect: - visible: - - css: input[name="name"] - internal: true - continueOnFailure: true - - - id: fill-bylaws-slug - title: Enter the Bylaws project slug - action: - fill: - css: input[name="slug"] - internal: true - value: bylaws - expect: - visible: - - css: input[name="slug"] - internal: true - continueOnFailure: true - - - id: choose-research-template - title: Choose the research template - action: - click: - css: label[for="template-research"] - internal: true - expect: - visible: - - css: label[for="template-research"] - internal: true - continueOnFailure: true - - - id: fill-bylaws-objective - title: Describe the Bylaws research objective - action: - fill: - css: textarea[name="coreObjective"] - internal: true - value: Build a research project for organizing TreeSeed bylaws, governance notes, decision records, and portfolio policy. - expect: - visible: - - css: textarea[name="coreObjective"] - internal: true - continueOnFailure: true - - - id: submit-bylaws-project - title: Submit the Bylaws project launch - action: - click: - role: button - name: Create project - expect: - visible: - - css: "body" - internal: true - continueOnFailure: true - checkpoint: - resumable: true - - - id: open-new-project-sdk - title: Open the new project screen for SDK - action: - goto: /app/projects/new - expect: - text: Create hosted project - continueOnFailure: true - - - id: fill-sdk-name - title: Enter the SDK project name - action: - fill: - css: input[name="name"] - internal: true - value: SDK - expect: - visible: - - css: input[name="name"] - internal: true - continueOnFailure: true - - - id: fill-sdk-slug - title: Enter the SDK project slug - action: - fill: - css: input[name="slug"] - internal: true - value: sdk - expect: - visible: - - css: input[name="slug"] - internal: true - continueOnFailure: true - - - id: capture-sdk-linking-gap - title: Capture the linked SDK project gap - action: - pause: - mode: timed - durationSeconds: 6 - prompt: >- - Expected linked software project: public GitHub repository github.com/treeseed-ai/sdk with a docs repository request. Current gap: this operation is not exposed by the scene runtime or obvious project UI. - demoOnly: true - continueOnFailure: true - checkpoint: - resumable: true - - - id: review-gap-summary - title: Review portfolio demo evidence and gaps - action: - goto: /app/projects - expect: - visible: - - css: "body" - internal: true - continueOnFailure: true - checkpoint: - resumable: true diff --git a/templates/platform-market-codex/template/seeds/treeseed.yaml b/templates/platform-market-codex/template/seeds/treeseed.yaml deleted file mode 100644 index fac2b439..00000000 --- a/templates/platform-market-codex/template/seeds/treeseed.yaml +++ /dev/null @@ -1,77 +0,0 @@ -schemaVersion: treeseed.seed-bundle/v3 -name: treeseed -version: 4 -description: Reproducible local TreeSeed portfolio with one unified capacity-provider battery. -environments: [local, staging, prod] -digest: sha256:e983c02364fb1e292018acf264c447da697d3fc106608ba76ce8d9656671c116 -resources: - teams: - - { key: 'team:treeseed', slug: treeseed, name: treeseed, displayName: TreeSeed, profileSummary: 'TreeSeed platform, packages, products, and agent operations.' } - memberships: - - { key: 'membership:treeseed/adrian-webb', team: 'team:treeseed', principal: { kind: user, email: 'adrian.webb@knowledge.coop' }, roles: [team_owner], missingUser: reject } - - key: membership:treeseed/automation - team: team:treeseed - principal: { kind: service-principal, key: 'service-principal:treeseed/automation', displayName: TreeSeed Automation, interactiveLogin: false } - roles: [team_owner] - projects: - - { key: 'project:treeseed/platform', team: 'team:treeseed', slug: platform, name: TreeSeed Platform, description: Public installer and portfolio integration workspace., kind: platform, primaryRepository: 'repository:treeseed/platform', libraryRepository: 'repository:treeseed/platform-library' } - - { key: 'project:treeseed/deployment', team: 'team:treeseed', slug: deployment, name: TreeSeed Deployment, description: Shared Debian bootstrap, host manager, edge, and component integration system., kind: platform, primaryRepository: 'repository:treeseed/deployment', libraryRepository: 'repository:treeseed/deployment-library' } - - { key: 'project:treeseed/api', team: 'team:treeseed', slug: api, name: TreeSeed API, description: Authoritative TreeSeed control plane., kind: package, primaryRepository: 'repository:treeseed/api', libraryRepository: 'repository:treeseed/api-library', metadata: { packageId: '@treeseed/api' } } - - { key: 'project:treeseed/treedx', team: 'team:treeseed', slug: treedx, name: TreeDX, description: Independent content and knowledge service., kind: service, primaryRepository: 'repository:treeseed/treedx', libraryRepository: 'repository:treeseed/treedx-library' } - - { key: 'project:treeseed/sdk', team: 'team:treeseed', slug: sdk, name: TreeSeed SDK, description: Portable contracts and remote clients., kind: package, primaryRepository: 'repository:treeseed/sdk', libraryRepository: 'repository:treeseed/sdk-library', metadata: { packageId: '@treeseed/sdk' } } - - { key: 'project:treeseed/ui', team: 'team:treeseed', slug: ui, name: TreeSeed UI, description: TreeSeed user-interface package., kind: package, primaryRepository: 'repository:treeseed/ui', libraryRepository: 'repository:treeseed/ui-library', metadata: { packageId: '@treeseed/ui' } } - - { key: 'project:treeseed/cli', team: 'team:treeseed', slug: cli, name: TreeSeed CLI, description: Human-centered TreeSeed command-line interface., kind: package, primaryRepository: 'repository:treeseed/cli', libraryRepository: 'repository:treeseed/cli-library', metadata: { packageId: '@treeseed/cli' } } - - { key: 'project:treeseed/core', team: 'team:treeseed', slug: core, name: TreeSeed Core, description: Core TreeSeed package., kind: package, primaryRepository: 'repository:treeseed/core', libraryRepository: 'repository:treeseed/core-library', metadata: { packageId: '@treeseed/core' } } - - { key: 'project:treeseed/admin', team: 'team:treeseed', slug: admin, name: TreeSeed Admin, description: TreeSeed administration interface., kind: package, primaryRepository: 'repository:treeseed/admin', libraryRepository: 'repository:treeseed/admin-library', metadata: { packageId: '@treeseed/admin' } } - - { key: 'project:treeseed/agent', team: 'team:treeseed', slug: agent, name: TreeSeed Agent, description: Unified capacity-provider and agent execution runtime., kind: package, primaryRepository: 'repository:treeseed/agent', libraryRepository: 'repository:treeseed/agent-library', metadata: { packageId: '@treeseed/agent' } } - - { key: 'project:treeseed/reviewer', team: 'team:treeseed', slug: reviewer, name: TreeSeed Reviewer, description: Independent review package., kind: package, primaryRepository: 'repository:treeseed/reviewer', libraryRepository: 'repository:treeseed/reviewer-library', metadata: { packageId: '@treeseed/reviewer' } } - - { key: 'project:treeseed/ai', team: 'team:treeseed', slug: ai, name: TreeSeed AI, description: AI integration package., kind: package, primaryRepository: 'repository:treeseed/ai', libraryRepository: 'repository:treeseed/ai-library', metadata: { packageId: '@treeseed/ai' } } - - { key: 'project:treeseed/template-engineering', team: 'team:treeseed', slug: template-engineering, name: Engineering Template, description: Engineering project template., kind: template, primaryRepository: 'repository:treeseed/template-engineering', libraryRepository: 'repository:treeseed/template-engineering-library' } - - { key: 'project:treeseed/template-research', team: 'team:treeseed', slug: template-research, name: Research Template, description: Research project template., kind: template, primaryRepository: 'repository:treeseed/template-research', libraryRepository: 'repository:treeseed/template-research-library' } - - { key: 'project:treeseed/market', team: 'team:treeseed', slug: market, name: TreeSeed Market, description: First-party portfolio product managed independently from Platform deployment., kind: product, primaryRepository: 'repository:treeseed/market', libraryRepository: 'repository:treeseed/market-library' } - - { key: 'project:treeseed/market-api', team: 'team:treeseed', slug: market-api, name: TreeSeed Market API, description: First-party Market service managed independently from Platform deployment., kind: service, primaryRepository: 'repository:treeseed/market-api', libraryRepository: 'repository:treeseed/market-api-library' } - repositories: - - &platform_repo { key: 'repository:treeseed/platform', project: 'project:treeseed/platform', role: primary, provider: github, owner: treeseed-ai, name: platform, gitUrl: 'git@github.com:treeseed-ai/platform.git', defaultBranch: main, checkoutPath: '.', repositoryPolicy: &public_repo { visibility: public, lifecycle: create-or-adopt, deletionPolicy: retain, defaultBranch: main, stagingBranch: staging, issues: true, actions: true, workflows: [verify.yml] } } - - { key: 'repository:treeseed/deployment', project: 'project:treeseed/deployment', role: primary, provider: github, owner: treeseed-ai, name: deployment, gitUrl: 'git@github.com:treeseed-ai/deployment.git', defaultBranch: main, checkoutPath: packages/deployment, repositoryPolicy: *public_repo, metadata: { deploymentAuthority: host-manager } } - - { key: 'repository:treeseed/api', project: 'project:treeseed/api', role: primary, provider: github, owner: treeseed-ai, name: api, gitUrl: 'git@github.com:treeseed-ai/api.git', defaultBranch: main, checkoutPath: packages/api, submodulePath: packages/api, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/treedx', project: 'project:treeseed/treedx', role: primary, provider: github, owner: treeseed-ai, name: treedx, gitUrl: 'git@github.com:treeseed-ai/treedx.git', defaultBranch: main, checkoutPath: packages/treedx, submodulePath: packages/treedx, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/sdk', project: 'project:treeseed/sdk', role: primary, provider: github, owner: treeseed-ai, name: sdk, gitUrl: 'git@github.com:treeseed-ai/sdk.git', defaultBranch: main, checkoutPath: packages/sdk, submodulePath: packages/sdk, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/ui', project: 'project:treeseed/ui', role: primary, provider: github, owner: treeseed-ai, name: ui, gitUrl: 'git@github.com:treeseed-ai/ui.git', defaultBranch: main, checkoutPath: packages/ui, submodulePath: packages/ui, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/cli', project: 'project:treeseed/cli', role: primary, provider: github, owner: treeseed-ai, name: cli, gitUrl: 'git@github.com:treeseed-ai/cli.git', defaultBranch: main, checkoutPath: packages/cli, submodulePath: packages/cli, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/core', project: 'project:treeseed/core', role: primary, provider: github, owner: treeseed-ai, name: core, gitUrl: 'git@github.com:treeseed-ai/core.git', defaultBranch: main, checkoutPath: packages/core, submodulePath: packages/core, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/admin', project: 'project:treeseed/admin', role: primary, provider: github, owner: treeseed-ai, name: admin, gitUrl: 'git@github.com:treeseed-ai/admin.git', defaultBranch: main, checkoutPath: packages/admin, submodulePath: packages/admin, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/agent', project: 'project:treeseed/agent', role: primary, provider: github, owner: treeseed-ai, name: agent, gitUrl: 'git@github.com:treeseed-ai/agent.git', defaultBranch: main, checkoutPath: packages/agent, submodulePath: packages/agent, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/reviewer', project: 'project:treeseed/reviewer', role: primary, provider: github, owner: treeseed-ai, name: reviewer, gitUrl: 'git@github.com:treeseed-ai/reviewer.git', defaultBranch: main, checkoutPath: packages/reviewer, submodulePath: packages/reviewer, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/ai', project: 'project:treeseed/ai', role: primary, provider: github, owner: treeseed-ai, name: ai, gitUrl: 'git@github.com:treeseed-ai/ai.git', defaultBranch: main, checkoutPath: packages/ai, submodulePath: packages/ai, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/template-engineering', project: 'project:treeseed/template-engineering', role: primary, provider: github, owner: treeseed-ai, name: template-engineering, gitUrl: 'git@github.com:treeseed-ai/template-engineering.git', defaultBranch: main, checkoutPath: templates/engineering, submodulePath: templates/engineering, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/template-research', project: 'project:treeseed/template-research', role: primary, provider: github, owner: treeseed-ai, name: template-research, gitUrl: 'git@github.com:treeseed-ai/template-research.git', defaultBranch: main, checkoutPath: templates/research, submodulePath: templates/research, repositoryPolicy: *public_repo } - - { key: 'repository:treeseed/market', project: 'project:treeseed/market', role: primary, provider: github, owner: treeseed-ai, name: market, gitUrl: 'git@github.com:treeseed-ai/market.git', defaultBranch: main, checkoutPath: products/market, repositoryPolicy: *public_repo, metadata: { platformCustody: portfolio-only, deployableByPlatform: false } } - - { key: 'repository:treeseed/market-api', project: 'project:treeseed/market-api', role: primary, provider: github, owner: treeseed-ai, name: market-api, gitUrl: 'git@github.com:treeseed-ai/market-api.git', defaultBranch: main, checkoutPath: services/market-api, repositoryPolicy: &private_repo { visibility: private, lifecycle: create-or-adopt, deletionPolicy: retain, defaultBranch: main, stagingBranch: staging, issues: true, actions: true, workflows: [verify.yml] }, metadata: { platformCustody: portfolio-only, deployableByPlatform: false } } - - { key: 'repository:treeseed/platform-library', project: 'project:treeseed/platform', role: library, provider: github, owner: treeseed-ai, name: platform-library, gitUrl: 'https://github.com/treeseed-ai/platform-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: &library_metadata { libraryRoot: '.', synchronizedRefs: [main, staging] } } - - { key: 'repository:treeseed/deployment-library', project: 'project:treeseed/deployment', role: library, provider: github, owner: treeseed-ai, name: deployment-library, gitUrl: 'https://github.com/treeseed-ai/deployment-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/api-library', project: 'project:treeseed/api', role: library, provider: github, owner: treeseed-ai, name: api-library, gitUrl: 'https://github.com/treeseed-ai/api-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/treedx-library', project: 'project:treeseed/treedx', role: library, provider: github, owner: treeseed-ai, name: treedx-library, gitUrl: 'https://github.com/treeseed-ai/treedx-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/sdk-library', project: 'project:treeseed/sdk', role: library, provider: github, owner: treeseed-ai, name: sdk-library, gitUrl: 'https://github.com/treeseed-ai/sdk-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/ui-library', project: 'project:treeseed/ui', role: library, provider: github, owner: treeseed-ai, name: ui-library, gitUrl: 'https://github.com/treeseed-ai/ui-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/cli-library', project: 'project:treeseed/cli', role: library, provider: github, owner: treeseed-ai, name: cli-library, gitUrl: 'https://github.com/treeseed-ai/cli-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/core-library', project: 'project:treeseed/core', role: library, provider: github, owner: treeseed-ai, name: core-library, gitUrl: 'https://github.com/treeseed-ai/core-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/admin-library', project: 'project:treeseed/admin', role: library, provider: github, owner: treeseed-ai, name: admin-library, gitUrl: 'https://github.com/treeseed-ai/admin-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/agent-library', project: 'project:treeseed/agent', role: library, provider: github, owner: treeseed-ai, name: agent-library, gitUrl: 'https://github.com/treeseed-ai/agent-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/reviewer-library', project: 'project:treeseed/reviewer', role: library, provider: github, owner: treeseed-ai, name: reviewer-library, gitUrl: 'https://github.com/treeseed-ai/reviewer-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/ai-library', project: 'project:treeseed/ai', role: library, provider: github, owner: treeseed-ai, name: ai-library, gitUrl: 'https://github.com/treeseed-ai/ai-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/template-engineering-library', project: 'project:treeseed/template-engineering', role: library, provider: github, owner: treeseed-ai, name: template-engineering-library, gitUrl: 'https://github.com/treeseed-ai/template-engineering-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/template-research-library', project: 'project:treeseed/template-research', role: library, provider: github, owner: treeseed-ai, name: template-research-library, gitUrl: 'https://github.com/treeseed-ai/template-research-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/market-library', project: 'project:treeseed/market', role: library, provider: github, owner: treeseed-ai, name: market-library, gitUrl: 'https://github.com/treeseed-ai/market-library.git', defaultBranch: main, repositoryPolicy: *public_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/market-api-library', project: 'project:treeseed/market-api', role: library, provider: github, owner: treeseed-ai, name: market-api-library, gitUrl: 'https://github.com/treeseed-ai/market-api-library.git', defaultBranch: main, repositoryPolicy: *private_repo, metadata: *library_metadata } - - { key: 'repository:treeseed/fixtures', project: 'project:treeseed/platform', role: fixture, provider: github, owner: treeseed-ai, name: fixtures, gitUrl: 'git@github.com:treeseed-ai/fixtures.git', defaultBranch: main, checkoutPath: fixtures, submodulePath: fixtures, repositoryPolicy: { visibility: public, lifecycle: create-or-adopt, deletionPolicy: retain, defaultBranch: main, stagingBranch: staging, issues: true, actions: false, workflows: [] } } -runtime: - capacityProviders: - - key: capacity-provider:treeseed/local - team: team:treeseed - environments: [local] - manifestDigest: sha256:9b3f675f40a7f23d66cc7429600d68438cb28ba866ebe4ce8688e240a4fa482c - manifestRef: treeseed.capacity-provider.yaml - approval: trusted-local-owner - projects: ['project:treeseed/platform', 'project:treeseed/deployment', 'project:treeseed/api', 'project:treeseed/treedx', 'project:treeseed/sdk', 'project:treeseed/ui', 'project:treeseed/cli', 'project:treeseed/core', 'project:treeseed/admin', 'project:treeseed/agent', 'project:treeseed/reviewer', 'project:treeseed/ai', 'project:treeseed/template-engineering', 'project:treeseed/template-research', 'project:treeseed/market', 'project:treeseed/market-api'] - allowedModes: [planning, acting] - requiredLanePurposes: [communication, platform, workday] diff --git a/templates/platform-market-codex/template/treeseed.capacity-provider.yaml b/templates/platform-market-codex/template/treeseed.capacity-provider.yaml deleted file mode 100644 index f240e115..00000000 --- a/templates/platform-market-codex/template/treeseed.capacity-provider.yaml +++ /dev/null @@ -1,84 +0,0 @@ -schemaVersion: 3 -ownership: - type: team - teamId: team:treeseed -configuration: - generation: local-battery-v2 -identity: - privateKeyRef: data://identity-v3.json - displayName: TreeSeed local capacity battery -capacity: - maxConcurrentWorkers: 4 - cpuCores: 8 - memoryBytes: 17179869184 - maxActiveSeconds: 28800 - maxInputTokens: 4000000 - maxOutputTokens: 1000000 - maxCost: 100 - currency: USD - maxAttempts: 3 -credentialProfiles: - - { id: codex-auth, source: process-environment, reference: TREESEED_CODEX_AUTH_FILE, required: true } - - { id: codex-executable, source: process-environment, reference: TREESEED_CODEX_EXECUTABLE, required: true } - - { id: platform-github, source: process-environment, reference: TREESEED_GITHUB_TOKEN, required: false } - - { id: platform-cloudflare, source: process-environment, reference: TREESEED_CLOUDFLARE_API_TOKEN, required: false } -lanes: - - id: communication - purpose: communication - priority: 100 - reservedConcurrentWorkers: 1 - maxConcurrentWorkers: 2 - borrowWhenIdle: true - lendWhenIdle: true - reclaimPolicy: admission - queueLimit: 100 - timeoutSeconds: 120 - capabilities: [communication, agent-execution, research, planning] - - id: platform - purpose: platform - priority: 70 - reservedConcurrentWorkers: 0 - maxConcurrentWorkers: 2 - borrowWhenIdle: true - lendWhenIdle: true - reclaimPolicy: admission - queueLimit: 25 - timeoutSeconds: 900 - capabilities: [platform_operation, infrastructure_reconciliation, repository_reconciliation] - - id: workday - purpose: workday - priority: 50 - reservedConcurrentWorkers: 0 - maxConcurrentWorkers: 4 - borrowWhenIdle: true - lendWhenIdle: true - reclaimPolicy: admission - queueLimit: 100 - timeoutSeconds: 900 - minimumAssignmentDuration: { amount: 600, unit: seconds } - capabilities: [agent-execution, engineering, research, planning, acting, verification, repository_work] -adapters: - - id: codex-local - adapter: codex - isolation: process - module: module:codex-chat - profile: subscription - protocol: responses - credentialProfiles: [codex-auth, codex-executable] - laneIds: [communication] - maxConcurrentWorkers: 2 - minimumAssignmentDuration: { amount: 600, unit: seconds } - nativeLimits: { availableAgentSeconds: 28800 } - capabilities: [communication, agent-execution] - - id: platform-local - adapter: platform-operation - isolation: process - credentialProfiles: [platform-github, platform-cloudflare] - laneIds: [platform] - maxConcurrentWorkers: 2 - nativeLimits: { availableAgentSeconds: 14400 } - capabilities: [platform_operation, infrastructure_reconciliation, repository_reconciliation] -connections: [] -metadata: - custody: local-only - sharedBattery: true diff --git a/templates/platform-market-codex/template/treeseed.site.yaml b/templates/platform-market-codex/template/treeseed.site.yaml deleted file mode 100644 index 9f347117..00000000 --- a/templates/platform-market-codex/template/treeseed.site.yaml +++ /dev/null @@ -1,12 +0,0 @@ -name: TreeSeed Platform -slug: treeseed-platform -siteUrl: https://treeseed.dev/platform -contactEmail: hello@treeseed.email -authority: { kind: customer-platform } -market: { profile: treeseed } -controlPlane: { mode: market-passthrough } -hub: { mode: treeseed_hosted } -runtime: { mode: none, registration: none } -processing: { mode: market-assigned, providerRef: codex-sub } -surfaces: { web: { enabled: true }, admin: { enabled: true }, api: { enabled: false } } -services: {} diff --git a/treeseed.capacity-provider.yaml b/treeseed.capacity-provider.yaml deleted file mode 100644 index f240e115..00000000 --- a/treeseed.capacity-provider.yaml +++ /dev/null @@ -1,84 +0,0 @@ -schemaVersion: 3 -ownership: - type: team - teamId: team:treeseed -configuration: - generation: local-battery-v2 -identity: - privateKeyRef: data://identity-v3.json - displayName: TreeSeed local capacity battery -capacity: - maxConcurrentWorkers: 4 - cpuCores: 8 - memoryBytes: 17179869184 - maxActiveSeconds: 28800 - maxInputTokens: 4000000 - maxOutputTokens: 1000000 - maxCost: 100 - currency: USD - maxAttempts: 3 -credentialProfiles: - - { id: codex-auth, source: process-environment, reference: TREESEED_CODEX_AUTH_FILE, required: true } - - { id: codex-executable, source: process-environment, reference: TREESEED_CODEX_EXECUTABLE, required: true } - - { id: platform-github, source: process-environment, reference: TREESEED_GITHUB_TOKEN, required: false } - - { id: platform-cloudflare, source: process-environment, reference: TREESEED_CLOUDFLARE_API_TOKEN, required: false } -lanes: - - id: communication - purpose: communication - priority: 100 - reservedConcurrentWorkers: 1 - maxConcurrentWorkers: 2 - borrowWhenIdle: true - lendWhenIdle: true - reclaimPolicy: admission - queueLimit: 100 - timeoutSeconds: 120 - capabilities: [communication, agent-execution, research, planning] - - id: platform - purpose: platform - priority: 70 - reservedConcurrentWorkers: 0 - maxConcurrentWorkers: 2 - borrowWhenIdle: true - lendWhenIdle: true - reclaimPolicy: admission - queueLimit: 25 - timeoutSeconds: 900 - capabilities: [platform_operation, infrastructure_reconciliation, repository_reconciliation] - - id: workday - purpose: workday - priority: 50 - reservedConcurrentWorkers: 0 - maxConcurrentWorkers: 4 - borrowWhenIdle: true - lendWhenIdle: true - reclaimPolicy: admission - queueLimit: 100 - timeoutSeconds: 900 - minimumAssignmentDuration: { amount: 600, unit: seconds } - capabilities: [agent-execution, engineering, research, planning, acting, verification, repository_work] -adapters: - - id: codex-local - adapter: codex - isolation: process - module: module:codex-chat - profile: subscription - protocol: responses - credentialProfiles: [codex-auth, codex-executable] - laneIds: [communication] - maxConcurrentWorkers: 2 - minimumAssignmentDuration: { amount: 600, unit: seconds } - nativeLimits: { availableAgentSeconds: 28800 } - capabilities: [communication, agent-execution] - - id: platform-local - adapter: platform-operation - isolation: process - credentialProfiles: [platform-github, platform-cloudflare] - laneIds: [platform] - maxConcurrentWorkers: 2 - nativeLimits: { availableAgentSeconds: 14400 } - capabilities: [platform_operation, infrastructure_reconciliation, repository_reconciliation] -connections: [] -metadata: - custody: local-only - sharedBattery: true diff --git a/treeseed.site.yaml b/treeseed.site.yaml index 3751753f..24cbb523 100644 --- a/treeseed.site.yaml +++ b/treeseed.site.yaml @@ -1,22 +1,14 @@ +schemaVersion: treeseed.platform/v1 name: TreeSeed Platform slug: treeseed-platform -siteUrl: https://treeseed.dev/platform -contactEmail: hello@treeseed.email -authority: { kind: customer-platform } -market: { profile: treeseed } -controlPlane: { mode: managed } +authority: { kind: integration-workspace } development: local: - marketConnectivity: disabled inventory: { source: seed, path: seeds/treeseed.yaml } -hub: { mode: customer_hosted } -runtime: { mode: none, registration: none } -processing: { mode: local, providerRef: codex-sub } -surfaces: { web: { enabled: false }, admin: { enabled: false }, api: { enabled: true } } -services: - api: { enabled: true, provider: local } - treeseedDatabase: { enabled: true, provider: local } - operationsRunner: { enabled: true, provider: local } - treedx: { enabled: true, provider: local } - agentProvider: { enabled: true, provider: local } -publicTreeDxFederation: {} +profiles: { path: profiles } +integrations: { development: config/integrations/development.yaml, stablePromotion: config/promotions/stable.yaml } +skill: { lock: config/skills/treeseed.lock.yaml } +runtime: { mode: none, identity: installation-input } +staging: { mutation: approval-required, topology: config/topologies/staging.yaml } +production: { mutation: blocked, topology: config/topologies/production.yaml } +capacityProviders: { topology: config/topologies/capacity-providers.yaml }