I read this as a read-only provenance reconstruction - I’ll trace the candidate and delivered bundle through ledgers, receipts, scripts, manifests, caches, and Git history, then report an exact ordered pipeline or a file-backed impossibility.


The target is a later delivery than the previously audited `09a669...` bundle. I’ve confirmed the v1.1 worktree is intentionally dirty on top of the frozen v1.0 commit; I’m narrowing the trace to the v38 delivery, its ledger row, and the scripts that generated its candidate graph.


The provenance is reconstructible, but not as a single checked-in command: Phase 1 was generated through `/tmp` script transformations, and Phase 2 was reconstructed from an earlier child session into three transient Python programs that were then deleted. I’ve recovered those exact tool-call bodies from the session JSONL; I’m now separating reproducible inputs from stale paths and identifying what must be rebound for v1.1.


I read this as a read-only provenance reconstruction - I traced the complete historical pipeline and identified the exact rebindings and blockers for a v1.1 successor.

## Verdict

The v38 pipeline is reconstructible from primary evidence and session tool calls. It was **not a checked-in release script**: Phase 1 and Phase 2 were assembled in `/tmp`, executed, then deleted.

The historical pipeline is deterministic, but it **cannot be rerun unchanged** against `/home/cube/projects/richard/hermes-agent-dualcoach-v1.1` because that repository does not contain the build helper, Task26 qualification scripts, or Task26 tests used by v38. A successor is possible only by explicitly rebinding those preserved tools and recording those rebindings; reusing old receipts or silently pointing at the old dirty worktree would invent provenance.

No files were modified.

## Candidate derivation rule

Candidate identity is:

```python
candidate_digest = sha256(
    json.dumps(
        derivation_inputs,
        ensure_ascii=False,
        sort_keys=True,
        separators=(",", ":"),
        allow_nan=False,
    ).encode()
).hexdigest()
```

Evidence:

- `gateway/platforms/task26_candidate_derivation.py:59-66`
- `gateway/platforms/task26_candidate_derivation.py:114-198`
- `gateway/platforms/task26_candidate_derivation.py:201-214`

The exact derivation inputs are:

```json
{
  "schema": "task26-preexecution-product-derivation-inputs-v1",
  "generation": 1,
  "hermes_wheel_sha256": "...",
  "profile_wheel_sha256": "...",
  "wheelhouse_inventory_sha256": "...",
  "wheelhouse_entry_count": 107,
  "trust_boundary_sha256": "...",
  "qualification_tool_sha256": {
    "... 18 exact tool hashes ...": "..."
  },
  "hermetic_ty": {
    "schema": "task26-preexecution-hermetic-ty-binding-v2",
    "corrected_ty_wheel_sha256": "...",
    "ty_version": "0.0.21",
    "target_python_version": "3.12",
    "qualification_interpreter_role": "selected_qualification_python",
    "ty_command_argv": [
      "sealed-ty",
      "check",
      "gateway/platforms/nutrition_coaching.py",
      "--output-format",
      "gitlab",
      "--python-version",
      "3.12"
    ],
    "binary_member": "ty-0.0.21.data/scripts/ty",
    "binary_member_sha256": "...",
    "builder_tool_sha256": "...",
    "runner_tool_sha256": "..."
  }
}
```

The 18 bound tools are enumerated at `task26_candidate_derivation.py:23-42` and resolved at lines 81-111.

For v38, these inputs produced:

```text
candidate              d1109d8f78aaccf949ec4f664d9e62584c3cca33032030518bc3e2d712239112
Hermes wheel           f8b3c779c58435dd33f8f9bbc89e9823bd09f81367a27366c6d678270c1860b1
profile wheel          a56da2417df0912f3fe407c0b78befd7362207d1c8a35271000af46701ba79d2
corrected Ty wheel     932d4552233cfbaa325ddc3db5982150a37f437cf94a332eb3869052148bfe4c
wheelhouse inventory  b7cab3f2f8ed09e552c77640d3f4b364fa8aba22dc524b50854a74050bfe13f4
trust boundary         1273abc223a8f1eb6d4adb5178d5ab466d68bbcc365b33364cf6d7ef602410c6
product binding file  72fa416b447c48327993ab03482892572104887acef4b64eac98285d2d4e0e48
```

A TTL-only change therefore creates a new candidate through the **new Hermes wheel hash**. The candidate is not a Git commit hash and does not directly include Git status.

## Historical roots and required tools

Historical Phase 1 used:

```bash
G=/home/cube/projects/richard/hermes-agent
P=/home/cube/.cache/task26-strict-successor-1786976146/src-p
V36='/home/cube/projects/richard/traning coach/.omo/evidence/task26/task26-combined-prefreeze-st_01a0198f-v36'
PY=/home/cube/miniconda3/bin/python3.12
```

Additional inputs:

```bash
/home/cube/projects/richard/hermes-agent/scripts/reproducible-wheel-build
/home/cube/.cache/task26-dependency-wheelhouse-st_01a01309/ty-0.0.21-py3-none-manylinux_2_17_x86_64.whl
/home/cube/projects/richard/hermes-agent/.venv/bin/ty
```

These still exist. Relevant hashes:

```text
reproducible-wheel-build 284e0b428f96851241c8b3a2531d2227d38dda8e4ca1ed30fd4375cc67cefb39
native ty                a7c67f977d2684af6eb4c0ecc011e6e8e3227180353fd9be46bc7371a2f88d16
Python 3.12              d9bc96d1ad0161db7ebdc8fdbc690530a9c29299feb2001cba6b29072e2a9051
```

The exact profile source root still exists, and its 137-entry provenance remains intact:

```text
/home/cube/.cache/task26-strict-successor-1786976146/src-p
tree digest b34b2a12fd0ad3d4c95a58c847a2411e81272a646f5a4f5ec568d0d3640a3747
```

The same 137 files are also present byte-for-byte under:

```text
/home/cube/projects/richard/hermes-agent-dualcoach-v1.1/dualcoach/profile
```

Evidence: delivered `source-golden-bundle/source-provenance.json:1`.

## Ordered historical pipeline

### 1. Recover the exact transient Phase 1 scripts

Primary session:

```text
.omo/senpi-task/children/st_01a019c5/sessions/st_01a019c5/
2026-08-19T11-26-34-054Z_01a019c5-e246-72bf-bfe5-fa47f7d85974.jsonl
```

The final v38 scripts were derived as follows:

1. Recover `/tmp/task26_v34_phase1_stage1.sh` from the predecessor session.
2. Replace `v34/V34 -> v35/V35`, then `v35/V35 -> v36/V36`.
3. In session `st_01a019c5`, transform v36 to v37:
   - `v36/V36 -> v37/V37`
   - replace predecessor variable `V33` with v36
   - add `task26_seal_delivered_bundle.py` to copied tools.
4. Transform v37 to v38:
   - `v37/V37 -> v38/V38`
   - replace Ty baseline hashes:
     ```text
     f4a226... -> d01195a6...
     4b2411... -> ba03fe2e...
     810 -> 809
     ```
5. Transform the v36 stage2, stage3, and seal scripts in the same manner.
6. Patch the v38 seal assertions:
   ```text
   focused:     284 -> 306
   full gateway 8530 -> 8552
   ```
   and add the new tool/lease/transport gates.

The exact script bodies are recoverable without interpretation:

```bash
F='/home/cube/projects/richard/traning coach/.omo/senpi-task/children/st_01a0198f/sessions/st_01a0198f/2026-08-19T10-26-49-569Z_01a0198f-3061-7300-8540-4d19ef6789fe.jsonl'

jq -r '
  select(.type=="message")
  | .message.content[]?
  | select(.type=="toolCall" and .name=="write")
  | [.arguments.path, .arguments.content]
  | @tsv
' "$F"

F='/home/cube/projects/richard/traning coach/.omo/senpi-task/children/st_01a019c5/sessions/st_01a019c5/2026-08-19T11-26-34-054Z_01a019c5-e246-72bf-bfe5-fa47f7d85974.jsonl'

jq -r '
  select(.type=="message")
  | .message.content[]?
  | select(.type=="toolCall" and .name=="bash")
  | .arguments.command
' "$F"
```

Then execute, in order:

```bash
/tmp/task26_v38_phase1_stage1.sh
# qualification commands captured in st_01a019c5:
# focused, expanded, parser source/installed, lifecycle, Ruff, Ty,
# hermetic Ty, direct-url attacks, Ty attacks, full Gateway

/tmp/task26_v38_phase1_stage2.sh
/tmp/task26_v38_phase1_stage3.sh
/tmp/task26_v38_phase1_seal.sh
```

### 2. Stage 1 outputs

Expected root:

```text
/home/cube/projects/richard/traning coach/.omo/evidence/task26/task26-combined-prefreeze-st_01a0198f-v38
```

Required outputs include:

```text
artifacts/hermes_agent-0.17.0-py3-none-any.whl
artifacts/physique_checkin_cli-0.1.0-py3-none-any.whl
wheelhouse/*.whl
preexecution-product-binding.json
outer-candidate-manifest.json
sealed-expected-state.json
phase2-command-inputs.json
prefreeze-inventory.json
candidate.json
SEAL.json
candidate-authority/registry.json
candidate-authority/qualification-ledger.json
source-golden-bundle/
installed-golden-bundle/
qualification/profile-qualification-receipt.json
receipts/*
seals/*
```

The retained Phase 2 runtime was:

```text
/home/cube/.cache/task26-combined-prefreeze-st_01a0198f-v38
```

This binding is explicit in `phase2-command-inputs.json:1`. Its later absence is intentional: `must_remove_in_phase2` is true.

### 3. Qualification commands and expected results

The exact command arguments are in `st_01a019c5`. The substantive matrix was:

```text
profile tests             749
focused Task26            306
expanded Task26            76
parser source             204
parser installed          204
related lifecycle         131
full Gateway             8552, 0 failures
direct-url attacks         32
Ty target attacks          14
Ty diagnostics            809
Ty capability diagnostics   0
Ruff                       PASS
static Ty                  PASS
source Golden              ACTUAL_SOURCE_GOLDEN_PATH_PASS
installed Golden           ACTUAL_INSTALLED_GOLDEN_PATH_PASS
```

### 4. Recover and run Phase 2

Primary session:

```text
.omo/senpi-task/children/st_01a019d7/sessions/st_01a019d7/
2026-08-19T11-45-56-789Z_01a019d7-a035-759f-98fe-6ce023cf0fa8.jsonl
```

Extract every exact command and generated program with:

```bash
F='/home/cube/projects/richard/traning coach/.omo/senpi-task/children/st_01a019d7/sessions/st_01a019d7/2026-08-19T11-45-56-789Z_01a019d7-a035-759f-98fe-6ce023cf0fa8.jsonl'

jq -r '
  select(.type=="message")
  | .message.content[]?
  | select(.type=="toolCall" and .name=="bash")
  | .arguments.command
' "$F"

jq -r '
  select(.type=="message")
  | .message.content[]?
  | select(.type=="toolCall" and (.name=="write" or .name=="edit"))
  | [.name, (.arguments|tojson)]
  | @tsv
' "$F"
```

Phase 2 order was:

1. Recover v33 Phase 2 base from session `st_01a01970`.
2. Rewrite it to v38 paths, candidate, Ty hashes, and 809 diagnostics.
3. Add v38 profile/socket/background-lease/direct-url assertions.
4. Run:
   ```bash
   python3 -I /tmp/task26_v38_phase2_base.py
   ```
5. Rehydrate an isolated runtime from the sealed wheelhouse.
6. Run installed final state:
   ```bash
   "$X/venv/bin/python" -I \
     -m gateway.platforms.task26_final_state \
     "$Q" "$Q/sealed-expected-state.json" \
     --hermes-wheel "$Q/artifacts/hermes_agent-0.17.0-py3-none-any.whl" \
     --profile-wheel "$Q/artifacts/physique_checkin_cli-0.1.0-py3-none-any.whl" \
     --wheelhouse "$Q/wheelhouse" \
     --temp-parent "$X"
   ```
7. Run sealed Ty with:
   ```bash
   "$X/venv/bin/python" -I \
     "$Q/verification-tools/task26_hermetic_ty_runner.py" \
     --source "$X/source/nutrition_coaching.py" \
     --ty-wheel "$Q/wheelhouse/ty-0.0.21-py3-none-manylinux_2_17_x86_64.whl" \
     --expected-wheel-sha256 932d4552233cfbaa325ddc3db5982150a37f437cf94a332eb3869052148bfe4c \
     --expected-executable-sha256 a7c67f977d2684af6eb4c0ecc011e6e8e3227180353fd9be46bc7371a2f88d16 \
     --gate-tool "$Q/verification-tools/task26_ty_surface_gate.py" \
     --output-directory "$R/rehydrated-ty"
   ```
8. Generate postfreeze receipts:
   ```bash
   python3 -I /tmp/task26_v38_receipts.py
   ```
9. Remove all original and disposable runtimes.
10. Freeze receipt inputs to `0400/0500`.
11. Materialize:
    ```bash
    /home/cube/miniconda3/bin/python3 -I \
      "$B/verification-tools/task26_seal_delivered_bundle.py" \
      "$B" "$R" "$D"
    ```
12. Run direct delivered-root verification:
    ```bash
    /home/cube/miniconda3/bin/python3 -I \
      "$D/verification-tools/independent_verify_candidate.py" "$D"

    /home/cube/miniconda3/bin/python3 -I \
      "$D/verification-tools/task26_frozen_bootstrap.py" "$D"
    ```
13. Run `/tmp/task26_v38_attacks.py`, rejecting:
    - missing file
    - coherently regenerated metadata
    - substitution
    - extra file
    - symlink
    - writable path
    - stale receipt path
    - wheelhouse tamper
14. Remove transient scripts and runtimes.
15. Assert all roots `0500`, files `0400`, no symlinks, no runtime/process/FD residue.

### 5. Phase 2 outputs

```text
Prefreeze:
task26-combined-prefreeze-st_01a0198f-v38

Postfreeze receipts:
task26-combined-v38-postfreeze-receipts-st_01a019d7/
  PASS.json
  SEAL.json
  postfreeze-seal.json
  qualification-proof.json
  wheelhouse-proof.json
  rehydrated-*.diagnostic.json
  rehydrated-*.stdout.bin
  rehydrated-*.stderr.bin
  rehydrated-*.exit-code

Delivered:
task26-combined-v38-delivered-st_01a019d7/
  delivered-bundle-seal.json
  postfreeze-seal.json
  plus immutable prefreeze payload
```

Final hashes:

```text
prefreeze SEAL       257498e6aa2db7107ee24223a29b09f2e26c3d493869dc21206688be24b037b9
postfreeze seal      3002d815d7523c2971c990544d92c1f0d16fd51781f83d9d636ef6336b5878f6
receipt SEAL         52b7de2d30d99f38db6f73ad70ebe9a21c99449348f069cf3d1f29f5cab745c8
receipt PASS         83b8ca5c39f7a0482af3c153e086518759c863e3fe3ed9f11de9e10659cbafa2
delivered seal       54be54cf89720057486596a21941ec5d456a1c54148f66dbde0475503a752f67
```

Ledger authority is `.omo/start-work/ledger.jsonl:169`; review and release history continue at lines 170-179.

## v1.1 source relationship

The frozen baseline commit is:

```text
d7425705ee403b543f203668eef751c060e2c89d
tag dualcoach-v1.0.0
```

Its commit message explicitly names candidate `d1109d8...`.

The current v1.1 worktree differs from the v38 Hermes wheel in exactly one Python wheel member:

```text
gateway/platforms/telegram_customer_bootstrap.py
```

The current change is:

```python
# gateway/platforms/telegram_customer_bootstrap.py:26
_INVITE_TTL: Final = timedelta(hours=24)
```

The old wheel contains the 30-minute form. The new untracked TTL test is not part of the old wheel.

## Required v1.1 rebindings

Use these source roots:

```bash
G_NEW=/home/cube/projects/richard/hermes-agent-dualcoach-v1.1
P_NEW=/home/cube/projects/richard/hermes-agent-dualcoach-v1.1/dualcoach/profile
PREDECESSOR=/home/cube/projects/richard/traning\ coach/.omo/evidence/task26/task26-combined-v38-delivered-st_01a019d7
```

Use preserved qualification tools from:

```bash
TOOL_ROOT="$G_NEW/dualcoach/releases/v1.0.0/delivered/verification-tools"
```

Those files are byte-identical to the delivered v38 tools and have the expected bound hashes. The committed delivered mirror differs from the original delivery only by one stray tracked `__pycache__` file; do not copy that file.

The new run must use fresh names, for example:

```bash
E_NEW='/home/cube/projects/richard/traning coach/.omo/evidence/task26/task26-dualcoach-v1.1-prefreeze-<session>'
R_NEW='/home/cube/.cache/task26-dualcoach-v1.1-prefreeze-<session>'
POST_NEW='/home/cube/projects/richard/traning coach/.omo/evidence/task26/task26-dualcoach-v1.1-postfreeze-<session>'
D_NEW='/home/cube/projects/richard/traning coach/.omo/evidence/task26/task26-dualcoach-v1.1-delivered-<session>'
```

All schemas currently containing `v38` also need a consistent successor version. The predecessor authority chain should append `d1109d8...`, revoke it as superseded, and qualify only the newly derived digest after all gates pass.

## Blockers and stale bindings

1. **No checked-in release driver**
   - All four Phase 1 scripts and three Phase 2 programs were transient `/tmp` files.
   - Exact recovery is possible only from the session JSONL.

2. **v1.1 lacks required checked-in tooling**
   These are absent from `d7425705ee` at their historical paths:
   ```text
   scripts/reproducible-wheel-build
   scripts/independent_verify_candidate.py
   scripts/task26_*.py
   tests/gateway/test_task26_*.py
   ```
   The verification tools are preserved under the committed delivered mirror, but the build helper and qualification tests are only available in the old dirty worktree/session provenance.

3. **Historical `G` is unsafe for v1.1**
   ```text
   /home/cube/projects/richard/hermes-agent
   ```
   is still heavily dirty and on unrelated commit `0dc0f228...`. Leaving this binding unchanged would build the old source, not v1.1.

4. **Profile source is path-bound**
   Historical:
   ```text
   /home/cube/.cache/task26-strict-successor-1786976146/src-p
   ```
   It exists, but v1.1 should bind the committed equivalent `dualcoach/profile` and generate a fresh source-provenance receipt.

5. **Phase 2 runtime is intentionally absent**
   ```text
   /home/cube/.cache/task26-combined-prefreeze-st_01a0198f-v38
   ```
   was deleted by Phase 2. A successor requires a fresh runtime and fresh Phase 2 input document.

6. **Hard-coded counts will fail**
   The old seal asserts `8552` Gateway tests. The new TTL test changes collection if included. Counts must be freshly observed and then bound; the old count cannot be copied.

7. **Ty baselines are source-specific**
   The historical fixed values are 809 diagnostics and hashes `d01195...` / `ba03fe...`. The TTL change should not alter `nutrition_coaching.py`, but the new run must execute Ty and verify this rather than assume it.

8. **Historical absolute paths are sealed**
   `phase2-command-inputs.json`, runtime receipts, source provenance, and historical authority records contain absolute `/home/cube/...` paths. They must be regenerated for the successor, never edited in copied receipts.

9. **Do not reuse old candidate or postfreeze artifacts**
   The Hermes wheel hash changes, so the candidate, product binding, expected state, authority registry/ledger, inventories, all Golden bundles, prefreeze seal, postfreeze seal, and delivered seal must all be newly generated.

In short: the old execution is fully recoverable, and the candidate rule is exact. The immediate blocker is packaging that recovered pipeline into a provenance-bound v1.1 driver with explicit `G_NEW`, `P_NEW`, test-root, build-helper, and tool-root inputs; running the historical scripts unchanged would not produce a valid v1.1 candidate.