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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
//! qexo — the Exocortex coordinator, phext-native from scratch.
//!
//! One binary; modules by concern: the format (phext), the seal
//! (xz), the hash, GPG mechanics (crypto), the inference edge
//! (infer), the plan's pure core (plan), doctor's two layers
//! (doctor), the state lattice and its Layer 2 addressing
//! (lattice), the state commands (core), the wiring gate
//! (wiring), and this CLI.
mod cli;
mod core;
mod crypto;
mod doctor;
#[allow(dead_code)]
mod hash;
mod infer;
mod inventory;
mod lattice;
mod learn;
mod phext;
mod plan;
mod wiring;
mod xz;
use cli::Command;
fn main() {
let args: Vec<String> = std::env::args().skip(1).collect();
let code = run(cli::parse(&args), &args);
std::process::exit(code);
}
fn run(cmd: Command, args: &[String]) -> i32 {
// Intent first (v1.4.1): state resolution is intent-aware —
// a write-intending verb in unprivileged hands selects the
// per-user state when the system state is not writable by
// it, instead of adopting a state its first save will fail
// on; read-only verbs keep the v1.4.0 order exactly. The
// classification is the command enum itself, case by case:
// anything that can end in a state save is write-intending.
// (learn refines this in v1.4.2: a SESSION is
// write-intending, since it saves grades; --status is not,
// but learn in both forms carries the learn preference —
// an existing per-user deck is the operator's own and is
// read in preference to the system deck.)
if matches!(cmd, Command::Learn { .. }) {
lattice::set_learn_preference();
}
let write_intent = matches!(
cmd,
Command::Config { .. }
| Command::Register(_)
| Command::Host { .. }
| Command::Unhost(_)
| Command::Message { .. }
| Command::Release
| Command::Learn { status: false }
| Command::Bare
| Command::Plan
| Command::Update { check: false }
| Command::Evolve { check: false }
| Command::Doctor { fix: true }
);
if write_intent {
lattice::set_write_intent();
}
match cmd {
Command::Help => {
print!("{}", cli::help_text());
0
}
Command::Version => {
println!("qexo v1.4.2 (Cargo 1.4.2)");
0
}
Command::WiringCheck(dir) => {
let dir = dir.unwrap_or_else(|| "src".to_string());
match wiring::check_dir(std::path::Path::new(&dir)) {
Ok((orphaned, missing, n)) => {
if orphaned.is_empty() && missing.is_empty() {
println!("wiring ok: {} module files, every one declared, every declaration filed", n);
0
} else {
for o in &orphaned {
eprintln!("orphaned (file without declaration): src/{}.rs", o);
}
for m in &missing {
eprintln!("missing (declaration without file): {}", m);
}
1
}
}
Err(e) => {
eprintln!("wiring-check: {}", e);
2
}
}
}
Command::FileOp(_) => phext_file_ops(args),
Command::Doctor { fix } => {
// Both layers: filesystem facts, then — when the
// state is born — the lattice neighborhoods.
let dir = lattice::state_dir();
let file = lattice::state_path();
if fix {
let mut done = doctor::fix(&dir, &file);
if let Ok(Some(mut lat)) = lattice::Lattice::load() {
done.extend(doctor::fix_lattice(&mut lat));
if let Err(e) = lat.save() {
eprintln!("doctor: cannot save repaired state: {}", e);
return 1;
}
}
for d in &done {
println!("fixed: {}", d);
}
if done.is_empty() {
println!("nothing to fix");
}
}
let mut report = doctor::check(&dir, &file);
if let Ok(Some(lat)) = lattice::Lattice::load() {
report.findings.extend(doctor::check_lattice(&lat).findings);
}
print!("{}", report.render());
if report.ok() { 0 } else { 1 }
}
Command::Unknown(word) => {
eprintln!("qexo: unknown command '{}' — qexo --help lists the surface", word);
2
}
Command::Bare | Command::Plan => core::plan_cmd(),
Command::Config { auto_update, evolve, release_signer } => core::config(auto_update, evolve, release_signer),
Command::List { json } => core::list(json),
Command::Learn { status } => learn::learn(status),
Command::Inventory { name, install } => inventory::inventory(name, install),
Command::Register(args) => core::register(&args),
Command::Release => core::release(),
Command::Update { check } => core::update(check),
Command::Evolve { check } => core::evolve(check),
Command::Host { persona, boot } => core::host(persona, boot),
Command::Unhost(name) => core::unhost(&name),
Command::Message { persona, text } => core::message(&persona, &text),
Command::Status => core::status(),
Command::Serve(port) => core::serve(port.unwrap_or(8484)),
}
}
/// File-level phext operations (the libphext surface in the CLI):
/// parse/explode/implode/seal/unseal/select/get operate on files,
/// not node state. Carried from the old line's implementation
/// (the from-scratch brief's named reuse), verbatim in behavior.
fn phext_file_ops(args: &[String]) -> i32 {
let op = args[0].as_str();
let path = args.get(1).cloned().unwrap_or_default();
match op {
"parse" | "implode" => {
let text = match std::fs::read_to_string(&path) {
Ok(t) => t,
Err(e) => {
eprintln!("{}: {}", path, e);
return 2;
}
};
let px = phext::Phext::parse(&text);
println!("{}: {} scrolls, {} bytes serialized", path, px.scrolls.len(), px.serialize().len());
for (c, body) in &px.scrolls {
println!(" {} ({} bytes)", phext::fmt_coord(c), body.len());
}
0
}
"explode" => {
let text = match std::fs::read_to_string(&path) {
Ok(t) => t,
Err(e) => {
eprintln!("{}: {}", path, e);
return 2;
}
};
let px = phext::Phext::parse(&text);
let dir = args.get(2).cloned().unwrap_or_else(|| "exploded".into());
for (c, body) in &px.scrolls {
let f = format!("{}/{}.scroll", dir, phext::fmt_coord(c).replace('/', "-"));
let _ = std::fs::create_dir_all(&dir);
if std::fs::write(&f, body).is_err() {
eprintln!("cannot write {}", f);
return 2;
}
}
println!("exploded {} scrolls into {}/", px.scrolls.len(), dir);
0
}
"seal" => {
let bytes = match std::fs::read(&path) {
Ok(b) => b,
Err(e) => {
eprintln!("{}: {}", path, e);
return 2;
}
};
let sealed = xz::encode_stored(&bytes);
let out = format!("{}.xz", path);
match std::fs::write(&out, &sealed) {
Ok(()) => {
println!("sealed {} -> {} ({} bytes; stored-form seal, compressible form interchangeable)", path, out, sealed.len());
0
}
Err(e) => {
eprintln!("{}", e);
2
}
}
}
"unseal" => {
let bytes = match std::fs::read(&path) {
Ok(b) => b,
Err(e) => {
eprintln!("{}: {}", path, e);
return 2;
}
};
match xz::unseal(&bytes) {
Ok(raw) => {
print!("{}", String::from_utf8_lossy(&raw));
0
}
Err(e) => {
eprintln!("unseal: {}", e);
1
}
}
}
"select" | "get" => {
// Two forms: `qexo select <file> <coord>` reads any
// phext file; `qexo select <coord>` reads this node's
// state. Before v1.3.0 the one-argument form took the
// coordinate AS the file path and reported it missing
// ("<coord>: The system cannot find the path
// specified") — the coordinate was never a path; the
// verb simply had no state form.
let (path, coord_s) = if args.len() >= 3 {
(args[1].clone(), args[2].clone())
} else if args.len() == 2 && phext::parse_coord(&args[1]).is_some() {
(lattice::state_path().display().to_string(), args[1].clone())
} else {
eprintln!("usage: qexo select <file> <coord> — or qexo select <coord> for this node's state");
return 2;
};
let text = match std::fs::read_to_string(&path) {
Ok(t) => t,
Err(e) => {
eprintln!("{}: {}", path, e);
return 2;
}
};
let px = phext::Phext::parse(&text);
match phext::parse_coord(&coord_s).and_then(|c| px.get(&c)) {
Some(body) => {
print!("{}", body);
0
}
None => {
eprintln!("no scroll at {}", coord_s);
1
}
}
}
_ => 2,
}
}