I read this as an advisory security architecture review - I’ll trace the credential-evidence contracts end to end, compare fail-closed designs, and recommend or reject the no-rotation alternative without changing anything.


I read this as a security architecture decision - I’ll finish the end-to-end contract trace, compare viable designs, and give a fail-closed recommendation without changing anything.


I read this as a security architecture decision - I’ll state whether no-rotation evidence is acceptable and the exact fail-closed contract required.

## Decision

**Reject a direct replacement today.** The current system must continue requiring `token_rotated: true`.

**Approve a future no-rotation alternative only as a versioned, detached, independently signed and validated receipt.** It must establish observable credential controls and continuous provenance; it must not claim to cryptographically prove that a token was “never exposed.”

For the existing token, no dedicated provenance or credential-hygiene receipt exists. Repository scans, private file permissions, operator assertions, and a successful `getMe` call cannot retrospectively prove non-exposure. Therefore the present activation choices are:

1. rotate under the existing contract; or
2. implement the versioned receipt authority first, then generate fresh qualifying evidence.

Until then, remain disabled.

## End-to-end contract findings

- `customer_admin.py` is the activation authority. Its G5 validator requires six fields, including unconditional `token_rotated is True`.
- The current checklist envelope is permissive: evidence may appear under `checklist`, `evidence`, or at top level, while profile/customer bindings are optional.
- Activation stores only the resolved checklist **path** in its journal and audit record—not the checklist digest or its credential evidence.
- Subsequent `validate_committed_activation()` checks journal versions 1/2, registry state, audit linkage, paths, and nutrition readiness, but does not reread or hash the checklist.
- `dualcoach_activation_cutover.py` invokes the target profile’s local `customer_admin`, validates the committed activation, and only then transitions bootstrap to active. Consequently, credential evidence must be committed by `customer_admin`; a gateway-only check is insufficient.
- Telegram startup provides useful controls:
  - token-scoped local process locking;
  - duplicate-token rejection among profiles served by one multiplexer;
  - authenticated startup identity through `getMe`;
  - in-process bot-identity pinning.

  These do not prove historical secrecy. Duplicate detection is not global, and the pinned identity is not compared with a persisted, independently approved expected identity.
- The current target profile’s `.env`, `config.yaml`, and `auth.json` are regular owner-owned `0600` files under `0700` profile directories. That supports present storage hygiene but says nothing about earlier copies, shell history, logs, backups, screenshots, or disclosure.
- Persisted Task23 evidence uses the legacy `token_rotated: true` shape.
- The production successor remains bound to full candidate digest `4e9962be49b72951c3b9ed7e1a4fe36d0ca03e757872ae03364c1ab7a790f32b` and wheel digest `33688875a0d1ce20955bd8272257ee34d84cb138f6a23a43e5d16682368ae5e5`; its live boundary still records the customer and delivery as disabled.

## Designs considered

### 1. Structured no-rotation object inside the checklist

Example:

```json
{
  "credential_hygiene": {
    "method": "retained_unexposed",
    "storage_private": true,
    "scan_passed": true,
    "get_me_passed": true
  }
}
```

**Reject.**

It is still self-attestation, remains mutable after activation, lacks durable digest binding, and is not independently validated downstream. It would be weaker than the stated security goal.

### 2. Detached credential-hygiene receipt committed as activation authority

A dedicated command performs the bounded read-only probe and local checks. `customer_admin` independently validates the receipt, recomputes local bindings, and commits its digest in a new journal version and audit record.

**Recommend.** This is the smallest design that can fail closed across preflight, activation, restart, and cutover.

It is acceptable only when backed by issuance-time provenance or an independently approved exposure review. Without that provenance, the no-rotation branch remains unavailable.

### 3. External secret-manager provenance chain

Create or rotate the token directly into an approved secret manager, maintain immutable version/access logs, inject it without operator-controlled intermediate storage, and have an external authority sign the resulting provenance.

**Strongest prospective design**, but operationally larger. It cannot retrospectively establish provenance for an existing unmanaged token.

## Recommended checklist union

New activations should use an exact, discriminated schema:

```json
{
  "schema": "g5-activation-checklist-v2",
  "credential_hygiene": {
    "method": "rotation",
    "token_rotated": true
  }
}
```

or:

```json
{
  "schema": "g5-activation-checklist-v2",
  "credential_hygiene": {
    "method": "no_rotation_receipt",
    "receipt_path": "...",
    "receipt_sha256": "..."
  }
}
```

Rules:

- exactly one method;
- no fallback between methods;
- `token_rotated: false` is always invalid;
- no bare boolean in v2;
- unknown method or field fails;
- receipt path must be within the profile’s private receipt directory;
- the receipt digest must be persisted in both the activation journal and audit record.

## Smallest qualifying receipt

The receipt needs these authoritative bindings:

```json
{
  "schema": "telegram-credential-hygiene-receipt-v1",
  "receipt_id": "...",
  "issued_at_utc": "...",
  "expires_at_utc": "...",
  "profile_authority_sha256": "...",
  "customer_key": "...",
  "full_candidate_sha256": "...",
  "wheel_sha256": "...",
  "activation_authority_sha256": "...",
  "config_sha256": "...",
  "credential_hmac_sha256": "...",
  "approved_bot_identity_sha256": "...",
  "observed_bot_identity_sha256": "...",
  "protected_pre_sha256": "...",
  "protected_post_sha256": "...",
  "storage_policy": "posix-private-v1",
  "other_profile_matches": 0,
  "probe": {
    "kind": "telegram.getMe",
    "result": "authenticated",
    "read_only": true
  },
  "effects": {
    "messages_sent": 0,
    "updates_consumed": 0,
    "webhooks_changed": 0,
    "registry_mutations": 0,
    "service_actions": 0
  },
  "provenance_receipt_sha256": "...",
  "exposure_review_sha256": "...",
  "signer_key_id": "...",
  "signature_ed25519": "..."
}
```

The token itself, Telegram IDs, username, routes, and other secrets must not appear. `credential_hmac_sha256` should use a domain-separated verifier-held key rather than an unkeyed token hash.

## Fail-closed validation rules

1. Require the exact schema and key set; reject unknown, missing, null, or incorrectly typed values.
2. Require canonical receipt hashing and a valid signature from a trusted release authority distinct from the generating process. If that independence is unavailable, require rotation.
3. Require:
   - issue time no more than 60 seconds in the future;
   - expiry no more than 15 minutes after issue;
   - activation consumption within that window.

   Expiry governs initial consumption, not the lifetime of an already committed activation.
4. Bind the receipt to:
   - exact profile authority;
   - customer key;
   - full candidate and wheel;
   - the exact profile-local `customer_admin.py` loaded by cutover;
   - relevant configuration;
   - current credential commitment;
   - separately approved expected bot identity.
5. Recompute storage properties:
   - expected `.env` path;
   - regular file, no symlink or hardlink;
   - service owner;
   - exact `0600`;
   - private parent chain;
   - no granting ACL;
   - unknown filesystem metadata is failure.
6. Require authenticated `telegram.getMe`, with observed identity digest exactly equal to the independently approved identity digest. Timeout, malformed response, changed identity, or ambiguous result fails.
7. Inspect every configured profile, not merely active multiplex profiles. Require zero other credential matches; unreadable or unenumerable profile scope fails.
8. Require pre/post protected snapshots to match, and recompute the current snapshot immediately before activation while holding a credential/config lock shared by all trusted writers.
9. Require a signed provenance record covering issuance or last rotation through receipt generation. A scan result or operator statement alone is insufficient.
10. Record the human review separately as **“no known exposure found within the reviewed scope.”** Its signature identifies accountability but does not convert the negative claim into cryptographic proof.
11. Consume each receipt ID once. Persist its digest in a new activation journal version, recommended `version: 3`, and in the audit record.
12. On later committed-activation validation, verify the immutable receipt linkage and current local credential/config commitment.
13. At gateway startup, perform a fresh authenticated `getMe` and compare its identity with the committed receipt before serving an enabled customer.
14. Any missing evidence, mismatch, replay, stale receipt, unsafe path, unknown outcome, or changed state blocks activation.

## Legacy evidence

- Keep journal versions 1 and 2 readable exactly as they are.
- Preserve already committed `token_rotated: true` evidence without rewriting or reinterpretation.
- Do not treat legacy `token_rotated: true` as a no-rotation receipt.
- Do not invalidate immutable historical journals merely because v3 exists.
- New activations should use the exact v2 checklist union and v3 journal.
- If a legacy activation needs stronger forward assurance, append a separately linked migration/overlay receipt; never mutate its historical activation transaction.

## Bottom line

A no-rotation receipt can become a valid **alternative control**, but only prospectively with durable provenance, independent validation, one-time consumption, committed digest linkage, and startup identity enforcement. The current repository has none of that, so accepting `token_rotated: false` now would be fail-open.

This was a static, local review only: no files or services were changed, and no network or Telegram calls were made. One read-only `git status` attempt was made from a non-repository directory and failed immediately; no Git state was accessed or modified.