1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
//! Installation-substrate seeding — the `lernie prime` verb (ARCH §2.2).
//!
//! [`prime`] idempotently **founds the harness root**: it resolves the
//! config root and data root exactly as every other verb does (via
//! [`crate::harness_root`] — the XDG split, collapsed to one directory by
//! `LERNIE_HOME`) and lays down what a ready installation carries — the
//! default `models.yaml` (ARCH §4.2), the `tools/` schema pool and the
//! `skills/` pool (ARCH §3.3), and the empty `workflows/` / `workspaces/`
//! directories — **creating what is absent and never clobbering what
//! exists**. `models.yaml` is hand-edited by contract (§4.2), so it is
//! seeded only if absent; every pool entry is likewise seed-if-absent, so
//! a second run changes nothing and a hand-edited entry survives.
//!
//! The shipped assets are **embedded in the binary** at build time (the
//! same `include_dir!` discipline [`crate::template`] uses for the config
//! template), so the `lernie` binary is self-contained: seeding a fresh
//! `LERNIE_HOME` never reaches back to the source tree. `make install`
//! invokes `lernie prime` rather than duplicating the seeding — the verb
//! is the single source of truth for what a ready installation looks like
//! (`docs/PRINCIPLES.md`, single source of truth; §3.4 front door).
use crate;
use crate;
use ;
use fs;
use io;
use ;
/// Config-root subdir holding workflow templates (ARCH §2.2).
const WORKFLOWS_DIR: &str = "workflows";
/// Data-root subdir holding the workspaces tree (ARCH §2.2).
const WORKSPACES_DIR: &str = "workspaces";
/// The default global `models.yaml` (ARCH §4.2), embedded verbatim.
const MODELS_YAML: &str = include_str!;
/// The tool JSON-schema pool (ARCH §3.3 point 2), embedded as flat files.
static TOOLS: = include_dir!;
/// The skill pool (ARCH §3.3), embedded as `<name>/SKILL.md` directories.
static SKILLS: = include_dir!;
/// Why [`prime`] could not complete. The only failure is filesystem I/O;
/// the resolver's own failure is the caller's to surface (§3.4).
/// Found the harness root (ARCH §2.2), seed-if-absent throughout.
///
/// Idempotent by construction: directories are `create_dir_all` (a no-op
/// when present) and every file is written only when absent, so a second
/// run changes nothing and a hand-edited entry (a curated `models.yaml`,
/// an edited `SKILL.md`) is never clobbered. Under `LERNIE_HOME` both
/// roots collapse to one directory and every path below lands there.
/// Recursively seed an embedded directory into `target`, seed-if-absent
/// per leaf file. `target` is the on-disk directory that mirrors `dir`;
/// each embedded file lands at `target/<file-name>`, each embedded subdir
/// recurses into `target/<subdir-name>`. Only files are seed-guarded —
/// directories are `create_dir_all`, so an existing pool with extra
/// entries keeps them and gains only what the binary ships and disk lacks.
/// The final path component of an embedded entry. Embedded paths always
/// have a name (the macro never yields a rootless entry), so the `None`
/// arm is a programmer-error panic, excluded from coverage.
/// Write `bytes` to `path` iff `path` is absent; a present path is left
/// untouched (seed-if-absent — the non-clobber contract, §2.2). Parity
/// with the Makefile's retired `test -e` guard on `models.yaml`.
/// `create_dir_all`, mapping the error to [`Error::Io`] with the path.