Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/website/public/agents/spec-agents.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion apps/website/public/crons/spec-crons.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion apps/website/public/docs/system-docs.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion apps/website/public/functions/spec-functions.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion apps/website/public/skills/skills-core.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"version":1,"provenance":{"manifestSha256":"cd5b4b346ddd51c1cc4f9ea81dd96a3ba3d452ad7adb33f06066b161064bbfae","specManifestSha256":"14951edb8e3b9938389547ce6680d739e74a6787aed46a360bf37e2caf584b62","indexerSha256":"e7ad55414d2d48fa05cc7e2619af06bc4d3c82d6018c8a373adf3dc7402faff3"},"skillCount":27,"coverage":{"skillsBound":["t27/tri","t27/tri-pipeline","t27/wrap-up"],"skillsUnbound":["t27/measure-corpus","t27/phi-loop","t27/wave-audit","trinity/blog-post","trinity/board-sync","trinity/cloud","trinity/connect-accounts","trinity/doctor","trinity/farm-garden","trinity/fpga-synth","trinity/god-mode","trinity/implement-issue","trinity/queen-hive-visuals","trinity/review-code","trinity/run-tests","trinity/scholar","trinity/status","trinity/tech-tree","trinity/tri","trinity/trinity-test","trinity/ux-wave","trinity/vibee-gen","trinity/vsa-verify","trinity/wave"],"skillsBroken":[],"specsWithSkill":["compiler/skill/registry.t27","specs/automation/wrapup-auto.t27","specs/pipeline/e2e_test.t27"],"specsWithoutSkill":1574,"baselineUnbound":24},"skillToSpecs":{"t27/tri":["compiler/skill/registry.t27"],"t27/tri-pipeline":["specs/pipeline/e2e_test.t27"],"t27/wrap-up":["specs/automation/wrapup-auto.t27"]},"specToSkills":{"compiler/skill/registry.t27":["t27/tri"],"specs/automation/wrapup-auto.t27":["t27/wrap-up"],"specs/pipeline/e2e_test.t27":["t27/tri-pipeline"]}}
{"version":1,"provenance":{"manifestSha256":"cd5b4b346ddd51c1cc4f9ea81dd96a3ba3d452ad7adb33f06066b161064bbfae","specManifestSha256":"1d4f0f9c9c294ff7ddb8e243dbff6ecba46925f7dd5166eeb01a5e92391d7f56","indexerSha256":"e7ad55414d2d48fa05cc7e2619af06bc4d3c82d6018c8a373adf3dc7402faff3"},"skillCount":27,"coverage":{"skillsBound":["t27/tri","t27/tri-pipeline","t27/wrap-up"],"skillsUnbound":["t27/measure-corpus","t27/phi-loop","t27/wave-audit","trinity/blog-post","trinity/board-sync","trinity/cloud","trinity/connect-accounts","trinity/doctor","trinity/farm-garden","trinity/fpga-synth","trinity/god-mode","trinity/implement-issue","trinity/queen-hive-visuals","trinity/review-code","trinity/run-tests","trinity/scholar","trinity/status","trinity/tech-tree","trinity/tri","trinity/trinity-test","trinity/ux-wave","trinity/vibee-gen","trinity/vsa-verify","trinity/wave"],"skillsBroken":[],"specsWithSkill":["compiler/skill/registry.t27","specs/automation/wrapup-auto.t27","specs/pipeline/e2e_test.t27"],"specsWithoutSkill":1692,"baselineUnbound":24},"skillToSpecs":{"t27/tri":["compiler/skill/registry.t27"],"t27/tri-pipeline":["specs/pipeline/e2e_test.t27"],"t27/wrap-up":["specs/automation/wrapup-auto.t27"]},"specToSkills":{"compiler/skill/registry.t27":["t27/tri"],"specs/automation/wrapup-auto.t27":["t27/wrap-up"],"specs/pipeline/e2e_test.t27":["t27/tri-pipeline"]}}
2 changes: 1 addition & 1 deletion apps/website/public/skills/spec-skills.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,22 @@ module TrinityMemoryBridgeSpec {
pub const TMS_BRIDGE_IDENTITY_BYTES: u32 = 16;
pub const TMS_BRIDGE_IDENTITY_ANCHOR: u32 = 18368;

// 10. Device backend (issue #64; a fork-local extension, not in the upstream
// emulator-only v1 copy). The emulator stays the default and every
// emulator response is unchanged. Backend fpga reports the device
// transport and the evidence block of the captures the build ran with:
// bitstream sha256, capture sha256, IDCODE and DNA. A server constructed
// with backend fpga but without the whole evidence block is rejected at
// construction, and its device methods answer with the transport error
// until a device is linked behind them.
pub const TMS_BRIDGE_TRANSPORT_IN_PROCESS: u32 = 0;
pub const TMS_BRIDGE_TRANSPORT_UART: u32 = 1;
pub const TMS_BRIDGE_EVIDENCE_BITSTREAM: u32 = 1;
pub const TMS_BRIDGE_EVIDENCE_CAPTURE: u32 = 2;
pub const TMS_BRIDGE_EVIDENCE_IDCODE: u32 = 4;
pub const TMS_BRIDGE_EVIDENCE_DNA: u32 = 8;
pub const TMS_BRIDGE_EVIDENCE_REQUIRED: u32 = 15;

// Reference functions.
pub fn tms_bridge_request_status(size: u64, max_request: u64, json_valid: bool) -> i32 {
if (size > max_request) { return TMS_HTTP_PAYLOAD_TOO_LARGE; }
Expand Down Expand Up @@ -260,6 +276,33 @@ module TrinityMemoryBridgeSpec {
+ max_trits * TMS_BRIDGE_RESPONSE_BYTES_PER_TRIT;
}

pub fn tms_bridge_backend_valid(backend: u32) -> bool {
return backend == 0 || backend == 1;
}

pub fn tms_bridge_backend_is_hardware(backend: u32) -> bool {
return backend == 1;
}

// The emulator computes in process; the device backend reaches the board over
// the loader's UART line.
pub fn tms_bridge_transport_valid(backend: u32, transport: u32) -> bool {
if (backend == 0) { return transport == TMS_BRIDGE_TRANSPORT_IN_PROCESS; }
return transport == TMS_BRIDGE_TRANSPORT_UART;
}

// The emulator carries no evidence; the device backend requires all four fields.
pub fn tms_bridge_evidence_valid(backend: u32, present: u32) -> bool {
if (backend == 0) { return present == 0; }
return present == TMS_BRIDGE_EVIDENCE_REQUIRED;
}

// A device identity needs a nonzero IDCODE read from the board (0x3636093 on
// the AX7203, XC7A200T); DNA covers the rest of the receipt.
pub fn tms_bridge_idcode_valid(idcode: u32) -> bool {
return idcode != 0;
}

// Invariants: constant expressions, compiled as static assertions.
invariant error_codes_are_distinct_and_negative {
assert TMS_RPC_ERR_PARSE < TMS_RPC_ERR_INTERNAL && TMS_RPC_ERR_INTERNAL < TMS_RPC_ERR_INVALID_PARAMS
Expand Down Expand Up @@ -313,6 +356,10 @@ module TrinityMemoryBridgeSpec {
assert TMS_HTTP_OK == 200 && TMS_HTTP_BAD_REQUEST == 400 && TMS_HTTP_FORBIDDEN == 403 && TMS_HTTP_METHOD_NOT_ALLOWED == 405
&& TMS_HTTP_PAYLOAD_TOO_LARGE == 413 && TMS_HTTP_UNSUPPORTED_MEDIA_TYPE == 415 && TMS_HTTP_HEADERS_TOO_LARGE == 431;
}
invariant evidence_mask_is_the_sum_of_its_four_fields {
assert TMS_BRIDGE_EVIDENCE_REQUIRED == (TMS_BRIDGE_EVIDENCE_BITSTREAM | TMS_BRIDGE_EVIDENCE_CAPTURE
| TMS_BRIDGE_EVIDENCE_IDCODE | TMS_BRIDGE_EVIDENCE_DNA);
}

// Tests execute in the generated C test runner.
test "request size and json validity decide the http status" {
Expand Down Expand Up @@ -412,4 +459,18 @@ module TrinityMemoryBridgeSpec {
assert tms_bridge_request_capacity(2097152) == 2162688;
assert tms_bridge_response_capacity(524288, 1000000) == 41064960;
}
test "the emulator is the default and the device backend needs its transport" {
assert tms_bridge_backend_valid(0) && tms_bridge_backend_valid(1);
assert !tms_bridge_backend_valid(2);
assert !tms_bridge_backend_is_hardware(0) && tms_bridge_backend_is_hardware(1);
assert tms_bridge_transport_valid(0, 0) && !tms_bridge_transport_valid(0, 1);
assert tms_bridge_transport_valid(1, 1) && !tms_bridge_transport_valid(1, 0);
}
test "the device backend requires the whole evidence block and the emulator none" {
assert tms_bridge_evidence_valid(0, 0) && !tms_bridge_evidence_valid(0, 15);
assert tms_bridge_evidence_valid(1, 15) && !tms_bridge_evidence_valid(1, 0);
assert !tms_bridge_evidence_valid(1, 7) && !tms_bridge_evidence_valid(1, 31);
// 0x3636093 in decimal digits: the Artix-7 XC7A200T of the AX7203.
assert tms_bridge_idcode_valid(56762515) && tms_bridge_idcode_valid(1) && !tms_bridge_idcode_valid(0);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ struct TMBridgeState {
json_tokens: []TMJsonToken, token_capacity: usize,
json_arena: []u8, arena_capacity: usize,
tensor_work: *TMTPJSONWorkspace,
backend: u32, transport: u32, evidence: u32,
ev_idcode: u32, ev_dna: u64, ev_bitstream: []u8, ev_capture: []u8,
}

fn tm_bridge_put(w: *TMJsonWriter, byte: u8) -> void { tm_json_write_byte(w, byte); }
Expand Down Expand Up @@ -126,6 +128,12 @@ fn tm_bridge_init(s: *TMBridgeState) -> i32 {
|| s.max_storage_bytes == 0 || s.max_trits == 0
|| s.max_trits > s.value_capacity || s.temporary_capacity < s.object_capacity
|| s.object_capacity > s.pool_capacity / s.slot_capacity) { return -1; }
// The backend seam of issue #64: the emulator (0, in-process, no evidence) is
// the default; the device backend (1) requires the UART transport, the whole
// evidence block (specs/memory/bridge.t27 10) and a nonzero IDCODE.
if (s.backend > 1) { return -1; }
if (s.backend == 0 && (s.transport != 0 || s.evidence != 0)) { return -1; }
if (s.backend == 1 && (s.transport != 1 || s.evidence != 15 || s.ev_idcode == 0)) { return -1; }
var i: usize = 0;
while (i < s.slot_capacity) { s.slots[i].active = false; s.slots[i].size = 0; i = i + 1; }
s.stored_bytes = 0; s.object_count = 0;
Expand All @@ -140,6 +148,40 @@ fn tm_bridge_codec_name(codec: i32) -> str {
return "sparse82";
}

// Backend and identity text of the seam (specs/memory/bridge.t27 10): the emulator
// fields are exactly the v1 strings; the device fields add transport and evidence.
fn tm_bridge_backend_name(s: *TMBridgeState, w: *TMJsonWriter) -> void {
tm_bridge_text(w, "\"backend\":\"");
tm_bridge_text(w, tm_backend_name(s.backend));
tm_bridge_put(w, 34);
}
fn tm_backend_name(backend: u32) -> str {
if (backend == 1) { return "fpga"; }
return "emulator";
}
fn tm_bridge_backend_fields(s: *TMBridgeState, w: *TMJsonWriter) -> void {
if (s.backend == 0) {
tm_bridge_text(w, "\"backend\":\"emulator\",\"hardware\":false");
return;
}
tm_bridge_text(w, "\"backend\":\"fpga\",\"hardware\":true,\"transport\":\"uart\"");
}
fn tm_bridge_evidence_block(s: *TMBridgeState, w: *TMJsonWriter) -> void {
tm_bridge_text(w, "{\"bitstream_sha256\":\"");
tm_bridge_hex(w, s.ev_bitstream, 32);
tm_bridge_text(w, "\",\"capture_sha256\":\"");
tm_bridge_hex(w, s.ev_capture, 32);
tm_bridge_text(w, "\",\"idcode\":"); tm_bridge_unsigned(w, s.ev_idcode as u64);
// DNA prints as sixteen big-endian hex digits, the order of the board records.
tm_bridge_text(w, ",\"dna\":\"");
var d: u32 = 0;
while (d < 16) {
tm_bridge_put(w, tm_bridge_hex_digit(((s.ev_dna >> ((15 - d) << 2)) & 15) as u8));
d = d + 1;
}
tm_bridge_text(w, "\"}");
}

struct TMBridgeError { code: i32, message: str, }
fn tm_bridge_error(e: *TMBridgeError, code: i32, message: str) -> i32 {
e.code = code; e.message = message; return code;
Expand Down Expand Up @@ -236,22 +278,35 @@ fn tm_bridge_inspect(s: *TMBridgeState, data: []u8, size: usize, e: *TMBridgeErr
tm_bridge_error(e, -32602, "upload must contain a valid TMEM or TensorPack container"); return -1;
}
fn tm_bridge_capabilities(s: *TMBridgeState, w: *TMJsonWriter) -> void {
tm_bridge_text(w, "{\"protocol\":\"trinity-memory-bridge\",\"version\":1,\"backend\":\"emulator\",\"hardware\":false,\"persistence\":\"process-memory\",\"authentication\":\"none-loopback-only\",\"formats\":[\"TMEM/1\",\"TensorPack/1\"],\"codecs\":[\"baseline2\",\"dense5\",\"dense17\",\"dense22\",\"sparse41\",\"sparse82\"],\"methods\":[\"trinity.capabilities\",\"memory.upload\",\"memory.read\",\"memory.info\",\"memory.delete\",\"compute.dot\",\"chip_info\",\"trinity_chipInfo\"],\"limits\":{\"max_request_bytes\":");
tm_bridge_text(w, "{\"protocol\":\"trinity-memory-bridge\",\"version\":1,");
tm_bridge_backend_fields(s, w);
tm_bridge_text(w, ",\"persistence\":\"process-memory\",\"authentication\":\"none-loopback-only\",\"formats\":[\"TMEM/1\",\"TensorPack/1\"],\"codecs\":[\"baseline2\",\"dense5\",\"dense17\",\"dense22\",\"sparse41\",\"sparse82\"],\"methods\":[\"trinity.capabilities\",\"memory.upload\",\"memory.read\",\"memory.info\",\"memory.delete\",\"compute.dot\",\"chip_info\",\"trinity_chipInfo\"],\"limits\":{\"max_request_bytes\":");
tm_bridge_unsigned(w, s.max_request_bytes as u64);
tm_bridge_text(w, ",\"max_object_bytes\":"); tm_bridge_unsigned(w, s.object_capacity as u64);
tm_bridge_text(w, ",\"max_storage_bytes\":"); tm_bridge_unsigned(w, s.max_storage_bytes as u64);
tm_bridge_text(w, ",\"max_objects\":"); tm_bridge_unsigned(w, s.slot_capacity as u64);
tm_bridge_text(w, ",\"max_trits\":"); tm_bridge_unsigned(w, s.max_trits as u64);
tm_bridge_text(w, "}}");
tm_bridge_text(w, "}");
if (s.backend == 1) {
tm_bridge_text(w, ",\"evidence\":");
tm_bridge_evidence_block(s, w);
}
tm_bridge_text(w, "}");
}
fn tm_bridge_identity(w: *TMJsonWriter, old_name: bool) -> void {
fn tm_bridge_identity(s: *TMBridgeState, w: *TMJsonWriter, old_name: bool) -> void {
// These public constants are SHA256("trinity-memory-emulator-v1:"+part)[:16].
if (old_name) {
tm_bridge_text(w, "{\"phi\":\"7f2a2badfec845842e9d0890f06b68ad\",\"euler\":\"753ddc8a3afc49c2d25fb1e66391c65f\",\"gamma\":\"71f69df85da14b24f17e187e95bbd35b\",\"anchor\":\"0x47C0\"");
} else {
tm_bridge_text(w, "{\"phi_id\":\"7f2a2badfec845842e9d0890f06b68ad\",\"euler_id\":\"753ddc8a3afc49c2d25fb1e66391c65f\",\"gamma_id\":\"71f69df85da14b24f17e187e95bbd35b\",\"anchor\":18368");
}
tm_bridge_text(w, ",\"backend\":\"emulator\",\"hardware\":false,\"identity_kind\":\"synthetic-public-16-byte\",\"status\":\"memory emulator\"}");
if (s.backend == 0) {
tm_bridge_text(w, ",\"backend\":\"emulator\",\"hardware\":false,\"identity_kind\":\"synthetic-public-16-byte\",\"status\":\"memory emulator\"}");
return;
}
tm_bridge_text(w, ",\"backend\":\"fpga\",\"hardware\":true,\"transport\":\"uart\",\"identity_kind\":\"device-evidence\",\"status\":\"memory device\",\"evidence\":");
tm_bridge_evidence_block(s, w);
tm_bridge_put(w, 125);
}

fn tm_bridge_u64_array(w: *TMJsonWriter, values: []u64, count: usize) -> void {
Expand Down Expand Up @@ -393,7 +448,9 @@ fn tm_bridge_dot(s: *TMBridgeState, slot: usize, name: i64, activations: i64,
var scale: usize = 0; if (scale_axis == 0) { scale = row; }
tm_bridge_float(w, scales[scale]); row = row + 1;
}
tm_bridge_text(w, "],\"backend\":\"emulator\",\"arithmetic\":\"exact-integer\",\"tensor_name\":");
tm_bridge_text(w, "],");
tm_bridge_backend_name(s, w);
tm_bridge_text(w, ",\"arithmetic\":\"exact-integer\",\"tensor_name\":");
tm_bridge_string(w, tokens[name].text, tokens[name].text_size);
tm_bridge_text(w, ",\"input_shape\":"); tm_bridge_u64_array(w, shape, rank);
tm_bridge_text(w, ",\"output_shape\":["); tm_bridge_unsigned(w, rows as u64);
Expand Down Expand Up @@ -438,7 +495,7 @@ fn tm_bridge_upload(s: *TMBridgeState, data_token: i64, w: *TMJsonWriter, e: *TM
if (!unique) { return tm_bridge_error(e, -32603, "internal RPC error"); }
tm_bridge_text(w, "{\"handle\":"); tm_bridge_handle(w, &candidate);
tm_bridge_text(w, ",\"bytes\":"); tm_bridge_unsigned(w, size as u64);
tm_bridge_text(w, ",\"backend\":\"emulator\"}");
tm_bridge_put(w, 44); tm_bridge_backend_name(s, w); tm_bridge_put(w, 125);
// Reserve the final response-envelope byte before committing any mutation.
if (w.error != 0 || w.used >= w.capacity) { return tm_bridge_error(e, -32603, "internal RPC error"); }
var offset: usize = target * s.object_capacity; var i: usize = 0;
Expand All @@ -454,10 +511,11 @@ fn tm_bridge_dispatch(s: *TMBridgeState, method: i64, params: i64, w: *TMJsonWri
}
if (tm_bridge_token_equal(tokens, method, "chip_info") || tm_bridge_token_equal(tokens, method, "trinity_chipInfo")) {
if (!tm_bridge_fields(tokens, params, 0, 0)) { return tm_bridge_error(e, -32602, "invalid method parameters"); }
tm_bridge_identity(w, tm_bridge_token_equal(tokens, method, "chip_info")); return 0;
tm_bridge_identity(s, w, tm_bridge_token_equal(tokens, method, "chip_info")); return 0;
}
if (tm_bridge_token_equal(tokens, method, "memory.upload")) {
if (!tm_bridge_fields(tokens, params, 1, 1)) { return tm_bridge_error(e, -32602, "invalid method parameters"); }
if (s.backend == 1) { return tm_bridge_error(e, -32000, "device transport not linked in this process"); }
return tm_bridge_upload(s, tm_bridge_field(tokens, params, "data"), w, e);
}
var reading: bool = tm_bridge_token_equal(tokens, method, "memory.read");
Expand All @@ -469,6 +527,7 @@ fn tm_bridge_dispatch(s: *TMBridgeState, method: i64, params: i64, w: *TMJsonWri
if (reading) { allowed = 14; }
if (dot) { required = 50; allowed = 50; }
if (!tm_bridge_fields(tokens, params, required, allowed)) { return tm_bridge_error(e, -32602, "invalid method parameters"); }
if (s.backend == 1) { return tm_bridge_error(e, -32000, "device transport not linked in this process"); }
var found: i64 = tm_bridge_find_slot(s, tm_bridge_field(tokens, params, "handle"), e);
if (found < 0) { return e.code; }
var slot: usize = found as usize; var size: usize = s.slots[slot].size;
Expand All @@ -490,7 +549,7 @@ fn tm_bridge_dispatch(s: *TMBridgeState, method: i64, params: i64, w: *TMJsonWri
tm_bridge_text(w, "\",\"offset\":"); tm_bridge_unsigned(w, offset as u64);
tm_bridge_text(w, ",\"length\":"); tm_bridge_unsigned(w, length as u64);
tm_bridge_text(w, ",\"total_bytes\":"); tm_bridge_unsigned(w, size as u64);
tm_bridge_text(w, ",\"backend\":\"emulator\"}"); return 0;
tm_bridge_put(w, 44); tm_bridge_backend_name(s, w); tm_bridge_put(w, 125); return 0;
}
if (info) {
var count: i64 = tm_bridge_inspect(s, data, size, e);
Expand All @@ -501,10 +560,12 @@ fn tm_bridge_dispatch(s: *TMBridgeState, method: i64, params: i64, w: *TMJsonWri
else { tm_bridge_tp_info(s, w, data, size, count as u64); }
tm_bridge_text(w, ",\"handle\":"); tm_bridge_handle(w, &s.slots[slot]);
tm_bridge_text(w, ",\"sha256\":\""); tm_bridge_hex(w, digest, 32);
tm_bridge_text(w, "\",\"backend\":\"emulator\"}"); return 0;
tm_bridge_text(w, "\","); tm_bridge_backend_name(s, w); tm_bridge_put(w, 125); return 0;
}
if (deleting) {
tm_bridge_text(w, "{\"deleted\":true,\"backend\":\"emulator\"}");
tm_bridge_text(w, "{\"deleted\":true,");
tm_bridge_backend_name(s, w);
tm_bridge_put(w, 125);
if (w.error != 0 || w.used >= w.capacity) { return tm_bridge_error(e, -32603, "internal RPC error"); }
s.slots[slot].active = false; s.slots[slot].size = 0;
s.object_count = s.object_count - 1; s.stored_bytes = s.stored_bytes - size;
Expand Down
Loading