docs(release): release model usage + recorded M3 drills (#13)
- README: Release model section (package/activate/rollback/status, pointer + append-only log, gate-then-flip guarantee) - BUILD-LOG Phase 7: drills recorded (update, refusal, rollback), two harness/product corrections documented Drill evidence: 0.0.3 -> 0.0.4 update with unchanged config checksum and green verify; fault-injected refusal left pointer untouched; health-gated rollback restored 0.0.3; full append-only event history. Closes #13
This commit is contained in:
@@ -163,4 +163,33 @@ Configuration-driven Hello World verified. `main` merged with M1 and tagged `con
|
|||||||
|
|
||||||
Mission/task layer verified end-to-end. `main` merged with M2 and tagged `mission-task-v1`.
|
Mission/task layer verified end-to-end. `main` merged with M2 and tagged `mission-task-v1`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 7: Release model and safe updates (M3)
|
||||||
|
|
||||||
|
### Entry 7.1 — before
|
||||||
|
|
||||||
|
- Timestamp: 2026-09-03
|
||||||
|
- Intended action: Add the release substrate (Gitea milestone M3, issues #10-#13): RELEASE file single-sources the version (0.0.X line per owner direction), image tags derive from it, scripts/release.sh provides package/activate/rollback/status, activation is health-gated by the M2 task runner, pointer + append-only log under <dataRoot>/state/.
|
||||||
|
- Reason: The owner's top invariant — updates must never corrupt a working installation — needs a mechanism, not a convention: gate-then-flip with recorded history and rollback.
|
||||||
|
- Expected result: Update, refusal, and rollback drills all green with config checksums unchanged.
|
||||||
|
|
||||||
|
### Entry 7.2 — after
|
||||||
|
|
||||||
|
- Timestamp: 2026-09-03
|
||||||
|
- Commands run: scripts/test-release.sh (14 cases); recorded drills: update (0.0.3 -> 0.0.4 package+activate+verify), fault-injected refusal, rollback to 0.0.3.
|
||||||
|
- Observed result:
|
||||||
|
- Selftests: 14 passed, 0 failed.
|
||||||
|
- Update drill: packaged and activated r0.0.4 after exact-marker health gate; verify green under the new tag; config checksum unchanged.
|
||||||
|
- Refusal drill: health-gate fault injection -> activation refused (exit 1), pointer untouched, refusal appended to the log.
|
||||||
|
- Rollback drill: health-gated rollback to r0.0.3; pointer restored; log records package/activate/refused/rollback history append-only.
|
||||||
|
- Failure or correction:
|
||||||
|
1. release.sh initially failed with missing state/ directory (no mkdir before pointer/log writes); fixed.
|
||||||
|
2. Selftest harness mutated the repo RELEASE and restored the mutated copy (mv-back bug) plus a second trap replacing the first; fixed with inline backup restore and one self-healing exit trap. Product code unaffected.
|
||||||
|
- Credential check: no credential material in release state, logs, or drills.
|
||||||
|
|
||||||
|
## Result (M3)
|
||||||
|
|
||||||
|
Release model and safe updates verified by drills. `main` merged with M3 and tagged `release-model-v1`.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -83,6 +83,24 @@ scripts/test-task.sh # selftests (schema negat
|
|||||||
|
|
||||||
A run exits 0 only when its expectation is met (`expectExact` match); mismatches, nonzero agent exits, and timeouts record `status: failed` in `result.json` and exit 1. Each run gets a unique directory — rerunning never rewrites history.
|
A run exits 0 only when its expectation is met (`expectExact` match); mismatches, nonzero agent exits, and timeouts record `status: failed` in `result.json` and exit 1. Each run gets a unique directory — rerunning never rewrites history.
|
||||||
|
|
||||||
|
## Release model (M3)
|
||||||
|
|
||||||
|
`RELEASE` single-sources the release version (0.0.X until declared stable); the image tag derives from it plus the pinned Pi version. Activation is health-gated and every event is recorded:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
scripts/release.sh package # build + tag the release image
|
||||||
|
scripts/release.sh activate # health check (exact marker) -> atomic pointer swap
|
||||||
|
scripts/release.sh activate --fault-injection # prove the refusal path (drills only)
|
||||||
|
scripts/release.sh rollback # health-gated return to the previous release
|
||||||
|
scripts/release.sh status # release, tag, active pointer, recent log
|
||||||
|
scripts/test-release.sh # release selftests
|
||||||
|
```
|
||||||
|
|
||||||
|
- `<dataRoot>/state/active.json` — the activation pointer (atomic tmp+rename replace)
|
||||||
|
- `<dataRoot>/state/activation-log.jsonl` — append-only history: package / activate / refused / rollback
|
||||||
|
|
||||||
|
A failed health check never activates; the previously active release remains deployed. Updating the software therefore cannot corrupt the running installation: package beside, gate, then flip. Verified by the update/refusal/rollback drills in BUILD-LOG Phase 7.
|
||||||
|
|
||||||
See `docs/plans/2026-09-02_atomic-mosaic-foundation.md` for the full plan.
|
See `docs/plans/2026-09-02_atomic-mosaic-foundation.md` for the full plan.
|
||||||
|
|
||||||
Inside the container:
|
Inside the container:
|
||||||
@@ -95,7 +113,8 @@ Inside the container:
|
|||||||
|
|
||||||
## How it works
|
## How it works
|
||||||
|
|
||||||
1. `scripts/build.sh` builds `mosaic-poc-agent:0.84.4` with Docker Compose.
|
1. `scripts/build.sh` builds the release image (`mosaic-poc-agent:<pi>-r<release>`,
|
||||||
|
tag derived from `RELEASE` + the pinned Pi version) with Docker Compose.
|
||||||
2. On each run, `/opt/mosaic/src/load-contracts.sh` reads the four contract files
|
2. On each run, `/opt/mosaic/src/load-contracts.sh` reads the four contract files
|
||||||
in fixed order (CONSTITUTION, STANDARDS, SOUL, USER), joins them with clear
|
in fixed order (CONSTITUTION, STANDARDS, SOUL, USER), joins them with clear
|
||||||
separators, and writes `/var/lib/mosaic/system-prompt.md`.
|
separators, and writes `/var/lib/mosaic/system-prompt.md`.
|
||||||
@@ -116,8 +135,10 @@ scripts/build.sh # build the image
|
|||||||
scripts/hello.sh # one-shot request; prints the model response
|
scripts/hello.sh # one-shot request; prints the model response
|
||||||
scripts/verify.sh # full gated test; exit 0 only on exact MOSAIC_HELLO_OK
|
scripts/verify.sh # full gated test; exit 0 only on exact MOSAIC_HELLO_OK
|
||||||
scripts/run-task.sh # run a mission/task file (see Missions & tasks)
|
scripts/run-task.sh # run a mission/task file (see Missions & tasks)
|
||||||
|
scripts/release.sh # package / activate / rollback / status (see Release model)
|
||||||
scripts/test-config.sh # fast config-layer selftests (no Docker)
|
scripts/test-config.sh # fast config-layer selftests (no Docker)
|
||||||
scripts/test-task.sh # mission/task selftests (schema + live runs)
|
scripts/test-task.sh # mission/task selftests (schema + live runs)
|
||||||
|
scripts/test-release.sh # release selftests
|
||||||
scripts/reset.sh # delete the configured data root (safety-checked)
|
scripts/reset.sh # delete the configured data root (safety-checked)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user