# mgf-secrets

> **The Magogi Foundation credential plane.** Phase 1: the committed **registry**
> (every credential declared, no values) and a read-only **doctor** that proves
> *declared == deployed == consumed* across every surface — Woodpecker scopes,
> forge deploy keys, local `my_stuff/` caches, and on-host files. Stdlib-only.
> Sibling of `mgf-common` under the `mgf.*` namespace.

Secrets in the Foundation live in five unmanaged planes (plaintext `my_stuff/`,
one shared Woodpecker org pool, forge deploy keys, root-600 host files,
doc-prose), and every failure class has already fired in production — always as
*silent drift*. `mgf-secrets` applies the pattern the estate already trusts:
**declare → reconcile → verify → page on drift.** This repo is Phase 1 of that
program: **the registry + the read-only doctor.** No values are stored, encrypted,
or synced yet (that is P2+); nothing here writes to any secret, host, Woodpecker,
or forge state.

## What it does (P1)

- **Registry** — `SECRETS.toml` in `mgf-standard` (family `mgf` + shared infra)
  and `sooth-standard` (family `sooth`). One entry per credential: `kind`,
  `surfaces[]`, `policy`, `rotation`, `verify`, `recovery`, `state`. The loader
  **fails closed**: a missing field, an unknown kind/surface/state, a duplicate id
  across families, or a `held` entry marked armed is a load error (exit 2).
- **Doctor** (`mgf-secrets doctor`) — read-only checks C1–C8: Woodpecker
  declared↔actual scopes, consumed↔declared (the CIR-02 audit, ported for
  parity), unregistered-actual (the steward-class detector), held discipline
  (the CIR-33 inversion), forge deploy-key coverage (CIR-34), local hygiene
  (modes, doc-form files, expired JWTs, `.bak`/`old_*` leftovers, gitignore), and
  host-file perms. Human table + `--json`.
- **Probes** (`mgf-secrets probe <id>`) — a per-kind, non-destructive liveness
  check.
- **`list` / `show`** — the registry as a table / full metadata (never a value).

Exit codes: `0` clean · `1` findings · `2` usage / credential / load error.

## Usage

```sh
mgf-secrets list [--family mgf|sooth] [--kind KIND] [--state STATE] [--json]
mgf-secrets show <id> [--json]
mgf-secrets doctor [--surface woodpecker|forge|local|hosts]… [--json]
mgf-secrets probe <id> [--json]
```

Default doctor surfaces are `woodpecker` + `local`; `forge` and `hosts` are opt-in
(the forge sweep respects the Codeberg rate budget, PAPER-110). The Woodpecker
token comes from `$WOODPECKER_TOKEN` → `mgf-standard/my_stuff/woodpecker_token.txt`
(mint per `MGF_INFRA.md` §2 on a 401). The registry resolves sibling checkouts from
`$MGF_ROOT` (default `~/PycharmProjects`).

## Security posture (AG-18)

Secret **values never enter** this tool's context, output, transcripts, or logs.
`show` and `list` are metadata-only; `doctor` C6 decodes a JWT `exp` in-process and
emits only the integer. The redaction property test drives the whole CLI with
planted canaries and asserts their absence.

## Non-goals (P1)

No store/encryption, no `sync`, no value-printing verbs, no rotation, and no
mutation of any secret, host, Woodpecker, or forge state — Phase 1 is strictly
read-only against the world. See the program proposal for the phase table.
