Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,17 @@ jobs:
- name: Two-app reuse contract
run: bash scripts/ci/two_app_reuse_contract_check.sh

- name: Two-app reuse lifecycle (happy)
run: bash scripts/ci/two_app_reuse_lifecycle.sh

- name: Two-app reuse lifecycle (unsupported must fail)
run: |
if bash scripts/ci/two_app_reuse_lifecycle.sh --case unsupported-deprecated-only; then
echo "FAIL: unsupported-deprecated-only must exit non-zero" >&2
exit 1
fi
echo "OK: unsupported-deprecated-only failed closed"

quality:
runs-on: ubuntu-latest

Expand Down
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ gh project item-list 2 --owner traverse-framework --format json --limit 300 \
| `pin-ci-traverse-0-10` | **Done** (#292) | CI / embedder / runtime.wasm → Traverse v0.10.0 |
| `llm-mcp-0-10-live-cutover` | **Done** (absorbed) | Mode A → `llm-mcp-traverse-starter-catalog`; Mode B → `llm-mcp-embedded-host` Future; pin already #292 |
| `two-app-reuse-host-execute` | **Blocked** | Traverse [#1240](https://github.com/traverse-framework/traverse/issues/1240) — BundleEmbedder still fails WASI `proc_exit(0)` on 1.3.2 |
| `two-app-reuse-lifecycle` | **Ready** | Fixture pin-flip + documented deprecation for meeting-notes + loop (not BundleEmbedder; not production release-train) |
| `two-app-reuse-lifecycle` | **Done** (#283) | Fixture pin-flip + documented deprecation for meeting-notes + loop (not BundleEmbedder; not production release-train) |

Full gap table + wave notes: [`docs/production-reference-plan.md`](docs/production-reference-plan.md).

Expand Down
2 changes: 1 addition & 1 deletion docs/adr/0006-two-app-reuse-contract.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Traverse #1168 requires proof that a published capability is a reusable platform

Pin **both** `meeting-notes` and `loop` to public `meeting-notes.process` **1.3.2** (`registry_ref.version_range` exactly `1.3.2`, artifact digest `sha256:ec192a0c2104b08bee76418c5c6d44358036568d655d8465e506858d1aaadbf2`). Full pin, host routes, and current drift: [`../two-app-reuse-contract.md`](../two-app-reuse-contract.md).

This ADR does not implement alignment or execution. `#286` applies the pin and produces evidence. `#283` (`two-app-reuse-lifecycle`) covers fixture-level upgrade/deprecation outcomes (Ready — see decision-log 2026-09-05).
This ADR does not implement alignment or execution. `#286` applies the pin and produces evidence. `#283` (`two-app-reuse-lifecycle`) covers fixture-level upgrade/deprecation outcomes (Donefixture-only; not production release-train; not BundleEmbedder — see decision-log 2026-09-05 and `docs/two-app-reuse-contract.md` Lifecycle section).

## Consequences

Expand Down
31 changes: 30 additions & 1 deletion docs/two-app-reuse-contract.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,36 @@ Host CLI execute via public `BundleEmbedder` (`meeting-notes-cli` / `loop-cli`)
| `#286` `two-app-reuse-execute` | Align meeting-notes pin; execute both apps; publish digest-equal evidence (Done) |
| `#287` `two-app-reuse-execute-ci` | Fixture-only CI evidence (Done) |
| `two-app-reuse-host-execute` | Public BundleEmbedder CLI execute — Blocked on Traverse #1240 |
| `#283` `two-app-reuse-lifecycle` | **Ready** — fixture pin-flip + documented deprecation for the same pair (not BundleEmbedder; not production release-train). See `docs/decision-log.md` 2026-09-05 |
| `#283` `two-app-reuse-lifecycle` | Fixture pin-flip + documented deprecation for the same pair (Done — fixture-only; **not** production release-train; **not** BundleEmbedder). See below and `docs/decision-log.md` 2026-09-05 |

## Lifecycle (fixture-only) — `two-app-reuse-lifecycle`

**Scope:** consumer upgrade/deprecation **outcomes** for the shared pin pair using checked-in fixtures under `scripts/ci/fixtures/two-app-reuse/lifecycle/`.

**Non-claims (mandatory):**

- This is **not** a production registry release-train proof (no new public `meeting-notes.process` publish required).
- This is **not** a BundleEmbedder / `meeting-notes-cli` / `loop-cli` host proof (`two-app-reuse-host-execute` / Traverse #1240).
- App-References does **not** author WASM or invent registry deprecation policy.

### Fixture procedure

1. Both apps start on shared pin `meeting-notes.process` **1.3.2** (digest `sha256:ec192a0c2104b08bee76418c5c6d44358036568d655d8465e506858d1aaadbf2` — same as `scripts/ci/fixtures/two-app-reuse/pin.json`).
2. Fixture catalog introduces stand-in next exact pin `1.4.0-fixture` with the **same** published digest (registry `1.1.0`–`1.3.2` already share that artifact; the stand-in avoids inventing WASM).
3. Per-app pin-flip choices (recorded in `lifecycle/scenario.json` + evidence):
- `meeting-notes` → **advance** to `1.4.0-fixture` (digest-compatible).
- `loop` → **remain** on `1.3.2` until a real next publish + host proof exist.
4. Deprecation step marks fixture baseline `1.3.2` as deprecated. Supported consumer responses (no invented policy): **migrate** / **continue_pinning** / **fail_closed**.
- `meeting-notes` → **migrate** to `1.4.0-fixture`.
- `loop` → **continue_pinning** `1.3.2` (immutable digest; explicit awareness).

```bash
bash scripts/ci/two_app_reuse_lifecycle.sh
# negative: unsupported deprecated-only resolution must fail closed
bash scripts/ci/two_app_reuse_lifecycle.sh --case unsupported-deprecated-only # exit non-zero
```

Evidence artifact: [`scripts/ci/fixtures/two-app-reuse/lifecycle/evidence.json`](../scripts/ci/fixtures/two-app-reuse/lifecycle/evidence.json).

## Re-verification

Expand Down
30 changes: 30 additions & 0 deletions scripts/ci/fixtures/two-app-reuse/lifecycle/catalog.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"capability_id": "meeting-notes.process",
"namespace": "meeting-notes",
"scope": "fixture-only",
"non_claims": [
"Not a production registry release-train proof.",
"Not a BundleEmbedder / host-CLI execute proof (see two-app-reuse-host-execute / Traverse #1240).",
"App-References does not author meeting-notes.process WASM or invent registry deprecation policy."
],
"releases": {
"1.3.2": {
"release_version": "1.3.2",
"digest": "sha256:ec192a0c2104b08bee76418c5c6d44358036568d655d8465e506858d1aaadbf2",
"contract_schema_version": "1.0.0",
"lifecycle": "active",
"pin_file": "../pin.json",
"artifact_url": "https://github.com/traverse-framework/registry/releases/download/artifacts/meeting-notes.process-1.1.0/meeting-process-agent.wasm",
"note": "Published immutable baseline shared by meeting-notes + loop (two-app-reuse-contract)."
},
"1.4.0-fixture": {
"release_version": "1.4.0-fixture",
"digest": "sha256:ec192a0c2104b08bee76418c5c6d44358036568d655d8465e506858d1aaadbf2",
"contract_schema_version": "1.0.0",
"lifecycle": "active",
"stand_in": true,
"artifact_url": "https://github.com/traverse-framework/registry/releases/download/artifacts/meeting-notes.process-1.1.0/meeting-process-agent.wasm",
"note": "Fixture-only stand-in next exact pin. Same published artifact digest as 1.3.2 (registry 1.1.0–1.3.2 share that digest). Demonstrates consumer pin-flip without a new public publish."
}
}
}
83 changes: 83 additions & 0 deletions scripts/ci/fixtures/two-app-reuse/lifecycle/evidence.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
{
"ticket_id": "two-app-reuse-lifecycle",
"upstream": "https://github.com/traverse-framework/Traverse/issues/1168",
"scope": "fixture-only",
"non_claims": [
"Not a production registry release-train proof.",
"Not a BundleEmbedder / host-CLI execute proof (see two-app-reuse-host-execute / Traverse #1240).",
"App-References does not author meeting-notes.process WASM or invent registry deprecation policy."
],
"shared_capability_id": "meeting-notes.process",
"baseline": {
"release_version": "1.3.2",
"digest": "sha256:ec192a0c2104b08bee76418c5c6d44358036568d655d8465e506858d1aaadbf2",
"lifecycle_before": "active",
"lifecycle_after_deprecation_step": "deprecated"
},
"fixture_target": {
"release_version": "1.4.0-fixture",
"digest": "sha256:ec192a0c2104b08bee76418c5c6d44358036568d655d8465e506858d1aaadbf2",
"stand_in": true,
"note": "Fixture-only stand-in next exact pin. Same published artifact digest as 1.3.2 (registry 1.1.0\u20131.3.2 share that digest). Demonstrates consumer pin-flip without a new public publish."
},
"pin_flip": [
{
"app_id": "meeting-notes",
"choice": "advance",
"before": {
"release_version": "1.3.2",
"digest": "sha256:ec192a0c2104b08bee76418c5c6d44358036568d655d8465e506858d1aaadbf2"
},
"after": {
"release_version": "1.4.0-fixture",
"digest": "sha256:ec192a0c2104b08bee76418c5c6d44358036568d655d8465e506858d1aaadbf2"
},
"compatibility_rationale": "Standalone meeting-notes adopts the fixture next exact pin when the stand-in release is digest-compatible with the shared baseline (same sha256 as 1.3.2)."
},
{
"app_id": "loop",
"choice": "remain",
"before": {
"release_version": "1.3.2",
"digest": "sha256:ec192a0c2104b08bee76418c5c6d44358036568d655d8465e506858d1aaadbf2"
},
"after": {
"release_version": "1.3.2",
"digest": "sha256:ec192a0c2104b08bee76418c5c6d44358036568d655d8465e506858d1aaadbf2"
},
"compatibility_rationale": "Loop WF1 keeps the validated shared 1.3.2 pin until a real registry next release and BundleEmbedder host proof exist; remain is an explicit per-app choice, not a floating range."
}
],
"deprecation": [
{
"app_id": "meeting-notes",
"response": "migrate",
"deprecated_release": "1.3.2",
"resolved_pin": {
"release_version": "1.4.0-fixture",
"digest": "sha256:ec192a0c2104b08bee76418c5c6d44358036568d655d8465e506858d1aaadbf2",
"lifecycle": "active"
},
"rationale": "When the baseline pin is fixture-deprecated, meeting-notes migrates to the stand-in next pin already chosen at pin-flip."
},
{
"app_id": "loop",
"response": "continue_pinning",
"deprecated_release": "1.3.2",
"resolved_pin": {
"release_version": "1.3.2",
"digest": "sha256:ec192a0c2104b08bee76418c5c6d44358036568d655d8465e506858d1aaadbf2",
"lifecycle": "deprecated"
},
"rationale": "Loop continues pinning the immutable digest while recording fixture deprecation; continue_pinning is a supported consumer response (not invented registry policy)."
}
],
"assert": {
"both_apps_start_on_baseline": true,
"per_app_advance_or_remain_recorded": true,
"deprecation_responses_recorded": true,
"fixture_only": true,
"not_production_release_train": true,
"not_bundle_embedder_host_proof": true
}
}
38 changes: 38 additions & 0 deletions scripts/ci/fixtures/two-app-reuse/lifecycle/scenario.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"ticket_id": "two-app-reuse-lifecycle",
"upstream": "https://github.com/traverse-framework/Traverse/issues/1168",
"baseline_pin": "1.3.2",
"target_pin": "1.4.0-fixture",
"apps": ["meeting-notes", "loop"],
"pin_flip": {
"meeting-notes": {
"choice": "advance",
"from": "1.3.2",
"to": "1.4.0-fixture",
"compatibility_rationale": "Standalone meeting-notes adopts the fixture next exact pin when the stand-in release is digest-compatible with the shared baseline (same sha256 as 1.3.2)."
},
"loop": {
"choice": "remain",
"from": "1.3.2",
"to": "1.3.2",
"compatibility_rationale": "Loop WF1 keeps the validated shared 1.3.2 pin until a real registry next release and BundleEmbedder host proof exist; remain is an explicit per-app choice, not a floating range."
}
},
"deprecation": {
"deprecated_release": "1.3.2",
"fixture_lifecycle_after": "deprecated",
"supported_responses": ["migrate", "continue_pinning", "fail_closed"],
"responses": {
"meeting-notes": {
"response": "migrate",
"resolved_pin": "1.4.0-fixture",
"rationale": "When the baseline pin is fixture-deprecated, meeting-notes migrates to the stand-in next pin already chosen at pin-flip."
},
"loop": {
"response": "continue_pinning",
"resolved_pin": "1.3.2",
"rationale": "Loop continues pinning the immutable digest while recording fixture deprecation; continue_pinning is a supported consumer response (not invented registry policy)."
}
}
}
}
4 changes: 4 additions & 0 deletions scripts/ci/repository_checks.sh
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,13 @@ check "docs/two-app-reuse-contract.md" "Two-app reuse contract"
check "docs/adr/0006-two-app-reuse-contract.md" "ADR 0006 two-app reuse contract"
check "scripts/ci/two_app_reuse_contract_check.sh" "Two-app reuse contract check"
check "scripts/ci/two_app_reuse_execute.sh" "Two-app reuse execute evidence"
check "scripts/ci/two_app_reuse_lifecycle.sh" "Two-app reuse lifecycle check"
check "scripts/ci/fixtures/two-app-reuse/pin.json" "Two-app reuse pin fixture"
check "scripts/ci/fixtures/two-app-reuse/meeting-notes.process-1.3.2.wasm" "Two-app reuse published wasm"
check "scripts/ci/fixtures/two-app-reuse/meeting-notes.process-1.3.2.contract.json" "Two-app reuse published contract"
check "scripts/ci/fixtures/two-app-reuse/lifecycle/catalog.json" "Two-app reuse lifecycle catalog"
check "scripts/ci/fixtures/two-app-reuse/lifecycle/scenario.json" "Two-app reuse lifecycle scenario"
check "scripts/ci/fixtures/two-app-reuse/lifecycle/evidence.json" "Two-app reuse lifecycle evidence"

# Platform clients
check "apps/traverse-starter/ios-swift/TraverseStarter.xcodeproj" "ios-swift Xcode project"
Expand Down
Loading
Loading