feat(registry): complete ATLAS-WP-0002 T04 (canon mapping) + T01 (surface schema)

T04: add docs/canon-mapping.md mapping config-atlas concepts to InfoTechCanon
(itc-gov/data/devsecops/land/org/access/sec/tag) and sibling repos with
consume/reference/align/own ownership, plus gaps, validation hooks, and
extension candidates. Resolves the (planned) refs in PRD and ecosystem-boundaries.

T01: add schemas/surface-entry.schema.json (Draft 2020-12, additionalProperties
false to forbid inline values/secrets), docs/configuration-surface-schema.md
(fields, kind taxonomy, L0-L9 ordering, explicit merge rules), a validating seed
entry (surface.infotech.state-hub.api-config), and expand registry/README.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-26 22:47:40 +02:00
parent 0f869584d1
commit a52b77a0e7
6 changed files with 448 additions and 3 deletions

View File

@@ -0,0 +1,94 @@
# Configuration Surface Schema
**Status:** draft
**Updated:** 2026-06-26
**Repo:** config-atlas
**Schema:** [`../schemas/surface-entry.schema.json`](../schemas/surface-entry.schema.json)
**Related:** [`canon-mapping.md`](canon-mapping.md), [`../specs/ProductRequirementsDocument.md`](../specs/ProductRequirementsDocument.md) §7/§10,
[`../specs/ArchitectureBlueprint.md`](../specs/ArchitectureBlueprint.md) §3
A **configuration surface** is a bounded, named place where configuration is
defined, read, or overridden. Each surface is one markdown file in
`registry/surfaces/` whose **YAML frontmatter** validates against
`schemas/surface-entry.schema.json`; the markdown body holds prose (meaning,
precedence notes, gotchas).
The atlas stores the **map**: where a surface lives, who owns it, its kind, scope,
and source links. It **never** stores live configuration values and **never** stores
secret values (PRD NFR-2, NFR-4). `additionalProperties: false` throughout the schema
prevents an entry from sneaking a `value` field anywhere.
## Fields
| Field | Required | Meaning |
|-------|----------|---------|
| `id` | yes | Stable id `surface.<domain>.<system>.<name>` (lowercase, dashes). |
| `name` | yes | Human-readable name. |
| `kind` | yes | Closed taxonomy (below). Drives kind-separation. |
| `summary` | yes | One-line description. |
| `owner` | yes | Team/agent identity, resolved against `domain-tree`. Not a person. |
| `status` | yes | `draft` \| `active` \| `deprecated`. |
| `scope` | yes | `allowed_layers` (subset of the layer ordering) + `default_layer`. |
| `mutability` | yes | Delivery stage / blast radius (below). |
| `security_class` | yes | `operational` \| `sensitive` \| `secret-ref` \| `policy`. |
| `schema` | no | The **contract** (type/default/min/max/validator) — metadata, not a live value. |
| `sources` | yes | Canonical sources by reference, each with a layer `role`. Never inlines a value. |
| `relations` | no | `consumed_by`, `overrides`, `depends_on_secret` (refs only), `related_to`. |
| `evidence` | no | `last_seen`, `discovery_method`, `change_log_ref`. |
### `kind` taxonomy
`app-config`, `deploy-config`, `secret-ref`, `feature-flag`, `policy`,
`tenant-config`, `infra-state`, `runtime-override`. Secrets, flags, and infra-state
are never treated as ordinary config. A `feature-flag` surface links to a
`feature-control` key (via a `sources[].role: feature-control-key`) and contains no
evaluation logic. A `secret-ref` surface references a secret by id/path only.
### `mutability` classes
`build-time`, `deploy-time`, `startup-time`, `hot-reloadable`, `per-request`,
`emergency`. Prevents treating structural config like a harmless flag.
## Scope / layer ordering (L0L9)
`allowed_layers` and `default_layer` draw from the **shared scope vocabulary** — an
ordering, not a new set of names (aligned to ITC-LAND/ITC-ORG and `feature-control`
`EvaluationScope`; see `canon-mapping.md`):
```text
L0 product-default L5 installation
L1 company L6 tenant
L2 platform L7 group
L3 environment L8 user / agent
L4 region L9 emergency
```
"More specific wins" by default; higher layers may declare **non-overridable
guardrails**. A surface declares which layers may set it, e.g.
`allowed_layers: [company, environment, tenant]`.
## Merge rules (explicit — no hidden last-writer-wins)
```text
scalar more specific layer replaces earlier value
object/map deep merge by key
array/list replace by default; keyed merge only if declared
null not deletion unless tombstone semantics are defined
secret never merged into normal config
policy restrictive rule wins unless explicitly delegated
```
Resolution of the *effective value* is out of scope (delegated downstream). The
atlas renders only the **effective-config path** — the ordered override path with
owner and validating-schema references (PRD FR-5).
## Authoring
1. Copy the example below into `registry/surfaces/surface.<domain>.<system>.<name>.md`.
2. Fill frontmatter; link `sources[]` to canonical files (no values, no secrets).
3. Add the row to `registry/indexes/surfaces.yaml` (ATLAS-WP-0002-T03).
4. Validate (ATLAS-WP-0002-T06): frontmatter against the schema, plus
`reuse-surface validate --root .` and `git diff --check`.
## Example
See [`../registry/surfaces/surface.infotech.state-hub.api-config.md`](../registry/surfaces/surface.infotech.state-hub.api-config.md)
— a real, validating entry for the State Hub API configuration surface.