diff --git a/docs/canon-mapping.md b/docs/canon-mapping.md new file mode 100644 index 0000000..201a6bc --- /dev/null +++ b/docs/canon-mapping.md @@ -0,0 +1,142 @@ +# Canon Mapping + +**Status:** draft +**Updated:** 2026-06-26 +**Repo:** config-atlas +**Related:** [`../INTENT.md`](../INTENT.md), [`../specs/ProductRequirementsDocument.md`](../specs/ProductRequirementsDocument.md) (PRD §5), +[`../specs/ArchitectureBlueprint.md`](../specs/ArchitectureBlueprint.md), +[`ecosystem-boundaries.md`](ecosystem-boundaries.md) §2.3, +[`configuration-surface-schema.md`](configuration-surface-schema.md) (ATLAS-WP-0002-T01) + +This document maps `config-atlas` concepts to **InfoTechCanon** (ITC) and sibling +repos. It is explicit about owned facts, consumed facts, references, proposed +extensions, and gaps. It follows the pattern of +`~/feature-control/docs/canon-mapping.md` and resolves the `(planned)` references +in PRD §5 and `ecosystem-boundaries.md` §2.3. + +## Mapping Stance + +`config-atlas` is the **read-first, cross-kind configuration map and evidence +layer**. Its novel core is the **configuration surface** entry, the **L0–L9 +layering order**, and the **effective-config *path*** rendering. Everything else is +referenced, not owned (see [`../.claude/rules/repo-boundary.md`](../.claude/rules/repo-boundary.md)). + +`config-atlas` **consumes** ITC for governance (policy/decision/evidence), data +(schema/contract/classification), delivery (mutability), and landscape +(environment/deployment/service/repository). It **references** ITC-ORG ownership via +`domain-tree`, and **aligns** its scope vocabulary with `feature-control`'s +`EvaluationScope`. It **extends** the canon only where a configuration surface needs +precision the canon does not yet provide. + +It **must not**: +- Become a runtime **resolver / delivery / control plane** (resolution is delegated). +- Own the **runtime control of feature availability** — that is `feature-control` + (ITC-GOV `Control` + OpenFeature); config surfaces of kind `feature-flag` link out. +- Store **secret values** (ITC-ACCESS / OpenBao own values) — references only. +- Become a **second source of truth** for configuration values. +- **Redefine** the configuration vocabulary — it maps to ITC. + +Terminology rule (per ITC "import concepts instead of redefining them"): the L0–L9 +**layer** model is an *ordering over* the shared ITC-LAND / ITC-ORG / +`EvaluationScope` scope vocabulary, **not** a new set of scope names. + +## Entity Mapping + +| config-atlas concept | Canon concept | Ownership | Notes | +| --- | --- | --- | --- | +| `Configuration surface` (bounded named place where config is defined/read/overridden) | `ProducerCapability` (ITC-GOV purpose-demand ext) + Landscape resource (ITC-LAND); relates to repo-scoping `Scope→Ability→Capability→Feature→Evidence→Fact` | **owned** (extension candidate) | The first-class atlas entry. Maps the surface; does not own the underlying system. | +| `kind` (app-config, deploy-config, secret-ref, feature-flag, policy, tenant-config, infra-state, runtime-override) | classification (ITC-DATA) crossed with ITC-GOV (policy), ITC-LAND (infra/deploy), ITC-ACCESS (secret-ref) | **owned** (taxonomy) on consumed concepts | Drives kind-separation: secrets/flags/infra-state never treated as ordinary config. | +| `scope` / `layer` (L0–L9 over company, environment, region, installation, tenant, group, user, agent, …) | ITC-LAND dimensions (Environment, Deployment, Service, Repository) + ITC-ORG `Membership` (scope_type/scope_id) + `feature-control` `EvaluationScope` | **align + own ordering** | config-atlas owns only the *ordering and precedence*; the scope names are shared, not new. | +| `Effective configuration` | derived state from layered Sources + precedence (resolution **delegated**) | **own the *path***, not the resolved value | The `config explain` path: winning layer, overrides, validator, owner. | +| `Source` (repo/path/endpoint + layer `role`, no values) | ITC-LAND (Repository, Service, Environment, Deployment) + ITC-DEVSECOPS delivery artifacts | **reference** | Source-linked; never inlines a value. | +| `Merge semantics` (scalar/object/array/null/secret/policy rules) | ITC-GOV `Policy` precedence; restrictive-wins | **owned** | Explicit; no hidden last-writer-wins. | +| `mutability` class (build/deploy/startup/hot/per-request/emergency) | ITC-DEVSECOPS delivery stages | **reference** | Prevents treating structural config like a harmless flag. | +| `security_class` (operational/sensitive/secret-ref/policy) | ITC-DATA classification + ITC-SEC | **reference** | `secret-ref` never carries a value. | +| `Evidence` (last_seen, discovery_method, change_log_ref) | ITC-GOV `Evidence` / `Audit` | **reference** | Answers who/what/why/when and "is this still used?". | +| `Relationship` / edge (`consumed_by`, `overrides`, `depends_on_secret`, `related_to`) | ITC-GOV relations + State Hub graph; `consumed_by`→ITC-LAND Service; `depends_on_secret`→ITC-ACCESS (ref) | **own config semantics**, reference topology | config-atlas owns the config meaning of the edge; State Hub stores it. | +| `owner` | ITC-ORG `Ownership`/`Stewardship`/`Actor`, resolved via `domain-tree` bindings | **reference** | Mandatory; references identity, not a person. | +| `feature-flag` surface | `feature-control` key (ITC-GOV `Control` + OpenFeature) | **reference / link** | Never re-derives rules, resolver, or kill switches. | +| `secret-ref` surface | ITC-ACCESS secret + OpenBao | **reference only** | Records dependency/injection point, never the value. | + +## Relationship Mapping + +| Relationship | Source | Target | Notes | +| --- | --- | --- | --- | +| `consumed_by` | Configuration surface | Service / Repository (ITC-LAND) | Which systems read the surface. | +| `overrides` | Surface (higher specificity) | Surface (broader layer) | config-atlas owns; honors L0–L9 + guardrails. | +| `depends_on_secret` | Surface | Secret (ITC-ACCESS, OpenBao) | Reference only; never the value. | +| `owned_by` | Surface | Actor / Team (ITC-ORG via domain-tree) | Mandatory metadata. | +| `sourced_from` | Surface | Repository/Service/Environment (ITC-LAND) | Source-linked, layer `role` per source. | +| `emits_evidence_for` | Surface change | Evidence (ITC-GOV) | Audit + change-log reference. | +| `links_to_control` | `feature-flag` surface | feature-control key | Delegation boundary; no local resolution. | +| `classified_by` | Surface | Tag (ITC-TAG) | `kind`/category tagging. | + +## Read model / projection surface + +A canon-aligned atlas read surface should expose (without leaking values or +secrets): the normalized owner (ITC-ORG via domain-tree); the surface `kind` and +allowed `scope`/layers; source links with layer `role`; the effective-config +**path** (winning layer, overrides, validating schema, owner) — *not* the resolved +value; relationship edges (consumed_by, overrides, depends_on_secret); and +evidence (last_seen, change_log_ref). Entries must remain parseable by agents +without live hub or resolver data (PRD NFR-1, NFR-3). + +## Current gaps (config-atlas side) + +- No first-class `Configuration surface` / `EffectiveConfigPath` / `MergeSemantics` + in the current ITC seed — these are the primary **extension candidates**. +- The scope/layer ordering (L0–L9) has no canon owner yet; aligned to ITC-LAND/ORG + and `EvaluationScope` but the *precedence/guardrail* semantics are config-atlas owned. +- `domain-tree` ownership-binding resolution is referenced but not yet wired + (ATLAS-WP-0002-T03/T06). +- Effective-config *value* resolution is intentionally **out of scope** (delegated); + only the path is modeled. +- "AI/agent configuration" as a named scope class is an open question (PRD §14 Q5). + +## Validation hooks / checks (for the schema + CI, ATLAS-WP-0002-T01/T06) + +- Entry requires `owner` (ITC-ORG reference) and `kind` (closed taxonomy). +- Schema **forbids** literal configuration values and secret values (NFR-2, NFR-4). +- Layer names must come from the shared scope vocabulary — no new scope names. +- `feature-flag` surfaces must carry a `sources[]` link to a feature-control key and + contain no evaluation logic. +- `secret-ref` surfaces reference a secret by id only; never a value. +- References to canon concepts use short owner IDs (e.g. `ITC-GOV.Evidence`, + `ITC-LAND.Environment`, `ITC-DATA.Classification`). + +## Extension candidates (for assimilation back into InfoTechCanon) + +Record for feedback to canon owners (via State Hub messages / ITC workplans): + +- `ConfigurationSurface` (typed ProducerCapability/Landscape-resource specialization + with kind, scope, source links, and evidence). +- `EffectiveConfigPath` (an explainable override path; specialized Governance + Decision/Evidence projection without a resolved value). +- `LayeringOrder` / `MergeSemantics` (precedence + merge-rule vocabulary, with + non-overridable guardrails). +- `ConfigurationKind` taxonomy (data/governance/landscape/access crossing). + +These preserve orthogonality: canon owns general concepts; config-atlas owns the +cross-kind map, layering order, and effective-config path. + +## Related canon artifacts + +- `infospace/kernel/InfoTechCanonCore.md` (itc-core), `itc-kernel-map` +- `infospace/models/governance/InfoTechCanonGovernanceModel.md` (itc-gov) +- `infospace/models/data/InfoTechCanonDataModel.md` (itc-data) +- `infospace/models/devsecops/InfoTechCanonDevSecOpsModel.md` (itc-devsecops) +- `infospace/models/landscape/InfoTechCanonLandscapeModel.md` (itc-land) +- `infospace/models/organization/InfoTechCanonOrganizationModel.md` (itc-org) +- `infospace/models/access-control/InfoTechCanonAccessControlModel.md` (itc-access) +- `infospace/models/security/InfoTechCanonSecurityModel.md` (itc-sec) +- `infospace/standards/tagging/InfoTechCanonTaggingStandard.md` (itc-tag) +- `~/feature-control/docs/canon-mapping.md` (alignment style + `EvaluationScope`) + +## Next steps (tied to ATLAS-WP-0002) + +- T01: encode the validation hooks above in `schemas/surface-entry.schema.json` and + `docs/configuration-surface-schema.md`. +- T03/T06: wire `owner` resolution to `domain-tree`; enforce checks in CI. +- Assimilation: submit the Extension Candidates to ITC owners; update this mapping + (Status, Updated) and run `make fix-consistency REPO=config-atlas`. + diff --git a/docs/configuration-surface-schema.md b/docs/configuration-surface-schema.md new file mode 100644 index 0000000..d192b35 --- /dev/null +++ b/docs/configuration-surface-schema.md @@ -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...` (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 (L0–L9) + +`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....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. diff --git a/registry/README.md b/registry/README.md index 569abe9..a40d3c2 100644 --- a/registry/README.md +++ b/registry/README.md @@ -1,4 +1,20 @@ -# Capability Registry +# Registry + +Markdown-first registry for config-atlas. Two entry families: + +- **Configuration surfaces** (`surfaces/`) — the atlas's core artifact. Each entry + maps a configuration surface (where it lives, owner, kind, scope, source links), + validated against [`../schemas/surface-entry.schema.json`](../schemas/surface-entry.schema.json). + See [`../docs/configuration-surface-schema.md`](../docs/configuration-surface-schema.md) + for the model and [`../docs/canon-mapping.md`](../docs/canon-mapping.md) for ITC alignment. + Index: `indexes/surfaces.yaml` (ATLAS-WP-0002-T03). +- **Capabilities** (`capabilities/`) — capability index for reuse-surface federation + (below). + +Surfaces store the **map only** — never live configuration values, never secret +values. + +## Capability Registry Markdown-first capability index for federation and reuse planning. diff --git a/registry/surfaces/surface.infotech.state-hub.api-config.md b/registry/surfaces/surface.infotech.state-hub.api-config.md new file mode 100644 index 0000000..535b54a --- /dev/null +++ b/registry/surfaces/surface.infotech.state-hub.api-config.md @@ -0,0 +1,53 @@ +--- +id: surface.infotech.state-hub.api-config +name: State Hub API configuration +kind: app-config +summary: Runtime configuration for the Custodian State Hub API (bind host/port, database URL, environment mode). +owner: custodian +status: active +scope: + allowed_layers: [product-default, company, environment, installation] + default_layer: company +mutability: startup-time +security_class: operational +schema: + type: object + validator: ~/state-hub/config/schema.json +sources: + - repo: state-hub + path: Makefile + role: product-default + - repo: state-hub + path: .env.example + role: company-baseline +relations: + consumed_by: + - service.state-hub-api + overrides: [] + depends_on_secret: + - state-hub/database-url + related_to: + - surface.infotech.ops-bridge.tunnel-config +evidence: + last_seen: '2026-06-26' + discovery_method: manual + change_log_ref: ATLAS-WP-0002-T01 +--- + +# State Hub API configuration + +The Custodian State Hub API (`http://127.0.0.1:8000`) reads its runtime +configuration at startup: bind host/port, database connection, and environment +mode. This surface **maps** that configuration — it does not duplicate the values. + +- **Source of truth:** the `state-hub` repo (`make api` / `.env`); the database URL + is a secret reference (`depends_on_secret`), never stored here. +- **Precedence:** product defaults in the Makefile, overridden by a company/env + `.env`, optionally per-installation. Startup-time mutability — changes require an + API restart (`make api`). +- **Consumers:** the State Hub API service; related to the ops-bridge tunnel config + that exposes it to remote machines. + +This is a seed example proving the surface-entry schema +([`../../docs/configuration-surface-schema.md`](../../docs/configuration-surface-schema.md)). +The broader Phase 1 seed is ATLAS-WP-0002-T03. diff --git a/schemas/surface-entry.schema.json b/schemas/surface-entry.schema.json new file mode 100644 index 0000000..1008b99 --- /dev/null +++ b/schemas/surface-entry.schema.json @@ -0,0 +1,125 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://config-atlas/schemas/surface-entry.schema.json", + "title": "Configuration Surface Entry", + "description": "Schema for the YAML frontmatter of a config-atlas configuration-surface entry (registry/surfaces/*.md). Records the MAP of a configuration surface: where it lives, who owns it, its kind, scope, and source links. It stores metadata and references only -- never live configuration values and never secret values. See docs/configuration-surface-schema.md and docs/canon-mapping.md.", + "type": "object", + "additionalProperties": false, + "required": ["id", "name", "kind", "summary", "owner", "status", "scope", "mutability", "security_class", "sources"], + "properties": { + "id": { + "type": "string", + "description": "Stable id: surface...", + "pattern": "^surface\\.[a-z0-9-]+\\.[a-z0-9-]+\\.[a-z0-9-]+$" + }, + "name": { "type": "string", "minLength": 1 }, + "kind": { + "type": "string", + "description": "Closed taxonomy. Drives kind-separation.", + "enum": ["app-config", "deploy-config", "secret-ref", "feature-flag", "policy", "tenant-config", "infra-state", "runtime-override"] + }, + "summary": { "type": "string", "minLength": 1 }, + "owner": { + "type": "string", + "description": "Team/agent identity, resolved against domain-tree bindings. Not a person.", + "minLength": 1 + }, + "status": { "type": "string", "enum": ["draft", "active", "deprecated"] }, + "scope": { + "type": "object", + "additionalProperties": false, + "required": ["allowed_layers", "default_layer"], + "properties": { + "allowed_layers": { + "type": "array", + "minItems": 1, + "uniqueItems": true, + "items": { "$ref": "#/$defs/layer" } + }, + "default_layer": { "$ref": "#/$defs/layer" } + } + }, + "mutability": { + "type": "string", + "description": "How the surface may change (delivery stage / blast radius).", + "enum": ["build-time", "deploy-time", "startup-time", "hot-reloadable", "per-request", "emergency"] + }, + "security_class": { + "type": "string", + "enum": ["operational", "sensitive", "secret-ref", "policy"] + }, + "schema": { + "type": "object", + "description": "The CONTRACT for the surface (metadata), not a live value. 'default' is the declared product default, treated as contract documentation.", + "additionalProperties": false, + "properties": { + "type": { "type": "string", "enum": ["string", "integer", "number", "boolean", "object", "array", "enum"] }, + "default": {}, + "enum": { "type": "array" }, + "minimum": { "type": "number" }, + "maximum": { "type": "number" }, + "validator": { + "type": "string", + "description": "Reference to a JSON Schema / CUE file. A pointer, not an inlined value." + } + } + }, + "sources": { + "type": "array", + "description": "Canonical sources, by reference. NEVER inlines a configuration or secret value.", + "minItems": 1, + "items": { + "type": "object", + "additionalProperties": false, + "required": ["role"], + "properties": { + "repo": { "type": "string" }, + "path": { "type": "string" }, + "endpoint": { "type": "string" }, + "role": { + "type": "string", + "description": "The layer contribution this source makes, e.g. company-baseline, environment-overlay, feature-control-key." + } + }, + "anyOf": [ + { "required": ["path"] }, + { "required": ["endpoint"] } + ] + } + }, + "relations": { + "type": "object", + "additionalProperties": false, + "properties": { + "consumed_by": { "$ref": "#/$defs/idlist" }, + "overrides": { "$ref": "#/$defs/idlist" }, + "depends_on_secret": { + "type": "array", + "description": "Secret references only -- ids/paths, never values.", + "items": { "type": "string" } + }, + "related_to": { "$ref": "#/$defs/idlist" } + } + }, + "evidence": { + "type": "object", + "additionalProperties": false, + "properties": { + "last_seen": { "type": "string", "format": "date" }, + "discovery_method": { "type": "string" }, + "change_log_ref": { "type": "string" } + } + } + }, + "$defs": { + "layer": { + "type": "string", + "description": "Shared scope vocabulary (L0-L9 ordering, aligned to ITC-LAND/ITC-ORG and feature-control EvaluationScope). NOT a new set of names.", + "enum": ["product-default", "company", "platform", "environment", "region", "installation", "tenant", "group", "user", "agent", "emergency"] + }, + "idlist": { + "type": "array", + "items": { "type": "string" } + } + } +} diff --git a/workplans/ATLAS-WP-0002-registry-foundation.md b/workplans/ATLAS-WP-0002-registry-foundation.md index 9cb93d0..caedf5f 100644 --- a/workplans/ATLAS-WP-0002-registry-foundation.md +++ b/workplans/ATLAS-WP-0002-registry-foundation.md @@ -38,11 +38,17 @@ blueprint Phases 2–3) will be separate workplans, not tasks here. ```task id: ATLAS-WP-0002-T04 -status: todo +status: done priority: high state_hub_task_id: "e96f00bc-d858-4cfa-be6c-10de8de7b529" ``` +Result 2026-06-26: Authored `docs/canon-mapping.md` mirroring feature-control's +pattern, using real ITC ids (itc-gov/data/devsecops/land/org/access/sec/tag). +Entity + relationship mapping (consume/reference/align/own), read-model surface, +gaps, validation hooks, extension candidates, and ITC artifact references. +Resolves the `(planned)` links in PRD §5 and ecosystem-boundaries §2.3. + Create `docs/canon-mapping.md` mapping config-atlas terms to InfoTechCanon and sibling repos: **consume** ITC-GOV (policy/decision/evidence), ITC-DATA (schema/contract/classification), ITC-DEVSECOPS (delivery/mutability), ITC-LAND @@ -60,11 +66,20 @@ references in PRD §5 and `docs/ecosystem-boundaries.md` §2.3. ```task id: ATLAS-WP-0002-T01 -status: todo +status: done priority: high state_hub_task_id: "125a4ad3-ddd4-4aee-bb94-9433a5fa4651" ``` +Result 2026-06-26: Added `schemas/surface-entry.schema.json` (JSON Schema +Draft 2020-12; `additionalProperties:false` throughout to forbid inline values), +`docs/configuration-surface-schema.md` (fields, kind taxonomy, L0–L9 ordering, +explicit merge rules), and a validating seed entry +`registry/surfaces/surface.infotech.state-hub.api-config.md`. Expanded +`registry/README.md`. Verified: schema is valid Draft 2020-12, the example entry +validates, and a forbidden inline `value` field is correctly rejected. CUE deferred +(PRD open question 4). + Author the machine-checkable surface-entry schema and the layering/merge model. Add `schemas/surface-entry.schema.json` (JSON Schema; evaluate CUE per PRD open question 4) matching the entry shape in ArchitectureBlueprint §3 / PRD §10: