137 lines
7.0 KiB
Markdown
137 lines
7.0 KiB
Markdown
# 25 — Implementation defaults and decision boundaries
|
|
|
|
## Purpose
|
|
|
|
This document removes routine ambiguity for autonomous implementation. Codex may choose compatible current stable versions, but it should not substitute a materially different architecture without recording an ADR and proving that all acceptance criteria remain satisfied.
|
|
|
|
## Workspace and package management
|
|
|
|
Use a TypeScript monorepo with `pnpm` workspaces.
|
|
|
|
Recommended layout:
|
|
|
|
```text
|
|
apps/
|
|
web/ Next.js application and HTTP API
|
|
worker/ PostgreSQL-backed background worker
|
|
packages/
|
|
domain/ entities, value objects and policy rules
|
|
application/ use cases and ports
|
|
db/ schema, migrations and repositories
|
|
content/ package loading, schemas and registry services
|
|
composer/ condition evaluation, policy resolution, rendering and lint
|
|
integrations/ forge adapters and encrypted-secret services
|
|
config/ typed environment and instance configuration
|
|
observability/ logs, metrics and audit helpers
|
|
ui/ shared accessible components and design tokens
|
|
testing/ fixtures and test utilities
|
|
content/playbooks/ canonical built-in Playbook Packages
|
|
```
|
|
|
|
Turborepo is the default task orchestrator. Remote caching must remain disabled and unnecessary for local or self-hosted builds unless an operator explicitly configures it later.
|
|
|
|
The exact root commands and bootstrap file contract are defined in `docs/40-bootstrap-repository-contract.md`.
|
|
|
|
## Application stack
|
|
|
|
- Next.js App Router and strict TypeScript.
|
|
- React Server Components for read-heavy pages where practical.
|
|
- Client components only for interactive composer, editors, command palette and visualizations.
|
|
- PostgreSQL as the only required data service.
|
|
- A typed SQL/ORM layer with explicit migrations; Drizzle is the preferred default unless compatibility testing identifies a blocker.
|
|
- Zod or an equivalent runtime schema layer at every external boundary.
|
|
- YAML parsing in safe mode with aliases and resource expansion bounded.
|
|
- A restricted template engine with strict missing-variable behavior and no arbitrary helpers or code execution.
|
|
- Vitest for unit and integration-oriented TypeScript tests.
|
|
- Playwright for browser flows and accessibility-oriented interaction checks.
|
|
- Structured JSON logging through a maintained logger such as Pino.
|
|
|
|
## UI foundations
|
|
|
|
- Tailwind CSS for tokens and layout utilities.
|
|
- An accessible headless component foundation; shadcn/ui may be used as a starting point but copied components become application-owned code.
|
|
- React Hook Form or equivalent for complex composer forms.
|
|
- Monaco or CodeMirror only inside Prompt Lab; normal prompt previews use lighter read-only rendering.
|
|
- Mermaid diagrams in documentation only. Runtime topology should use an accessible application-owned graph implementation, not raw Mermaid execution from untrusted content.
|
|
|
|
## API and contracts
|
|
|
|
- JSON REST API under `/api/v1`.
|
|
- Runtime routes and the checked-in OpenAPI contract must be generated from or tested against one source of truth.
|
|
- Cursor pagination for potentially unbounded resources.
|
|
- Idempotency keys for final generation, imports and retryable write actions.
|
|
- RFC 3339 UTC timestamps in APIs and storage.
|
|
- UUIDv7 or another sortable opaque identifier may be used consistently; do not expose sequential database IDs.
|
|
|
|
## Authentication decision boundary
|
|
|
|
Use Better Auth as the preferred implementation, integrated with Next.js and the selected Drizzle/PostgreSQL layer. Configure local email/password credentials and database-backed revocable sessions. Verify the current stable version, migration behavior, cookie/CSRF model and password-reset hooks during Milestone 0. A different maintained library requires a blocker-level ADR with compatibility and security evidence. Do not implement home-grown cryptography or session signing. The product-level behavior in `docs/26-authentication-authorization.md` remains mandatory regardless of library.
|
|
|
|
## Background jobs
|
|
|
|
Use a PostgreSQL job table and worker process.
|
|
|
|
- Claim work using transactions and `FOR UPDATE SKIP LOCKED` or an equivalent safe lease mechanism.
|
|
- Every job has an idempotency key or a domain-specific duplicate-prevention rule.
|
|
- A worker restart must release or eventually expire leases.
|
|
- Retry only classified transient failures with bounded exponential backoff and jitter.
|
|
- Permanent validation or authorization failures are not retried automatically.
|
|
- Redis and an external queue are prohibited in the MVP.
|
|
|
|
## Search
|
|
|
|
Start with PostgreSQL full-text search and ordinary indexed facets.
|
|
|
|
- Store a normalized search document per published playbook version.
|
|
- Use trigram matching only when the extension is available and measured useful.
|
|
- Do not add embeddings or a vector database until a recorded search-quality evaluation proves a need.
|
|
|
|
## Files and artifacts
|
|
|
|
- Built-in content is read-only at runtime and imported into PostgreSQL idempotently.
|
|
- Private draft content is stored in PostgreSQL and exported to files for Git review.
|
|
- Binary artifacts use opaque storage keys beneath the configured artifact root.
|
|
- No user-provided path may become a direct filesystem path.
|
|
- Local-disk storage is the MVP adapter; an S3-compatible adapter is future work.
|
|
|
|
## Encryption
|
|
|
|
Integration secrets use authenticated encryption with a 256-bit key supplied outside the database. AES-256-GCM is the default reference design.
|
|
|
|
Stored envelope fields:
|
|
|
|
- format version;
|
|
- key version;
|
|
- nonce;
|
|
- ciphertext;
|
|
- authentication tag;
|
|
- optional associated-data version.
|
|
|
|
Associated data must bind the ciphertext to integration ID, workspace ID and secret kind. Never reuse a nonce with the same key.
|
|
|
|
## Content rendering
|
|
|
|
- Condition evaluation uses the declarative AST in `docs/28-conditions-and-policy-dsl.md`.
|
|
- Templates receive only allowlisted normalized values.
|
|
- Missing required variables are blocking errors.
|
|
- Arrays and key/value inputs use platform-owned deterministic Markdown renderers.
|
|
- Repository evidence cannot be interpreted as template source.
|
|
- Canonicalization follows `docs/29-package-integrity-canonicalization.md`.
|
|
|
|
## Dependency policy
|
|
|
|
- Pin exact dependency versions in the lockfile.
|
|
- Use current stable versions verified for mutual compatibility during Milestone 0.
|
|
- Avoid dependencies whose core function can be implemented safely in a small application-owned module.
|
|
- Record any dependency that processes untrusted archives, Markdown, YAML, templates, authentication or cryptography in the security review.
|
|
- Configure automated dependency and license scanning in CI.
|
|
|
|
## Disallowed shortcuts
|
|
|
|
- No SQLite fallback hidden in production.
|
|
- No in-memory persistence outside tests and explicit demo fixtures.
|
|
- No mocked Gitea responses in production code paths.
|
|
- No `eval`, `Function`, shell execution or dynamic module loading for conditions or templates.
|
|
- No direct code execution, repository checkout or Codex invocation in the MVP.
|
|
- No silent creation of default administrator credentials.
|