Pular para conteúdo

AUR-003: Definir schema de card atômico

Documento histórico do board. Pode descrever componentes removidos; para uso atual, consulte o guia do produto.

Behavior

internal/governance/taskspec accepts one YAML TaskSpec document, including the JSON-compatible subset, and returns a normalized value only after validating the complete contract. The contract has exactly one scalar outcome and one reversible mutation; a missing or additional field is not silently ignored.

The loader rejects malformed YAML, duplicate keys, unknown keys, missing required fields, closed-enum values outside the contract, duplicate list items, and self-dependencies. It returns *taskspec.FieldError, whose Field and Code identify the failing field without echoing input values.

Contract

  • .board/schemas/task-spec.schema.json is the machine-readable contract.
  • The root object is closed with additionalProperties: false and requires schema: aurum.task-spec, version: 1, card identity, ownership, evidence identity, one outcome, and one mutation object.
  • status, validation, risk, data_class, and trust-boundary values use closed enums. The mutation boundary must also be named in trust_boundaries.
  • paths, read_paths, and forbidden_paths are relative normalized POSIX paths. Absolute paths, drive-letter paths, backslashes, traversal components, interior whitespace, control characters, empty components such as src//file, duplicates, and overlapping read/write/forbidden scopes are rejected before a spec is returned. The schema's x-aurumcode.path_policy and x-aurumcode.scope_disjointness declarations are checked by ValidateSchema and mirror the Go loader's cross-field checks.
  • Digest validates first and returns a stable sha256: digest of the normalized JSON representation. It performs no I/O.

The loader has no board, filesystem, network, authorization, or publication side effects. Parsing a field called authorization is not an authorization event: it is an unknown field and fails closed.

tests/acceptance/AUR-003.sh builds tests/unit/AUR-003.go and executes that runner once per vector. The runner validates the JSON Schema, calls taskspec.Load, calls Digest for accepted input, and emits the typed observation used by the acceptance comparison. Invalid vectors return their raw program exit (1) without allowing go run to rewrite it; the package's real TestAUR003 lives under the declared internal/governance/taskspec directory and is executed by go test.

Limits

tests/specs/AUR-003/cases.yaml is bounded to 64 vectors, 4 MiB total input, and a 30-second declared deadline. The loader bounds text, path, list, and trust-boundary sizes as declared in the JSON schema and applies the same limits when validating an already normalized value.

Example

schema: aurum.task-spec
version: 1
id: AUR-003
title: Definir schema de card atômico
status: doing
validation: tested
office: O00-governance
depends_on: [AUR-001]
requirements: [PR-ARCH-001, PR-EVD-001]
controls: [CR-EVD-001]
paths: [internal/governance/taskspec, tests/acceptance/AUR-003.sh]
forbidden_paths: [.git, .env, secrets, .board/cards]
base_sha: lock-at-execution
spec_digest: lock-at-execution
risk: medium
data_class: internal
trust_boundaries: [repository, authorization-source]
outcome: incomplete cards are refused
mutation:
  id: MUT-001
  boundary: repository
  change: remove the mutation requirement from the schema
  expected: acceptance returns a typed failure before any effect

The example contains no secret and declares no capability beyond the owned paths.

Diagnosis

  • missing_field or unknown_field: compare the document with the required root and mutation fields in the schema; do not add an unreviewed alias.
  • duplicate_field: remove the repeated YAML key. Last-write-wins behavior is deliberately unavailable.
  • invalid_field: check the closed enum, identifier format, cardinality, or text bound named in FieldError.Field.
  • unsafe_path: use a repository-relative POSIX path and keep read, write, and forbidden scopes disjoint.
  • A missing Go toolchain or OCI engine is infrastructure (exit 3), not a behavioral result. Run bash -n tests/acceptance/AUR-003.sh, then go test ./internal/governance/taskspec and go run tests/unit/AUR-003.go --schema .board/schemas/task-spec.schema.json --case nominal when Go is available; the OCI command is the card's external acceptance gate.

The acceptance observation is not approval and does not move the board card. MUT-001 must make the same acceptance command fail, and a restored candidate must reproduce the nominal exit code and artifact digest. The canary AURUM_SECRET_CANARY must not appear in stdout, stderr, fixtures, logs, or evidence.