tensorfs 0.1.0__tar.gz → 0.1.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {tensorfs-0.1.0 → tensorfs-0.1.2}/Cargo.lock +2 -2
- {tensorfs-0.1.0 → tensorfs-0.1.2}/Cargo.toml +1 -1
- {tensorfs-0.1.0 → tensorfs-0.1.2}/PKG-INFO +1 -1
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/src/bin/tfs/ckpt.rs +7 -25
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/src/bin/tfs/conform.rs +4 -1
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/src/bin/tfs/ingest.rs +6 -14
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/src/bin/tfs/layout.rs +110 -147
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/src/bin/tfs/main.rs +89 -56
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/src/bin/tfs/rd.rs +8 -8
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/src/bin/tfs/repo.rs +298 -29
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/src/checkpoint.rs +32 -3
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/src/corpus.rs +7 -19
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/src/derived.rs +171 -15
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/src/fetch.rs +159 -2
- tensorfs-0.1.0/crates/tensorfs-core/src/compat.rs → tensorfs-0.1.2/crates/tensorfs-core/src/fit.rs +703 -407
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/src/grade.rs +14 -21
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/src/header.rs +90 -3
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/src/ingest/fingerprint.rs +27 -26
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/src/ingest/source.rs +12 -16
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/src/ingest/transaction.rs +5 -6
- tensorfs-0.1.2/crates/tensorfs-core/src/jcs.rs +527 -0
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/src/lib.rs +4 -6
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/src/machine.rs +89 -8
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/src/read.rs +21 -2
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/src/repository.rs +414 -271
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/src/storage.rs +528 -80
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/src/store.rs +6 -3
- tensorfs-0.1.2/crates/tensorfs-core/tests/fixtures/repo_apply/evidence.json +1 -0
- tensorfs-0.1.2/crates/tensorfs-core/tests/fixtures/repo_apply/expected_list.jsonl +1 -0
- tensorfs-0.1.2/crates/tensorfs-core/tests/fixtures/repo_apply/expected_repository.json +1 -0
- tensorfs-0.1.2/crates/tensorfs-core/tests/fixtures/repo_apply/expected_rows.jsonl +3 -0
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/tests/grade.rs +9 -86
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/tests/liveness.rs +0 -2
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/tests/repo_store.rs +51 -18
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/tests/source_plan.rs +1 -9
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/tests/topology_projection.rs +15 -20
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-py/src/docs.rs +135 -10
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-py/src/lib.rs +7 -1
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-py/src/store.rs +44 -9
- {tensorfs-0.1.0 → tensorfs-0.1.2}/pyproject.toml +1 -1
- {tensorfs-0.1.0 → tensorfs-0.1.2}/python/tensorfs/__init__.py +34 -6
- tensorfs-0.1.0/crates/tensorfs-core/src/bin/tfs/fixtures.rs +0 -286
- tensorfs-0.1.0/crates/tensorfs-core/src/structure.rs +0 -282
- tensorfs-0.1.0/crates/tensorfs-core/src/verifier.rs +0 -256
- tensorfs-0.1.0/crates/tensorfs-core/tests/fixtures/repo_apply/evidence.json +0 -1
- tensorfs-0.1.0/crates/tensorfs-core/tests/fixtures/repo_apply/expected_list.jsonl +0 -1
- tensorfs-0.1.0/crates/tensorfs-core/tests/fixtures/repo_apply/expected_repository.json +0 -1
- tensorfs-0.1.0/crates/tensorfs-core/tests/fixtures/repo_apply/expected_rows.jsonl +0 -3
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/Cargo.toml +0 -0
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/src/b64.rs +0 -0
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/src/bin/tfs/fetch.rs +0 -0
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/src/bin/tfs/snap.rs +0 -0
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/src/bin/tfs/watch.rs +0 -0
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/src/canon.rs +0 -0
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/src/capability.rs +0 -0
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/src/catalog.rs +0 -0
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/src/cbor.rs +0 -0
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/src/dtype.rs +0 -0
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/src/err.rs +0 -0
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/src/fill.rs +0 -0
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/src/ids.rs +0 -0
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/src/ingest/carrier.rs +0 -0
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/src/ingest/convert.rs +0 -0
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/src/ingest/gguf.rs +0 -0
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/src/ingest/mod.rs +0 -0
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/src/ingest/stamp.rs +0 -0
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/src/limits.rs +0 -0
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/src/manifest.rs +0 -0
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/src/meta.rs +0 -0
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/src/project.rs +0 -0
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/src/receipt.rs +0 -0
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/src/registry.rs +0 -0
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/src/relation.rs +0 -0
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/src/sha256.rs +0 -0
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/src/spec.rs +0 -0
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/src/vectors.rs +0 -0
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/tests/fixtures/repo_apply/blobs.jsonl +0 -0
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/tests/fixtures/repo_apply/header.cbor +0 -0
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/tests/fixtures/repo_apply/manifest.json +0 -0
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-core/tests/fixtures/repo_apply/mutation.json +0 -0
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-py/Cargo.toml +0 -0
- {tensorfs-0.1.0 → tensorfs-0.1.2}/crates/tensorfs-py/src/errors.rs +0 -0
- {tensorfs-0.1.0 → tensorfs-0.1.2}/python/tensorfs/errors.py +0 -0
|
@@ -249,7 +249,7 @@ checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca"
|
|
|
249
249
|
|
|
250
250
|
[[package]]
|
|
251
251
|
name = "tensorfs-core"
|
|
252
|
-
version = "0.1.
|
|
252
|
+
version = "0.1.2"
|
|
253
253
|
dependencies = [
|
|
254
254
|
"fs2",
|
|
255
255
|
"minicbor",
|
|
@@ -258,7 +258,7 @@ dependencies = [
|
|
|
258
258
|
|
|
259
259
|
[[package]]
|
|
260
260
|
name = "tensorfs-py"
|
|
261
|
-
version = "0.1.
|
|
261
|
+
version = "0.1.2"
|
|
262
262
|
dependencies = [
|
|
263
263
|
"pyo3",
|
|
264
264
|
"tensorfs-core",
|
|
@@ -543,13 +543,18 @@ pub fn cmd_read(root: &Path, hex: &str, f: &Flags) -> ExitCode {
|
|
|
543
543
|
ExitCode::SUCCESS
|
|
544
544
|
}
|
|
545
545
|
|
|
546
|
-
// ------------------------------------------------------------------ info / locate
|
|
546
|
+
// ------------------------------------------------------------------ info / locate
|
|
547
547
|
|
|
548
548
|
pub fn cmd_info(root: &Path, hex: &str) -> ExitCode {
|
|
549
549
|
let (store, href) = opened!(root, hex);
|
|
550
550
|
let header = ok!(ck::load_header(&store, &href));
|
|
551
551
|
println!("header {} ({} B)", href.id(), href.length);
|
|
552
|
-
|
|
552
|
+
let digests = ok!(ck::digests(&store, &header));
|
|
553
|
+
println!("topology_digest {}", digests.topology_digest);
|
|
554
|
+
println!("shape_digest {}", digests.shape_digest);
|
|
555
|
+
if let Some(config) = &digests.config_digest {
|
|
556
|
+
println!("config_digest {config}");
|
|
557
|
+
}
|
|
553
558
|
for (name, c) in &header.configs {
|
|
554
559
|
println!(
|
|
555
560
|
"config {name:<14} sha256:{} {} B {}",
|
|
@@ -651,29 +656,6 @@ pub fn cmd_locate(
|
|
|
651
656
|
ExitCode::SUCCESS
|
|
652
657
|
}
|
|
653
658
|
|
|
654
|
-
pub fn cmd_admit(root: &Path, hex: &str, f: &Flags) -> ExitCode {
|
|
655
|
-
let (store, href) = opened!(root, hex);
|
|
656
|
-
let header = ok!(ck::load_header(&store, &href));
|
|
657
|
-
let closure = ok!(ck::load_closure(&store, &header));
|
|
658
|
-
let pin: Vec<String> = match flag(f, "pin") {
|
|
659
|
-
Some("empty") => Vec::new(),
|
|
660
|
-
Some(alias) => registry::seeds()
|
|
661
|
-
.iter()
|
|
662
|
-
.filter(|s| s.alias == alias)
|
|
663
|
-
.map(|s| s.spec.object_id())
|
|
664
|
-
.collect(),
|
|
665
|
-
None => registry::platform_digests(),
|
|
666
|
-
};
|
|
667
|
-
println!("local pin: {} aliased spec digests", pin.len());
|
|
668
|
-
match header.admit_for_serving(&closure, &pin) {
|
|
669
|
-
Ok(()) => {
|
|
670
|
-
println!("ADMITTED for serving: every cited spec digest carries a local alias");
|
|
671
|
-
ExitCode::SUCCESS
|
|
672
|
-
}
|
|
673
|
-
Err(e) => bail(e),
|
|
674
|
-
}
|
|
675
|
-
}
|
|
676
|
-
|
|
677
659
|
// ------------------------------------------------------------------ caps / size
|
|
678
660
|
|
|
679
661
|
/// The whole-document totals are red-armed in memory: the over-cap documents are far too
|
|
@@ -596,7 +596,10 @@ pub fn cmd_mine(rows: &std::path::Path, name: &str, f: &Flags) -> ExitCode {
|
|
|
596
596
|
if let Err(e) = EncodingVectors::parse_fixture(&bytes) {
|
|
597
597
|
return bail(e);
|
|
598
598
|
}
|
|
599
|
-
let d =
|
|
599
|
+
let d: std::path::PathBuf = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"))
|
|
600
|
+
.join("../../vectors/mined")
|
|
601
|
+
.components()
|
|
602
|
+
.collect();
|
|
600
603
|
if let Err(e) = std::fs::create_dir_all(&d) {
|
|
601
604
|
eprintln!("{}: {e}", d.display());
|
|
602
605
|
return ExitCode::FAILURE;
|
|
@@ -36,6 +36,7 @@ use tensorfs_core::ingest::convert::{self, Class, Effect, Rekey, Source, Target}
|
|
|
36
36
|
use tensorfs_core::ingest::fingerprint::{
|
|
37
37
|
self, Banked, FingerprintRegistry, SourceProfile, SourceProfileComponent, SourceProfileVariant,
|
|
38
38
|
};
|
|
39
|
+
use tensorfs_core::ingest::fingerprint::{Provenance, REAL};
|
|
39
40
|
use tensorfs_core::ingest::source as source_core;
|
|
40
41
|
use tensorfs_core::ingest::stamp::{self, Stamp};
|
|
41
42
|
use tensorfs_core::ingest::transaction::{self as tx};
|
|
@@ -44,7 +45,6 @@ use tensorfs_core::limits;
|
|
|
44
45
|
use tensorfs_core::manifest::{Draft, Entry};
|
|
45
46
|
use tensorfs_core::registry;
|
|
46
47
|
use tensorfs_core::store::{Progress, Store};
|
|
47
|
-
use tensorfs_core::structure::{Provenance, REAL};
|
|
48
48
|
|
|
49
49
|
use crate::watch::{self, Verdict, PROGRESS_PREFIX};
|
|
50
50
|
use crate::{bail, flag, flag_num, flag_on, rss_kb, Flags};
|
|
@@ -364,8 +364,8 @@ pub fn cmd_inspect(f: &Flags) -> ExitCode {
|
|
|
364
364
|
None => println!(" verdict (no registry loaded)"),
|
|
365
365
|
Some(r) => match r.classify(&fp) {
|
|
366
366
|
fingerprint::Verdict::Authorized(b) => println!(
|
|
367
|
-
" verdict AUTHORIZED {}
|
|
368
|
-
b.
|
|
367
|
+
" verdict AUTHORIZED {} via {} -> {}",
|
|
368
|
+
b.component, b.dialect, b.converter
|
|
369
369
|
),
|
|
370
370
|
fingerprint::Verdict::ComponentAmbiguous { banked_as } => println!(
|
|
371
371
|
" verdict AMBIGUOUS — this key set is reviewed, but not as \
|
|
@@ -396,13 +396,7 @@ pub fn cmd_inspect(f: &Flags) -> ExitCode {
|
|
|
396
396
|
|
|
397
397
|
/// Bank a reviewed registry entry. This is the REVIEW ACT, performed by a platform operator
|
|
398
398
|
/// against bytes they have in hand — never by an uploader and never from a filename.
|
|
399
|
-
pub fn cmd_bank(
|
|
400
|
-
dialect: &str,
|
|
401
|
-
family: &str,
|
|
402
|
-
variant: &str,
|
|
403
|
-
converter: &str,
|
|
404
|
-
f: &Flags,
|
|
405
|
-
) -> ExitCode {
|
|
399
|
+
pub fn cmd_bank(dialect: &str, converter: &str, f: &Flags) -> ExitCode {
|
|
406
400
|
let srcs = match sources(f) {
|
|
407
401
|
Ok(s) => s,
|
|
408
402
|
Err(c) => return c,
|
|
@@ -440,8 +434,6 @@ pub fn cmd_bank(
|
|
|
440
434
|
reg.merge(Banked {
|
|
441
435
|
keyset_digest: fp.keyset_digest.clone(),
|
|
442
436
|
dialect: dialect.to_string(),
|
|
443
|
-
task_family: family.to_string(),
|
|
444
|
-
structural_variant: variant.to_string(),
|
|
445
437
|
component: component.clone(),
|
|
446
438
|
converter: converter.to_string(),
|
|
447
439
|
topology_digest: fp.topology_digest.clone(),
|
|
@@ -1028,8 +1020,8 @@ pub fn cmd_plan(target: &str, f: &Flags) -> ExitCode {
|
|
|
1028
1020
|
}
|
|
1029
1021
|
for (i, b) in p.verdicts.iter().enumerate() {
|
|
1030
1022
|
println!(
|
|
1031
|
-
"verdict {}
|
|
1032
|
-
b.component, b.
|
|
1023
|
+
"verdict {} via {} -> {} ({} keys)",
|
|
1024
|
+
b.component, b.dialect, b.converter, p.fps[i].logical_keys
|
|
1033
1025
|
);
|
|
1034
1026
|
}
|
|
1035
1027
|
print_plan(&p);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
//! The layout
|
|
2
|
-
//!
|
|
1
|
+
//! The fit and layout CLI: `tfs fit` (tfs-042, the one code <-> checkpoint answer), the
|
|
2
|
+
//! grade plane's walk and ranking (search only, D11), and the round-trip registration act.
|
|
3
3
|
//!
|
|
4
|
-
//! This file is a CONSUMER of the
|
|
5
|
-
//!
|
|
4
|
+
//! This file is a CONSUMER of the decision modules. It prints answers because someone has
|
|
5
|
+
//! to; it never decides one.
|
|
6
6
|
|
|
7
7
|
use std::fs;
|
|
8
8
|
use std::io::{BufRead, BufReader, Read, Write};
|
|
@@ -10,20 +10,19 @@ use std::path::Path;
|
|
|
10
10
|
use std::process::ExitCode;
|
|
11
11
|
use std::time::Instant;
|
|
12
12
|
|
|
13
|
+
use tensorfs_core::capability::CapabilityRecords;
|
|
13
14
|
use tensorfs_core::checkpoint as ck;
|
|
14
|
-
use tensorfs_core::compat::{
|
|
15
|
-
self, Accepts, CodeTopology, CompatibilityReport, Lane, Requirement, Satisfaction,
|
|
16
|
-
};
|
|
17
15
|
use tensorfs_core::dtype::Dtype;
|
|
16
|
+
use tensorfs_core::fit::{
|
|
17
|
+
self, Accepts, CodeTopology, CompatibilityReport, Custody, Fit, Requirement,
|
|
18
|
+
};
|
|
18
19
|
use tensorfs_core::grade::{self, ConversionRegistration, Grade, GradeDecision, Mapping, Registry};
|
|
19
20
|
use tensorfs_core::header::Header;
|
|
20
21
|
use tensorfs_core::ids::{ObjectRef, Plain};
|
|
21
|
-
use tensorfs_core::ingest::fingerprint::MARKER_SUFFIXES;
|
|
22
22
|
use tensorfs_core::limits;
|
|
23
23
|
use tensorfs_core::registry;
|
|
24
24
|
use tensorfs_core::spec::EncodingSpec;
|
|
25
25
|
use tensorfs_core::store::Store;
|
|
26
|
-
use tensorfs_core::verifier::{self, VerifyRequest};
|
|
27
26
|
|
|
28
27
|
use crate::{bail, flag, flag_on, rss_kb, Flags};
|
|
29
28
|
|
|
@@ -36,10 +35,6 @@ macro_rules! ok {
|
|
|
36
35
|
};
|
|
37
36
|
}
|
|
38
37
|
|
|
39
|
-
fn markers() -> Vec<String> {
|
|
40
|
-
MARKER_SUFFIXES.iter().map(|s| s.to_string()).collect()
|
|
41
|
-
}
|
|
42
|
-
|
|
43
38
|
fn read(p: &Path) -> Result<Vec<u8>, ExitCode> {
|
|
44
39
|
fs::read(p).map_err(|e| {
|
|
45
40
|
eprintln!("REFUSED IO_FAILED: read {}: {e}", p.display());
|
|
@@ -83,6 +78,7 @@ pub fn cmd_topology(root: &Path, hex: &str, flags: &Flags) -> ExitCode {
|
|
|
83
78
|
println!("contract {}", code.contract);
|
|
84
79
|
println!("tensors {}", code.count());
|
|
85
80
|
println!("topology {}", code.topology_digest());
|
|
81
|
+
println!("shape {}", code.shape_digest());
|
|
86
82
|
ExitCode::SUCCESS
|
|
87
83
|
}
|
|
88
84
|
|
|
@@ -103,6 +99,7 @@ pub fn project(h: &Header, contract_name: &str) -> CodeTopology {
|
|
|
103
99
|
dtype: t.dtype,
|
|
104
100
|
shape: t.shape.clone(),
|
|
105
101
|
accepts: Accepts::OneOf(vec![t.encoding.clone()]),
|
|
102
|
+
pinned: false,
|
|
106
103
|
},
|
|
107
104
|
)
|
|
108
105
|
})
|
|
@@ -110,9 +107,88 @@ pub fn project(h: &Header, contract_name: &str) -> CodeTopology {
|
|
|
110
107
|
)
|
|
111
108
|
})
|
|
112
109
|
.collect(),
|
|
110
|
+
constructed_components: h.components.iter().map(|(c, _)| c.clone()).collect(),
|
|
113
111
|
}
|
|
114
112
|
}
|
|
115
113
|
|
|
114
|
+
/// `tfs fit <code-topology.json> <root> <header> [--custody local] [--device <class>
|
|
115
|
+
/// --observations <obs.json>] [--json]` — design §3, the only compatibility verdict.
|
|
116
|
+
///
|
|
117
|
+
/// `<header>` is a header object id in `<root>` or a path to header bytes. Exit 0 on
|
|
118
|
+
/// `ok`; every refusal has its own exit code so a caller can branch without parsing, and
|
|
119
|
+
/// `--json` prints the total machine document (`machine::fit_json`).
|
|
120
|
+
pub fn cmd_fit(code_p: &Path, root: &Path, header_arg: &str, flags: &Flags) -> ExitCode {
|
|
121
|
+
let code = ok!(CodeTopology::parse(&rd!(code_p)));
|
|
122
|
+
let header = match tensorfs_core::ids::hex64("header", header_arg) {
|
|
123
|
+
Ok(_) => {
|
|
124
|
+
let store = ok!(Store::open(root));
|
|
125
|
+
let length = match fs::metadata(store.object_path(header_arg)) {
|
|
126
|
+
Ok(m) => m.len(),
|
|
127
|
+
Err(e) => {
|
|
128
|
+
eprintln!("REFUSED OBJECT_ABSENT: {header_arg}: {e}");
|
|
129
|
+
return ExitCode::FAILURE;
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
ok!(ck::load_header(
|
|
133
|
+
&store,
|
|
134
|
+
&ObjectRef {
|
|
135
|
+
sha256: header_arg.to_string(),
|
|
136
|
+
length,
|
|
137
|
+
}
|
|
138
|
+
))
|
|
139
|
+
}
|
|
140
|
+
Err(_) => ok!(Header::parse(&rd!(Path::new(header_arg)))),
|
|
141
|
+
};
|
|
142
|
+
let custody = ok!(Custody::parse(
|
|
143
|
+
flag(flags, "custody").unwrap_or("canonical")
|
|
144
|
+
));
|
|
145
|
+
let observations = match flag(flags, "observations") {
|
|
146
|
+
Some(p) => Some(ok!(CapabilityRecords::parse_observed(&rd!(Path::new(p))))),
|
|
147
|
+
None => None,
|
|
148
|
+
};
|
|
149
|
+
let device = flag(flags, "device");
|
|
150
|
+
if observations.is_some() && device.is_none() {
|
|
151
|
+
eprintln!("REFUSED MISSING_FIELD: --observations names records for a --device");
|
|
152
|
+
return ExitCode::FAILURE;
|
|
153
|
+
}
|
|
154
|
+
let t = Instant::now();
|
|
155
|
+
let verdict = ok!(fit::fit(
|
|
156
|
+
&code,
|
|
157
|
+
&header,
|
|
158
|
+
custody,
|
|
159
|
+
device,
|
|
160
|
+
observations.as_ref()
|
|
161
|
+
));
|
|
162
|
+
let us = t.elapsed().as_secs_f64() * 1e6;
|
|
163
|
+
if flag_on(flags, "json") {
|
|
164
|
+
println!(
|
|
165
|
+
"{}",
|
|
166
|
+
String::from_utf8_lossy(&tensorfs_core::machine::fit_json(&verdict, custody))
|
|
167
|
+
);
|
|
168
|
+
return ExitCode::from(verdict.exit_code());
|
|
169
|
+
}
|
|
170
|
+
println!("fit {}", verdict.code());
|
|
171
|
+
println!("detail {}", verdict.text());
|
|
172
|
+
println!("custody {}", custody.name());
|
|
173
|
+
println!(
|
|
174
|
+
"shape code {} / checkpoint {} — {}",
|
|
175
|
+
&code.shape_digest()[7..19],
|
|
176
|
+
&header.shape_digest()[7..19],
|
|
177
|
+
if code.shape_digest() == header.shape_digest() {
|
|
178
|
+
"the fit index HITS"
|
|
179
|
+
} else {
|
|
180
|
+
"index miss; the answer is the walk above"
|
|
181
|
+
}
|
|
182
|
+
);
|
|
183
|
+
if let Fit::Ok { ignored, .. } = &verdict {
|
|
184
|
+
for key in ignored {
|
|
185
|
+
println!("ignored {key}");
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
println!("in {us:.0} us");
|
|
189
|
+
ExitCode::from(verdict.exit_code())
|
|
190
|
+
}
|
|
191
|
+
|
|
116
192
|
/// Build a canonical header + code topology out of NEUTRAL measured rows.
|
|
117
193
|
///
|
|
118
194
|
/// The rows carry component, key, logical dtype/shape and the measured role geometry, and
|
|
@@ -266,6 +342,7 @@ pub fn cmd_import(rows_p: &Path, flags: &Flags) -> ExitCode {
|
|
|
266
342
|
dtype,
|
|
267
343
|
shape,
|
|
268
344
|
accepts: Accepts::OneOf(vec![sid]),
|
|
345
|
+
pinned: false,
|
|
269
346
|
},
|
|
270
347
|
));
|
|
271
348
|
}
|
|
@@ -302,7 +379,8 @@ pub fn cmd_import(rows_p: &Path, flags: &Flags) -> ExitCode {
|
|
|
302
379
|
ok!(header.validate(&closure));
|
|
303
380
|
let code = CodeTopology {
|
|
304
381
|
contract: tensorfs_core::ids::object_id(provenance.as_bytes()),
|
|
305
|
-
components: vec![(component, reqs)],
|
|
382
|
+
components: vec![(component.clone(), reqs)],
|
|
383
|
+
constructed_components: vec![component],
|
|
306
384
|
};
|
|
307
385
|
if let Some(p) = flag(flags, "out-header") {
|
|
308
386
|
let _ = fs::write(p, ok!(header.canonical_bytes()));
|
|
@@ -465,22 +543,18 @@ pub fn cmd_check(code_p: &Path, header_p: &Path, flags: &Flags) -> ExitCode {
|
|
|
465
543
|
v
|
|
466
544
|
}
|
|
467
545
|
};
|
|
468
|
-
let
|
|
469
|
-
|
|
546
|
+
let custody = ok!(Custody::parse(
|
|
547
|
+
flag(flags, "custody").unwrap_or("canonical")
|
|
548
|
+
));
|
|
549
|
+
let depth = ok!(fit::Depth::parse(
|
|
470
550
|
flag(flags, "depth").unwrap_or("first-mismatch")
|
|
471
551
|
));
|
|
472
552
|
let t = Instant::now();
|
|
473
|
-
let out = ok!(
|
|
474
|
-
&code,
|
|
475
|
-
&header,
|
|
476
|
-
&closure,
|
|
477
|
-
&pin,
|
|
478
|
-
lane,
|
|
479
|
-
&markers(),
|
|
480
|
-
depth
|
|
553
|
+
let out = ok!(fit::check_compatibility(
|
|
554
|
+
&code, &header, &closure, &pin, custody, depth
|
|
481
555
|
));
|
|
482
556
|
let us = t.elapsed().as_secs_f64() * 1e6;
|
|
483
|
-
let report = ok!(CompatibilityReport::of(&code, &header,
|
|
557
|
+
let report = ok!(CompatibilityReport::of(&code, &header, custody, &out));
|
|
484
558
|
emit(&report, flags);
|
|
485
559
|
|
|
486
560
|
// The machine surface (proto-020). A caller that shells out to this command must not
|
|
@@ -497,7 +571,7 @@ pub fn cmd_check(code_p: &Path, header_p: &Path, flags: &Flags) -> ExitCode {
|
|
|
497
571
|
return ExitCode::SUCCESS;
|
|
498
572
|
}
|
|
499
573
|
|
|
500
|
-
println!("
|
|
574
|
+
println!("custody {}", custody.name());
|
|
501
575
|
println!(
|
|
502
576
|
"topology required {} / present {} — {}",
|
|
503
577
|
&report.topology_required[7..19],
|
|
@@ -510,9 +584,9 @@ pub fn cmd_check(code_p: &Path, header_p: &Path, flags: &Flags) -> ExitCode {
|
|
|
510
584
|
);
|
|
511
585
|
println!(
|
|
512
586
|
"shape required {} / present {} — {}",
|
|
513
|
-
&report.
|
|
514
|
-
&report.
|
|
515
|
-
if report.
|
|
587
|
+
&report.shape_required[7..19],
|
|
588
|
+
&report.shape_present[7..19],
|
|
589
|
+
if report.shape_required == report.shape_present {
|
|
516
590
|
"same shapes, so any difference is dtype or encoding alone (a search bucket)"
|
|
517
591
|
} else {
|
|
518
592
|
"different shapes: a different model, not a different packaging"
|
|
@@ -556,7 +630,7 @@ pub fn cmd_check(code_p: &Path, header_p: &Path, flags: &Flags) -> ExitCode {
|
|
|
556
630
|
}
|
|
557
631
|
if !out.unconsumed.is_empty() {
|
|
558
632
|
println!(
|
|
559
|
-
"unconsumed {} key(s)
|
|
633
|
+
"unconsumed {} key(s) listed and ignored on local custody, first {:?}",
|
|
560
634
|
out.unconsumed.len(),
|
|
561
635
|
out.unconsumed[0]
|
|
562
636
|
);
|
|
@@ -569,7 +643,7 @@ pub fn cmd_check(code_p: &Path, header_p: &Path, flags: &Flags) -> ExitCode {
|
|
|
569
643
|
ExitCode::SUCCESS
|
|
570
644
|
}
|
|
571
645
|
|
|
572
|
-
fn side(s: &
|
|
646
|
+
fn side(s: &fit::Side) -> String {
|
|
573
647
|
let mut v = Vec::new();
|
|
574
648
|
if let Some(d) = s.dtype {
|
|
575
649
|
v.push(d.name().to_string());
|
|
@@ -736,8 +810,8 @@ pub fn cmd_grade(report_p: &Path, flags: &Flags) -> ExitCode {
|
|
|
736
810
|
Ok(r) => r,
|
|
737
811
|
Err(c) => return c,
|
|
738
812
|
};
|
|
739
|
-
// Grading over a report ALONE cannot prove a registration closes the whole gap
|
|
740
|
-
//
|
|
813
|
+
// Grading over a report ALONE cannot prove a registration closes the whole gap; holding
|
|
814
|
+
// both documents can. `--code`/`--header` supply them here.
|
|
741
815
|
let t = Instant::now();
|
|
742
816
|
let g = match (flag(flags, "code"), flag(flags, "header")) {
|
|
743
817
|
(Some(c), Some(h)) => {
|
|
@@ -762,8 +836,7 @@ pub fn cmd_grade(report_p: &Path, flags: &Flags) -> ExitCode {
|
|
|
762
836
|
&header,
|
|
763
837
|
&closure,
|
|
764
838
|
&pin,
|
|
765
|
-
report.
|
|
766
|
-
&markers(),
|
|
839
|
+
report.custody,
|
|
767
840
|
®
|
|
768
841
|
))
|
|
769
842
|
.1
|
|
@@ -787,8 +860,8 @@ pub fn cmd_grade(report_p: &Path, flags: &Flags) -> ExitCode {
|
|
|
787
860
|
"grade {} — the {} of {} fact(s) at depth {}",
|
|
788
861
|
g.name(),
|
|
789
862
|
match report.depth {
|
|
790
|
-
|
|
791
|
-
|
|
863
|
+
fit::Depth::Full => "WORST",
|
|
864
|
+
fit::Depth::FirstMismatch => "first",
|
|
792
865
|
},
|
|
793
866
|
report.mismatches.len(),
|
|
794
867
|
report.depth.name()
|
|
@@ -954,113 +1027,3 @@ pub fn cmd_grade_stream(path: Option<&Path>, flags: &Flags) -> ExitCode {
|
|
|
954
1027
|
Ok(tensorfs_core::machine::grade_json(&decision, &report))
|
|
955
1028
|
})
|
|
956
1029
|
}
|
|
957
|
-
|
|
958
|
-
// ------------------------------------------------------------------ the hermetic verifier
|
|
959
|
-
|
|
960
|
-
/// Build a request out of loose documents, so the seam can be driven by hand.
|
|
961
|
-
pub fn cmd_request(code_p: &Path, header_p: &Path, flags: &Flags) -> ExitCode {
|
|
962
|
-
let code_topology = rd!(code_p);
|
|
963
|
-
let header_bytes = rd!(header_p);
|
|
964
|
-
let header = ok!(Header::parse(&header_bytes));
|
|
965
|
-
let mut closure = Vec::new();
|
|
966
|
-
for p in flag(flags, "closure").unwrap_or("").split(',') {
|
|
967
|
-
if !p.is_empty() {
|
|
968
|
-
closure.push(rd!(Path::new(p)));
|
|
969
|
-
}
|
|
970
|
-
}
|
|
971
|
-
let mut registrations = Vec::new();
|
|
972
|
-
for p in flag(flags, "registry").unwrap_or("").split(',') {
|
|
973
|
-
if !p.is_empty() {
|
|
974
|
-
registrations.push(rd!(Path::new(p)));
|
|
975
|
-
}
|
|
976
|
-
}
|
|
977
|
-
let pin: Vec<String> = match flag(flags, "pin") {
|
|
978
|
-
Some(p) if !p.is_empty() => p.split(',').map(|s| s.to_string()).collect(),
|
|
979
|
-
_ => header
|
|
980
|
-
.encodings
|
|
981
|
-
.iter()
|
|
982
|
-
.map(EncodingSpec::object_id)
|
|
983
|
-
.collect(),
|
|
984
|
-
};
|
|
985
|
-
let req = VerifyRequest {
|
|
986
|
-
code_topology,
|
|
987
|
-
header: header_bytes,
|
|
988
|
-
closure,
|
|
989
|
-
registrations,
|
|
990
|
-
lane: ok!(Lane::parse(flag(flags, "lane").unwrap_or("canonical"))),
|
|
991
|
-
pin,
|
|
992
|
-
known_markers: markers(),
|
|
993
|
-
};
|
|
994
|
-
emit(&req, flags);
|
|
995
|
-
println!("request {}", req.object_id());
|
|
996
|
-
println!("bytes {}", req.canonical_bytes().len());
|
|
997
|
-
ExitCode::SUCCESS
|
|
998
|
-
}
|
|
999
|
-
|
|
1000
|
-
/// The verifier process. One file in, one file out, written whole or not at all.
|
|
1001
|
-
pub fn cmd_verify(req_p: &Path, out_p: &Path, flags: &Flags) -> ExitCode {
|
|
1002
|
-
let bytes = rd!(req_p);
|
|
1003
|
-
if bytes.len() > limits::DOC_MAX_BYTES {
|
|
1004
|
-
eprintln!("REFUSED SIZE_CAP: request over the document cap");
|
|
1005
|
-
return ExitCode::FAILURE;
|
|
1006
|
-
}
|
|
1007
|
-
let t = Instant::now();
|
|
1008
|
-
let response = ok!(verifier::run(&bytes));
|
|
1009
|
-
// A dev-only truncation point, so the CONSUMER's partial-output refusal can be armed
|
|
1010
|
-
// against a real short file rather than described.
|
|
1011
|
-
let response = match flag(flags, "truncate-at") {
|
|
1012
|
-
Some(n) => response[..n.parse::<usize>().unwrap_or(0).min(response.len())].to_vec(),
|
|
1013
|
-
None => response,
|
|
1014
|
-
};
|
|
1015
|
-
let tmp = out_p.with_extension("partial");
|
|
1016
|
-
if let Err(e) = fs::write(&tmp, &response).and_then(|_| fs::rename(&tmp, out_p)) {
|
|
1017
|
-
eprintln!("REFUSED IO_FAILED: write response: {e}");
|
|
1018
|
-
return ExitCode::FAILURE;
|
|
1019
|
-
}
|
|
1020
|
-
println!(
|
|
1021
|
-
"verified {} B response in {:.2} ms, peak RSS {:.1} MiB",
|
|
1022
|
-
response.len(),
|
|
1023
|
-
t.elapsed().as_secs_f64() * 1000.0,
|
|
1024
|
-
rss_kb("VmHWM") as f64 / 1024.0
|
|
1025
|
-
);
|
|
1026
|
-
ExitCode::SUCCESS
|
|
1027
|
-
}
|
|
1028
|
-
|
|
1029
|
-
/// The verifier as a STREAM, over the same bounded document interface: one canonical
|
|
1030
|
-
/// `VerifyRequest` per line in, one canonical `VerifyResponse` per line out, each response
|
|
1031
|
-
/// still naming the sha256 of its own request. `verifier::run` is unchanged and still the
|
|
1032
|
-
/// whole verifier as a pure function of bytes to bytes — this only stops paying a process
|
|
1033
|
-
/// for each call to it, which is the end-to-end shape a catalog search wants: one code
|
|
1034
|
-
/// topology against many checkpoints without a fork per pair.
|
|
1035
|
-
///
|
|
1036
|
-
/// Every input still arrives inside its request, so the loop resolves no digest, opens no
|
|
1037
|
-
/// store and reaches no network. Long-lived does not mean stateful.
|
|
1038
|
-
pub fn cmd_verify_stream(path: Option<&Path>) -> ExitCode {
|
|
1039
|
-
let (mut reader, flush_each) = match stream_in(path) {
|
|
1040
|
-
Ok(v) => v,
|
|
1041
|
-
Err(c) => return c,
|
|
1042
|
-
};
|
|
1043
|
-
each_line(&mut reader, flush_each, verifier::run)
|
|
1044
|
-
}
|
|
1045
|
-
|
|
1046
|
-
/// The hub's side: consume a response, or refuse. Nothing between those two.
|
|
1047
|
-
pub fn cmd_consume(req_p: &Path, resp_p: &Path) -> ExitCode {
|
|
1048
|
-
let req = rd!(req_p);
|
|
1049
|
-
let resp = fs::read(resp_p).unwrap_or_default();
|
|
1050
|
-
let (report, decision) = ok!(verifier::consume(&req, &resp));
|
|
1051
|
-
println!("report {}", report.object_id());
|
|
1052
|
-
println!("lane {}", report.lane.name());
|
|
1053
|
-
match report.satisfaction() {
|
|
1054
|
-
Satisfaction::Satisfied => println!("satisfaction Satisfied"),
|
|
1055
|
-
Satisfaction::Mismatch(d) => println!(
|
|
1056
|
-
"satisfaction Mismatch {} at {}/{} ({} fact(s) at depth {})",
|
|
1057
|
-
d.code.as_str(),
|
|
1058
|
-
d.component,
|
|
1059
|
-
d.key,
|
|
1060
|
-
report.mismatches.len(),
|
|
1061
|
-
report.depth.name()
|
|
1062
|
-
),
|
|
1063
|
-
}
|
|
1064
|
-
println!("grade {}", decision.grade.name());
|
|
1065
|
-
ExitCode::SUCCESS
|
|
1066
|
-
}
|