I read this as a root-cause implementation task across the profile and Hermes - I’ll reproduce the 11 RED cases, trace the existing reconciliation flow, implement the shared deterministic compiler contract, and run the full requested verification without touching unrelated workspace state.


The RED failures converge on one root cause: provider-authored clarifications still own lifecycle state. I’ve finished tracing both seams and am replacing that ownership with a profile-level compiler, then wiring preview, persistence, publication reload, and revision binding to its typed output.


The authoritative suite is now GREEN (11/11). I’m moving into regression verification: profile onboarding suites and Hermes reconciliation/onboarding gateway suites first, then I’ll fix only contract regressions introduced by this change before static checks and manual malicious-provider QA.


Static/runtime verification is clean for the new contract (focused suite, ruff, compileall, manual QA). The broader repositories still contain legacy tests that explicitly require provider prose and provider-selected clarification kinds; those contradict the new source-of-truth contract, so I’m taking one final exact regression count rather than adding compatibility behavior that would reintroduce the vulnerability.


I read this as a completed source implementation task - reporting the RED-to-GREEN result, contract, verification, and remaining incompatible legacy tests.

Implemented a deterministic 22-field clarification compiler shared by production and preview.

### Changed files

Profile:
- `checkin_cli/nutrition_onboarding_clarification_policy.py` — new
- `checkin_cli/nutrition_onboarding_reconciliation.py`
- `checkin_cli/nutrition_onboarding.py`

Hermes:
- `gateway/platforms/telegram_nutrition_onboarding_copy.py`
- `gateway/platforms/telegram_nutrition_onboarding_preview_completion.py`
- `gateway/platforms/telegram_nutrition_onboarding_runtime_publication.py`
- `gateway/platforms/telegram_nutrition_onboarding_runtime_callback.py`
- `gateway/platforms/telegram_nutrition_onboarding_runtime_collection.py`

### Contract delivered

- Compiler exclusively owns canonical issues, holds, IDs, reason codes, copy, ordering, complete issue set, and three-item visible slice.
- Provider clarifications and question prose are discarded before persistence/publication.
- Unrelated advisory metadata remains stored separately.
- Production reloads the committed record before rendering.
- Preview uses the same compiler and cannot expose provider questions.
- Sensitive disclosures create holds only.
- Revision replies bind exact field, issue ID, answers digest, and reconciliation digest.
- Unbound owner revision is no longer published.
- Revision recomputes the complete issue set before applying the visible cap.
- Natural Korean fixture canonicalization added at the Hermes boundary.
- Existing typed baseline validation remains the broad validator.

### Verification

Authoritative suite:

- RED: **11 failed**
- GREEN: **11 passed in 0.25s**

Manual production/preview QA with all 22 natural Korean inputs plus malicious provider output:

```text
production 0 0 0 True
preview 0 0 0 True
phases resolved confirming
```

The values are issue count, hold count, visible count, and provider-question absence.

Other checks:

- Ruff: **passed**
- Compileall: **passed**
- Basedpyright: **0 errors, 339 warnings**; warnings are existing dynamic-mixin/type-stub diagnostics and cause its strict warning configuration to exit nonzero.

### Legacy regression suites

Profile onboarding suites: **110 passed, 2 failed**.
Gateway onboarding suites: **106 passed, 10 failed**.

These failures assert the superseded behavior: persisting provider-selected clarification kinds/questions, displaying provider summaries, accepting unbound revisions, or using provider clarifications in preview. Making them pass would directly violate the new committed contract; tests were not weakened or deleted.

Source is ready. No wheels, deployment, Git, service, plan, todo, or evidence operations were performed.


I read this as completing the migration by rewriting the 12 contradictory legacy tests around the deterministic contract, while treating any newly exposed behavior mismatch as a production regression and then running every requested suite and checker to green.


I read this as a priority hardening change before the legacy-test migration - I’ll make compilation exhaustive and date-explicit, map boundary and cross-field failures to exact canonical fields, add the four targeted profile tests, then resume the 12-test contract migration only after those invariants pass.


The audit findings were real. The compiler now evaluates every field despite other failures, treats malformed sensitive inputs as issues, uses field-local issue identity, persists an explicit reference date/compiler digest, sanitizes advisory data, and no longer depends on provider availability. I’ve added focused RED coverage for those cases and am now using the related suites to distinguish remaining obsolete assertions from genuine regressions.


All focused and related behavioral suites are now green: 127 profile tests and 138 gateway tests. The one suite-exposed defect was a real QA-preview replay bug where the fixed reference date was lost before clarification publication; production was corrected and the targeted test now passes. I’m at final static verification and exact change accounting.


I read this as final completion reporting - all deterministic-policy, audit, legacy migration, and verification work is now green.

Implemented all audit hardening:

- Exhaustive per-field issue compilation with deterministic precedence.
- Explicit cross-field mappings and loss/gain target-direction checks.
- Explicit persisted `reference_date` and compiler digest for replay stability.
- Malformed sensitive values produce issues; only valid disclosures produce holds.
- Recursive structured-item ambiguity detection.
- Exact canonical types and field-local stable issue IDs.
- Provider failure cannot block production or preview compilation.
- Provider advisory storage is reduced to status and digest.
- Owner revisions require valid SHA-256 digests and a current visible matching issue.
- Boundary parsing rejects substring matches, contradictions, and multiple values.
- Preview retains one reference date throughout its session.

### Changed tests

Profile:
- `tests/test_nutrition_onboarding.py`
- `tests/test_nutrition_onboarding_clarification_policy.py` — new

Hermes:
- `tests/gateway/test_nutrition_onboarding_clarification_policy.py`
- `tests/gateway/test_nutrition_onboarding_reconciliation.py`
- `tests/gateway/test_telegram_nutrition_onboarding.py`
- `tests/gateway/test_telegram_nutrition_onboarding_preview.py`
- `tests/gateway/test_telegram_nutrition_onboarding_preview_runtime.py`

### Classification of the original 12 failures

All 12 were obsolete authority expectations:

1–2. Provider-selected equation-basis clarification kinds persisted.
3. Provider advisory summary rendered as authoritative.
4. Provider-authored production question rendered.
5. Clarification revision accepted without exact issue/digest binding.
6. Restart resumed provider clarification cursor/list.
7. Mocked stale refresh rendered provider summary.
8. Real stale refresh rendered provider summary.
9. Owner revision used the first-field fallback.
10. Preview gave provider ambiguity precedence.
11. QA preview rendered provider-authored question.
12. Final preview rendered provider summary.

The owner-card test was additionally updated to verify that an unbound revision action is not published.

Real regressions found and fixed separately:

- Activity substring matching.
- Provider availability controlling policy execution.
- Sensitive malformed-input suppression.
- Incomplete mixed issue sets.
- Ambient-date replay drift.
- QA preview losing its fixed reference date before publication.

### Green verification

- Focused gateway policy file: **14 passed** — original 11 plus 3 audit regressions.
- Profile policy hardening file: **15 passed**.
- Full requested profile onboarding suites: **127 passed**.
- Full requested gateway onboarding/reconciliation suites: **138 passed**.
- Ruff: **passed**.
- Compileall: **passed**.
- Configured `ty check` over all changed production files: **passed, zero diagnostics**.

A raw strict scan of legacy test-double-heavy files still reports pre-existing mock typing diagnostics; the project’s configured CI checker handles those differentially with `--exit-zero`. No production diagnostics or behavioral failures remain.

No build, deploy, live, evidence, Git, plan, or todo operations were performed.


I read this as a final four-case expectation migration only - I’ll update the scalar canonicalization assertions from floats to decimal strings, run the exact 152-test glob, and report the source-resolving `ty` command without touching production.


I read this as final verification reporting - the four canonical string expectations are updated and the broader glob is green.

Changed only:

- `tests/gateway/test_telegram_nutrition_onboarding_copy.py`
  - `180cm` / `180 cm` → `"180"`
  - `80kg` → `"80"`
  - `75 kg` → `"75"`

Verification:

```text
152 passed in 1.36s
```

Source-resolving type gate used before wheel build:

```bash
cd /home/cube/projects/richard/hermes-agent
.venv/bin/ty check \
  --python .venv \
  --extra-search-path /home/cube/.cache/task26-strict-successor-1786976146/src-p \
  gateway/platforms/telegram_nutrition_onboarding_copy.py \
  gateway/platforms/telegram_nutrition_onboarding_preview.py \
  gateway/platforms/telegram_nutrition_onboarding_preview_completion.py \
  gateway/platforms/telegram_nutrition_onboarding_preview_flow.py \
  gateway/platforms/telegram_nutrition_onboarding_preview_publication.py \
  gateway/platforms/telegram_nutrition_onboarding_preview_types.py \
  gateway/platforms/telegram_nutrition_onboarding_runtime_publication.py \
  gateway/platforms/telegram_nutrition_onboarding_runtime_callback.py \
  gateway/platforms/telegram_nutrition_onboarding_runtime_collection.py \
  /home/cube/.cache/task26-strict-successor-1786976146/src-p/checkin_cli/nutrition_onboarding.py \
  /home/cube/.cache/task26-strict-successor-1786976146/src-p/checkin_cli/nutrition_onboarding_reconciliation.py \
  /home/cube/.cache/task26-strict-successor-1786976146/src-p/checkin_cli/nutrition_onboarding_clarification_policy.py \
  /home/cube/.cache/task26-strict-successor-1786976146/src-p/checkin_cli/nutrition_onboarding_clarification_rules.py
```

This invocation passed with zero diagnostics. No remaining failures.