message: 403: {"code":"ENTITLEMENT_ERROR","message":"Error 403: the user is not subscribed to required model plan"}

stop_reason: error


error_message: 403: {"code":"ENTITLEMENT_ERROR","message":"Error 403: the user is not subscribed to required model plan"}


I read this as an independent forensic review of V3-V12 lessons against frozen V13 - I’ll inspect only existing ledgers, sources, and artifacts, compare hashes and closure, and make no edits or migration/runtime calls.


message: WebSocket error


I read this as a forensic V3-V13 continuity judgment - I reconstructed the failure lineage, checked frozen hashes and static execution paths, and made no edits or live calls.

<verdict>FAIL</verdict>

V13 preserves most filesystem/isolation lessons, but it is not authorizable. Exact wheel identity, the startup-constructor path, transitive source closure, V13 rollback rehearsal, and active supersession state are incomplete.

### V3-V12 failure lineage

| Version | Failure learned | Package digest | Principal evidence SHA-256 |
|---|---|---|---|
| V3 | `/proc/1/ns/net` was unreadable; use current namespace `/proc/net` gate | `3fbaea7e19a77a1007e27f3f0a3610a727baeeb2ab7bded1f5301a3da5872dd9` | `v3-live-attempt-1-failure.json` = `28392825e18bffca461af6f0ea3c77e9f6b20b3a100ce7756143e3efa4f9dbd4` |
| V4 | Controller remained disposable/V3-target-bound | `cb18dad93de038d355a6feea866d89cb98be7eb990decab33d2e3154e2222f41` | `v4-rehearsal-blocker-receipt.json` = `9429231b07dba4a44bf58e9435859e4231ee9455e86fbf2ae7143c3ae9f4a27d` |
| V5 | 26,960 hardlinked runtime files were unsafe rollback copy sources | `6033ff140f60822c34e588fefffbf64c6630ea17a8c74f8aa524408b7313cd25` | `v5-rehearsal-blocker-receipt.json` = `e326d0acb1f40b3b36497125adfeabec4f1703ba7bd19e1454964e8f40e70eb2` |
| V6 | Read-only `/tmp`; cleanup followed successor symlinks | `7e2c228a757083fe2f8cebe06b03e854fb40b02fae1b18e30fd471c8d1b187ee` | `v6-rehearsal-blocker-receipt.json` = `22ffce99e7f27b07083af6943fb1ee83ae05a7aa17fe129e706086e36fc7c25e` |
| V7 | Isolated sandbox lacked usable `/dev/null` | `e1dd08b8b0333c462c17feb7f4e13e26ad9f49ab57125c66488570ce07638b42` | `v7-rehearsal-blocker-receipt.json` = `fc54ac3ef542ceeb62bc9df20447ce93e6dfcc1929016c45fd242e597a852942` |
| V8 | `logs/gateway.log` was incorrectly stable | `1835ddff25c2db60a4e2f8ea991f59051a0a3b1c89dcbc6a12f76cd08015c3f5` | `live-transaction-v8-independent-audit.json` = `a978031a9497db1f0edbaa960f8cc330f50affeddf5fbdd4328a22948240a623` |
| V9 | `--clearenv` omitted user-bus location | `f64ffbde677fa0f7413a7e5f0bafbcd9f442e61508b092ed56cb1f099ef2e92b` | `v9-live-attempt-1-failure.json` = `4a7ef0fe624d3fdeb459d309e167a56c9d4c03183dbfbae92776db5e36b6cc58` |
| V10 | Six service-lifecycle files were incorrectly stable | `e6ddec2ecc8802cb6bf94daa39a03672a19c61ae485d5e64ab387fbddb8f30c7` | terminal `9667ff4cd4eb75eb966c2d0ce5fa9f8c483a151d652ff3d4cdae7f92a26918eb`; recovery `cf0a43b88553d096f209da1fa4b232fd1f48721636f407415718719b8a95779b` |
| V11 | Root `state.db-shm` disappears while stopped | `9c2f7bcd06777bca77ea4d1c1d5f55588f6facd04a8eee4d22b3cc6394838ffb` | `v11-terminal-outcome.json` = `ba23bdf16847d099ba1201b5bbab92131ac7718869fd375bbe4bf8b665940aa0` |
| V12 | Transaction committed, but startup failed because canonical weekly authority/operator receipt was omitted | `4627a832bd84bbc8b534deb06019643d74f5e567640fd612fbcd8b8d7690d3a1` | rollback `07a07021d8696925261b017209408b42be6784972493b7ca11041f3d68b5140a`; terminal binding `c77cb0a25e426643818c1c61fbc6f1a198742dfec5bba7e15d5471e3a8a1b44b` |

The authoritative historical directive is at plan lines 823-849: V13 must **create and smoke-test** the complete canonical weekly authority; weakening startup checks is forbidden.

### V13 context matrix

| Constraint | Result | Evidence |
|---|---|---|
| Isolated net/dev/tmp and minimal user-bus environment | PASS | `execute_nutricoach_v150_sealed_live.py`: `--unshare-net`, read-only `/`, tmpfs `/tmp`, isolated `--dev /dev`, `--clearenv`, XDG-only; source SHA `86a14f743e2595f559f9a8235c0da53accb1d1ed61ed61c8da7d63fd6637c0ca`. |
| Hardlink-safe protected inventory | PASS | Snapshot authority copies only four mutable files and rejects `st_nlink != 1`; 86,083 target runtime rows remain verify-only stable inventory. |
| Symlink-safe cleanup | PASS | `runtime_ops.py` skips symlinks during permission normalization and refuses symlink roots before `rmtree`; SHA `a5c8d4534461d1ac48513d02ba308c8d96d0508a92b6351157e7732314e36811`. |
| Volatile logs/lifecycle/runtime state | PASS | V13 snapshot: 124,647 stable and 7,764 volatile rows. All 15 root `logs/` files, six lifecycle files, and `state.db{-shm,-wal}` are volatile; archived DBs remain stable. |
| Immutable consumed authorities | PARTIAL | Actual V10/V11 consumed SHA is `d06d951c...793b`; V12 is `c102a4fd...14d`; V13 copies V12 exactly. Active root supersession state is nevertheless stale, as noted below. |
| Historical rollback receipts | PASS | V10 recovery, V11 rolled-back phase, and V12 postcommit rollback all hash-match frozen copies. |
| V13-delta rollback proof | FAIL | `verification-evidence.json` explicitly says `"rehearsal_executed": false`; the new weekly-authority created paths and constructor path have no exact-chain rollback receipt. |
| Exact wheel identity | FAIL | Current wheel and archive-RECORD hashes match the seal, but the executable path does not enforce them. `install_fresh_runtime()` calculates RECORD/script/import data, `ConcreteLiveHost.install()` discards it at line 177, and `post_fence()` never checks installed identity. Wheel files are outside package inventory and `inspect_package()` does not hash them. |
| Startup constructor | FAIL | The test calls real `TelegramAdapter`, but only after inserting `dualcoach/profile` into `sys.path`. The sealed worker inserts only the project root. Its `.venv` has no `checkin_cli` installation/mapping, while `nutricoach_v150_weekly_authority.py` imports `checkin_cli` at lines 14-23. Static execution therefore reaches an unbound/unavailable import during migration. The transaction plan also contains no constructor-smoke stage, and post-fence checks only systemd/capacity/postimage state. |
| No V13 live side effects | PASS | Both `live-authorization-v13` and `live-executions-v13` are absent; before/after stable, contract, service PID/start identity are equal. |

### Frozen V13 hash and closure check

- Package digest: `25ca8f7708eb5c30d43984af8f73ebeafe191b7faeee37de1e7aead2bf7baae4`
- Permission package SHA: `71c3dd0078ceceda56491ead201f124352394502d28c74c7f5055217984e3614`
- Package manifest SHA: `fb629bba68ce4ccbcea108dc780502946697ce1e97f33a899d344eb9889f1311`
- Controller-source manifest SHA: `accfb84bdb403ae5d564f66376a5241bd3040ab07ef07b2cf3cbbda9c620e656`
- Controller derivation identifier: `7fb5e288a0d14742cc14ef07ab67573aaa8e3e998bcb71246f0a1f47cd164242`
- Protected snapshot SHA: `d2c084be0865f8e9844452a7b683f97800e31af9bc7e1a113241109a283aada5`
- Candidate manifest SHA: `78b2d1790b67cf0d9730cd9a4b0d2d0d3de5bf5f5836e31a70f5be3a62dd7786`
- Wheels:
  - Hermes `5829f799160a7341f5509043c17cecbe5d10cfe25c44eb3f8fde44bbf9720d91`
  - Profile `bdfe94b31d9c98c233301dc2cc552e5e2d672853901bac2bdf73df7e23c709b6`
- Wheel archive RECORDs:
  - Hermes `a605967e550740770bce32161ae7d827cd919f3e50bf232080b1c7bebf672643`
  - Profile `2cd0243514d41ba5d6a01e3e083806c4f22f39cd6e18f579e2264b333f25c6ed`
- Recomputed inventories:
  - 17/17 package entries match; canonical inventory closure `sha256:b67ed645a07e1d706f83aaaf8eb8b95d06e83e619ccd80522ee7c463b3b5a3d5`
  - 43/43 declared source entries match; canonical source closure `sha256:0b4d2c01391e3b3a67d2aa7a8593b1a9541e7532590a8f6484c7c7e09cb651a5`
  - V13 verifier source matches; closure `sha256:4631e9569f0fbe6bdf2bfa7b682622acfdc28bafe64653842cb770dfda78708f`

The declared hashes are internally consistent, but the 43-file source closure is not transitive: the newly execution-relevant `checkin_cli.*` and `gateway.platforms.*` imports are omitted from `controller-source-manifest.json`.

### Blockers and historical evidence gaps

1. **Exact-wheel enforcement is missing from the live controller.**
2. **The startup-constructor path is not present in the transaction fence and is statically unable to resolve `checkin_cli` under the documented sealed interpreter.**
3. **No V13 exact-chain rehearsal, rollback receipt, independent audit, or final verifier receipt exists.** `verification-evidence.json` remains `PASS_BEFORE_FINAL_READ_ONLY_VERIFIER`.
4. **Supersession authority is contradictory.** `sealed-target.json` points to root `package-supersession.json`, SHA `07ec0a085d7b9f36c96effd8536b78a9cd23386896a5fc316a83620a6f1fd3d4`, which still identifies V12 as active. Frozen V13’s intended ledger is SHA `5a5961f4e06451958773373fab16491ed74434f0ba6e367f1512b73428bf3623`.
5. **History ledgers were not synchronized.** `v3-state-ledger.json` SHA `0044870d...5846` records V12 as `IN_PROGRESS` and puts the postcommit startup failure under V11; `debug-journal.md` SHA `ebf2d813...e05a` stops at V10. Only the plan SHA `da3b99b3...ded0` contains the correct V11/V12 lineage and V13 directive.

Review was read-only; no verifier, test, migration, authorization, service, or live transaction was executed.


I read this as a product-contract investigation triggered by the disabled-draft mismatch - I’ll trace the qualified multi-customer semantics through registry, weekly startup, V17 evidence, and V13’s builder/tests, then report every additional missed constraint without changing or executing anything live.


I read this as confirming the disabled-draft contract and widening the audit to adjacent authority semantics - the product contract is unambiguous, and V13 plus the frozen candidate violate it in multiple layers.

<verdict>FAIL</verdict>

## Confirmed product contract

The registry contains:

- 2 total customers
- 1 enabled customer
- 1 disabled draft with consent not granted and no data root
- Registry SHA-256: `bd61ed95f80737ba8013db262fd0242a600e540f43f6627f5b9708a599660b29`

Disabled drafts are legitimate persistent registry members:

- Feature brief lines 71-90: capacity limits **enabled** customers; disabled drafts remain allowed and activation requires separate consent/onboarding/review.
- `RegistryDocument.validate_pilot_customer_boundary()`, lines 1049-1052: disabled entries remain parseable and do not count toward capacity.
- `customer_admin._register_customer_locked()`, lines 670-713: onboarding deliberately appends a disabled draft.
- Existing tests:
  - `test_registry_loads_one_enabled_customer_with_disabled_history`
  - `test_register_customer_allows_multiple_disabled_drafts`
  - `test_disabling_latest_customer_preserves_other_customer_receipt`

Relevant source hashes:

- Feature brief: `005295dd0af03b598a481259a1ef231916d01b4dfb8c980f60c24d525b51da2a`
- `customer_coaching.py`: `1a75a6b6f6063fd12b991dda09cd20e6c7d452227525666bc986787ef9be2f51`
- `customer_admin.py`: `dd9a1e957ef92e4948043f49e6b038e9498311173345721d53665c92cd4bdde0`

Correct weekly semantics are therefore:

1. Preserve and identity-bind every registry row.
2. Derive `enabled_customer_keys` exclusively from `spec.enabled`.
3. Register/open weekly capabilities only for those enabled keys.
4. Never require consent, authority sidecars, or existing data roots from disabled drafts.
5. Enabling a draft changes registry identity and requires a fresh customer activation and weekly authority.

## Three independent disabled-draft failures

### 1. Migration builder rejects the valid registry

`scripts/nutricoach_v150_weekly_authority.py:133-141`:

```python
enabled = tuple(... if runtime.spec.enabled)
customer_keys = tuple(...)
if len(customer_keys) != len(registry.customers):
    raise HostError("weekly_authority:disabled_customer_startup_contract")
```

This directly rejects the live 2-total/1-enabled state.

### 2. Frozen candidate startup bootstrap also rejects it

The exact candidate wheel contains:

```python
by_key = {runtime.spec.customer_key: runtime for runtime in registry.customers}
if set(by_key) != set(enabled_customer_keys):
    raise WeeklyReminderStartupAuthorityIncident(...)
```

Reference:

- `gateway/platforms/nutrition_weekly_reminder_bootstrap_customers.py:94-98`
- Frozen wheel member SHA: `59e51e8af24ec382d93082150cf7b8f400327d7ef6c9ffaa91d2ecf8794cf7ad`

Therefore removing only the migration-builder guard would not repair startup.

### 3. Frozen candidate owner verification rejects it again

The exact wheel’s `WeeklyReminderAuthorityOwner.verify_registry()` builds `current` from **all** registry customers and requires equality with the enabled capability map.

- Frozen wheel member SHA: `e40ce28b674a4b36d501043a912adc8efda7dd8d0014126230aa639b973d4ddc`
- Candidate snapshot contains the same bytes.

Current working source appears partially repaired to filter `if item.spec.enabled`, but that source is not in the frozen wheel. The candidate wheel remains defective.

## Consequence

This cannot be repaired by resealing only the V13 migration controller. The installed candidate itself must change, requiring:

- rebuilt Hermes wheel;
- new wheel SHA and RECORD identity;
- new full-product candidate digest;
- renewed qualification;
- new controller/source closure;
- fresh preflight snapshots, rehearsal, audit, package digest, and authorization.

## Other missed constraints

### A. Frozen V13 closure is already stale

At inspection time, two declared controller-source hashes differ:

| Path | Frozen expected | Current |
|---|---|---|
| `scripts/nutricoach_v150_weekly_authority.py` | `f2cd4f9fadfa655b0083ce7ced10c527834adff9df5592c30a530691f579f78d` | `d2b9f5fcfb09d7774303c64b0c705e8c652e50e78d63f834a5473d93b0fcd379` |
| `tests/test_nutricoach_v150_weekly_authority.py` | `996706f115427ce38eca5bc023ba9b5eb8507a2523cfc24e5ba37cb8f5e451b1` | `dbd66034b758cecb03f958f565173041ca07f1dba2efed3c5eeb07508e041ada` |

The detached bootstrap would now deny this preseal before mutation.

### B. The new disabled-draft regression is not live-shaped enough

The current unfrozen test clones the enabled customer and changes only `enabled=False`. The actual disabled draft has:

- `consent_granted=False`
- no data root

The regression must prove that startup never opens, consent-checks, registers, or requires storage for such a draft.

### C. One consent digest cannot represent capacity-five customers generally

`WeeklyOperationsAuthorityReceipt` carries one `consent_digest`, and builder/startup require every enabled customer to match it. Consent includes each customer’s independent `recorded_on` value.

Nothing in the product contract requires multiple customers to have identical consent dates. Capacity-five weekly authority therefore needs either per-customer consent bindings or separate per-customer receipts.

This is latent for the current one-enabled state but incompatible with the qualified multi-customer contract.

### D. Authority expiry is not fenced before reservation

V13 hard-codes:

- issued: `2026-08-27T00:00:00+09:00`
- expires: `2026-09-30T23:59:59+09:00`

Runtime ticks enforce expiry, but package inspection, startup construction, and transaction post-fence do not reject an expired receipt before reservation. A delayed execution could commit a service whose weekly authority is immediately inactive.

### E. Exact startup proof remains absent

The transaction still lacks a post-migration constructor/tick fence through the installed successor interpreter. V13 evidence explicitly records `"rehearsal_executed": false`.

A valid successor must prove before commit:

- exact enabled-key projection;
- disabled rows unchanged;
- real installed `TelegramAdapter` constructor;
- weekly owner construction;
- at least one authorization snapshot at the sealed current time;
- zero provider/Telegram/customer events.

No files were edited and no tests, migration, service action, or live transaction were executed.