Skip to content
Merged
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
26 changes: 21 additions & 5 deletions .github/workflows/spec-drift-guard.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,27 @@ jobs:
done
exit $STATUS

# The Zig leg was removed 2026-08-07: gen/zig/ was deleted in the repo cleanup
# (commit b0ef52c6, "minimal structure") but the leg kept diffing the now-missing
# files, so the job could never pass. Re-add the leg together with committed,
# zig-ast-check-clean gens if the Zig backend returns (current t27c master output
# fails `zig ast-check` on 66/68 specs: unused function parameters).
# The Zig leg RETURNED 2026-08-08: the gen-zig validity campaign (t27#1910,
# closed) took the backend from 66/68-invalid to 0/68, and gen/zig/ is
# committed again -- all 68 files zig-ast-check clean. Byte-exact diff
# against `t27c gen` (no formatter in the Zig path).
- name: Drift check — Zig (all specs)
working-directory: tri-net
run: |
T27C=../t27/target/release/t27c
STATUS=0
for spec in wire hello etx crc16 byte_utils mesh_routing key_management frame_buffer packet_queue congestion_control flow_control self_healing trust_manager timer transport_tx_fsm redundancy_management fault_detection lite_crypto network_metrics m3_multihop link_statistics access_control bandwidth_allocator cache_management compression_engine cross_layer_optimizer energy_aware_routing adaptive_retry link_quality_monitor multipath_router auto_config adaptive_routing anomaly_detector api_documenter area_optimization docs_generator fpga_synthesis_report health_dashboard health_monitoring integration_tests load_predictor local_processing mesh_node_sim mesh_protocol_stack multipath_routing network_coding network_orchestrator network_simulator olsr_routing pattern_predictor performance_benchmarks performance_profiler power_monitoring production_deployment production_scenarios quarantine_manager resource_scheduler swarm_coordinator test_framework timing_closure topology_visualizer traffic_animator failure_predictor hardware_validation integration_framework network_analytics packet_loss_injection test_validator; do
$T27C gen specs/${spec}.t27 > /tmp/${spec}_regen.zig
if ! diff -u gen/zig/${spec}.zig /tmp/${spec}_regen.zig; then
echo "::error file=gen/zig/${spec}.zig::DRIFT: gen/zig/${spec}.zig != t27c gen specs/${spec}.t27"
echo "Fix: t27c gen specs/${spec}.t27 > gen/zig/${spec}.zig"
STATUS=1
else
echo "gen/zig/${spec}.zig matches specs/${spec}.t27"
fi
done
exit $STATUS


# The C leg was removed 2026-08-07, same reason as the Zig leg: gen/c/ was
# deleted in the repo cleanup (commit b0ef52c6) but the leg kept diffing the
Expand Down
173 changes: 173 additions & 0 deletions gen/zig/access_control.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
// Generated from t27 spec: AccessControl (module name)
// DO NOT EDIT — generated by t27c
// phi^2 + 1/phi^2 = 3 | TRINITY

const std = @import("std");

const types = @import("types.zig");

const MAX_NODES: u32 = 8;
const ROLE_NONE: u32 = 0;
const ROLE_GUEST: u32 = 1;
const ROLE_USER: u32 = 2;
const ROLE_ADMIN: u32 = 3;
const PERMIT: u32 = 1;
const DENY: u32 = 0;
fn create_node_creds(node_id: u32, role: u32, auth_token: u32, authorized: u32) u32 {
return ((((node_id & 0xFF) << 24) | ((role & 0x3) << 22)) | ((auth_token & 0x3FF) << 12)) | ((authorized & 0x1) << 11);
}
fn get_node_id(creds: u32) u32 {
return (creds >> 24) & 0xFF;
}
fn get_role(creds: u32) u32 {
return (creds >> 22) & 0x3;
}
fn get_auth_token(creds: u32) u32 {
return (creds >> 12) & 0x3FF;
}
fn is_authorized(creds: u32) u32 {
return (creds >> 11) & 0x1;
}
fn create_policy(resource: u32, min_role: u32, guest_perm: u32, user_perm: u32, admin_perm: u32) u32 {
return (((((resource & 0xF) << 28) | ((min_role & 0x3) << 26)) | ((guest_perm & 0x1) << 25)) | ((user_perm & 0x1) << 24)) | ((admin_perm & 0x1) << 23);
}
fn get_resource(policy: u32) u32 {
return (policy >> 28) & 0xF;
}
fn get_min_role(policy: u32) u32 {
return (policy >> 26) & 0x3;
}
fn get_guest_perm(policy: u32) u32 {
return (policy >> 25) & 0x1;
}
fn get_user_perm(policy: u32) u32 {
return (policy >> 24) & 0x1;
}
fn get_admin_perm(policy: u32) u32 {
return (policy >> 23) & 0x1;
}
fn role_meets_minimum(role: u32, min_role: u32) bool {
return role >= min_role;
}
fn check_access(policy: u32, role: u32) u32 {
const min_role = get_min_role(policy);
if (!role_meets_minimum(role, min_role)) {
return DENY;
}
if (role == ROLE_GUEST) {
return get_guest_perm(policy);
} else if (role == ROLE_USER) {
return get_user_perm(policy);
} else if (role == ROLE_ADMIN) {
return get_admin_perm(policy);
}
return DENY;
}
fn verify_creds(creds: u32, provided_token: u32) bool {
if (is_authorized(creds) == 0) {
return false;
}
return get_auth_token(creds) == provided_token;
}
fn authorize_node(creds: u32) u32 {
const node_id = get_node_id(creds);
const role = get_role(creds);
const token = get_auth_token(creds);
return create_node_creds(node_id, role, token, PERMIT);
}
fn revoke_node(creds: u32) u32 {
const node_id = get_node_id(creds);
const role = get_role(creds);
const token = get_auth_token(creds);
return create_node_creds(node_id, role, token, DENY);
}
fn change_role(creds: u32, new_role: u32) u32 {
const node_id = get_node_id(creds);
const token = get_auth_token(creds);
const auth = is_authorized(creds);
return create_node_creds(node_id, new_role, token, auth);
}
fn check_resource_access(creds: u32, policy: u32, provided_token: u32) u32 {
if (!verify_creds(creds, provided_token)) {
return DENY;
}
const role = get_role(creds);
return check_access(policy, role);
}
test "create_node_creds_basic" {
const creds = create_node_creds(5, ROLE_USER, 0x123, 1);
if (!(get_node_id(creds) == 5)) @compileError("assertion failed");
if (!(get_role(creds) == ROLE_USER)) @compileError("assertion failed");
if (!(get_auth_token(creds) == 0x123)) @compileError("assertion failed");
if (!(is_authorized(creds) == 1)) @compileError("assertion failed");
}
test "create_policy_basic" {
const policy = create_policy(1, ROLE_USER, 0, 1, 1);
if (!(get_resource(policy) == 1)) @compileError("assertion failed");
if (!(get_min_role(policy) == ROLE_USER)) @compileError("assertion failed");
if (!(get_guest_perm(policy) == 0)) @compileError("assertion failed");
if (!(get_user_perm(policy) == 1)) @compileError("assertion failed");
}
test "role_meets_minimum_true" {
if (!(role_meets_minimum(ROLE_USER, ROLE_GUEST) == true)) @compileError("assertion failed");
if (!(role_meets_minimum(ROLE_ADMIN, ROLE_USER) == true)) @compileError("assertion failed");
}
test "role_meets_minimum_false" {
if (!(role_meets_minimum(ROLE_GUEST, ROLE_USER) == false)) @compileError("assertion failed");
if (!(role_meets_minimum(ROLE_USER, ROLE_ADMIN) == false)) @compileError("assertion failed");
}
test "check_access_admin" {
const policy = create_policy(1, ROLE_GUEST, 0, 0, 1);
if (!(check_access(policy, ROLE_ADMIN) == 1)) @compileError("assertion failed");
}
test "check_access_user" {
const policy = create_policy(1, ROLE_USER, 0, 1, 1);
if (!(check_access(policy, ROLE_USER) == 1)) @compileError("assertion failed");
}
test "check_access_guest_denied" {
const policy = create_policy(1, ROLE_USER, 0, 1, 1);
if (!(check_access(policy, ROLE_GUEST) == 0)) @compileError("assertion failed");
}
test "verify_creds_valid" {
const creds = create_node_creds(5, ROLE_USER, 0x123, 1);
if (!(verify_creds(creds, 0x123) == true)) @compileError("assertion failed");
}
test "verify_creds_invalid_token" {
const creds = create_node_creds(5, ROLE_USER, 0x123, 1);
if (!(verify_creds(creds, 0x999) == false)) @compileError("assertion failed");
}
test "verify_creds_unauthorized" {
const creds = create_node_creds(5, ROLE_USER, 0x123, 0);
if (!(verify_creds(creds, 0x123) == false)) @compileError("assertion failed");
}
test "authorize_node_works" {
const creds = create_node_creds(5, ROLE_USER, 0x123, 0);
const new_creds = authorize_node(creds);
if (!(is_authorized(new_creds) == 1)) @compileError("assertion failed");
}
test "revoke_node_works" {
const creds = create_node_creds(5, ROLE_USER, 0x123, 1);
const new_creds = revoke_node(creds);
if (!(is_authorized(new_creds) == 0)) @compileError("assertion failed");
}
test "change_role_works" {
const creds = create_node_creds(5, ROLE_USER, 0x123, 1);
const new_creds = change_role(creds, ROLE_ADMIN);
if (!(get_role(new_creds) == ROLE_ADMIN)) @compileError("assertion failed");
if (!(is_authorized(new_creds) == 1)) @compileError("assertion failed");
}
test "check_resource_access_full_grant" {
const creds = create_node_creds(5, ROLE_USER, 0x123, 1);
const policy = create_policy(1, ROLE_GUEST, 0, 1, 1);
if (!(check_resource_access(creds, policy, 0x123) == 1)) @compileError("assertion failed");
}
test "check_resource_access_invalid_creds" {
const creds = create_node_creds(5, ROLE_USER, 0x123, 1);
const policy = create_policy(1, ROLE_GUEST, 0, 1, 1);
if (!(check_resource_access(creds, policy, 0x999) == 0)) @compileError("assertion failed");
}
test "check_resource_access_role_too_low" {
const creds = create_node_creds(5, ROLE_GUEST, 0x123, 1);
const policy = create_policy(1, ROLE_USER, 0, 1, 1);
if (!(check_resource_access(creds, policy, 0x123) == 0)) @compileError("assertion failed");
}
34 changes: 34 additions & 0 deletions gen/zig/adaptive_retry.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Generated from t27 spec: AdaptiveRetry (module name)
// DO NOT EDIT — generated by t27c
// phi^2 + 1/phi^2 = 3 | TRINITY

const BASE_DELAY_MS: u8 = 10;
const MAX_RETRIES: u8 = 5;
const BACKOFF_MULTIPLIER: u8 = 2;
const QUALITY_HIGH: u8 = 0xCC;
const QUALITY_MEDIUM: u8 = 0x80;
fn backoff_delay_ms(attempt: u8) u16 {
_ = attempt; // unused by the spec body
@compileError("not yet implemented");
}
fn max_retries_for_quality(quality_q8: u8) u8 {
_ = quality_q8; // unused by the spec body
@compileError("not yet implemented");
}
fn should_retry(current_attempt: u8, link_quality_q8: u8) bool {
const max_retries: u8 = max_retries_for_quality(link_quality_q8);
current_attempt < max_retries;
}
fn base_probability(quality_q8: u8) u8 {
_ = quality_q8; // unused by the spec body
@compileError("not yet implemented");
}
fn retry_success_probability(attempt: u8, quality_q8: u8) u8 {
const base_prob: u8 = base_probability(quality_q8);
const decay: u8 = (base_prob / 4) * attempt;
_ = decay; // dead after const-inlining
}
fn total_retry_time(max_retries: u8) u16 {
_ = max_retries; // unused by the spec body
@compileError("not yet implemented");
}
Loading
Loading