generated from coulomb/repo-seed
feat(connectors): complete ATLAS-WP-0003 — discovery connectors (Phase 2)
Some checks failed
validate-registry / validate (push) Has been cancelled
Some checks failed
validate-registry / validate (push) Has been cancelled
T01 connector_base + docs/discovery-connectors.md (read-only/stateless, candidate->PR->promote; `candidate` added to schema status enum; candidates/ gitignored, excluded from gate). T02 connector_reposcoping (repo-scoping facts -> candidates; graceful degrade). T03 connector_gitconfig (deterministic scan; real .env -> secret-ref, no values; verified 4 real candidates from ~/state-hub). T04 connector_featurecontrol (feature-flag surfaces linking to feature-control keys, no eval logic; FR-12). T05 registry_health (unowned + stale detection). Make targets: connect-gitconfig/reposcoping/featurecontrol, registry-health. WP-0003 finished (5/5). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
68
docs/discovery-connectors.md
Normal file
68
docs/discovery-connectors.md
Normal file
@@ -0,0 +1,68 @@
|
||||
# Discovery Connectors
|
||||
|
||||
**Status:** draft
|
||||
**Updated:** 2026-06-27
|
||||
**Repo:** config-atlas
|
||||
**Workplan:** ATLAS-WP-0003 (Phase 2)
|
||||
**Related:** [`../specs/ArchitectureBlueprint.md`](../specs/ArchitectureBlueprint.md) §4/§6,
|
||||
[`ecosystem-boundaries.md`](ecosystem-boundaries.md) §2.4,
|
||||
[`configuration-surface-schema.md`](configuration-surface-schema.md)
|
||||
|
||||
Connectors grow the surface registry from **automated discovery** instead of only
|
||||
hand authoring — reusing `repo-scoping`'s scanner → candidate → approval model
|
||||
rather than building bespoke approval machinery.
|
||||
|
||||
## Contract
|
||||
|
||||
A connector **MUST**:
|
||||
|
||||
- be **read-only and stateless** — never write a source system, never auto-merge;
|
||||
- **never read or store configuration values or secret values** — record file
|
||||
*locations* and key/flag *identities* only;
|
||||
- emit **candidate** surface entries (`status: candidate`) with provenance in
|
||||
`evidence.discovery_method = connector:<name>`;
|
||||
- produce **schema-valid** entries (validated by `connector_base.emit_candidate`);
|
||||
- **never overwrite a promoted entry** — if an id already exists under
|
||||
`registry/surfaces/*.md`, the candidate is skipped (the registry is truth).
|
||||
|
||||
Connectors **propose**; humans/agents **dispose**.
|
||||
|
||||
## Candidate lifecycle
|
||||
|
||||
```text
|
||||
connector -> registry/surfaces/candidates/<id>.md (status: candidate)
|
||||
-> PR review (human or trusted agent)
|
||||
-> promote: move to registry/surfaces/<id>.md (status: draft|active),
|
||||
add row to registry/indexes/surfaces.yaml, set a real owner
|
||||
-> or reject: delete the candidate
|
||||
```
|
||||
|
||||
Candidates live in `registry/surfaces/candidates/` and are **excluded** from the
|
||||
promoted-entry validation/index gate (`tools/validate_registry.py` globs
|
||||
`registry/surfaces/*.md` non-recursively), so unreviewed candidates never become
|
||||
registry truth or break the index. The candidates directory is **gitignored** —
|
||||
candidates are ephemeral connector output; **promotion** moves an entry into the
|
||||
tracked `registry/surfaces/` and `surfaces.yaml`.
|
||||
|
||||
## Connectors
|
||||
|
||||
| Connector | Source | Emits | Command |
|
||||
|-----------|--------|-------|---------|
|
||||
| `git-config` | repo config files (`*.env.example`, `values*.yaml`, `config*.yaml`); real `.env` → secret-ref | app/deploy/secret-ref candidates | `make connect-gitconfig REPO=<slug>` |
|
||||
| `repo-scoping` | repo-scoping observed facts (`--facts` file or `REPO_SCOPING_URL`) | app-config candidates | `make connect-reposcoping REPO=<slug>` |
|
||||
| `feature-control` | feature-control key registry (`--keys` or its index) | feature-flag candidates (link only) | `make connect-featurecontrol` |
|
||||
|
||||
All degrade gracefully (emit nothing) when their source is unavailable.
|
||||
|
||||
## Health
|
||||
|
||||
`make registry-health` (`tools/registry_health.py`) reports **unowned** surfaces
|
||||
(missing owner, or owner not resolvable to a known identity) and **stale** surfaces
|
||||
(`evidence.last_seen` older than the threshold). Ownership resolution currently
|
||||
uses the reuse-surface roster as a stand-in until `domain-tree` binding is wired.
|
||||
|
||||
## Boundaries
|
||||
|
||||
Connectors reuse `repo-scoping`'s discovery model and never duplicate it; the
|
||||
`feature-control` connector **links** to feature-control keys and never re-derives
|
||||
evaluation logic (PRD FR-12). See [`ecosystem-boundaries.md`](ecosystem-boundaries.md).
|
||||
Reference in New Issue
Block a user