docs(web): document deletion and program v1
14
CHANGELOG.md
|
|
@ -2,6 +2,20 @@
|
|||
|
||||
## Unreleased — 0.1.2
|
||||
|
||||
- Completed Web Sessions deletion and Program V1 on desktop schema v25. Separate
|
||||
revision-guarded Core commands now withdraw manual preparations and AI
|
||||
proposals or causally delete inactive execution drafts and selected completed
|
||||
sessions. The accessible trash confirmation preserves derived preparations,
|
||||
active/concurrent drafts and unrelated performed history; proposal withdrawals
|
||||
use the bounded `trainlog-ai-session-drafts` V2 tombstone extension to prevent
|
||||
legacy replay resurrection on Android.
|
||||
|
||||
- Added Programs as the fourth Sessions subtab with complete paged listing,
|
||||
search/state filtering, stable detail links, archival, strict bounded
|
||||
`trainlog-program` V1 import preview and transactional commit. An explicit
|
||||
program-session action creates a distinct provenance-bearing manual
|
||||
preparation without automatic Android delivery or performed data.
|
||||
|
||||
- Completed the controlled Web Sessions presentation/withdrawal rollout on the
|
||||
paired private installation. Desktop migrated from schema v23 to v24 and
|
||||
Android from v22 to v23 without clearing application data. The requested
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@ evidence and chronology.
|
|||
|
||||
- [Web Sessions V1](web_sessions.md) owns the implemented preparation, resume,
|
||||
history and Android-delivery workflow.
|
||||
- [Program format V1](program_format_v1.md) owns the strict desktop planning
|
||||
import contract used by the Sessions Programs subtab.
|
||||
|
||||
- [Android](android.md) owns field-companion capture, local persistence,
|
||||
glanceable summaries, permissions, and Android interaction rules.
|
||||
|
|
|
|||
|
|
@ -6,7 +6,9 @@ preparation is inert until explicit start; an occupied singleton is never
|
|||
overwritten. Starting preserves the desktop-reserved execution `session_id`,
|
||||
copies targets only and creates no performed facts.
|
||||
|
||||
Android schema v23 adds the durable manual-preparation withdrawal ledger.
|
||||
Android schema v23 adds the durable manual-preparation withdrawal ledger. The
|
||||
schema is unchanged by Web proposal withdrawal: the existing durable AI draft
|
||||
state stores the V2 companion's `deleted` tombstone.
|
||||
Consumption is part of the outer generation transaction. Exact pending
|
||||
deliveries are changed to `cancelled`; exact started deliveries remain started,
|
||||
and their active or completed execution data is untouched. The stored result is
|
||||
|
|
@ -93,7 +95,9 @@ most 64 contiguous ordered SETS entries, target sets 1..99 and REPS targets
|
|||
1..999 (or the profile-required duration target). Entries must match the
|
||||
resolved exercise profile and known equipment.
|
||||
|
||||
Pending proposals can be explicitly started or deleted. Start is one local
|
||||
Pending proposals can be explicitly started or deleted. A desktop V2 proposal
|
||||
withdrawal uses that same permanent tombstone boundary, removes only proposal
|
||||
entries, and leaves started drafts and performed sessions untouched. Start is one local
|
||||
transaction: it refuses when the singleton active draft exists, copies targets
|
||||
only, marks the proposal `started`, and removes its proposal entries. Delete
|
||||
is gated by a destructive confirmation naming the proposal; Cancel, Back and
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ parallel implementation of its rules.
|
|||
| Boundary | Current state |
|
||||
|---|---|
|
||||
| Frozen project exchange | `TRAINLOG_FORMAT_V1=PASS/FROZEN` |
|
||||
| Desktop SQLite | schema v24 |
|
||||
| Desktop SQLite | schema v25 |
|
||||
| Android SQLite | schema v23 |
|
||||
| Mobile snapshot | V3 active; V1/V2 readable legacy inputs; explicit V4 codec staged, not selected by transport |
|
||||
| Desktop terminal backend | Notcurses only |
|
||||
|
|
@ -221,10 +221,11 @@ progression series, an original BODY ZONES SVG, and private versioned layout
|
|||
persistence with optimistic conflict and CSRF/Origin protection. It provides no
|
||||
automatic browser launch. Sessions provides complete paged preparation,
|
||||
resume and history views, stable details, optimistic manual-preparation writes,
|
||||
explicit proposal derivation and generation-backed Android delivery. Analyse,
|
||||
Programmes and Exercises remain explicit placeholders.
|
||||
explicit proposal derivation and generation-backed Android delivery. Programmes
|
||||
is implemented as the fourth Sessions subtab; Analyse and Exercises remain
|
||||
explicit placeholders, and no standalone Programs route exists.
|
||||
|
||||
Desktop schema v24 owns immutable manual-preparation revisions, stable ordered
|
||||
Desktop schema v25 owns immutable manual-preparation revisions, stable ordered
|
||||
occurrences, persistent HTTP idempotency keys, delivery-to-execution identity,
|
||||
and durable revision-bound withdrawal records. Android schema v23 stores
|
||||
received preparations and permanent withdrawal results separately from AI
|
||||
|
|
@ -241,6 +242,19 @@ presentation. The preparation detail exposes a protected, idempotent **Delete
|
|||
preparation** action; withdrawn rows remain technically inspectable but cannot
|
||||
be edited or delivered.
|
||||
|
||||
Sessions rows expose independent right-edge trash actions and an accessible
|
||||
destructive confirmation dialog. Proposal withdrawal preserves derived
|
||||
preparations and is propagated by `trainlog-ai-session-drafts` V2; inactive
|
||||
execution drafts and completed sessions use revision-guarded causal deletion.
|
||||
Active or concurrently changed drafts conflict instead of being erased.
|
||||
|
||||
Program V1 is desktop-owned planning data in schema v25. The Sessions Programs
|
||||
subtab lists, searches, filters, deep-links and archives programs. Local JSON
|
||||
import is strict and bounded, previews through Core before committing, and has
|
||||
deterministic replay/conflict behavior. One explicit program-session action
|
||||
creates a provenance-bearing manual preparation without Android delivery or
|
||||
performed work.
|
||||
|
||||
The controlled deployment preserved the installed Android signing identity and
|
||||
advanced its private `versionCode` from 13 to 14 without uninstalling or
|
||||
clearing data. The requested six-occurrence validation preparation was already
|
||||
|
|
|
|||
|
|
@ -1,5 +1,19 @@
|
|||
# Desktop database
|
||||
|
||||
## Schema v25: Web deletion requests and Program V1
|
||||
|
||||
Schema v25 adds durable Program V1 definitions, their ordered session and
|
||||
occurrence children, immutable import digests, request replay records and
|
||||
source provenance on derived manual preparations. It also adds the bounded Web
|
||||
session-deletion request ledger and nullable AI-proposal `withdrawn_at` state.
|
||||
Program import and each application command are transactional. Program rows
|
||||
contain planning targets only and cannot own performed sets.
|
||||
|
||||
Proposal deletion is logical. Draft and completed-session deletion append an
|
||||
immutable causal operation and advance deleted causal state in the same
|
||||
transaction; completed sessions also receive a durable deleted finalization.
|
||||
These paths do not implement a generic cascading browser delete.
|
||||
|
||||
## Schema v24: durable preparation withdrawal
|
||||
|
||||
Schema v24 adds nullable `session_preparations.withdrawn_at` and the immutable
|
||||
|
|
@ -37,8 +51,8 @@ is a later, separately versioned migration.
|
|||
## 1. Status
|
||||
|
||||
```text
|
||||
TRAINLOG_DATABASE_SCHEMA_VERSION=23
|
||||
DATABASE_SCHEMA_V23=IMPLEMENTED
|
||||
TRAINLOG_DATABASE_SCHEMA_VERSION=25
|
||||
DATABASE_SCHEMA_V25=IMPLEMENTED
|
||||
TRAINLOG_FORMAT_V1=FROZEN
|
||||
```
|
||||
|
||||
|
|
@ -57,7 +71,7 @@ PRAGMA user_version;
|
|||
Current value:
|
||||
|
||||
```text
|
||||
23
|
||||
25
|
||||
```
|
||||
|
||||
The independent actual-set loads documented in the current desktop, Android
|
||||
|
|
|
|||
|
|
@ -4,12 +4,13 @@ Status: implementation contract for `TRAINLOG_WEB_SESSIONS_V1`.
|
|||
|
||||
## Scope and domain boundaries
|
||||
|
||||
The Sessions route has three independent views:
|
||||
The Sessions route has four independent views:
|
||||
|
||||
- Preparation lists manual preparations and immutable imported AI proposals.
|
||||
- Resume lists lifecycle-backed execution drafts that are not finalized or causally deleted.
|
||||
- History lists completed sessions. A missing `ended_at` is rendered as an unknown end time; it
|
||||
does not make a historical row an active draft.
|
||||
- Programs lists durable planning definitions and can explicitly derive a manual preparation.
|
||||
|
||||
An AI proposal is never mutated by viewing it or by deriving a manual preparation. Derivation is
|
||||
an explicit command which creates a new `sp_<uuid-v4>` preparation and records the proposal ID and
|
||||
|
|
@ -78,6 +79,10 @@ generation containing it is published.
|
|||
|
||||
## Explicit exclusions
|
||||
|
||||
This V1 does not implement Programs, Analysis, or the standalone Exercises route. It does not add
|
||||
Program V1 and its import boundary are specified separately in
|
||||
[`program_format_v1.md`](../program_format_v1.md). They do not turn a program
|
||||
into a template, proposal, draft or completed session.
|
||||
|
||||
This V1 does not implement Analysis or the standalone Exercises route. It does not add
|
||||
live Web workout capture, historical correction, automatic training prescriptions, proposal
|
||||
acceptance, or automatic proposal-to-execution conversion.
|
||||
|
|
|
|||
62
docs/program_format_v1.md
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
# Trainlog Program format V1
|
||||
|
||||
`trainlog-program` V1 is a strict desktop import format for planning data. It
|
||||
does not change `TRAINLOG_FORMAT_V1` and is not an Android synchronization
|
||||
artifact.
|
||||
|
||||
## Identity and ownership
|
||||
|
||||
A program, each ordered session definition and each ordered exercise occurrence
|
||||
has a non-empty stable import identity of at most 128 UTF-8 bytes. The `pg_`,
|
||||
`pgs_`, and `pge_` UUIDv4 forms are recommended creator forms, while imported
|
||||
identities remain opaque. Display titles are not identities. A program is not a
|
||||
reusable session template, AI proposal, manual preparation, execution draft or
|
||||
completed session.
|
||||
|
||||
Desktop schema v25 owns the imported program and its exact source SHA-256.
|
||||
Exact same-ID content replay is idempotent. The same ID with a different byte
|
||||
payload is an explicit conflict. A different ID may reuse a title because titles
|
||||
have no identity semantics.
|
||||
|
||||
## Document shape
|
||||
|
||||
The root has exactly `format`, `version`, and `program`, with format
|
||||
`trainlog-program` and integer version `1`. The program object has exactly:
|
||||
|
||||
- `program_id`, `title`, nullable `note`, `state`, nullable `start_date`,
|
||||
nullable `end_date`, and `sessions`;
|
||||
- state `active` on import;
|
||||
- 1–64 ordered sessions;
|
||||
- title length 1–200 UTF-8 bytes and note length at most 4,000;
|
||||
- canonical `YYYY-MM-DD` civil dates, with the end not before the start.
|
||||
|
||||
Each session has exactly `program_session_id`, `title`, `session_type`, nullable
|
||||
`planned_for`, nullable `note`, and `occurrences`. Session type is `training` or
|
||||
`max_test`; each session contains 1–64 occurrences.
|
||||
|
||||
Each occurrence has exactly `entry_id`, `exercise_id`, nullable `equipment_id`,
|
||||
`load_mode`, `rest_seconds`, nullable `target_sets`, nullable `target_reps`,
|
||||
nullable `target_duration_seconds`, nullable `target_weight_kg`, and nullable
|
||||
`notes`. Exercise and equipment identities must already resolve in the desktop
|
||||
catalog. Recording/tracking profiles and target/load combinations are validated
|
||||
by the same Core rules used for manual preparations. No actual set, MAX result,
|
||||
completion timestamp or other performed field is accepted.
|
||||
|
||||
The complete UTF-8 JSON document is limited to 512 KiB. Duplicate object keys,
|
||||
unknown keys, non-finite numbers, invalid UTF-8, duplicate identities, excessive
|
||||
collections and incompatible profiles are rejected before any row is written.
|
||||
|
||||
## Preview, commit and lifecycle
|
||||
|
||||
The Web file picker sends bytes to the Core validation endpoint first. Its
|
||||
preview reports identity, title, dates, session count, unknown-exercise count
|
||||
and warnings while leaving the database unchanged. Import occurs only after the
|
||||
user confirms and commits all program/session/occurrence/source rows in one
|
||||
transaction.
|
||||
|
||||
Archive is a revision-guarded lifecycle transition. It hides no derived data
|
||||
and retains the source definition and digest. Creating a preparation from one
|
||||
session is a separate idempotent command that copies the ordered plan and stores
|
||||
program/session provenance on a new `sp_<uuid-v4>` manual preparation. It does
|
||||
not create a delivery, Android object, execution draft, completed session or
|
||||
performed measurement.
|
||||
BIN
docs/reviews/evidence/web-programs-empty-mobile.png
Normal file
|
After Width: | Height: | Size: 63 KiB |
|
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 61 KiB |
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 49 KiB |
|
Before Width: | Height: | Size: 103 KiB After Width: | Height: | Size: 105 KiB |
|
Before Width: | Height: | Size: 95 KiB After Width: | Height: | Size: 86 KiB |
47
docs/reviews/web_sessions_delete_programs_v1_evidence.md
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
# Web Sessions deletion and Programs V1 evidence
|
||||
|
||||
Date: 2026-09-18
|
||||
|
||||
This pre-deployment record covers the completed development branch. It does not
|
||||
claim installation, migration of real data, service restart, phone validation,
|
||||
tagging or release publication.
|
||||
|
||||
## Implemented boundaries
|
||||
|
||||
- Separate Core commands withdraw manual preparations and AI proposals, or
|
||||
causally delete inactive execution drafts and explicitly selected completed
|
||||
sessions. They require current revisions and durable request identities.
|
||||
- Proposal withdrawal retains its import ledger and every derived preparation.
|
||||
The V2 AI-proposal companion publishes a permanent Android tombstone; an
|
||||
older V1 proposal cannot recreate it. Started executions and performed work
|
||||
are not proposal-deletion effects.
|
||||
- The row trash action is independent from detail navigation. The accessible
|
||||
confirmation dialog has initial safe focus, an Escape path, a focus trap and
|
||||
trigger focus restoration.
|
||||
- Program V1 remains desktop planning data. Strict preview and transactional
|
||||
import share the Core validator. Archive is lifecycle state, and explicit
|
||||
preparation creation retains program/session provenance without delivery or
|
||||
performed data.
|
||||
|
||||
## Validation
|
||||
|
||||
- GCC/Web Meson suite: 88/88 passed.
|
||||
- Clang strict suite: 86/86 passed.
|
||||
- Clang ASan/UBSan suite: 86/86 passed.
|
||||
- Frontend typecheck, production build and 93 Vitest tests passed.
|
||||
- Android `testDebugUnitTest` and `assembleDebug` passed.
|
||||
- JSON, import-contract and Python contract tests passed; the two Firefox tests
|
||||
passed separately in an isolated temporary Python environment.
|
||||
- The real embedded server was exercised at desktop size and at an exact
|
||||
390×844 viewport. Its synthetic-only captures include the Sessions list,
|
||||
destructive confirmation and Programs empty state.
|
||||
- `tools/check_changed_c_format.sh main` and `git diff --check` passed.
|
||||
|
||||
## Deployment gate
|
||||
|
||||
Desktop schema v25 and proposal synchronization V2 require the grouped gate:
|
||||
retain the installed package, create consistent desktop and Android backups,
|
||||
validate v24→v25 migration on a database copy, verify Android package signing
|
||||
and monotonic versioning, then install/restart/synchronize and inspect the real
|
||||
Web routes only after explicit authorization. No operation in this record
|
||||
crossed that gate.
|
||||
|
|
@ -24,7 +24,7 @@ distinction between measured values and estimates.
|
|||
|
||||
## Current baseline
|
||||
|
||||
Desktop schema v24, Android schema v23, Notcurses, direct
|
||||
Desktop schema v25, Android schema v23, Notcurses, direct
|
||||
`Documents/Trainlog` storage, mobile export V3, Training Knowledge V1, Body
|
||||
Zones V1, Training Feedback V1/V2, STATS V1, and Session Generator V1 are
|
||||
implemented. Session Generator V1 is hidden pending V2. AI session-draft
|
||||
|
|
@ -33,7 +33,9 @@ exchange and APP_SHELL_V1 retain their explicit manual validation/review gates.
|
|||
CLI/HTTP infrastructure, embedded frontend shell and the frozen Dashboard data
|
||||
contract, frozen interactive grid, versioned layout persistence and factual
|
||||
tile rendering exist. The Dashboard's bounded progression and BODY ZONES
|
||||
visualizations and Sessions V1 are implemented; the other three Web routes remain placeholders.
|
||||
visualizations and Sessions V1 are implemented. Programs is implemented inside
|
||||
Sessions; Analyse, Exercises and the standalone top-level Programs route remain
|
||||
placeholders or out of scope.
|
||||
The corrective prepared-item projection, bounded phase-owned MTP outbox,
|
||||
Sessions presentation correction, local date preference and durable preparation
|
||||
withdrawal are implemented. The withdrawal uses the separate versioned
|
||||
|
|
@ -55,8 +57,9 @@ transactional consumption, durable correlated ACK and restart/replay entry
|
|||
points. The orchestrator, Web API and Web control are complete behind an
|
||||
explicit trusted opt-in. The authorized private direct-MTP rollout passed on
|
||||
real hardware; automatic V3 selection remains unchanged without that opt-in.
|
||||
The next separately contracted Web surface is Exercises. Sessions V1 is
|
||||
complete in software and is not reopened by that future contract.
|
||||
The next separately contracted Web surface is Exercises. Sessions deletion and
|
||||
its Programs subtab are complete in software and are not reopened by that
|
||||
future contract.
|
||||
|
||||
`TRAINLOG_SYNC_GAP_CONTRACT_V1=CONTRACT_FROZEN / IMPLEMENTATION_IN_PROGRESS`
|
||||
defines the complete-sync target and its bounded dependency order.
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ available because availability is independently guarded by causal state.
|
|||
|
||||
## Machine-exercise Phase 1 compatibility
|
||||
|
||||
Desktop schema v24 and Android schema v23 retain mobile export V3, readable V1/V2 imports,
|
||||
Desktop schema v25 and Android schema v23 retain mobile export V3, readable V1/V2 imports,
|
||||
equipment definitions V1, equipment associations V2, exercise aliases V1, and
|
||||
the BODY ZONES companion without wire-format changes. Machine metadata is not
|
||||
silently added to a frozen artifact: stable exercise IDs and canonical names
|
||||
|
|
@ -143,7 +143,7 @@ does not publish to it or let it override an artifact in the new endpoint.
|
|||
| PC -> Android | `trainlog-equipment-associations-v2.json` | `trainlog-equipment-associations` v2 |
|
||||
| PC -> Android | `trainlog-exercise-body-zones-v1.json` | `trainlog-exercise-body-zones` v1 |
|
||||
| PC -> Android | `trainlog-exercise-aliases-v1.json` | `trainlog-exercise-aliases` v1 |
|
||||
| PC -> Android | `trainlog-ai-session-drafts-v1.json` | `trainlog-ai-session-drafts` v1 companion |
|
||||
| PC -> Android | `trainlog-ai-session-drafts-v1.json` | `trainlog-ai-session-drafts` v1/v2 companion; v2 adds proposal withdrawals |
|
||||
| Android -> PC agent | `trainlog-sync-request-v1.json` | `trainlog-sync-request` v1 |
|
||||
| PC agent -> Android | `trainlog-sync-receipt-v1.json` | `trainlog-sync-receipt` v1 |
|
||||
|
||||
|
|
@ -522,7 +522,11 @@ retryable desktop status and never undoes the committed import. The desktop
|
|||
outbound companion selects at most 256 not-yet-published proposals in stable
|
||||
creation/identity order. Successful MTP publication transactionally marks only
|
||||
that exact batch; failure leaves it unchanged for retry, while later normal
|
||||
syncs drain further batches. The permanent Drive import ledger is independent.
|
||||
syncs drain further batches. V2 additionally carries at most 256 permanent
|
||||
proposal withdrawals. Desktop admission keeps the complete withdrawal set
|
||||
within that bound. Android stores each as a deleted tombstone before removing
|
||||
pending proposal entries, so an older V1 replay cannot resurrect the proposal.
|
||||
The permanent Drive import ledger is independent.
|
||||
The inbound outcome (`NONE`, `IMPORTED`, `ALREADY_IMPORTED`, `REJECTED`,
|
||||
`DRIVE_FAIL`, or `ARCHIVE_FAIL`) is retained in the successful sync report and
|
||||
history; fetched-invalid, Drive, and archive outcomes do not fail an otherwise
|
||||
|
|
|
|||
|
|
@ -41,6 +41,23 @@ The C MTP regression keeps a malformed retained generation beside the current
|
|||
reference and proves that pull downloads only the referenced generation while
|
||||
still rejecting a truncated object inside that current generation.
|
||||
|
||||
`web_session_deletions` exercises proposal withdrawal replay, preservation of a
|
||||
derived preparation, active-draft conflict, causal draft/session deletion and
|
||||
completed-session finalization. The HTTP suite covers stale and successful
|
||||
proposal DELETE requests and post-delete deep-link absence. Vitest covers the
|
||||
focus-managed confirmation, Cancel and Escape zero-mutation paths, the real
|
||||
DELETE call and focus restoration. AI companion tests prove that V2 exports a
|
||||
withdrawal without the proposal and that Android's tombstone rejects later V1
|
||||
replay.
|
||||
|
||||
`web_programs` exercises validation preview without writes, transactional
|
||||
import, exact replay, detail serialization, archive replay, preparation
|
||||
creation, provenance and absence of delivery. Schema migration coverage checks
|
||||
all v25 tables and columns. Programs Vitest covers preview before the only
|
||||
importing mutation and explicit preparation creation/navigation. The full HTTP,
|
||||
pagination, strict-parser and Core suites retain malformed, duplicate-key,
|
||||
bounds, catalog/profile/equipment, conflict and rollback coverage.
|
||||
|
||||
`test_web_sessions_browser.py` runs headless Firefox against the embedded
|
||||
production assets and C HTTP server with private temporary XDG roots. It creates
|
||||
only a synthetic ready preparation and delivery, verifies French then persisted
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
# Web Sessions V1
|
||||
|
||||
The Sessions route implements three distinct views:
|
||||
The Sessions route implements four distinct views:
|
||||
|
||||
- Preparation: manual preparations and immutable AI proposals;
|
||||
- Resume: lifecycle-backed execution drafts, continued only on Android;
|
||||
- History: completed sessions, including explicit unknown end times.
|
||||
- Programs: durable desktop planning definitions, import and explicit manual
|
||||
preparation creation.
|
||||
|
||||
Manual preparation supports a title, session type, optional calendar date,
|
||||
note, catalogue selection, duplicate occurrences, keyboard reordering,
|
||||
|
|
@ -58,5 +60,22 @@ The tombstone rejects an older delivery replay, including after process restart.
|
|||
Desktop marks a withdrawal acknowledged only after the correlated Android
|
||||
generation ACK. Until then Web reports that Android synchronization is pending.
|
||||
|
||||
Every deletable row has a separate right-edge trash action with an accessible
|
||||
target. It never opens the detail. A focus-managed `alertdialog` names the item,
|
||||
kind, relevant date and consequence; Cancel and Escape write nothing. Proposal
|
||||
deletion records a durable logical withdrawal and publishes a bounded V2
|
||||
proposal tombstone without deleting derived preparations or performed work.
|
||||
Inactive execution drafts and completed sessions use the existing causal
|
||||
operation/state boundary. Active or stale drafts conflict, and completed-session
|
||||
deletion records a finalization so older snapshots cannot recreate the session.
|
||||
|
||||
Programs are planning data owned by desktop schema v25. Import first runs the
|
||||
same strict Core validator in preview mode, then commits only after explicit
|
||||
confirmation. Exact content replay is idempotent; same-ID divergent content is
|
||||
a conflict. Archiving preserves definitions and derived preparations. Creating
|
||||
a preparation from one program session copies targets and provenance into a
|
||||
new manual preparation but creates no delivery, execution or performed data.
|
||||
See [Program format V1](program_format_v1.md).
|
||||
|
||||
This V1 does not provide live Web capture, historical correction, automatic
|
||||
training generation, Programs, Analysis or the standalone Exercises route.
|
||||
training generation, Analysis or the standalone Exercises route.
|
||||
|
|
|
|||