205 lines
7.5 KiB
Markdown
205 lines
7.5 KiB
Markdown
# Development Policy
|
|
|
|
This document is the contributor workflow policy for `weatherreporter`.
|
|
Developers and LLM coding agents should use it with
|
|
`docs/policy/architecture.md` and `docs/policy/documentation.md`.
|
|
|
|
## Repository Layout
|
|
|
|
- `cmd/weatherreporter`: binary entry point.
|
|
- `internal/app`: orchestration for generation, batches, fetch helpers, and
|
|
inspection.
|
|
- `internal/cli`: command parsing, flag handling, help text, and JSON output.
|
|
- `internal/config`: configuration structs, defaults, loading, overrides, and
|
|
validation.
|
|
- `internal/fileutil`: shared atomic filesystem write and copy helpers.
|
|
- `internal/adapters/distributor`: Distributor upload adapter.
|
|
- `internal/adapters/weatherapi`: Weather API HTTP adapter.
|
|
- `internal/adapters/scriptorium`: Scriptorium subprocess adapter.
|
|
- `internal/weatherdata`: normalized weather source facts, source metadata, and
|
|
source warnings.
|
|
- `internal/forecast`: deterministic forecast derivation.
|
|
- `internal/facts`: collected and derived report fact contracts.
|
|
- `internal/module`: module IDs, config items, output envelopes, and snapshots.
|
|
- `internal/report`: report definitions, valid periods, batches, output names,
|
|
and comparison declarations.
|
|
- `internal/briefing`: prompt-facing module value builders and module registry.
|
|
- `internal/changes`: structured Recent Changes comparison.
|
|
- `internal/promptinput`: Scriptorium `data_package` construction and
|
|
validation.
|
|
- `internal/state`: filesystem paths, atomic JSON writes, metadata, lookup, and
|
|
inspection support.
|
|
- `internal/timeutil`: clock, date, timezone, and period helpers.
|
|
- `docs`: user, operator, developer, integration, internal, policy, and roadmap
|
|
documentation.
|
|
- `examples`: maintained copyable examples.
|
|
|
|
## Local Validation
|
|
|
|
Use focused checks while editing and broader checks before committing:
|
|
|
|
```bash
|
|
go test ./...
|
|
go run ./cmd/weatherreporter --help
|
|
git diff --check
|
|
```
|
|
|
|
Useful focused checks:
|
|
|
|
```bash
|
|
go test ./internal/cli ./internal/config
|
|
go test ./internal/app ./internal/state
|
|
go test ./internal/adapters/distributor ./internal/adapters/weatherapi ./internal/adapters/scriptorium
|
|
go test ./internal/forecast ./internal/report ./internal/briefing ./internal/changes ./internal/promptinput
|
|
```
|
|
|
|
Run `gofmt -w` on changed Go files before committing.
|
|
|
|
## Coding Conventions
|
|
|
|
- Keep domain logic out of `cmd`, `internal/cli`, and adapter packages.
|
|
- Prefer small explicit structs and functions over broad framework-style
|
|
abstractions.
|
|
- Keep package APIs narrow and named around implemented behavior.
|
|
- Return errors with operation, path, endpoint, report, or RunID context.
|
|
- Do not log or expose secrets.
|
|
- Use `context.Context` for external calls, subprocesses, and orchestrated
|
|
workflows that may be canceled.
|
|
- Use atomic writes for durable JSON artifacts where practical.
|
|
- Keep report selection and prompt IDs centralized in `internal/report`.
|
|
- Keep Scriptorium argv construction inside `internal/adapters/scriptorium`.
|
|
- Keep distributor package types and upload-client construction inside
|
|
`internal/adapters/distributor`.
|
|
- Keep Weather API transport and envelope handling inside
|
|
`internal/adapters/weatherapi`.
|
|
|
|
## Dependency Policy
|
|
|
|
Prefer the Go standard library. Add dependencies only when they materially
|
|
improve correctness, interoperability, security, or maintainability.
|
|
|
|
Current external dependencies:
|
|
|
|
- `gitea.maximumdirect.net/eric/distributor` for distributor source bundle
|
|
construction and HTTP upload client behavior.
|
|
- `gopkg.in/yaml.v3` for YAML configuration parsing.
|
|
|
|
When adding a dependency:
|
|
|
|
- explain why the standard library is not enough;
|
|
- keep dependency types from leaking across unrelated package boundaries;
|
|
- add tests for the behavior the dependency supports;
|
|
- update this policy if the dependency becomes part of contributor workflow.
|
|
|
|
## Configuration Changes
|
|
|
|
Configuration is owned by `internal/config`.
|
|
|
|
When adding or changing a field:
|
|
|
|
- update `Config` and the nested config struct in `config.go`;
|
|
- add or adjust defaults in `defaults.go` when the field has a safe default;
|
|
- update loading or CLI override behavior in `load.go` only when needed;
|
|
- validate required values and accepted ranges in `validate.go`;
|
|
- add or update config tests;
|
|
- update `docs/config.md` and maintained examples when the field is user
|
|
visible;
|
|
- keep secrets out of example config files.
|
|
|
|
Configuration precedence is:
|
|
|
|
1. CLI overrides supported by `config.LoadOptions`;
|
|
2. configuration file values;
|
|
3. built-in defaults.
|
|
|
|
The default config path is `/usr/local/etc/weatherreporter/config.yml`.
|
|
|
|
## CLI Changes
|
|
|
|
The CLI is owned by `internal/cli`.
|
|
|
|
When adding or changing a command or flag:
|
|
|
|
- update help text and parser behavior together;
|
|
- convert parsed values into app-layer request structs;
|
|
- keep domain decisions in `internal/app` or domain packages;
|
|
- add parser or command tests in `internal/cli`;
|
|
- update `docs/cli.md`;
|
|
- update `docs/operations.md` or `docs/troubleshooting.md` when behavior affects
|
|
operators.
|
|
|
|
CLI commands should return concise actionable errors and avoid printing partial
|
|
JSON when command construction fails.
|
|
|
|
## Components And Adapters
|
|
|
|
Use existing package boundaries before adding a package.
|
|
|
|
Add a new internal component only when it owns a distinct implemented contract.
|
|
Define its inputs, outputs, state behavior, failure behavior, tests, and
|
|
invariants in `docs/internal/`.
|
|
|
|
Adapters should stay thin:
|
|
|
|
- HTTP adapters own transport, request construction, envelope handling, and
|
|
decode boundaries.
|
|
- subprocess adapters own argv construction, timeout handling, stdout/stderr
|
|
capture, and exit-code interpretation.
|
|
- adapter packages should not own report selection, forecast summarization,
|
|
Recent Changes, or prompt input schema decisions.
|
|
|
|
When an external contract changes, update the matching file under
|
|
`docs/integrations/`.
|
|
|
|
## Tests
|
|
|
|
Core tests must not require live Weather API, Scriptorium, or distributor
|
|
services.
|
|
|
|
Preferred test patterns:
|
|
|
|
- fake command runners for subprocess behavior;
|
|
- `httptest.Server` for Weather API behavior;
|
|
- fake distributor upload clients for notification behavior;
|
|
- filesystem temp directories for state behavior;
|
|
- deterministic clocks for report periods and RunIDs;
|
|
- table tests for config validation, CLI parsing, period resolution, and
|
|
threshold behavior.
|
|
|
|
Add focused tests near the package that owns the behavior. Use app-level tests
|
|
for workflow ordering, persistence, and cross-package contracts.
|
|
|
|
## Examples
|
|
|
|
Examples under `examples/` must be real, maintained, and free of secrets.
|
|
|
|
When updating examples:
|
|
|
|
- use implemented config fields only;
|
|
- avoid private endpoints and credentials;
|
|
- keep comments short and operationally useful;
|
|
- add or update validation coverage when a new example file is introduced;
|
|
- link maintained examples from `docs/config.md`.
|
|
|
|
Do not add generated report examples unless they can be kept current without
|
|
live external services.
|
|
|
|
## Documentation Checklist
|
|
|
|
Documentation updates are part of behavior changes.
|
|
|
|
Update:
|
|
|
|
- `README.md` for project orientation or quickstart changes;
|
|
- `docs/cli.md` for command and flag changes;
|
|
- `docs/config.md` for config fields, defaults, and precedence changes;
|
|
- `docs/operations.md` for state, artifact, batch, inspection, and recovery
|
|
behavior;
|
|
- `docs/troubleshooting.md` for recurring operator-facing failure modes;
|
|
- `docs/internal/` for component contracts and invariants;
|
|
- `docs/integrations/` for external Weather API, Scriptorium, or distributor
|
|
contract changes;
|
|
- `docs/roadmap/` only for unimplemented or deferred work.
|
|
|
|
Non-roadmap docs must describe implemented behavior only.
|