# Development Guide This document defines contributor workflow for Scriptorium. ## Repository Layout - root package `scriptorium`: public Go facade, options, types, and error mapping. - `cmd/scriptorium`: application entrypoint. - `internal/domain`: core contracts. - `internal/usecase`: runner orchestration. - `internal/adapter/cli`: CLI adapter. - `internal/adapter/http`: HTTP adapter. - `internal/config`: application settings loading and precedence. - `internal/defaults`: default constants. - `internal/promptdef`: prompt-definition repository. - `internal/profile`: execution-profile repository. - `internal/profile/builtin`: embedded built-in execution profiles. - `internal/filecatalog`: shared source discovery and path helpers. - `internal/artifact`: artifact readers. - `internal/prompt`: prompt rendering. - `internal/llm`: LLM client interface and OpenAI-compatible implementation. - `internal/validate`: validation interfaces and implementation. - `internal/format`: prepared-run formatting. - `docs/`: canonical documentation. - `examples/`: copyable maintained examples and fixtures. ## Common Commands Build: ```bash go build ./cmd/scriptorium ``` Test: ```bash go test ./... ``` Targeted test runs commonly used during changes: ```bash go test . go test ./internal/adapter/cli ./internal/adapter/http ./internal/usecase go test ./internal/... ``` ## Coding Conventions - Prefer small interfaces at package boundaries. - Keep adapter packages focused on translation and IO concerns. - Keep domain/use-case logic outside adapters. - Wrap errors with operation context. - Use strict decoding for user-provided YAML/JSON where applicable. - Avoid introducing dependencies unless they materially reduce risk/complexity. ## Dependency Policy - Prefer standard library unless an external library is clearly justified. - Current non-stdlib dependencies are intentionally small: - `gopkg.in/yaml.v3` for YAML decoding. - `github.com/santhosh-tekuri/jsonschema/v6` for JSON Schema validation. - Do not leak dependency-specific types across unrelated package boundaries. ## How To Add App Config Fields 1. Add fields in `internal/config/config.go` (`Config`, `AppSettings`, and/or `CLIOverrides` as needed). 2. Apply defaults in `BuiltInDefaults()` when required. 3. Parse and validate in `applyConfig` / `ApplyCLIOverrides`. 4. Wire the field through the consuming adapter(s). 5. Add/update config tests in `internal/config/config_test.go`. 6. Update canonical docs (`docs/config.md`, and other affected docs). ## How To Add CLI Flags 1. Add flags in `internal/adapter/cli/run.go` for the relevant command. 2. Ensure precedence behavior remains consistent with app config rules. 3. Keep `run`, `render`, and `serve` flag surfaces intentionally scoped. 4. Add/update parser and command tests in `internal/adapter/cli/run_test.go`. 5. Update `docs/cli.md` and any related docs/examples. ## How To Add Adapters Or Adapter Capabilities 1. Define or reuse the appropriate interface boundary in domain/use-case packages. 2. Implement adapter code under `internal/adapter/` (or relevant boundary package). 3. Keep business decisions in `internal/usecase`. 4. Add focused adapter tests for mapping, parse, and error behavior. 5. Document the new/changed boundary in `docs/internal/adapters.md`. 6. If source-loading behavior changes, update `docs/internal/sources.md`. 7. If an external contract changes, update the canonical public or integration doc in the same change. ## How To Update Prompt/Profile/Schema Assets 1. Keep prompt/profile/schema files valid under strict loaders. 2. Keep examples secret-free. 3. Re-run tests that cover prompt/profile/validation behavior. 4. Update `docs/config.md` and any docs that reference changed contracts. ## Documentation Update Expectations When behavior changes: 1. Update canonical doc locations, not duplicate files. 2. Keep non-roadmap docs limited to implemented behavior. 3. Update links after file moves/renames. 4. Re-run relevant tests and smoke commands. 5. For internal boundary docs, check references with `rg "docs/internal|internal/sources" docs/policy docs/internal`. Docs work is complete only when code/tests/examples/docs agree.