Designs track-2 lifecycle and persistence end-to-end: per-command write-through to db+yaml+csv+history.log gated by the combined db persistence logic with commit-db-last ordering; existence-only load with explicit rebuild command; --resume CLI flag backed by <data-root>/last_project; in-TUI list-with-browse picker; lock file for single-instance enforcement; fatal-banner-then-quit failure model (with --resume making restart cheap); fatal CSV row-load errors with full diagnosis; YYYYMMDD-word-word-word temp naming with display-name prettifier; collision-checked names for both temp and user-supplied projects. Project name lives only on the filesystem (not duplicated in YAML). ADR-0004 and ADR-0007 amended in place. requirements.md and CLAUDE.md updated; OOS-6 (global rolling history) tracked as deferred.
3.6 KiB
ADR-0007: Sharing and export
Status
Accepted. Amended by ADR-0015 — see the "Amendments" section at the end of this file for the specifics; the rest of this ADR remains the canonical reference for sharing and export.
Context
Learners and instructors will want to share projects: an instructor distributing an exercise, a student attaching a project to a question, a collaborator sending a snapshot.
The need is real, but committing to a hosted "publish" feature (account system, server, namespace, moderation) would dwarf the core app and is not warranted for a teaching tool. We can satisfy the need entirely with local artifacts and documentation.
Decision
No hosted publishing feature. Sharing is supported via two mechanisms:
-
exportcommand.- Available as an app-level command in both input modes (ADR-0003).
- Produces a single zip file containing
project.yamlanddata/, excludingplayground.db(the recipient rebuilds it on open per ADR-0004) and excludinghistory.log(the user's working log is private; see Amendment 1 below). - Default output path is the parent directory of the project.
- Default filename:
YYYYMMDD-<projectname>-export-<sequence>.zip, whereYYYYMMDDis today's local date and<sequence>is a two-digit zero-padded counter that starts at01and is incremented to avoid clobbering an existing file in the output directory on the same day. - An explicit path and/or filename may be given to override the default.
-
Documented recipes.
- Each new project includes a
.gitignoretemplate that excludesplayground.db, so committing a project to git yields a clean, diff-friendly history. - The user-facing documentation includes recipes for sharing via git, email, and direct file transfer.
- Each new project includes a
If real-world usage later reveals friction these mechanisms cannot solve, a publish feature can be revisited as a separate ADR.
Amendments
Amendment 1 — history.log excluded from export (ADR-0015)
The export zip's contents are now project.yaml + data/
only. Both playground.db (always derived) and history.log
(the user's private working log) are excluded.
Rationale: the history captures every successful command the
user has run in the project, including exploratory or
embarrassing detours. Sharing it by default is wrong — users
will share more than they intend. A user who does want to
share their session log can attach history.log separately
or re-export with a future flag if real demand emerges.
The .gitignore template (Decision item 2) is not
updated to exclude history.log. The template's purpose is
to give a sensible default for committing a project to git,
which is a different question from "what gets shared in an
export zip." Some users will want their working log in
version control (lessons, audits, reproducible
problem-reports); others won't. We don't make that call for
them — the user decides whether history.log belongs in
their git history. The export zip remains the
auto-curated-for-strangers artifact; the gitignore remains
neutral on history.log.
Consequences
- Zero server-side surface area, zero accounts, zero hosting costs.
- Sharing is a power-user-friendly workflow from day one without blocking on infrastructure decisions.
- Recipients reconstruct the database deterministically from the authoritative text sources — sharing is automatically a validation of the rebuild path.
- If a future hosted feature is ever added, this ADR is superseded, not extended.