implements PLN-0031

This commit is contained in:
bQUARKz 2026-04-19 08:40:22 +01:00
parent aaf4dff69d
commit 52785b5a8c
Signed by: bquarkz
SSH Key Fingerprint: SHA256:Z7dgqoglWwoK6j6u4QC87OveEq74WOhFN+gitsxtkf8
9 changed files with 80 additions and 27 deletions

View File

@ -64,7 +64,6 @@ pub enum Syscall {
AssetCommit = 0x6003,
AssetCancel = 0x6004,
BankInfo = 0x6101,
BankSlotInfo = 0x6102,
}
/// Canonical metadata describing a syscall using the unified slot-based ABI.

View File

@ -3,10 +3,6 @@ use crate::syscalls::{Syscall, SyscallRegistryEntry, caps};
pub(crate) const ENTRIES: &[SyscallRegistryEntry] = &[
SyscallRegistryEntry::builder(Syscall::BankInfo, "bank", "info")
.args(1)
.rets(1)
.caps(caps::BANK),
SyscallRegistryEntry::builder(Syscall::BankSlotInfo, "bank", "slot_info")
.args(2)
.rets(1)
.rets(2)
.caps(caps::BANK),
];

View File

@ -48,7 +48,6 @@ impl Syscall {
0x6003 => Some(Self::AssetCommit),
0x6004 => Some(Self::AssetCancel),
0x6101 => Some(Self::BankInfo),
0x6102 => Some(Self::BankSlotInfo),
_ => None,
}
}
@ -99,7 +98,6 @@ impl Syscall {
Self::AssetCommit => "AssetCommit",
Self::AssetCancel => "AssetCancel",
Self::BankInfo => "BankInfo",
Self::BankSlotInfo => "BankSlotInfo",
}
}
}

View File

@ -249,6 +249,22 @@ fn status_first_syscall_signatures_are_pinned() {
let asset_cancel = meta_for(Syscall::AssetCancel);
assert_eq!(asset_cancel.arg_slots, 1);
assert_eq!(asset_cancel.ret_slots, 1);
let bank_info = meta_for(Syscall::BankInfo);
assert_eq!(bank_info.arg_slots, 1);
assert_eq!(bank_info.ret_slots, 2);
}
#[test]
fn resolver_rejects_removed_bank_slot_info_identity() {
assert!(resolve_syscall("bank", "slot_info", 1).is_none());
let requested = [SyscallIdentity { module: "bank", name: "slot_info", version: 1 }];
let err = resolve_program_syscalls(&requested, caps::ALL).unwrap_err();
assert_eq!(
err,
LoadError::UnknownSyscall { module: "bank".into(), name: "slot_info".into(), version: 1 }
);
}
#[test]

View File

@ -567,19 +567,8 @@ impl NativeInterface for VirtualMachineRuntime {
used_slots: 0,
total_slots: 0,
});
let json = serde_json::to_string(&telemetry).unwrap_or_default();
ret.push_string(json);
Ok(())
}
Syscall::BankSlotInfo => {
let asset_type = match expect_int(args, 0)? as u32 {
0 => BankType::GLYPH,
1 => BankType::SOUNDS,
_ => return Err(VmFault::Trap(TRAP_TYPE, "Invalid asset type".to_string())),
};
let slot = SlotRef { asset_type, index: expect_int(args, 1)? as usize };
let json = serde_json::to_string(&hw.assets().slot_info(slot)).unwrap_or_default();
ret.push_string(json);
ret.push_int(telemetry.used_slots as i64);
ret.push_int(telemetry.total_slots as i64);
Ok(())
}
}

View File

@ -937,6 +937,60 @@ fn tick_asset_status_unknown_handle_returns_status_not_crash() {
assert_eq!(vm.operand_stack_top(1), vec![Value::Int64(LoadStatus::UnknownHandle as i64)]);
}
#[test]
fn tick_bank_info_returns_slot_summary_not_json() {
let mut runtime = VirtualMachineRuntime::new(None);
let mut vm = VirtualMachine::default();
let mut hardware = Hardware::new();
let signals = InputSignals::default();
let asset_data = test_glyph_asset_data();
hardware.assets.initialize_for_cartridge(
vec![test_glyph_asset_entry("tile_asset", asset_data.len())],
vec![prometeu_hal::asset::PreloadEntry { asset_id: 7, slot: 0 }],
AssetsPayloadSource::from_bytes(asset_data),
);
let code = assemble("PUSH_I32 0\nHOSTCALL 0\nHALT").expect("assemble");
let program = serialized_single_function_module(
code,
vec![SyscallDecl {
module: "bank".into(),
name: "info".into(),
version: 1,
arg_slots: 1,
ret_slots: 2,
}],
);
let cartridge = cartridge_with_program(program, caps::BANK);
runtime.initialize_vm(&mut vm, &cartridge).expect("runtime must initialize");
let report = runtime.tick(&mut vm, &signals, &mut hardware);
assert!(report.is_none(), "bank summary must not crash");
assert!(vm.is_halted());
assert_eq!(vm.operand_stack_top(2), vec![Value::Int64(16), Value::Int64(1)]);
}
#[test]
fn initialize_vm_rejects_removed_bank_slot_info_syscall_identity() {
let mut runtime = VirtualMachineRuntime::new(None);
let mut vm = VirtualMachine::default();
let code = assemble("PUSH_I32 0\nPUSH_I32 0\nHOSTCALL 0\nHALT").expect("assemble");
let program = serialized_single_function_module(
code,
vec![SyscallDecl {
module: "bank".into(),
name: "slot_info".into(),
version: 1,
arg_slots: 2,
ret_slots: 1,
}],
);
let cartridge = cartridge_with_program(program, caps::BANK);
let res = runtime.initialize_vm(&mut vm, &cartridge);
assert!(matches!(res, Err(CrashReport::VmInit { error: VmInitError::LoaderPatchFailed(_) })));
}
#[test]
fn tick_asset_commit_invalid_transition_returns_status_not_crash() {
let mut runtime = VirtualMachineRuntime::new(None);

View File

@ -14,7 +14,7 @@
{"type":"discussion","id":"DSC-0009","status":"open","ticket":"perf-async-background-work-lanes-for-assets-and-fs","title":"Agenda - [PERF] Async Background Work Lanes for Assets and FS","created_at":"2026-03-27","updated_at":"2026-03-27","tags":[],"agendas":[{"id":"AGD-0008","file":"workflow/agendas/AGD-0008-perf-async-background-work-lanes-for-assets-and-fs.md","status":"open","created_at":"2026-03-27","updated_at":"2026-03-27"}],"decisions":[],"plans":[],"lessons":[]}
{"type":"discussion","id":"DSC-0010","status":"open","ticket":"perf-host-desktop-frame-pacing-and-presentation","title":"Agenda - [PERF] Host Desktop Frame Pacing and Presentation","created_at":"2026-03-27","updated_at":"2026-03-27","tags":[],"agendas":[{"id":"AGD-0009","file":"workflow/agendas/AGD-0009-perf-host-desktop-frame-pacing-and-presentation.md","status":"open","created_at":"2026-03-27","updated_at":"2026-03-27"}],"decisions":[],"plans":[],"lessons":[]}
{"type":"discussion","id":"DSC-0011","status":"open","ticket":"perf-gfx-render-pipeline-and-dirty-regions","title":"Agenda - [PERF] GFX Render Pipeline and Dirty Regions","created_at":"2026-03-27","updated_at":"2026-03-27","tags":[],"agendas":[{"id":"AGD-0010","file":"workflow/agendas/AGD-0010-perf-gfx-render-pipeline-and-dirty-regions.md","status":"open","created_at":"2026-03-27","updated_at":"2026-03-27"}],"decisions":[],"plans":[],"lessons":[]}
{"type":"discussion","id":"DSC-0012","status":"review","ticket":"perf-runtime-introspection-syscalls","title":"Agenda - [PERF] Runtime Introspection Syscalls","created_at":"2026-03-27","updated_at":"2026-04-19","tags":["perf","runtime","syscall","telemetry","debug","asset"],"agendas":[{"id":"AGD-0011","file":"workflow/agendas/AGD-0011-perf-runtime-introspection-syscalls.md","status":"accepted","created_at":"2026-03-27","updated_at":"2026-04-18"}],"decisions":[{"id":"DEC-0009","file":"workflow/decisions/DEC-0009-host-owned-debug-and-certification.md","status":"accepted","created_at":"2026-04-18","updated_at":"2026-04-19","ref_agenda":"AGD-0011"}],"plans":[{"id":"PLN-0030","file":"workflow/plans/PLN-0030-dec9-spec-boundary-propagation.md","status":"done","created_at":"2026-04-19","updated_at":"2026-04-19","ref_decisions":["DEC-0009"]},{"id":"PLN-0031","file":"workflow/plans/PLN-0031-dec9-runtime-bank-abi-cleanup.md","status":"review","created_at":"2026-04-19","updated_at":"2026-04-19","ref_decisions":["DEC-0009"]},{"id":"PLN-0032","file":"workflow/plans/PLN-0032-dec9-host-debugger-and-certification-alignment.md","status":"review","created_at":"2026-04-19","updated_at":"2026-04-19","ref_decisions":["DEC-0009"]}],"lessons":[]}
{"type":"discussion","id":"DSC-0012","status":"review","ticket":"perf-runtime-introspection-syscalls","title":"Agenda - [PERF] Runtime Introspection Syscalls","created_at":"2026-03-27","updated_at":"2026-04-19","tags":["perf","runtime","syscall","telemetry","debug","asset"],"agendas":[{"id":"AGD-0011","file":"workflow/agendas/AGD-0011-perf-runtime-introspection-syscalls.md","status":"accepted","created_at":"2026-03-27","updated_at":"2026-04-18"}],"decisions":[{"id":"DEC-0009","file":"workflow/decisions/DEC-0009-host-owned-debug-and-certification.md","status":"accepted","created_at":"2026-04-18","updated_at":"2026-04-19","ref_agenda":"AGD-0011"}],"plans":[{"id":"PLN-0030","file":"workflow/plans/PLN-0030-dec9-spec-boundary-propagation.md","status":"done","created_at":"2026-04-19","updated_at":"2026-04-19","ref_decisions":["DEC-0009"]},{"id":"PLN-0031","file":"workflow/plans/PLN-0031-dec9-runtime-bank-abi-cleanup.md","status":"done","created_at":"2026-04-19","updated_at":"2026-04-19","ref_decisions":["DEC-0009"]},{"id":"PLN-0032","file":"workflow/plans/PLN-0032-dec9-host-debugger-and-certification-alignment.md","status":"review","created_at":"2026-04-19","updated_at":"2026-04-19","ref_decisions":["DEC-0009"]}],"lessons":[]}
{"type":"discussion","id":"DSC-0013","status":"done","ticket":"perf-host-debug-overlay-isolation","title":"Agenda - [PERF] Host Debug Overlay Isolation","created_at":"2026-03-27","updated_at":"2026-04-10","tags":[],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0027","file":"lessons/DSC-0013-perf-host-debug-overlay-isolation/LSN-0027-host-debug-overlay-isolation.md","status":"done","created_at":"2026-04-10","updated_at":"2026-04-10"}]}
{"type":"discussion","id":"DSC-0024","status":"done","ticket":"generic-memory-bank-slot-contract","title":"Agenda - Generic Memory Bank Slot Contract","created_at":"2026-04-10","updated_at":"2026-04-10","tags":["runtime","asset","memory-bank","slots","host"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0029","file":"lessons/DSC-0024-generic-memory-bank-slot-contract/LSN-0029-slot-first-bank-telemetry-belongs-in-asset-manager.md","status":"done","created_at":"2026-04-10","updated_at":"2026-04-10"}]}
{"type":"discussion","id":"DSC-0025","status":"done","ticket":"scene-bank-and-viewport-cache-refactor","title":"Scene Bank and Viewport Cache Refactor","created_at":"2026-04-11","updated_at":"2026-04-14","tags":["gfx","tilemap","runtime","render"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0030","file":"lessons/DSC-0025-scene-bank-and-viewport-cache-refactor/LSN-0030-canonical-scene-cache-and-resolver-split.md","status":"done","created_at":"2026-04-14","updated_at":"2026-04-14"}]}

View File

@ -2,9 +2,9 @@
id: PLN-0031
ticket: perf-runtime-introspection-syscalls
title: DEC-0009 Runtime Bank ABI Cleanup
status: review
status: done
created: 2026-04-19
completed:
completed: 2026-04-19
tags: [runtime, syscall, abi, bank, telemetry, debug]
---

View File

@ -205,10 +205,11 @@ For `asset.load`:
`DEC-0009` narrows the public bank contract:
- `bank.slot_info` is host/debug tooling surface and is not part of the canonical long-term guest ABI;
- `bank.info(bank_type) -> (used_slots, total_slots)` is the only surviving public bank diagnostic shape in v1;
- `bank.info` exists only as a cheap deterministic operational summary aligned with the slot-first bank telemetry contract from [`15-asset-management.md`](15-asset-management.md);
- `bank.slot_info` is host/debug tooling surface and is not part of the canonical public guest ABI;
- JSON-on-the-wire bank inspection payloads are not valid public ABI;
- if a public `bank.info` surface survives implementation cleanup, it must be reduced to a cheap deterministic operational summary aligned with the slot-first bank telemetry contract from [`15-asset-management.md`](15-asset-management.md);
- if no machine-facing operational need remains, `bank.info` should also be removed from the public guest ABI.
- `bank.info` returns stack values, not textual structured payloads.
### Composition surface (`composer`, v1)