AGENTS.md@packages/ai · git:20260827.ca77bd1 · 2026-08-27 · sha256 ff7392d63ec4c433
AGENTS.md@packages/ai git:20260827.ca77bd1A
Immutable. This exact content never changes and is served at /api/v1/blob/ff7392d63ec4c433.
# AGENTS.md — packages/ai Parent execution contract for Nebutra AI packages. Package-local `AGENTS.md` files may add stricter rules; this file owns the cross-package boundaries. ## Layering `packages/ai` is split by responsibility, not by upstream project names: | Role | Canonical package | Boundary | | --- | --- | --- | | Model execution runtime | `@nebutra/agents` | The canonical model-execution runtime. It owns Vercel AI SDK integration, provider selection, fallback, embeddings, generation helpers, and observability hooks. | | Provider metadata | `@nebutra/ai-providers` | Metadata only. It owns provider IDs, categories, status flags, env-var requirements, and scaffolding templates. Do not add runtime SDK calls here. | | Public API gateway | `backends/gateway` + `@nebutra/gateway-core` | External `sk-sailor-*` auth, tenant usage metering, upstream pool routing, and response accounting. | | Agent protocol/runtime grammar | `@nebutra/agent-runtime` | Thread/turn/item model, policy, tool/MCP bridge, rollout, sandbox seam. It must not own provider SDK execution. | | Tool integration | `@nebutra/mcp`, `@nebutra/tool-registry`, `@nebutra/sandbox-runtime` | MCP/tool discovery, SKILL.md parsing/loading, consent, audit, and sandbox routing boundaries. | | Execution capability tools | `@nebutra/browser-control`, `@nebutra/code-execution`, `@nebutra/document-pipeline` | Deterministic or semi-deterministic tool execution. They must not own Thread/Turn/Item state, prompt generation, model/provider execution, sub-agent scheduling, or approval lifecycle. | | Generation capability tools | `@nebutra/image-pipeline`, `@nebutra/video-pipeline`, `@nebutra/audio-pipeline`, `@nebutra/voice-realtime`, `@nebutra/3d-pipeline` | BrandContext-first media generation surfaces. They may expose local deterministic fallbacks and sidecar adapter ports, but must not own Thread/Turn/Item state, prompt orchestration, model/provider routing, or approval lifecycle. | | Shared support contracts | `@nebutra/generation-context`, `@nebutra/execution-policy`, `@nebutra/local-embedding`, `@nebutra/ai-primitives`, `@nebutra/ecosystem-safety` | Single TypeScript owners for facts consumed across surfaces: `BrandContext`, command permission/approval primitives, deterministic local embeddings, pure AI support primitives, and public-disclosure safety checks. | | Persistence contracts | `@nebutra/content-store` | File truth, frontmatter parsing/serialization, paragraph chunk helpers, and rebuildable indexes. Parser packages consume these helpers rather than defining file-truth grammar. | | Capability DX primitives | `@nebutra/capability-kit` | Platform package outside `packages/ai` that owns suggestion-bearing capability errors, doctor/debug CLI switching, package-local tenant fallback selection, and `.nebutra/debug/<capability>.jsonl` helpers. AI packages must import these primitives instead of re-implementing them. | | RAG/indexing/dataflow | `@nebutra/knowledge-rag`, `@nebutra/knowledge-graph`, `@nebutra/code-index`, `@nebutra/reel`, `@nebutra/atelier-canvas`, `@nebutra/cinema` | Product capabilities built on injected model/vector/store/tool/graph ports. | | Knowledge product layer | `@nebutra/knowledge-base` | Company cognition over connectors, memory, graph, citations, and explainable search. It consumes lower retrieval/ingestion primitives and must not redefine them. | | Play product layer | `@nebutra/brand-genesis`, `@nebutra/landing-builder`, `@nebutra/outreach-engine`, `@nebutra/support-deflector` | Complete user-story Plays over lower capabilities. Owns orchestration and SKILL.md assets only. | | Ecosystem product layer | `@nebutra/time-machine`, `@nebutra/idea-plaza`, `@nebutra/founder-cemetery`, `@nebutra/cofounder-match`, `@nebutra/play-marketplace` | Network-effect product surfaces over lower persistence, knowledge, and Play primitives. They own explicit opt-in workflows, lineage, annotations, marketplace records, and consent gates, not event truth, content truth, runtime loops, transports, or billing credentials. | The complete surface registry lives in `packages/ai/PACKAGE_MAP.md`. Every `@nebutra/*` package under `packages/ai` must declare `nebutra.featureId` and `nebutra.surface` in `package.json`. ## Consolidation Rules 1. Do not merge packages across surfaces. A runtime grammar package and a deterministic tool package have different owners even when both are small. 2. If two packages in the same surface own the same fact or public concept, choose one owner and move the other behind a subpath export or delete it. 3. Shared facts used by multiple capability families must live in a `support-contract` package. Do not duplicate those types in each capability. 4. Capability packages expose adapters and deterministic APIs; they do not own prompts, provider routing, tenant billing, approval lifecycle, or runtime state. 5. Capability debug storage, CLI command dispatch, and suggestion-bearing base errors belong to `@nebutra/capability-kit`; do not hand-roll debug JSONL path, append, or tail-read helpers inside individual AI packages. 6. Capability package tenant selection belongs to `@nebutra/capability-kit`. This means the local explicit `tenantId` vs constructor/open default fallback primitive. It is intentionally not `@nebutra/tenant`, which owns request-scoped tenant context, tenant resolution strategies, DB/RLS isolation, and identity-facing tenancy contracts. 7. Media graph facts belong to `@nebutra/reel` subpaths. Video/image/audio pipelines may render or adapt media, but shared storyboard shot/scene/plan types must come from `@nebutra/reel/storyboard`. 8. Command permission and shell approval defaults belong to `@nebutra/execution-policy`. Runtime packages may decide when to ask a human; execution packages only evaluate that shared contract. 9. File-truth frontmatter parsing, frontmatter serialization, and paragraph chunk helpers belong to `@nebutra/content-store`. Document ingestion packages may parse external formats, but must not define a parallel frontmatter grammar. 10. Deterministic zero-config embeddings belong to `@nebutra/local-embedding`. Persistence and RAG packages may choose different dimensions, but must not define parallel local hashing/tokenization algorithms. 11. Pure AI support primitives belong to `@nebutra/ai-primitives`: `sha256`, numeric `clamp`, policy-parameterized cosine similarity, tenant/source scoped-key derivation, and cheap token estimates. Domain packages may keep branded types and fail-loud public wrappers, but must not re-own the pure helper logic. 12. Public-disclosure PII and secret scanning belongs to `@nebutra/ecosystem-safety`. Ecosystem packages may decide whether an action is publishable, cloneable, or memorialized, but they must not define local email/secret regexes or parallel sensitive-field scanners. 13. SKILL.md frontmatter parsing belongs to `@nebutra/tool-registry`. `@nebutra/play-loader` extends the parsed document into Play metadata; it must not parse YAML/frontmatter independently. `@nebutra/agent-runtime` definitions are a separate runtime grammar with source tiers, invocation gates, and tenant merge semantics, so do not merge them into SKILL.md without an RFC. 14. Runtime tool dispatch belongs to `@nebutra/agent-runtime` as `RuntimeToolRegistry`. Do not confuse it with the SKILL.md package registry in `@nebutra/tool-registry`. 15. Company knowledge cognition belongs to `@nebutra/knowledge-base`. It may own connector sync state, memory classes, entity/relation records, citations, and explain output. It must consume `@nebutra/content-store`, `@nebutra/document-pipeline`, `@nebutra/knowledge-rag`, and `@nebutra/knowledge-graph` rather than defining another parser, chunker, embedder, vector store, reranker, or deterministic graph/entity-edge extractor. 16. Complete Play products belong to play product packages such as `@nebutra/brand-genesis`, `@nebutra/landing-builder`, `@nebutra/outreach-engine`, and `@nebutra/support-deflector`. These packages may coordinate lower capabilities, store SKILL.md declarations, and produce user-story bundles. They must not own agent-loop internals, media generation providers, deploy credentials, sender credentials, channel transports, BrandContext schemas, or prompt islands outside SKILL.md. 17. Ecosystem product packages such as `@nebutra/time-machine`, `@nebutra/idea-plaza`, `@nebutra/founder-cemetery`, `@nebutra/cofounder-match`, and `@nebutra/play-marketplace` may project lower-layer data into network-effect workflows. They must not redefine event-log, content-store, SKILL.md parsing, auth, billing, chat transport, public registry transport, or global moderation systems. 18. Similar ecosystem words are not automatically the same primitive. Plaza publish levels are fork visibility depth (`surface` / `detail` / `cloneable`); Cemetery publish levels are audience and permanence (`private` / `community` / `public`); Match consent is bilateral interest. Do not merge them into a generic `PublishLevel` or `Consent` type without a real shared state machine. 19. Legacy experiments stay WIP and blocked from new production consumers until they are either retired or promoted through a separate RFC. ## 2026 AI SaaS Defaults 1. Use production-proven provider surfaces first: Vercel AI SDK for app/runtime model calls, provider SDKs for direct integrations, and managed/self-hosted gateway layers such as Vercel AI Gateway, LiteLLM, Portkey, OpenRouter, or a Nebutra gateway adapter for tenant metering. 2. Keep key material out of checked-in configuration. Package APIs should accept injected clients, env-var names, or vault-backed resolvers rather than raw secrets. 3. Runtime packages must emit tenant/user/request/provider metadata where the boundary allows it. Usage accounting and audit events belong at gateway or runtime adapter seams, not scattered through product packages. 4. RAG, code indexing, canvas, media, and tool packages should depend on ports and injected adapters. They may call `@nebutra/agents` helpers only through explicit provider adapters. 5. New packages must declare whether they are runtime, metadata, tool, persistence, product-capability, or legacy/compatibility surfaces before exposing public exports. ## Import Rules - New model execution code imports from `@nebutra/agents`. The local `@nebutra/llm-gateway` and `@nebutra/provider-registry` experiments have been retired; route through `@nebutra/agents` and the production gateway instead. - `@nebutra/ai-providers` must remain metadata only and dependency-light. - `@nebutra/agent-runtime` may bridge to MCP/tool/sandbox contracts, but model calls stay injected or delegated to `@nebutra/agents`. - Execution capability packages must not import `@nebutra/agent-runtime`, `@nebutra/agents`, or `ai` from production source. They expose tool-shaped ports; the runtime decides when to call them. - `@nebutra/agent-runtime` must not hard-import concrete execution capability packages. Composition happens through tool registry/adapters so execution capabilities remain replaceable. - Generation capability packages must import `BrandContext` from `@nebutra/generation-context`; do not define parallel brand schemas inside individual media packages. - AI packages must import debug JSONL helpers from `@nebutra/capability-kit/debug`; do not define local `debugPath`, `appendDebug`, `.nebutra/debug` path joins, or `readFile(debugPath(...))` variants. Package-specific `readXDebug` compatibility wrappers are allowed only when they delegate directly to `readCapabilityDebug`. - Capability, Play product, Knowledge product, and Ecosystem product packages must import `requireCapabilityTenant` from `@nebutra/capability-kit` when selecting between an explicit request tenant and a constructor/open default tenant. `@nebutra/agent-runtime` may keep runtime-local tenant admission validation because it guards channel dispatch and invocation boundaries, not package-local fallback selection. - Generation capability packages must not import `@nebutra/agent-runtime`, `@nebutra/agents`, or `ai` from production source. - `@nebutra/video-pipeline` must consume storyboard plan primitives from `@nebutra/reel/storyboard`; it should not define a parallel Storyboard model. - `@nebutra/code-execution` must consume command approval rules from `@nebutra/execution-policy`; it should not define a parallel default safety policy. - `@nebutra/document-pipeline` must consume frontmatter and paragraph helpers from `@nebutra/content-store`; file-truth schema parsing belongs to persistence, not parser adapters. - `@nebutra/content-store` and `@nebutra/knowledge-rag` must consume deterministic local embedding helpers from `@nebutra/local-embedding`; do not duplicate FNV/hash embedding logic inside either package. - `@nebutra/code-index`, `@nebutra/knowledge-graph`, `@nebutra/knowledge-rag`, and `@nebutra/agent-runtime` must consume pure hash, numeric, scoped-key, and token-estimate helpers from `@nebutra/ai-primitives`. Keep package-specific branded keys and domain errors as wrappers; do not copy the primitive bodies. - `@nebutra/idea-plaza` and `@nebutra/founder-cemetery` must consume public-disclosure checks from `@nebutra/ecosystem-safety`; do not define local email/secret regexes or sensitive-field scanner types. - `@nebutra/play-loader` must consume parsed SKILL.md documents from `@nebutra/tool-registry`; do not import YAML parsers or call `parseSkillFrontmatter(markdown)` after `parseSkillMarkdown(markdown)`. - New runtime code should use `RuntimeToolRegistry` for in-memory tool dispatch. `ToolRegistry` remains a compatibility alias in `@nebutra/agent-runtime`, while `@nebutra/tool-registry` remains the package name for SKILL.md registry semantics. - `@nebutra/knowledge-base` must not import or define local embedding/chunking implementations. Use `@nebutra/knowledge-rag` for retrieval, `@nebutra/content-store` for file truth, `@nebutra/document-pipeline` for source parsing, and `@nebutra/knowledge-graph` for deterministic entity-edge derivation. - `@nebutra/brand-genesis` must not import `@nebutra/agent-runtime` or define media primitives. It composes `@nebutra/generation-context`, content/event persistence, and generation capability packages through a SKILL.md Play. - `@nebutra/landing-builder` must not own deploy credentials or sandbox preview execution. It writes brand-aware site artifacts and deploy handoff manifests; real preview/deploy adapters stay in lower capability/integration packages. - `@nebutra/outreach-engine` must never send directly from a Play run. It produces compliance-gated campaign drafts; sender, lead-source, CRM, and vault adapters stay outside the package. - `@nebutra/support-deflector` must not own customer channel transports. It owns confidence-gated ticket decisions only; support-channel bridges remain adapter seams. - `@nebutra/time-machine` must not own event or content truth. It consumes `@nebutra/event-log` and `@nebutra/content-store`, and rollback apply remains outside the package. - `@nebutra/idea-plaza` and `@nebutra/founder-cemetery` must default to private data, require explicit publication intent, and write audit-friendly snapshots rather than exposing cross-tenant source stores. - `@nebutra/cofounder-match` must not own identity providers or chat transport. It owns activity-derived profiles, explainable matching, and mutual-consent handoff artifacts. - `@nebutra/play-marketplace` must validate Plays through `@nebutra/play-loader`. It must not parse SKILL.md locally, own payment credentials, or mark quality metrics as production stats before telemetry exists. - Product capability packages should not own billing deduction, gateway auth, or provider-key selection. - Examples may import legacy packages to demonstrate migration, but production source must not create new runtime dependencies on them. ## Validation Run the cross-package boundary test after changing package exports, dependency edges, provider routing, or package status metadata: ```bash pnpm exec vitest run tests/architecture/ai-package-governance.test.ts ``` Run the touched package's own tests/typecheck next. Do not update generated `dist/` output by hand.