docs Realign steering and README with the repository

Rewrite the steering files and the README in ASD-STE100 Simplified Technical English, and correct the statements that no longer match the code. - Name doc/hd1.md as the doctrine source. - Describe the real dependencies of hito.import and hito.app. - Make scripts/ci.sh and the pre-push hook the verification owner, so that agents do not repeat checks that automation already did. - Describe what the deployment hook verifies. - Replace the stale ogit watch-process example with hito. ARCHITECTURE.org is not yet realigned.

Commit
22565d0d1786f99f6fe5642d7f0c81d7aa17f90b
Author
Marius Peter <dev@marius-peter.com>
Author date
Committer
Marius Peter <dev@marius-peter.com>
Committer date
Changed files
.kiro/skills/doctrine-check/SKILL.md
index 2e601d4b..d63442f6 100644..100644
@@ -17,10 +17,10 @@
17 17
18 18 The doctrine lives in two places, in this order of authority:
19 19
20 Removed: 1. `doc/Mike_Mentzer_Heavy_Duty_I.md` (HD1) — the primary source. It is
21 Removed: copyrighted, gitignored, and never committed. Read it to cite exact wording.
22 Removed: 2. `.kiro/steering/domain.md` — the distilled, binding principles. Use it when
23 Removed: HD1 is not present.
20 Added: 1. `doc/hd1.md` (HD1) is the primary source. It is copyrighted. Git ignores
21 Added: it. Never commit it. Read it to quote the exact words.
22 Added: 2. `.kiro/steering/domain.md` contains the binding principles in short form.
23 Added: Use it when HD1 is not available.
24 24
25 25 Cite HD1 by section name. The sections are:
26 26
.kiro/steering/domain.md
index 5be32bf1..54e1a9f7 100644..100644
@@ -2,69 +2,77 @@
2 2
3 3 hito is a Heavy Duty training tracker.
4 4
5 Removed: - Source of doctrine: `doc/Mike_Mentzer_Heavy_Duty_I.md` (HD1). You must
6 Removed: justify every domain decision against it.
7 Removed: - It is copyrighted local reference material, gitignored, and never committed.
8 Removed: - On conflict between a design choice and the doctrine:
9 Removed: 1. The doctrine wins, or
10 Removed: 2. The conflict is raised explicitly.
5 Added: - The source of doctrine is `doc/hd1.md` (HD1). `doc/hd1.docx` is the original
6 Added: file. Justify each domain decision against HD1.
7 Added: - HD1 is copyrighted local reference material. Git ignores `doc/`. Never
8 Added: commit it.
9 Added: - If a design choice and the doctrine do not agree, one of these outcomes
10 Added: applies:
11 Added: 1. The doctrine wins.
12 Added: 2. You tell the user about the conflict explicitly.
11 13
12 14 ## Principles that bind the model
13 15
14 16 - **Intensity is categorical, not scalar.**
15 Removed: - You take a working set to momentary muscular failure. That *is* its
16 Removed: definition (HD1, "The Intensity Factor": the only accurate measures are 0%
17 Removed: at rest and 100% at failure).
18 Removed: - Going further is qualitative — `Beyond_failure`: forced reps, negatives,
19 Removed: static hold. Each is a count (reps, or seconds held). Rest-pause is not in
20 Removed: HD1 and is not modeled.
21 Removed: - Never introduce a numeric "intensity score".
22 Removed: - **Recovery produces growth. The gym only stimulates it.**
23 Removed: - Stimulation is immediate. Production is not (HD1, "The Economics of Growth
24 Removed: and Recovery": recovery precedes growth).
25 Removed: - Recovery is systemic and time-based — any hard workout gates the next one.
26 Removed: - **Volume beyond the minimum is harmful.**
27 Removed: - One working set per exercise is nominal. Three sets per muscle is the ceiling.
28 Removed: A prescription that exceeds it is unrepresentable — `Prescription.Workout.make`
29 Removed: refuses it.
30 Removed: - The net negative effect of each extra set increases geometrically.
31 Removed: - Rising volume is a diagnostic warning — never an achievement or a progress
32 Removed: target.
17 Added: - A working set continues to momentary muscular failure. This is the
18 Added: definition of a working set (HD1, "The Intensity Factor": the only accurate
19 Added: measures are 0% at rest and 100% at failure).
20 Added: - Work past failure is qualitative. The model calls it `Beyond_failure`:
21 Added: forced reps, negatives, or a static hold. Each one is a count (reps, or
22 Added: seconds held). HD1 does not contain rest-pause, so the model does not
23 Added: contain it.
24 Added: - Never add a numeric "intensity score".
25 Added: - **Recovery produces growth. The gym only stimulates growth.**
26 Added: - Stimulation is immediate. Production is not immediate (HD1, "The Economics
27 Added: of Growth and Recovery": recovery comes before growth).
28 Added: - Recovery is systemic and depends on time. Each hard workout gates the next
29 Added: workout.
30 Added: - **Volume above the minimum is harmful.**
31 Added: - One working set for each exercise is nominal. Three sets for each muscle
32 Added: is the maximum. The model cannot represent a prescription that is more
33 Added: than the maximum. `Prescription.Workout.make` refuses it.
34 Added: - The negative effect of each extra set increases geometrically.
35 Added: - An increase in volume is a diagnostic warning. It is never an achievement
36 Added: or a progress target.
33 37 - **Progressive overload is the progress signal.**
34 Removed: - Progress is an increase in reps, weight, or both. One extra rep counts.
35 Removed: - Reps are an *outcome*, never a target — a set ends at failure, not at a
36 Removed: number. The prescribed band only calibrates load.
37 Removed: - Raise the load once twelve reps are reached, by 10-20%, so failure returns
38 Removed: inside the band.
39 Removed: - Note the slack: a 6-10 band is not breached at eleven.
38 Added: - Progress is an increase in reps, in weight, or in both. One extra rep is
39 Added: progress.
40 Added: - Reps are an outcome, never a target. A set stops at failure, not at a
41 Added: number. The prescribed band only calibrates the load.
42 Added: - When the trainee gets twelve reps, increase the load by 10 to 20 percent.
43 Added: Failure then occurs in the band again.
44 Added: - The trigger is twelve reps for all bands. Eleven reps in a 6 to 10 band do
45 Added: not trigger an increase.
40 46 - **Brief, infrequent, intense.**
41 Removed: - Shorter sessions at equal or better overload are favourable.
47 Added: - A shorter session with equal or better overload is better.
42 48 - **Focus over novelty.**
43 49 - Exercises come from a curated catalog.
44 Removed: - Author-specified allowlists limit substitutions. A routine may only
45 Removed: narrow them.
50 Added: - Allowlists from the author limit substitutions. A routine can only make an
51 Added: allowlist smaller.
46 52
47 53 ## Encoding rules
48 54
49 Removed: - Prefer making an illegal training state unrepresentable over validating it at
50 Removed: runtime.
51 Removed: - Deviations from doctrine (training early, extra volume) must be *possible* but
52 Removed: never *silent*:
55 Added: - Make an illegal training state impossible to represent. Prefer this to a
56 Added: runtime check.
57 Added: - A deviation from doctrine (early training, extra volume) must be possible,
58 Added: but never silent:
53 59 - Require an explicit acknowledgement.
54 Removed: - Retain that acknowledgement.
55 Removed: - Keep plan and record distinct:
56 Removed: - Prescription/routine vs logged workout.
57 Removed: - Prescription vs progression (plan vs observation).
60 Added: - Keep that acknowledgement.
61 Added: - Keep the plan and the record separate:
62 Added: - A prescription or routine is different from a logged workout.
63 Added: - A prescription is different from a progression (plan against
64 Added: observation).
58 65 - The logbook records. It never interprets.
59 Removed: - Judgement belongs to one module.
60 Removed: - Invariants belong on plans, which are authored — not on history, which is
61 Removed: observed.
62 Removed: - A log that refuses to state what happened is worse than one recording an
63 Removed: error.
64 Removed: - On a stall, the answer is never more work.
65 Removed: - HD1 names two failure states: a *stall* (progress halts, strength holds)
66 Removed: and *decompensation* (strength is lost). Both get the same corrective.
67 Removed: - No remedy may add volume or frequency.
68 Removed: - Doctrinal remedy (HD1, "Regulating Volume and Frequency"): after two weeks
69 Removed: of no progress, take a week off, then *reduce* volume and frequency —
70 Removed: drop sets and add rest days.
66 Added: - One module owns all judgement.
67 Added: - Invariants apply to plans, which are authored. They do not apply to
68 Added: history, which is observed.
69 Added: - A log that refuses to record what occurred is worse than a log that
70 Added: records an error.
71 Added: - When progress stops, the answer is never more work.
72 Added: - HD1 names two failure states. In a *stall*, progress stops and strength
73 Added: stays the same. In *decompensation*, strength decreases. Both get the same
74 Added: correction.
75 Added: - No remedy can add volume or frequency.
76 Added: - The doctrinal remedy (HD1, "Regulating Volume and Frequency"): after two
77 Added: weeks without progress, rest for one week. Then *decrease* volume and
78 Added: frequency. Remove sets and add rest days.
.kiro/steering/ocaml.md
index 78a8dc63..e4488564 100644..100644
@@ -2,63 +2,74 @@
2 2
3 3 ## Source of truth
4 4
5 Removed: - `.mli` files are the specification and outrank tests.
6 Removed: - If an interface and a test disagree, fix the test.
7 Removed: - Changing an interface is a deliberate design decision. Raise it. Do not let
8 Removed: the change drift in unannounced.
5 Added: - The `.mli` files are the specification. They have a higher authority than
6 Added: the tests.
7 Added: - If an interface and a test do not agree, correct the test.
8 Added: - A change to an interface is a design decision. Tell the user about it. Do
9 Added: not change an interface without an announcement.
9 10
10 11 ## Style
11 12
12 Removed: - Modern, idiomatic OCaml. Favour the principle of least surprise: a reader
13 Removed: should not need to learn a local idiom to follow the code.
14 Removed: - Prefer readable, shallow code. A flat sequence a reader can follow top to
15 Removed: bottom beats a deeply nested tower of `match` arms.
16 Removed: - Reach for `let*` when it flattens nested cases — chained `result` or
17 Removed: `result Lwt.t` plumbing where each step short-circuits on error. Used this
18 Removed: way, a bind improves flow and cuts indentation.
19 Removed: - A single `match` is clearer than a monad. Do not reach for one reflexively.
20 Removed: - Two or three cascading `match ... with Error _ -> ... | Ok x -> ...`
21 Removed: steps are the signal to change to `let*`.
22 Removed: - Abstract types with smart constructors for anything carrying an invariant.
23 Removed: - Use `result` for expected, recoverable failure.
24 Removed: - This includes converting untrusted external data and domain feedback a caller
25 Removed: can present or recover from.
26 Removed: - Each module defines its own errors; no shared catch-all error type or
27 Removed: `string` errors.
28 Removed: - Raise a module-specific exception for a violated authored-plan precondition
29 Removed: after validation.
30 Removed: - Do not use exceptions for normal domain outcomes or recorded deviations.
31 Removed: - Prefer closed variants — they keep `match` exhaustiveness complete.
32 Removed: - Total functions where practical; make partiality visible in the type.
13 Added: - Write modern, idiomatic OCaml. Follow the principle of least surprise. A
14 Added: reader must not have to learn a local idiom to follow the code.
15 Added: - Prefer shallow code that is easy to read. A flat sequence that a reader can
16 Added: follow from top to bottom is better than deeply nested `match` arms.
17 Added: - Use `let*` when it removes nested cases. A good example is a chain of
18 Added: `result` or `result Lwt.t` steps where each step stops on an error.
19 Added: - A single `match` is clearer than a monad. Do not use a monad by habit.
20 Added: - Two or three cascading `match ... with Error _ -> ... | Ok x -> ...` steps
21 Added: are the signal to change to `let*`.
22 Added: - Use abstract types with smart constructors for each value that has an
23 Added: invariant.
24 Added: - Use `result` for an expected failure that a caller can recover from.
25 Added: - This includes the conversion of untrusted external data and domain
26 Added: feedback that a caller can show or recover from.
27 Added: - Each module defines its own errors. Do not use a shared catch-all error
28 Added: type or `string` errors.
29 Added: - Raise a module-specific exception when validation finds a violated
30 Added: precondition of an authored plan.
31 Added: - Do not use exceptions for normal domain outcomes or for recorded
32 Added: deviations.
33 Added: - Prefer closed variants. They keep the exhaustiveness check of `match`
34 Added: complete.
35 Added: - Write total functions where possible. If a function is partial, show this in
36 Added: its type.
33 37
34 38 ## Layering
35 39
36 Removed: Six libraries, dependencies pointing inward only. The build graph enforces the
37 Removed: rule: a library cannot name what it does not link.
40 Added: The project has six libraries. All dependencies point inward. The build graph
41 Added: enforces this rule: a library cannot name a library that it does not link.
38 42
39 Removed: - `hito.core` — pure domain. No framework, database, serialization, or Lwt
40 Removed: dependency. Ever.
41 Removed: - `hito.app` — `Repository` and `Password_hash` ports, `Service`, `Catalog`,
42 Removed: `Workout_import`. Depends on `hito.core` and `lwt` only. Knows nothing of
43 Removed: Dream, Caqti, or any adapter.
44 Removed: - `hito.import` — adapters for third-party exports (`Hevy_csv`). Depends on
45 Removed: `hito.app` and the parser it needs. No web framework.
46 Removed: - `hito.persistence` — adapters that implement the ports: `Sqlite_repo`,
47 Removed: `Bcrypt_hash`, `Codec`, `Migrations`. The only place SQL appears.
48 Removed: - `hito.presenter` — view models, routes, pages. Depends on Dream and
49 Removed: dream-html only. It cannot name a core entity, a service, or an adapter.
50 Removed: - `hito.web` — Dream controllers. Maps entities to view models, owns all
51 Removed: user-facing phrasing (`Present`), and never reaches an adapter directly.
43 Added: - `hito.core` is the pure domain. It has no library dependencies: no
44 Added: framework, no database, no serialization, and no Lwt.
45 Added: - `hito.app` contains the ports `Repository`, `Password_hash`, and
46 Added: `Importer`, plus `Trainee`, `Service`, `Catalog`, and `Workout_import`. It
47 Added: depends on `hito.core` and `lwt` only. It does not know about Dream, Caqti,
48 Added: or any adapter.
49 Added: - `hito.import` contains the adapters for third-party exports (`Hevy_csv`). It
50 Added: depends on `hito.core`, `hito.app`, and `csv`. It does not link a web
51 Added: framework.
52 Added: - `hito.persistence` contains the adapters that implement the ports:
53 Added: `Sqlite_repo`, `Bcrypt_hash`, `Codec`, `Import_codec`, `Timestamp`, and
54 Added: `Migrations`. SQL occurs only in this library.
55 Added: - `hito.presenter` contains view models, routes, and pages. It depends on
56 Added: Dream and dream-html only. It cannot name a core entity, a service, or an
57 Added: adapter.
58 Added: - `hito.web` contains the Dream controllers. It depends on `hito.core`,
59 Added: `hito.app`, and `hito.presenter`. It maps entities to view models and owns
60 Added: all user-facing wording (`Present` in `Handlers_kit`). It reaches adapters
61 Added: only through ports.
52 62
53 Removed: `bin/` is the composition root: it alone names both an adapter and the use
54 Removed: case it plugs in.
63 Added: `bin/` is the composition root. Only `bin/` names both an adapter and the use
64 Added: case that the adapter plugs into.
55 65
56 66 Rules:
57 67
58 68 - Ports are module types. Adapters implement them. `Service.Make` and
59 69 `Handlers.Make` are the dependency inversion.
60 Removed: - Persistence identity is assigned in `hito.app`, not in the core.
61 Removed: - Data crossing a boundary is a plain value: a view-model DTO outward, a core
62 Removed: type inward. Never an entity into the presenter, never a row into the core.
63 Removed: - `pp` functions in the core are debugging output. User-facing wording lives in
64 Removed: `hito.web`'s `Present` and nowhere inward.
70 Added: - `hito.app` assigns persistence identity. The core does not.
71 Added: - Data that crosses a boundary is a plain value. A view-model DTO goes outward.
72 Added: A core type comes inward. Never send an entity into the presenter. Never
73 Added: send a database row into the core.
74 Added: - The `pp` functions in the core are debugging output. User-facing wording
75 Added: occurs only in `Present` in `hito.web`.
.kiro/steering/workflow.md
index 9848e768..1b582dc4 100644..100644
@@ -2,75 +2,109 @@
2 2
3 3 ## Definition of done
4 4
5 Removed: A feature is not finished until, in this order:
5 Added: A feature is complete only when these conditions are true, in this order:
6 6
7 Removed: 1. `dune build @check --build-dir _build-agent` is clean (type-checks library
8 Removed: *and* tests).
9 Removed: 2. Alcotests exist for it — unit tests for behaviour, end-to-end tests for flows
10 Removed: that cross module boundaries — and `dune runtest --build-dir _build-agent`
11 Removed: passes.
12 Removed: 3. Formatting is applied and `dune build @fmt --build-dir _build-agent` is
13 Removed: clean. Format with `ocamlformat --inplace` on the touched files, never
7 Added: 1. Alcotests exist for the feature. Write unit tests for behaviour. Write
8 Added: end-to-end tests for flows that cross module boundaries.
9 Added: 2. The touched files are formatted with `ocamlformat --inplace`. Do not use
14 10 `dune fmt` (see Build directory safety).
15 Removed: 4. Documentation reflects the change.
11 Added: 3. The documentation agrees with the change.
12 Added: 4. The exact tree passes verification (see Verification ownership).
16 13
17 Removed: Then, and only then:
14 Added: After these conditions are true:
18 15
19 Removed: - Commit — but only when asked.
20 Removed: - Never commit unformatted or failing code.
21 Removed: - Use `direnv exec . dune ...` if the local opam switch is not active.
16 Added: - Commit only when the user asks.
17 Added: - Do not commit code that is not formatted or that fails a check.
18 Added: - If the local opam switch is not active, use `direnv exec . dune ...`.
22 19
20 Added: ## Verification ownership
21 Added:
22 Added: `scripts/ci.sh` is the single full verification command. It does these checks
23 Added: in the `_build-ci` build directory:
24 Added:
25 Added: 1. `dune build @check` type-checks the libraries and the tests.
26 Added: 2. `dune runtest --force` runs all Alcotest suites.
27 Added: 3. `dune build @fmt` makes sure that the formatting is correct.
28 Added:
29 Added: The `.githooks/pre-push` hook runs `scripts/ci.sh` before each push.
30 Added: `scripts/install-hooks.sh` enables the hook once for each clone.
31 Added:
32 Added: On the deployment host, `deploy/post-receive` builds each push to `master`
33 Added: again. It installs the dependencies, then runs `dune build @check`,
34 Added: `dune runtest`, and a release build. It does not run the formatting check.
35 Added:
36 Added: Apply these rules:
37 Added:
38 Added: - A passing pre-push hook verifies the exact tree that the push sends.
39 Added: - A passing automated build verifies its exact tree.
40 Added: - After a successful push or pull, do not run the full checks again if
41 Added: automation verified the exact tree.
42 Added: - If the hook is disabled or bypassed, run `scripts/ci.sh` manually.
43 Added: - If automated verification fails, run `scripts/ci.sh` manually.
44 Added: - If a pull changes the tree without automated verification, run the checks
45 Added: after the merge.
46 Added: - If a pull causes conflicts, run the checks after you resolve them.
47 Added: - During development, use targeted checks for fast feedback.
48 Added: - Do not run the full suite again if the tree did not change and no
49 Added: verification step failed or was bypassed.
50 Added:
23 51 ## Commits
24 52
25 Removed: - Follow Conventional Commits:
53 Added: - Use Conventional Commits:
26 54
27 55 ```
28 Removed: <type>(<optional scope>): <imperative summary under 72 chars>
56 Added: <type>(<optional scope>): <imperative summary under 72 characters>
29 57
30 Removed: Body: why, not what. Wrap at 72. Note deviations from Heavy Duty doctrine
31 Removed: and the reasoning behind design decisions.
58 Added: Body: say why, not what. Wrap at 72 characters. Record each deviation
59 Added: from Heavy Duty doctrine and the reason for each design decision.
32 60 ```
33 61
34 62 - Types: `feat`, `fix`, `refactor`, `docs`, `test`, `chore`, `build`, `perf`.
35 Removed: - Scopes follow the layering: `core`, `app`, `web`, plus module names
36 Removed: (`core/set`, `core/recovery`).
37 Removed: - Commit only when asked.
38 Removed: - Stage specific files rather than `git add .`.
63 Added: - Scopes follow the layers: `core`, `app`, `import`, `persistence`,
64 Added: `presenter`, `web`, plus module names (`core/set`, `core/recovery`).
65 Added: - Commit only when the user asks.
66 Added: - Stage specific files. Do not use `git add .`.
39 67
40 68 ## Documentation
41 69
42 Removed: Written for a human skimming the repo, not for completeness.
70 Added: Write for a person who reads the repository quickly. Completeness is not the
71 Added: goal.
43 72
44 Removed: - Terse, idiomatic OCaml documentation.
45 Removed: - Refactor docs aggressively. Delete anything stale or redundant in the same
46 Removed: change that outdates it.
47 Removed: - Interface docs state **intention**, not implementation. One line where one
48 Removed: line will do.
49 Removed: - A module header says what the module is for and which invariant it upholds.
50 Removed: - No Markdown files unless asked.
51 Removed: - Do not restate the signature in prose. Document the *why* and the edge cases.
73 Added: - Write all prose in ASD-STE100 Simplified Technical English. This rule
74 Added: applies to steering, Org files, interface comments, and commit messages.
75 Added: - Keep OCaml documentation short and idiomatic.
76 Added: - When a change makes a document stale or redundant, correct or remove the
77 Added: document in the same change.
78 Added: - Interface comments state the intention, not the implementation. If one line
79 Added: is sufficient, write one line.
80 Added: - A module header states the purpose of the module and the invariant that it
81 Added: keeps.
82 Added: - Do not add Markdown files unless the user asks. Use Org mode for project
83 Added: documentation.
84 Added: - Do not repeat the signature in prose. Document the reason and the edge
85 Added: cases.
52 86
53 Removed:
54 87 ## Build directory safety
55 88
56 Removed: Never use the default Dune build directory. A persistent `dune exec -w ogit` process may use `_build`.
89 Added: Do not use the default Dune build directory. A persistent watch process, for
90 Added: example `dune exec -w hito`, can use `_build`.
57 91
58 Removed: Use these commands instead:
92 Added: Use an isolated build directory:
59 93
60 94 - `dune build --build-dir _build-agent`
61 95 - `dune runtest --build-dir _build-agent`
62 96
63 97 Do not run `dune clean` on the default `_build` directory.
64 98
65 Removed: Never run `dune fmt` while a watch build runs. `dune fmt` ignores
99 Added: Do not run `dune fmt` while a watch build runs. `dune fmt` ignores
66 100 `--build-dir` and connects to the Dune RPC server that the watch process owns.
67 Removed: Dune drops that connection mid-rebuild. The failure then looks like a build
68 Removed: error when the code is fine.
101 Added: Dune can drop that connection during a rebuild. The result looks like a build
102 Added: error, but the code is correct.
69 103
70 Removed: Format with `ocamlformat` directly, which does not touch the RPC server:
104 Added: Format with `ocamlformat` directly. It does not use the RPC server:
71 105
72 Removed: - `ocamlformat --inplace <files you changed>`
106 Added: - `ocamlformat --inplace <changed files>`
73 107
74 Removed: Then confirm with `dune build @fmt --build-dir _build-agent`, which uses the
75 Removed: isolated build directory. Do not chain formatting after passing steps with
76 Removed: `&&`. A dropped format connection must not mask a clean build and test run.
108 Added: Then run `dune build @fmt --build-dir _build-agent`. This command uses the
109 Added: isolated build directory. Do not chain the formatting step after other steps
110 Added: with `&&`. A dropped connection must not hide a clean build and test run.
README.org
index fcd06e47..b452d33a 100644..100644
@@ -1,31 +1,33 @@
1 1 #+TITLE: hito
2 2 #+AUTHOR: Marius Peter
3 3
4 Removed: A Heavy Duty training tracker. hito records workouts the way Mike Mentzer's
5 Removed: Heavy Duty prescribes them: one working set to failure per exercise, recovery
6 Removed: gating the next session, and progress measured as more reps or more load.
4 Added: hito is a Heavy Duty training tracker. It records workouts as Mike Mentzer's
5 Added: Heavy Duty prescribes them. Each exercise gets one working set to failure.
6 Added: Recovery gates the next session. Progress is an increase in reps, in load, or
7 Added: in both.
7 8
8 Removed: The domain refuses states the doctrine cannot read. A routine cannot exceed
9 Removed: three sets per muscle. A workout cannot begin before recovery without an
10 Removed: explicit, recorded override. A stall is corrected by resting more and doing
11 Removed: less, never by adding work.
9 Added: The domain refuses states that the doctrine does not permit. A routine cannot
10 Added: have more than three sets for each muscle. A workout cannot start before
11 Added: recovery is complete, unless the trainee gives an explicit override. The
12 Added: application records that override. When progress stops, the correction is
13 Added: more rest and less work. It is never more work.
12 14
13 15 * Layout
14 16
15 Removed: Six libraries, dependencies pointing inward only. The build graph enforces
16 Removed: the rule: a library cannot name what it does not link.
17 Added: The project has six libraries. All dependencies point inward. The build graph
18 Added: enforces this rule: a library cannot name a library that it does not link.
17 19
18 Removed: | Library | Role |
20 Added: | Library | Contents |
19 21 |--------------------+---------------------------------------------------------------|
20 Removed: | ~hito.core~ | Pure domain. No framework, database, or Lwt. |
21 Removed: | ~hito.app~ | Ports (~Repository~, ~Password_hash~, ~Importer~), ~Service~. |
22 Removed: | ~hito.import~ | Adapters for third-party exports (~Hevy_csv~). |
23 Removed: | ~hito.persistence~ | SQLite adapter, bcrypt adapter, stored-record codecs. |
24 Removed: | ~hito.presenter~ | View models and pages. Depends on Dream only. |
25 Removed: | ~hito.web~ | Controllers. Maps entities to view models. |
22 Added: | ~hito.core~ | The pure domain. No framework, database, or Lwt. |
23 Added: | ~hito.app~ | The ports (~Repository~, ~Password_hash~, ~Importer~) and ~Service~. |
24 Added: | ~hito.import~ | The adapters for third-party exports (~Hevy_csv~). |
25 Added: | ~hito.persistence~ | The SQLite adapter, the bcrypt adapter, and the record codecs. |
26 Added: | ~hito.presenter~ | The view models, routes, and pages. It depends on Dream only. |
27 Added: | ~hito.web~ | The controllers. They map entities to view models. |
26 28
27 Removed: ~bin/~ is the composition root: it alone names both an adapter and the port
28 Removed: it plugs into.
29 Added: ~bin/~ is the composition root. Only ~bin/~ names both an adapter and the port
30 Added: that the adapter implements.
29 31
30 32 * Run
31 33
@@ -37,39 +39,46 @@
37 39 dune exec hito
38 40 #+end_src
39 41
40 Removed: Configuration comes from the environment. All variables have defaults.
42 Added: The configuration comes from the environment. Each variable has a default.
41 43
42 Removed: | Variable | Purpose |
43 Removed: |----------------------+-------------------------------------------------------|
44 Removed: | ~HITO_DB~ | Caqti URI. Default ~sqlite3:local_db/hito.sqlite~. |
45 Removed: | ~HITO_SECRET~ | Signs sessions and CSRF tokens. Set it in production. |
46 Removed: | ~HITO_PORT~ | TCP port. Default ~8080~. The server binds loopback. |
47 Removed: | ~HITO_VERSION~ | Deployment identifier shown in the footer. |
48 Removed: | ~HITO_SEED~ | ~1~ seeds one account on startup. Default ~0~. |
49 Removed: | ~HITO_SEED_PASSWORD~ | Required when ~HITO_SEED=1~. |
50 Removed: | ~HITO_SEED_CSV~ | Hevy export imported for the seeded account. |
44 Added: | Variable | Purpose |
45 Added: |----------------------+----------------------------------------------------------|
46 Added: | ~HITO_DB~ | The Caqti URI. Default: ~sqlite3:local_db/hito.sqlite~. |
47 Added: | ~HITO_SECRET~ | Signs sessions and CSRF tokens. Set it in production. |
48 Added: | ~HITO_PORT~ | The TCP port. Default: ~8080~. The server binds loopback. |
49 Added: | ~HITO_VERSION~ | The deployment identifier in the footer. |
50 Added: | ~HITO_SEED~ | ~1~ seeds one account at startup. Default: ~0~. |
51 Added: | ~HITO_SEED_PASSWORD~ | Necessary when ~HITO_SEED=1~. |
52 Added: | ~HITO_SEED_CSV~ | The Hevy export to import for the seeded account. |
51 53
52 Removed: Sessions live in a signed cookie. The server sets a same-origin content
53 Removed: security policy and refuses framing. Put a TLS-terminating proxy in front of
54 Removed: it.
54 Added: Sessions are in a signed cookie. The server sets a same-origin content security
55 Added: policy and refuses framing. Put a proxy that terminates TLS in front of the
56 Added: server.
55 57
56 58 * Develop
57 59
58 Removed: Three gates define done, in this order. ~scripts/ci.sh~ runs all three and
59 Removed: exits non-zero on any failure.
60 Added: ~scripts/ci.sh~ is the full verification command. It does these checks in
61 Added: order and stops at the first failure:
60 62
61 63 #+begin_src sh
62 Removed: dune build @check # type-check libraries and tests
63 Removed: dune runtest # every Alcotest suite
64 Removed: dune build @fmt # ocamlformat and dune formatting applied
64 Added: dune build @check # type-check the libraries and the tests
65 Added: dune runtest # run all Alcotest suites
66 Added: dune build @fmt # make sure that the formatting is correct
65 67 #+end_src
66 68
67 Removed: Format with ~ocamlformat --inplace~ on the files you touched. Run
68 Removed: ~scripts/install-hooks.sh~ once per clone to run the gates before every push.
69 Added: Format the files that you change with ~ocamlformat --inplace~. Run
70 Added: ~scripts/install-hooks.sh~ once for each clone. The pre-push hook then runs
71 Added: ~scripts/ci.sh~ before each push.
69 72
73 Added: * Deploy
74 Added:
75 Added: ~deploy/setup.sh~ prepares the deployment host. ~deploy/post-receive~ builds
76 Added: and tests each push to ~master~, then replaces the live release. If the health
77 Added: check fails, the hook goes back to the previous release.
78 Added:
70 79 * Doctrine
71 80
72 Removed: Design decisions answer to /Heavy Duty I/. The steering files under
73 Removed: ~.kiro/steering/~ state the principles the model encodes and the rules the
74 Removed: code follows. The book itself is copyrighted reference material and is not
75 Removed: part of the repository.
81 Added: Design decisions follow /Heavy Duty I/. The steering files in ~.kiro/steering/~
82 Added: state the principles that the model encodes and the rules that the code
83 Added: follows. The book is copyrighted reference material. It is not part of the
84 Added: repository.