Autor: Arquitecto Jefe de Sistemas Operativos Versión: v0.2 Fecha: 2026-06-23 Estado: Documento histórico (v0.44.1) — implementado parcialmente. Nota: las numeraciones de syscalls citadas (p. ej.
RAX 60–66) están obsoletas; el ABI vigente esdocs/kernel/syscalls.md(Ob 40–48, Cm 50–59).
- Resumen Ejecutivo
- Diagnóstico del Estado Actual
- Principios de Diseño
- Arquitectura Propuesta: Ob (Object Manager)
- ObObject: El Recurso Universal
- ObHandle: Referencia por Proceso
- ObDirectory: Namespace Jerárquico
- ObOperations: Despacho Polimórfico
- Security Integration
- URN Integration
- Catálogo de Object Types
- Nuevas Syscalls
- Syscalls Existentes: Migración y Compatibilidad
- Mapa de Dependencias
- Decisiones Congeladas
NeoDOS tiene un kernel funcional con 40 syscalls, un KOBJ registry plano, un sistema de handles basado en tipos hardcoded, y una URN namespace que opera en paralelo. La plataforma ha madurado hasta un punto donde la desconexión entre estos tres sistemas es un riesgo arquitectónico.
El problema: Handles, KOBJ y URN existen como sistemas separados que:
- No comparten una visión unificada de "recurso"
- No permiten consultar metadatos de un recurso a partir de un handle
- Duplican lógica de ciclo de vida (cleanup en exit vs close vs pipe manager)
- No integran seguridad (el SecurityDescriptor existe pero no se verifica en cada acceso)
La solución: Un Object Manager (Ob) al estilo NT que unifica handles, objetos, seguridad y namespace bajo una sola abstracción. No se reescribe nada — se migra progresivamente.
pub struct HandleEntry {
pub kind: u8, // HANDLE_CLOSED, HANDLE_FILE, HANDLE_PIPE_READ, ...
pub id: u32, // pipe_id, inode, device_id (polimórfico)
pub extra: u32, // drive_index, etc.
pub offset: u64, // file/readdir position
}Problemas:
kindes un enum hardcoded de 10 valores — añadir un nuevo tipo requiere cambios enhandler_close,handler_exit,handler_kill,handler_dup2ides polimórfico (inode o pipe_id o device_id según el tipo) — sin tipo seguro- No hay forma de obtener metadatos del objeto desde un handle (necesitas conocer el tipo y hacer lookup manual)
- No hay referencia cruzada con KOBJ
pub struct KObjEntry {
pub id: KObjId,
pub refcount: u32,
pub obj_type: KObjType,
pub name: [u8; 24],
pub flags: u32,
pub creation_tick: u64,
pub native_id: u64,
}Problemas:
- Es metadata-only — no tiene un puntero al recurso real (native_id no es suficiente)
- No hay operaciones asociadas (query info, set info, wait)
- No hay despacho por tipo — es una colección plana
- El refcount no está sincronizado con el handle table (un handle puede existir sin refcount en KOBJ)
pub struct UrnHandle {
pub scheme: UrnScheme,
pub drive: u8,
pub inode: u32,
pub offset: u64,
pub device_ob_path: String,
}Problemas:
- Es un sistema paralelo — UrnHandle no es un HandleEntry
- registry y kobj schemes son stubs (no implementados)
- No hay integración con handles del scheduler (no puedes pasar un UrnHandle a sys_read)
pub struct SecurityDescriptor {
pub owner: Option<Sid>,
pub group: Option<Sid>,
pub dacl: Option<Acl>,
}Problemas:
- SecurityDescriptor existe en código pero no está integrado en KOBJ entries ni en HandleEntry
- SeAccessCheck se usa en muy pocos puntos (solo syscall 50)
- No hay acceso comprobado en ObOpen / sys_open
| Problema | Impacto | Subsistemas afectados |
|---|---|---|
| Tipos de handle hardcoded | Alto | syscall/mod.rs (5+ handlers), scheduler/mod.rs, pipe.rs |
| KOBJ no vinculado a handles | Alto | sys_kobj_enum devuelve datos separados |
| URN paralelo a handles | Medio | urn.rs, syscall dispatch |
| Security no integrado | Alto | token.rs, kobj, handle dispatch |
| Cleanup duplicado | Medio | handler_exit (230 líneas), kill_pid (70 líneas), sys_close |
-
Todo es un objeto. No existe recurso del sistema que no sea representable como ObObject. Un pipe, un archivo abierto, un driver, un proceso — todos son objetos.
-
Handle → Objeto → Operación. Todo handle referencia un ObObject. Toda operación sobre un handle pasa por el Object Manager.
-
Seguridad en cada acceso. Cada ObOpen verifica acceso. Cada operación posterior usa la access_mask del handle.
-
Migración progresiva. No se rompen syscalls existentes. Las syscalls viejas se convierten en wrappers que internamente llaman al Object Manager.
-
URN es un frontend de Ob.
neodos://file/C:/fooresuelve aObOpen("\Global\FileSystem\C:\foo").
┌────────────────────────────────────────────────────────────────┐
│ USERMODE (Ring 3) │
│ libneodos: ObOpen, ObCreate, ObQueryInfo, ObSetInfo, ObEnum │
│ │ │
│ ┌──────────────────────┴──────────────────────────────────┐ │
│ │ SYSCALL LAYER (INT 0x80) │ │
│ │ Ob syscalls (RAX 60–69) + Legacy wrappers (0–53) │ │
│ └──────────────────────┬──────────────────────────────────┘ │
├─────────────────────────┼──────────────────────────────────────┤
│ KERNEL (Ring 0) │
│ ┌──────────────────────┴──────────────────────────────────┐ │
│ │ OBJECT MANAGER (Ob) │ │
│ │ │ │
│ │ ┌──────────────────────────────────────────────────┐ │ │
│ │ │ ObObjectTable │ │ │
│ │ │ ├── Vec<Option<ObObject>> (slab alloc) │ │ │
│ │ │ ├── ObOpen(path, access) → Handle │ │ │
│ │ │ ├── ObCreate(type, path, attrs) → Handle │ │ │
│ │ │ ├── ObClose(handle) │ │ │
│ │ │ ├── ObQueryInfo(handle) → ObBasicInfo │ │ │
│ │ │ ├── ObSetInfo(handle, info) │ │ │
│ │ │ ├── ObEnum(path) → Vec<ObEntry> │ │ │
│ │ │ └── ObWait(handle, reason) → KWait integration │ │ │
│ │ └──────────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ Current KOBJ registry → refactored as ObObjectTable │ │
│ │ Current HandleTable → stores ObObjectId + access_mask │ │
│ │ Current URN → frontend over ObOpen/ObEnum │ │
│ └──────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────────┘
/// Identificador único de objeto (hereda de KOBJ)
pub type ObId = u64;
/// Tipos de objeto (extensible)
#[repr(u32)]
pub enum ObType {
// Core system
Process = 1,
Thread = 2,
// I/O
File = 3,
Directory = 4,
Pipe = 5,
Device = 6,
// IPC & Sync
Event = 7,
Semaphore = 8,
Timer = 9,
// Registry
RegistryKey = 10,
RegistryValue = 11,
// Drivers & Kernel
Driver = 12,
SymbolicLink = 13,
Token = 14,
MemorySection = 15,
// Virtual
MountPoint = 16,
DirectoryObject = 17,
}
/// Operaciones polimórficas por tipo de objeto
pub struct ObOperations {
pub query_info: fn(ObId, ObInfoClass, &mut [u8]) -> Result<usize, ObError>,
pub set_info: fn(ObId, ObInfoClass, &[u8]) -> Result<(), ObError>,
pub close: fn(ObId) -> Result<(), ObError>,
pub wait: fn(ObId, ObWaitReason) -> Result<ObWaitResult, ObError>,
}
/// Objeto base del Object Manager
pub struct ObObject {
pub id: ObId,
pub obj_type: ObType,
pub name: [u8; 256],
pub sd: SecurityDescriptor,
pub refcount: u32,
pub flags: ObFlags,
pub creation_tick: u64,
pub ops: Option<&'static ObOperations>,
pub context: *mut core::ffi::c_void, // back-pointer
}ObCreate (or native creation)
↓
ObObjectTable::insert(ObObject)
↓
ObOpen(path, access)
↓
HandleTable::push { object_id, access_mask }
↓
... operations via dispatch object_id → ops →
↓
ObClose(handle)
↓
HandleTable::remove
↓
if refcount == 0 → cleanup native + ObObjectTable::remove
KOBJ actual (KObjEntry, KObjRegistry) se refactoriza como ObObjectTable:
kobj_register→ob_create_object(más parámetros)kobj_unregister→ob_destroy_object(con refcount check)kobj_lookup→ob_lookupkobj_iter_snapshot→ob_enum_snapshot
Los tests existentes de KOBJ (8) se mantienen y amplían.
pub struct HandleEntry {
pub object_id: ObId, // Referencia al ObObject
pub access_mask: u32, // ObAccess::READ | WRITE | EXEC | DELETE
pub offset: u64, // Posición (file, pipe, dir)
pub flags: u16, // HANDLE_FLAG_INHERIT, HANDLE_FLAG_PROTECT
}Fase 1 (v0.41):
- Añadir
object_id: u64al HandleEntry actual (campo nuevo) - Toda creación de handle registra un ObObject si no existe
- Los handlers existentes pueden seguir usando
kind+id
Fase 2 (v0.45):
- Eliminar
kindyiddel HandleEntry (ahora es solo object_id) - Todo acceso va via object_id → ObObject → ObOperations
- Los handlers legacy se refactorizan para usar la dispatch table
pub mod ObAccess {
pub const READ: u32 = 1 << 0;
pub const WRITE: u32 = 1 << 1;
pub const EXECUTE: u32 = 1 << 2;
pub const DELETE: u32 = 1 << 3;
pub const ALL: u32 = READ | WRITE | EXECUTE | DELETE;
}El namespace existente en kobj/namespace.rs (ObNamespace) se refactoriza como capa superior de Ob:
\Global\ — Objetos globales compartidos
\Device\ — Dispositivos físicos/lógicos
\Driver\ — NEM drivers
\FileSystem\ — Filesystems montados
\C:\ — Drive letters (symlinks a \Device\Harddisk...)
\Registry\ — Registry keys (futuro)
\Process\ — Virtual, PID-indexed
\1\ — Proceso PID 1
\Threads\ — Threads del proceso
\ObjectTypes\ — Virtual, lista de tipos registrados
\SymbolicLinks\ — Symlinks del namespace
ObNamespaceactual (BTreeMap-based) se mantiene como backend- Se añade
ob_insert_path(path, object_id)yob_resolve_path(path) → ObId - Los symlinks existentes funcionan igual
- Se añade un directorio virtual
\Process\<PID>\que se genera dinámicamente
Cada tipo de objeto registra una tabla de operaciones. El Object Manager despacha llamadas según el tipo:
fn ob_query_info(object_id: ObId, class: ObInfoClass, buf: &mut [u8]) -> Result<usize, ObError> {
let obj = ob_table.lookup(object_id)?;
match obj.ops {
Some(ops) => (ops.query_info)(object_id, class, buf),
None => Err(ObError::NotSupported),
}
}pub enum ObInfoClass {
// All objects
BasicInfo, // ObBasicInfo: type, name, refcount, flags
NameInfo, // ObNameInfo: full name string
SecurityInfo, // SecurityDescriptor
// Type-specific
FileInfo, // size, drive, inode
ProcessInfo, // pid, parent, priority, thread_count, state
ThreadInfo, // tid, pid, state, priority
PipeInfo, // capacity, refcounts
DeviceInfo, // device_id, driver_name
RegistryInfo, // key path, value count
}| ObType | query_info | set_info | close | wait |
|---|---|---|---|---|
| Process | pid, parent, priority, threads | priority | cleanup_terminated_process | waitpid |
| Thread | tid, pid, state, priority | priority | recycle_thread | thread_join |
| File | inode, drive, size, mode | offset seek | close handle | — |
| Pipe | read_refs, write_refs, capacity | — | dec_read/write_ref | pipe block |
| Device | device_id, handler | ioctl | — | — |
| Driver | state, caps, abi | — | unload | — |
ObOpen(path, desired_access)
↓
ob_resolve_path(path) → ObId
↓
obj = ob_table.lookup(ObId)
↓
result = se_access_check(current_token, &obj.sd, desired_access)
↓
if GRANT: handle = HandleTable::push(ObId, desired_access)
if DENY: return ObError::AccessDenied
Cada handle almacena la access_mask concedida en open. Las operaciones posteriores verifican:
fn check_access(handle: HandleEntry, required: u32) -> Result<(), ObError> {
if handle.access_mask & required == required {
Ok(())
} else {
Err(ObError::AccessDenied)
}
}Cada ObObject tiene un SecurityDescriptor (owner SID + DACL). Los defaults por tipo:
| Object Type | Default Owner | Default DACL |
|---|---|---|
| Process | Creator SID | Creator: ALL |
| Thread | Creator SID | Creator: ALL |
| File | Creator SID | Creator: ALL, SYSTEM: ALL |
| Pipe | Creator SID | Creator: READ/WRITE |
| Driver | SYSTEM | SYSTEM: ALL |
| RegistryKey | SYSTEM | SYSTEM: ALL, USER: READ |
La URN actual (neodos://<scheme>/<path>) se convierte en un frontend de Ob:
| URN Scheme | Ob Path |
|---|---|
neodos://file/C:/path |
ob_open("\Global\FileSystem\C:\path") |
neodos://device/Harddisk0 |
ob_open("\Device\Harddisk0") |
neodos://registry/Machine/System |
ob_open("\Registry\Machine\System") |
neodos://kobj/Driver/ahci |
ob_open("\Driver\ahci") |
UrnHandle se elimina. urn_open() internamente llama a ObOpen() y devuelve un handle regular (fd).
| ObType | Recurso actual | Syscall asociada |
|---|---|---|
| Process | EPROCESS | spawn, exit, getpid, kill, set_priority |
| Thread | KTHREAD | thread_create, thread_join |
| File | NeoFS inode (via HandleEntry) | open, readfile, writefile, close |
| Directory | NeoFS directory inode | open (dir), readdir |
| Pipe | PipeManager slot | pipe, read (pipe), write (pipe), close, dup2 |
| Device | device_id (DeviceHandler) | register_device, ioctl |
| Driver | DriverInstance | ndreg syscalls (future) |
| SymbolicLink | ObSymlink (namespace.rs) | — |
| ObType | Descripción | Syscall |
|---|---|---|
| RegistryKey | Clave del registry | ob_open_key, ob_set_value, ob_query_value |
| Event | Evento de sincronización | ob_create_event, ob_set_event, ob_wait |
| Timer | Timer de notificación | ob_create_timer, ob_set_timer |
| Semaphore | Semáforo de conteo | ob_create_semaphore, ob_release_semaphore |
| MemorySection | Región de memoria compartida | ob_create_section, ob_map_section |
| Token | Security token | ob_duplicate_token |
| RAX | Syscall | Args | Reemplaza | Estado |
|---|---|---|---|---|
| 60 | sys_ob_open |
RBX=path_ptr, RCX=access_mask | sys_open parcial | IMPLEMENTADA (v0.44) |
| 61 | sys_ob_create |
RBX=path_ptr, RCX=type, RDX=attrs | sys_pipe, sys_mkdir parcial | IMPLEMENTADA (v0.44.1) |
| 62 | sys_ob_query_info |
RBX=fd, RCX=info_class, RDX=buf_ptr, R8=buf_size | sys_kobj_enum, sys_stat | IMPLEMENTADA (v0.44.1) |
| 63 | sys_ob_set_info |
RBX=fd, RCX=info_class, RDX=buf_ptr | — | IMPLEMENTADA (v0.44.1) |
| 64 | sys_ob_enum |
RBX=path_fd, RCX=buf_ptr, RDX=max_entries | sys_readdir extendido | IMPLEMENTADA (v0.44.1) |
| 65 | sys_ob_wait |
RBX=handle_count, RCX=handles_ptr, RDX=wait_type, R8=timeout | sys_waitpid, sys_thread_join, sleep_ex unificado | IMPLEMENTADA (v0.44.1) |
| 66 | sys_ob_destroy |
RBX=fd | sys_unlink, sys_rmdir | IMPLEMENTADA (v0.44.2) |
| RAX | Syscall | Nota |
|---|---|---|
| 67–79 | Reservados para Object Manager | 13 slots para futuro |
| RAX | Syscall | Wrapper de | Fase | Estado |
|---|---|---|---|---|
| 4 | sys_read |
ob_open(fd→object_id) + ObOperations::read | v0.45 | PENDIENTE |
| 10 | sys_open |
ob_open(path) + ob_query_info si dir | v0.45 | PARCIAL — Ob namespace paths migrados, legacy paths crean ObObject |
| 11 | sys_readfile |
ob_query_info(fd→ObId) + vfs::read | v0.45 | COMPLETADO — resuelve vía ob_lookup |
| 12 | sys_writefile |
ob_query_info(fd→ObId) + vfs::write | v0.45 | COMPLETADO — resuelve vía ob_lookup |
| 5 | sys_pipe |
ob_create(path_pipe) + ob_open x2 | v0.45 | COMPLETADO — crea ObType::Pipe con ObOperations |
| 13 | sys_close |
ob_close(handle) — ya existe semánticamente | v0.41 | COMPLETADO |
| 8 | sys_readdir |
ob_enum(fd→ob_enum_dir) | v0.45 | PENDIENTE |
| 22 | sys_thread_create |
ob_create(thread) | v0.45 | PENDIENTE |
| 9 | sys_waitpid |
ob_wait(process, CHILD_EXIT) | v0.45 | COMPLETADO — handler_ob_wait soporta ChildExit |
| 23 | sys_thread_join |
ob_wait(thread, THREAD_EXIT) | v0.45 | PENDIENTE |
| 48 | sys_kobj_enum |
ob_enum(global) — wrapper de compat | v0.45 | PENDIENTE (slot 48 = None) |
| RAX | Syscall | Motivo |
|---|---|---|
| 0 | sys_exit |
Demasiado kernel-interna para abstraer |
| 1 | sys_write |
Console write no es un objeto (todavía) |
| 2 | sys_yield |
Demasiado básica |
| 3 | sys_getpid |
Es un acceso directo a EPROCESS |
| 6 | sys_dup2 |
Opera solo sobre el handle table |
| 7 | sys_spawn |
Demasiado compleja para Ob (carga ELF + setup) |
| 16 | sys_chdir |
Opera solo sobre EPROCESS CWD |
| 17 | sys_getcwd |
Ídem |
| 18 | sys_brk |
Memoria interna del proceso |
| 19 | sys_mmap |
Mapeo de memoria |
| 20 | sys_munmap |
Desmapeo |
| 21 | sys_loadlib |
Carga de DLL |
| 24+ | Informational | get_cpuinfo, get_version, etc. |
- Cambio de firma: Ninguno. Los wrappers mantienen la firma exacta.
- ABI structs:
DirEntryRaw,KObjEntryRaw,MemInfose mantienen como compat. Los nuevos syscalls Ob usan structs nuevos. - libneodos: Se añaden wrappers Ob. Los wrappers existentes se refactorizan para llamar a Ob internamente.
Object Manager (Ob)
├── KOBJ actual → refactorizado como ObObjectTable
├── HandleTable → almacena ObId + access_mask
├── Security (SID, ACL, SeAccessCheck)
├── KWait (Unified Wait Engine) → ObWait
├── URN → frontend de Ob (dependencia invertida)
├── VFS → File ob_type implementa FileSystem trait
├── Scheduler → Process/Thread ob_types
├── Pipe → Pipe ob_type
└── Driver Runtime → Driver ob_type
Dependencias PROHIBIDAS:
✗── Ob → AHCI / ATA / NVMe (drivers de bloque)
✗── Ob → Console (framebuffer)
✗── Ob → HAL
| Elemento | Versión | Notas |
|---|---|---|
| ObId = u64 (hereda KObjId) | v0.45 | No cambiar tamaño |
| ObType enum (valores 1–17) | v0.45 | No reasignar tipos existentes |
| ObAccess mask bits | v0.45 | No reasignar bits 0–3 |
| ObInfoClass enum | v0.45 | Nuevas clases se añaden al final |
| Syscall RAX 60–65 | v0.45 | No reasignar números |
| Decisión | Motivo |
|---|---|
| No eliminar syscalls legacy | Compatibilidad con binarios existentes |
| No cambiar HandleEntry de golpe | Migración progresiva |
| No integrar Console como objeto | Es demasiado temprano y no aporta valor |
| No hacer Ob per-process namespace | Post-v0.50 |
| No eliminar KOBJ API | Ob extiende, no reemplaza |
~~v0.41 (Prep):~~ ✅ COMPLETADO
~~─ src/infra/handle.rs: añadir object_id campo~~ ✅
~~─ src/kobj/mod.rs: refactor → ObjectManager module~~ ✅
~~─ src/object/mod.rs: nuevo módulo~~ ✅
~~─ src/syscall/mod.rs: handler_close → ob_close~~ ✅
~~v0.45 (Ob APIs):~~ ✅ COMPLETADO (v0.44.1)
~~─ sys_ob_open (RAX=60)~~ ✅
~~─ sys_ob_create (RAX=61)~~ ✅
~~─ sys_ob_query_info (RAX=62)~~ ✅
~~─ sys_ob_set_info (RAX=63)~~ ✅
~~─ sys_ob_enum (RAX=64)~~ ✅
~~─ sys_ob_wait (RAX=65)~~ ✅
─ sys_open wrapper de ob_open 🔶 PARCIAL (Ob namespace paths ok)
─ sys_readdir wrapper de ob_enum ❌ PENDIENTE
~~v0.50 (Tools):~~ ✅ COMPLETADO
~~─ ps.nxe usa ob_enum(Process)~~ ✅
~~─ kill.nxe usa ob_open + ob_set_info~~ ✅
~~─ pri.nxe usa ob_open + ob_set_info~~ ✅
~~─ kobj.nxe usa ob_open + ob_enum~~ ✅
─ neoshell usa ob_enum para autocomplete ⏳ PENDIENTE
v0.52 (All Binaries F1–F2): Alta prioridad
─ neoinit (PID 1): spawn+wait via Ob ✅ ← CRÍTICO
─ neoshell: readdir→ob_enum, spawn→ob_create(Process)+ob_wait, pipe→ob_create(Pipe) ✅
─ coredir, tree: readdir→ob_enum ✅
─ corecopy, coretype: readfile→ob_query_info, writefile→ob_set_info ✅
─ cd: getcwd→ob_open("\Global\Info\Cwd")+ob_query_info ✅
v0.55 (All Binaries F3–F4): Media prioridad
─ coredel, coreren, coremd, corerd: VFS ops via Ob ✅
─ ndreg, loadnem: driver_enum/load/unload via Ob namespace ✅
─ fsck, drives: fsck/drives via Ob namespace ✅
─ vol, label, keyb: volume/label/keyboard via Ob ✅
v0.58 (All Binaries F5–F7): Baja prioridad
─ datetime, ver, mem, cpuinfo: info syscalls via Ob ✅
─ Binarios de test: migrados a Ob ✅
v1.0 (Stable):
─ URN sobre Ob 🔶 PARCIAL (device scheme migrado, file scheme parcial, registry/kobj stubs)
─ Security en ObOpen 🔶 PARCIAL (SeAccessCheck en ob_open_path, no en todas las rutas)
─ KWait integrado en ObWait 🔶 PARCIAL (solo ChildExit)
─ Documentación API ⏳ PENDIENTE
sys_open("C:\file.txt", 0)
→ vfs.resolve_path → (drive, inode)
→ HandleEntry { kind: HANDLE_FILE, id: inode, extra: drive, offset: 0 }
→ return fd
sys_readfile(fd, buf, 512)
→ HandleEntry { kind: HANDLE_FILE, id: inode, extra: drive, offset }
→ vfs.read(drive, inode, offset, buf)
→ HandleEntry.offset += bytes_read
→ return bytes_read
sys_open("C:\file.txt", 0) [wrapper]
→ ob_internal_open("\Global\FileSystem\C:\file.txt", OB_ACCESS_READ)
→ ob_resolve_path → ObId (file object)
→ ob_table.lookup(ObId) → ObObject { type: File, ops: &FILE_OPS }
→ se_access_check(current_token, &obj.sd, OB_ACCESS_READ) → GRANT
→ HandleEntry { object_id: ObId, access_mask: READ, offset: 0 }
→ return fd
sys_readfile(fd, buf, 512) [wrapper]
→ handle = HandleTable[fd]
→ check_access(handle, OB_ACCESS_READ) → OK
→ ob_table.lookup(handle.object_id) → ObObject
→ (FILE_OPS.read)(handle.object_id, handle.offset, buf, 512)
→ vfs.read(drive, inode, offset, buf)
→ HandleTable[fd].offset += bytes_read
→ return bytes_read
sys_close(fd) [wrapper]
→ handle = HandleTable[fd]
→ ob_table.lookup(handle.object_id) → ObObject
→ (FILE_OPS.close)(handle.object_id)
→ (no-op for file, dec refcount for pipe)
→ HandleTable[fd] = CLOSED
→ if ObObject.refcount == 0: ob_table.remove(ObId)
Hoy: el handler de syscall conoce el tipo y despacha manualmente.
Con Ob: el handler obtiene el objeto del Object Manager y delega en ObOperations.
La complejidad no desaparece — se centraliza en las implementaciones de ObOperations, que son fáciles de testear, seguras, y extensibles sin cambiar el dispatch.
v0.41 ── Preparación interna (sin romper ABI)
├── src/object/mod.rs (ObObject, ObObjectTable, ObOperations trait)
├── HandleEntry: añadir object_id field (mantener kind+id compat)
├── KOBJ refactor: KObjRegistry → ObObjectTable (wrappers compat)
├── sys_close → primer wrapper Ob
├── init_object_manager() en boot phase
└── 10+ tests de objeto base
v0.45 ── Object Manager initial (nuevas APIs)
├── ObOpen (RAX=60), ObCreate (RAX=61)
├── ObQueryInfo (RAX=62), ObSetInfo (RAX=63)
├── ObEnum (RAX=64)
├── HandleEntry: kind+id → object_id (breaking change interno)
├── sys_open → wrapper de ObOpen
├── sys_readfile/writefile → wrappers de Ob
├── sys_pipe → wrapper de ObCreate
├── sys_readdir → wrapper de ObEnum
├── sys_kobj_enum → wrapper de ObEnum
├── 6 ObOperations implementadas (Process, Thread, File, Pipe, Device, Driver)
├── URN: file scheme usa ObOpen
└── 20+ tests de syscalls Ob
v0.50 ── Migración de herramientas
├── ObWait (RAX=65) + KWait integration
├── ps.nxe → usa ObEnum(Process)
├── kill.nxe → usa ObOpen proc + ObSetInfo
├── pri.nxe → usa ObOpen proc + ObSetInfo
├── neoshell → ObEnum para autocomplete de objetos
├── URN rewrite completo como frontend de Ob
├── HandleEntry: eliminar kind+id legacy
├── Security: SeAccessCheck en ObOpen
└── 30+ tests de herramientas
v1.0 ── Arquitectura estable
├── Security completo: todo ObOpen verifica ACL
├── KWait full integration en ObWait
├── Legacy syscalls: todos los wrappers verificados
├── Documentación API completa
├── Test coverage >90% en Ob module
└── 40+ tests totales Ob
Descripción: Crear src/object/mod.rs con las estructuras base: ObObject, ObObjectTable, ObOperations trait, ObType, ObId, ObError. El módulo reemplazará progresivamente a kobj/mod.rs.
Archivos:
src/object/mod.rs(~670 líneas, implementado)src/object/types.rs(~136 líneas, implementado)
Estructura final:
// object/mod.rs
pub mod types;
pub type ObId = u64;
#[repr(u32)]
pub enum ObType { ... } // 15 tipos
pub trait ObOperations: Send + Sync { ... }
pub struct ObObject { ... }
pub struct ObObjectTable { ... }
pub fn ob_create_object(...) -> Result<ObId, ObError>;
pub fn ob_destroy_object(id: ObId) -> Result<(), ObError>;
pub fn ob_lookup(id: ObId) -> Option<&ObObject>;
pub fn ob_open_object(id: ObId, access: u32) -> Result<(), ObError>;
pub fn ob_close_object(id: ObId) -> Result<(), ObError>;
pub fn ob_reference(id: ObId);
pub fn ob_dereference(id: ObId);
pub fn ob_enum_snapshot() -> Vec<ObObjectSnapshot>;
pub fn ob_open_path(...) -> Result<ObId, ObError>;Criterio de aceptación ✅:
ob_create_objectregistra un nuevo objeto con tipo, nombre y opsob_lookupobtiene el objeto por IDob_destroy_objectfalla si refcount > 0ob_reference/ob_dereferencemantienen conteo- Tests: 5+ (create, lookup, destroy, refcount, double-destroy, open_path, access_denied)
Implementado en: v0.41 – src/object/mod.rs + src/object/types.rs
Descripción: Añadir object_id: u64 al HandleEntry actual. El campo kind fue eliminado completamente en OB-024.
Archivos:
src/infra/handle.rs(~285 líneas, implementado)
Estructura final:
pub struct HandleEntry {
pub object_id: ObId, // ObId del ObObject, sentinel para stdio
pub offset: u64, // posición para file-like objects
}El tipo se identifica mediante sentinelas en object_id (ObId::MAX, MAX-1, MAX-2 para stdin/stdout/stderr) u ob_lookup().obj_type para objetos reales.
Criterio ✅:
HandleEntry::closed()inicializaobject_id = 0- Los constructores (file, pipe_read, pipe_write, device, dir) registran ObObject automáticamente
- Tests existentes pasan sin cambios
Implementado en: v0.41 (object_id) + v0.44.1 (eliminación de kind)
Descripción: KOBJ refactorizado para usar ObObjectTable internamente. kobj_register() llama a ob_create_object(). kobj_unregister() llama a ob_destroy_object(). La API pública de KOBJ se mantiene para compatibilidad.
Archivos:
src/kobj/mod.rs(API compat sobre ObObjectTable)src/kobj/namespace.rs(sin cambios — funciona con ObObject IDs)
Criterio ✅:
- Todos los 8 tests existentes de KOBJ pasan sin cambios
kobj_registeralmacena un ObObject completo (no solo metadata)kobj_lookupfunciona igual- La integración con namespace (ob_insert_object_auto) no se rompe
Implementado en: v0.41
Descripción: Refactorizar handler_close para que llame a ob_close_object(handle.object_id) antes de marcar el handle como CLOSED. Esto es seguro porque:
ob_close_objectpara archivos es no-op (solo decrementa refcount y auto-destroy)ob_close_objectpara pipes decrementa refcount y libera si llega a 0- Elimina la lógica manual de
match entry.kinden handler_close
Archivos:
src/syscall/mod.rs(handler_close, ~10 líneas)src/object/mod.rs(ob_close_object auto-destroy, ~5 líneas)
Criterio:
sys_closeen pipe decrementa refcount via ObObject (comportamiento idéntico)sys_closeen file decrementa refcount via ObObject (no-op, mantiene compat)ob_close_objectauto-destroy al llegar a refcount 0- Tests: 4 (ob_close_object_auto_destroy, ob_close_object_keeps_alive_with_refs, handler_close_file, handler_close_pipe)
Prerequisitos: OB-002, OB-003 Estimación: ~15 líneas, 0.5 días
Descripción: object::init() llamado desde main.rs (Phase 2.759) que inicializa el Object Manager, registra los tipos de objeto base, y crea el directorio raíz del namespace Ob.
Archivos:
src/object/mod.rs(init_object_manager, ~40 líneas)src/main.rs(llamada en Phase 2.759)
Criterio ✅:
- Al boot, el Object Manager está inicializado con 9 directorios tipo (\Global, \Driver, \Device, \Pipe, etc.)
ob_lookupfunciona antes de que cualquier driver carguekobj_registercrea ObObject automáticamente en el namespace- Tests: 2 (root directory entries, type entries)
Implementado en: v0.41
Descripción: sys_ob_open(path, access_mask) → fd. Implementado con:
copy_user_string(path)→ path_strob_open_path(path_str, &token, desired_access)→ ObId (namespace + VFS fallback)se_access_check(current_token, &obj.sd, desired_access)→ checkHandleTable::alloc_handle(HandleEntry::ob_object(object_id, access_mask))→ fd
Archivos:
src/syscall/mod.rs(handler_ob_open registrado en slot 60)src/object/mod.rs(ob_open_path ~60 líneas con namespace + VFS + security)
Criterio ✅:
ObOpen("\Global\FileSystem\C:\boot.cfg", READ)→ fdObOpen("\Driver\ps2kbd", READ)→ fd (object existente)ObOpen("\NonExistent", READ)→ -ENOENT- SeAccessCheck integrado:
ob_open_pathverifica token contra SD - Tests: 4 (existing object, not found, access denied, non-existent namespace)
Implementado en: v0.44
Descripción: sys_ob_create(path, type, attrs) → fd. Implementado con ob_create_object_path() que soporta:
ObType::Pipe→ crea pipe + fd reader/writerObType::Directory→ crea directorio en namespace
Archivos:
src/syscall/mod.rs(handler_ob_create registrado en slot 61)src/object/mod.rs(ob_create_object_path, ~60 líneas)
Criterio ✅:
ObCreate("\Global\Pipe\my_pipe", Pipe)→ crea pipe + devuelve handlesObCreate("\Global\MyDir", Directory)→ directory handle- Namespace insert con creación automática de directorios padre
- Tests: 3 (pipe, directory, invalid type)
Implementado en: v0.44.1
Descripción: sys_ob_query_info(fd, info_class, buf, buf_size) → bytes_written. Clases de información soportadas: BasicInfo, NameInfo, FileInfo, ProcessInfo, ThreadInfo, PipeInfo, DeviceInfo.
Archivos:
src/syscall/mod.rs(handler_ob_query_info registrado en slot 62)src/object/types.rs(ObInfoClass enum con 7 clases)
Criterio ✅:
ObQueryInfo(fd, BasicInfo)→ type, name, refcountObQueryInfo(fd, FileInfo)→ size, drive, inode (vía ob_lookup)ObQueryInfo(fd, ProcessInfo)→ pid, parent, priority, thread_count, stateObQueryInfo(fd, PipeInfo)→ pipe metadataObQueryInfo(invalid_fd, BasicInfo)→ -EBADF
Implementado en: v0.44.1
Descripción: sys_ob_set_info(fd, info_class, buf). Soporta:
ProcessPriority→ cambia prioridad de procesoThreadPriority→ cambia prioridad de threadObjectName→ renombra objetoSecurityInfo→ cambia SecurityDescriptor
Archivos:
src/syscall/mod.rs(handler_ob_set_info registrado en slot 63)src/object/types.rs(ObSetInfoClass enum)
Criterio ✅:
ObSetInfo(proc_fd, ProcessPriority, &3)→ cambia prioridadObSetInfo(fd, ObjectName, "new_name")→ renombra- SecurityDescriptor modificable vía SecurityInfo class
- Tests: 4 (priority, name, invalid class, invalid fd)
Implementado en: v0.44.1
Descripción: sys_ob_enum(dir_fd, buf, max_entries) → count. Enumera objetos del namespace Ob mediante ob_enum_directory().
Archivos:
src/syscall/mod.rs(handler_ob_enum registrado en slot 64)src/object/mod.rs(ob_enum_directory, ~40 líneas)src/object/types.rs(ObEnumEntry struct ABI-stable)
Criterio ✅:
ObEnum(root_fd)→ lista directorios del namespaceObEnum(device_fd)→ lista dispositivos registradossys_kobj_enum(RAX=48)→ actualmente None (pendiente wrapper)- Tests: 4 (root, nested, empty, invalid fd)
Implementado en: v0.44.1
Descripción: handler_open usa ob_open_path() para TODAS las rutas: namespace paths (\...) van directas, drive-letter paths (C:\...) se convierten a \Global\FileSystem\C:\... antes de resolver.
Archivos:
src/syscall/mod.rs(handler_open, refactorizado ~linea 1038)
Criterio ✅:
- ✅
sys_open("\Driver\ps2kbd", 0)→ ObOpen path completo - ✅
sys_open("C:\System\boot.cfg", 0)→ ObOpen via\Global\FileSystem\C:\System\boot.cfg - ✅
sys_open("C:\nonexistent", 0)→ -ENOENT (fallback a VFS legacy) - ✅
sys_open("C:\dir", 0)→ handle de directorio con ObObject - ✅ Security check en ob_open_path para todas las rutas
Implementado en: v0.44.2
Descripción: handler_pipe crea un objeto ObType::Pipe via ob_create_object() con PIPE_OPS, comparte el mismo ob_id entre reader y writer handles.
Archivos:
src/syscall/mod.rs(handler_pipe, ~linea 853)src/pipe.rs(crate::pipe::PIPE_OPS como ObOperations)
Criterio ✅:
sys_pipe(fds)funciona exactamente igual que antes- El pipe se registra como ObObject con refcount: 1 (create) + 2 (handles) → drop create = 2 refs
- Namespace actual: nombre generado "PIPE{id}" (no path-based)
Implementado en: v0.44.1
Descripción: handler_readfile y handler_writefile resuelven el fd mediante ob_lookup(entry.object_id) para extraer drive (desde flags) e inode (desde native_id).
Archivos:
src/syscall/mod.rs(handler_readfile ~linea 1157, handler_writefile ~linea 1214)
Criterio ✅:
sys_readfile(fd, buf, len)funciona exactamente igualsys_writefile(fd, buf, len)funciona exactamente igual- El I/O de datos sigue yendo por VFS (Ob es capa de handles/namespace, no de block I/O)
Implementado en: v0.44.1
Descripción: urn_open para TODOS los schemes (file, device, registry, kobj) resuelve mediante ob_open_path() en el namespace Ob.
Archivos:
src/urn/mod.rs(~340 líneas)src/kobj/namespace.rs(init_object_namespace añade \Registry)
Criterio ✅:
- ✅ Device scheme:
urn_open("neodos://device/Harddisk0")→ob_open_path("\Device\Harddisk0") - ✅ File scheme:
urn_open("neodos://file/C:/file.txt")→ob_open_path("\Global\FileSystem\C:\file.txt") - ✅ Registry scheme:
urn_open("neodos://registry/Machine/System")→ob_open_path("\Registry\Machine\System") - ✅ KObj scheme:
urn_open("neodos://kobj/Driver/ahci")→ob_open_path("\Ob\Driver\ahci") - ✅ Namespace \Registry creado en init_object_namespace
- Tests: 19 pasan
Implementado en: v0.44.2
Descripción: handler_ob_wait implementado con integración KWait completa. Soporta ChildExit, PipeRead, Event, Timer. Pipe/ThreadJoin migrados de ad-hoc magic a KWait.
Archivos:
src/syscall/mod.rs(handler_ob_wait registrado en slot 65, ~linea 3407)src/kwait/(kwait_block/kwait_wake para 7 wait reasons)src/pipe.rs(block_current_for_pipe usa KWait)src/scheduler/mod.rs(block_current_for_thread usa KWait)
Soporte actual:
- ✅
WAIT_TYPE_ANYpara Process (viakwait_block(ChildExit { pid })) - ✅
WAIT_TYPE_ANYpara Pipe (viakwait_block(PipeRead { pipe_id })+ non-blocking peek) - ✅
WAIT_TYPE_ANYpara Event (viakwait_block(Event { event_type })) - ✅
WAIT_TYPE_ANYpara Timer (viakwait_block(Timer { timeout_ms })) - ⏳
WAIT_TYPE_ALL→ devuelveNoSys(multi-handle no implementado) - ⏳ Timeout → parámetro aceptado pero no procesado (0 = infinite)
Criterio ✅:
- ✅
ObWait([proc_handle], WAIT_TYPE_ANY, 0)→ ChildExit via KWait - ✅
ObWait([pipe_handle], WAIT_TYPE_ANY, 0)→ PipeRead via KWait (non-blocking peek first) - ✅
ObWait([event_handle], WAIT_TYPE_ANY, 0)→ Event via KWait - ✅ Pipe blocking:
block_current_for_pipeywake_pipe_readersusan KWait - ✅ ThreadJoin:
block_current_for_threadywake_thread_joinerusan KWait - ✅
handler_thread_join(RAX=23)refactorizado a KWait
Implementado en: v0.44.2
Descripción: userbin/ps/ usa sys_ob_enum (vía libneodos) en lugar de sys_kobj_enum.
Archivos:
userbin/ps/src/main.rs(migrado a ObEnum)
Criterio ✅:
PSdesde neoshell muestra los mismos procesos que antes- Usa
sys_ob_enumcon filtro de ObType::Process
Implementado en: v0.44.1
Descripción: userbin/kill/ usa sys_ob_set_info(proc_fd, ...) en lugar de sys_kill_process.
Archivos:
userbin/kill/src/main.rs(migrado a ObSetInfo)
Criterio ✅:
KILL 5termina PID 5 (funcionalidad idéntica)sys_kill_process(RAX=52)→ None actualmente (se invoca directamente)
Implementado en: v0.44.1
Descripción: userbin/pri/ usa sys_ob_set_info(proc_fd, ProcessPriority, ...) en lugar de sys_set_priority.
Archivos:
userbin/pri/src/main.rs(migrado a ObSetInfo)
Criterio ✅:
PRI 5 0cambia prioridad (comportamiento idéntico)sys_set_priority(RAX=51)→ None actualmente
Implementado en: v0.44.1
Descripción: HandleEntry ya no tiene campo kind. Solo almacena object_id: ObId + offset: u64. El tipo se identifica mediante sentinelas ObId (para stdio) y ob_lookup().obj_type para objetos reales.
Archivos:
src/infra/handle.rs(HandleEntry simplificado)src/syscall/mod.rs(todos los handlers migrados a object_id)src/scheduler/mod.rs(kill_pid, exit migrados)
Criterio ✅:
- HandleTable solo almacena
object_id+offset - Sentinelas:
HANDLE_STDIN = ObId::MAX,HANDLE_STDOUT = MAX-1,HANDLE_STDERR = MAX-2 - Constructores:
file(),pipe_read(),pipe_write(),device(),dir()registran ObObject automáticamente - Todos los handlers funcionan sin
kind
Implementado en: v0.44.1
Descripción: URN es un frontend completo de Ob. Todos los 4 schemes (file, device, registry, kobj) resuelven mediante ob_open_path() en el namespace Ob.
Archivos:
src/urn/mod.rs(~340 líneas)
Criterio ✅:
- ✅ File scheme:
urn_open("neodos://file/C:/file.txt")→ob_open_path("\Global\FileSystem\C:\file.txt") - ✅ Device scheme:
urn_open("neodos://device/Harddisk0")→ob_open_path("\Device\Harddisk0") - ✅ Registry scheme:
urn_open("neodos://registry/Machine/System")→ob_open_path("\Registry\Machine\System") - ✅ KObj scheme:
urn_open("neodos://kobj/Driver/ahci")→ob_open_path("\Ob\Driver\ahci") - ✅ 19 tests pasan
Implementado en: v0.44.2
Descripción: SeAccessCheck integrado en ob_open_path() y en todas las rutas legacy de VFS: sys_open (vía \Global\FileSystem\...), sys_spawn (ACCESS_EXECUTE), sys_mkdir (ACCESS_WRITE), sys_unlink, sys_rmdir (ACCESS_DELETE), sys_rename (ACCESS_WRITE|DELETE).
Archivos:
src/object/mod.rs(ob_open_path con se_access_check)src/syscall/mod.rs(check_legacy_path_access helper, ~linea 1366)
Criterio ✅:
- ✅
ob_open_pathsin acceso → ACCESS_DENIED - ✅ Admin bypass funciona
- ✅ Token de usuario no puede abrir objetos SYSTEM-only
- ✅
sys_spawn(path, ...)chequea ACCESS_EXECUTE via Ob - ✅
sys_mkdir(path)chequea ACCESS_WRITE via Ob - ✅
sys_unlink / sys_rmdirchequea ACCESS_DELETE via Ob - ✅
sys_renamechequea ACCESS_WRITE | DELETE via Ob - ✅ Todos los chequeos son no-intrusivos: sin SD → acceso concedido (backward compatible)
- Tests: 16 + todas las rutas legacy cubiertas
Implementado en: v0.44.2
Descripción: KWait completamente integrado. Todas las operaciones de bloqueo (PipeRead, ThreadJoin, ChildExit, Event, Timer, IrpComplete, Alertable) usan KWait. Ad-hoc magics (0xFFFF_0000, 0x8000_0000) eliminados.
Archivos:
src/syscall/mod.rs(handler_ob_wait, handler_thread_join, handler_exit)src/pipe.rs(block_current_for_pipe, wake_pipe_readers via KWait)src/scheduler/mod.rs(block_current_for_thread, wake_thread_joiner via KWait)src/kwait/mod.rs(7 wait reasons, ABI frozen v0.42)
Criterio ✅:
- ✅
ObWait([proc_handle], WAIT_TYPE_ANY, INFINITE)→ ChildExit via KWait - ✅
ObWait([pipe_handle], WAIT_TYPE_ANY, 0)→ PipeRead via KWait (non-blocking peek) - ✅
ObWait([event_handle], WAIT_TYPE_ANY, 0)→ Event via KWait - ✅
ObWait([timer_handle], WAIT_TYPE_ANY, 0)→ Timer via KWait - ✅ Pipe blocking usa KWait (no ad-hoc 0xFFFF_0000 magic)
- ✅ ThreadJoin usa KWait (no ad-hoc 0x8000_0000 magic)
- ✅
handler_thread_join(RAX=23)refactorizado a KWait - ⏳ Multi-handle y WAIT_TYPE_ALL → NoSys (próxima iteración)
Implementado en: v0.44.2
Descripción: Documentar toda la API del Object Manager:
- Estructuras ABI (ObBasicInfo, ObEntryRaw, ObWaitResult)
- Syscalls (RAX 60–65) con calling convention
- Códigos de error (ObError enum)
- Guía de migración para tooling
Archivos:
docs/OBJECT_MANAGER_ARCHITECTURE.md(completar secciones)docs/syscalls.md(tabla de syscalls actualizada)
Criterio:
- La documentación cubre todas las syscalls Ob
- La guía de migración es utilizable por un desarrollador nuevo
Prerequisitos: OB-030, OB-031 Estimación: 2 días
| Versión | Issues | Estado | Tests |
|---|---|---|---|
| v0.41 (Prep) | 5 | ✅ COMPLETADO todo | 12 |
| v0.45 (Ob APIs) | 9 | ✅ 9 COMPLETADOS | 31 |
| v0.50 (Tools) | 8 | ✅ 8 COMPLETADOS | 19 |
| v0.52 (Binarios F1–F2) | 7 | ❌ PENDIENTE | 0 |
| v0.55 (Binarios F3–F4) | 7 | ❌ PENDIENTE | 0 |
| v0.58 (Binarios F5–F7) | 5 | ❌ PENDIENTE | 0 |
| v1.0 (Stable) | 3 | 🔶 3 parciales (Security, KWait, docs) | 9 |
| Total | 43 | 13 completos, 6 parciales, 24 pendientes | 69 |
| Issue | Versión | Estado | Notas |
|---|---|---|---|
| OB-001 | v0.41 | ✅ COMPLETADO | src/object/mod.rs + types.rs |
| OB-002 | v0.41 | ✅ COMPLETADO | object_id en HandleEntry |
| OB-003 | v0.41 | ✅ COMPLETADO | KOBJ sobre ObObjectTable |
| OB-004 | v0.41 | ✅ COMPLETADO | sys_close via ob_close_object |
| OB-005 | v0.41 | ✅ COMPLETADO | init_object_manager en boot |
| OB-010 | v0.45 | ✅ COMPLETADO | sys_ob_open (RAX=60) |
| OB-011 | v0.45 | ✅ COMPLETADO | sys_ob_create (RAX=61) |
| OB-012 | v0.45 | ✅ COMPLETADO | sys_ob_query_info (RAX=62) |
| OB-013 | v0.45 | ✅ COMPLETADO | sys_ob_set_info (RAX=63) |
| OB-014 | v0.45 | ✅ COMPLETADO | sys_ob_enum (RAX=64) |
| OB-015 | v0.45 | ✅ COMPLETADO | Ob namespace paths migrados + legacy C:... via \Global\FileSystem\ bridge |
| OB-016 | v0.45 | ✅ COMPLETADO | sys_pipe via ob_create_object |
| OB-017 | v0.45 | ✅ COMPLETADO | readfile/writefile via ob_lookup |
| OB-018 | v0.45 | ✅ COMPLETADO | URN file scheme via ob_open_path, registry/kobj implementados |
| OB-020 | v0.50 | ✅ COMPLETADO | ObWait con ChildExit, PipeRead, Event, Timer via KWait |
| OB-021 | v0.50 | ✅ COMPLETADO | ps.nxe migrado a ObEnum |
| OB-022 | v0.50 | ✅ COMPLETADO | kill.nxe migrado a ObSetInfo |
| OB-023 | v0.50 | ✅ COMPLETADO | pri.nxe migrado a ObSetInfo |
| OB-024 | v0.50 | ✅ COMPLETADO | HandleEntry sin kind+id |
| OB-025 | v0.50 | ✅ COMPLETADO | URN frontend completo de Ob (file, device, registry, kobj) |
| OB-030 | v1.0 | ✅ COMPLETADO | SeAccessCheck en ob_open_path + legacy paths (spawn, mkdir, unlink, rmdir, rename) |
| OB-031 | v1.0 | ✅ COMPLETADO | KWait full integration: PipeRead, ThreadJoin migrados de ad-hoc magic |
| OB-032 | v1.0 | 🔶 PARCIAL | Documentación de API actualizada, falta doc completa de structs |
| OB-040 | v0.52 | ✅ COMPLETADO | neoshell: readdir+pipe→Ob, spawn→ob_create+ob_wait |
| OB-041 | v0.52 | ✅ COMPLETADO | coredir, tree: readdir→ob_enum |
| OB-042 | v0.52 | ✅ COMPLETADO | coretype/corecopy: readfile→ob_query_info, writefile→ob_set_info |
| OB-043 | v0.55 | ✅ COMPLETADO | coredel/coreren/coremd/corerd: VFS ops via Ob |
| OB-044 | v0.55 | 🔶 PARCIAL | ndreg/drives ✅, fsck ⛔ N/A, loadnem pendiente (sys_driver_load/unload sin equivalente Ob) |
| OB-045 | v0.58 | ✅ COMPLETADO | datetime/ver/mem/cpuinfo, vol, label: info via Ob |
| OB-046 | v0.52 | ✅ COMPLETADO | Processos registrados como ObObjects en namespace \Process<pid> |
| OB-047 | v0.58 | ❌ PENDIENTE | Binarios de test: migración completa a Ob |
v0.41: ✅ COMPLETED
OB-001 ─┬── OB-002 ── OB-004
└── OB-003 ── OB-005
v0.45: ✅ 9/9 COMPLETED
OB-005 ── OB-010 ──┬── OB-011 ── OB-016 ✅
├── OB-012 ──┬── OB-013 ✅
│ └── OB-017 ✅
├── OB-014 ── OB-015 ✅
└── OB-018 ✅
OB-030 ── (check_legacy_path_access en sys_open/spawn/mkdir/unlink/rmdir/rename)
v0.50: ✅ 8/8 COMPLETED
OB-012 ── OB-020 (ObWait) ✅
OB-014 ── OB-021 (ps) ✅
OB-013 ──┬── OB-022 (kill) ✅
└── OB-023 (pri) ✅
OB-024 (HandleEntry cleanup) ✅
OB-018 ── OB-025 (URN) ✅
OB-031 (KWait full integration) ✅
OB-046 (neoinit processes as ObObjects) ✅
v0.52 (F1–F2, alta prioridad): ✅ COMPLETADO
~~OB-014 ── OB-040 (neoshell autocomplete)~~ ✅
~~OB-014 ── OB-041 (coredir, tree → ob_enum)~~ ✅
~~OB-012 + OB-013 ── OB-042 (corecopy, coretype → ob_query/set_info)~~ ✅
~~OB-011 + OB-020 ── OB-046 (neoinit spawn+wait — PID 1)~~ ✅
v0.55 (F3–F4, media prioridad): ✅ PARCIAL
OB-011 + OB-013 ── ~~OB-043 (FS ops via Ob)~~ ✅
OB-014 ── OB-044 (loadnem: driver load/unload sin equivalente Ob) ❌
OB-014 ── OB-044 (driver/fs/drive via Ob namespace)
v0.58 (F5–F7, baja prioridad): ✅ COMPLETADO
~~OB-012 ── OB-045 (info syscalls via Ob)~~ ✅
~~OB-047 (test binaries — cmdtest migrado)~~ ✅
v1.0: ✅ COMPLETED
OB-010 ── OB-030 (Security) ✅
OB-020 ── OB-031 (KWait full) ✅
OB-030 + OB-031 ── OB-032 (Documentación) 🔶
Objetivo: Todos los 35 binarios de usuario deben usar exclusivamente syscalls Ob (RAX 60–65) para operaciones sobre objetos del sistema (archivos, directorios, procesos, pipes, dispositivos, drivers, etc.), eliminando las syscalls legacy equivalentes.
| Fase | Binarios | Syscalls Legacy a Eliminar | Syscall Ob Equivalente | Estado |
|---|---|---|---|---|
| F1 — YA MIGRADOS | ps, kill, pri, kobj | sys_kobj_enum, sys_kill_process, sys_set_priority | ob_open, ob_enum, ob_set_info, ob_query_info | |
| neoshell, coredir, tree, corehelp, coretype, corecopy | ob_open, ob_enum, ob_query_info, ob_wait, ob_create(Process), ob_set_info | ✅ COMPLETADO | ||
| coredel, coreren, coremd, corerd, label, vol | ob_open, ob_create(Directory), ob_destroy, ob_set_info(VfsRename/SetVolumeLabel), ob_query_info(VolumeLabel) | ✅ COMPLETADO | ||
| F4 — DRIVERS/SISTEMA | ndreg, loadnem, fsck, drives, keyb | sys_driver_enum, sys_driver_load, sys_driver_unload, sys_fsck, sys_get_drives, sys_set_keyboard_layout | ob_open_path + ob_enum en namespace \Driver\ y \Device\ | |
| cpuinfo, datetime, ver, mem | ob_open("\Global\Info...") + ob_query_info | ✅ COMPLETADO | ||
| hello, systest, filetest, alltest, cputest, cmdtest | ob_open, ob_create, ob_enum, wrappers Ob | ✅ COMPLETADO | ||
| F7 — TRIVIALES | echo, cls | Ninguna (solo foundation) | No requiere cambios |
| Binario | Estado Ob | Syscalls Ob | Syscalls Legacy Restantes |
|---|---|---|---|
| ps | ✅ COMPLETO | ob_open, ob_enum, ob_query_info | — |
| kill | ✅ COMPLETO | ob_open, ob_set_info | — |
| pri | ✅ COMPLETO | ob_open, ob_set_info | — |
| kobj | ✅ COMPLETO | ob_open, ob_enum | — |
| neoshell | 🔶 PARCIAL | ob_open, ob_enum, ob_create(Pipe), ob_create(Process), ob_wait, ob_set_info(SetCwd), ob_query_info(ReadContent) | sys_cursor_blink, sys_poweroff |
| cd | ✅ COMPLETO | ob_open, ob_query_info | — |
| coredir | ✅ COMPLETO | ob_open, ob_enum | — |
| corehelp | 🔶 PARCIAL | ob_open, ob_enum, ob_create(Pipe), ob_query_info(ReadContent), ob_create(Process), ob_wait | — |
| coretype | ✅ COMPLETO | ob_open, ob_query_info(ReadContent) | — |
| tree | ✅ COMPLETO | ob_open, ob_enum | — |
| corecopy | ✅ COMPLETO | ob_open, ob_destroy, ob_query_info(ReadContent), ob_set_info(WriteContent) | — |
| cmdtest | 🔶 PARCIAL | ob_open, ob_create(Directory), ob_destroy, ob_set_info, ob_query_info(ReadContent) | sys_open_with_flags |
| cpuinfo | ✅ COMPLETO | ob_open, ob_query_info | — |
| neoinit | ⛔ N/A (PID 1) | — | sys_spawn (no migrable — creación de procesos no es objeto) |
| datetime | ✅ COMPLETO | ob_open, ob_query_info | — |
| ver | ✅ COMPLETO | ob_open, ob_query_info | — |
| mem | ✅ COMPLETO | ob_open, ob_query_info | — |
| vol | ✅ COMPLETO | ob_open, ob_query_info(VolumeLabel) | — |
| coredel | ✅ COMPLETO | ob_open, ob_destroy | — |
| coreren | ✅ COMPLETO | ob_open, ob_set_info | — |
| coremd | ✅ COMPLETO | ob_create(Directory) | — |
| corerd | ✅ COMPLETO | ob_open, ob_destroy | — |
| drives | ✅ COMPLETO | ob_open, ob_query_info | — |
| keyb | ✅ COMPLETO | ob_open, ob_set_info | — |
| label | ✅ COMPLETO | ob_open, ob_query_info(VolumeLabel), ob_set_info(SetVolumeLabel) | — |
| fsck | ⛔ N/A | — | sys_fsck (no migrable — comando de reparación con argumentos) |
| ndreg | ✅ COMPLETO | ob_open, ob_query_info | — |
| loadnem | 🔶 PARCIAL | ob_create(Driver) | sys_driver_unload |
| echo | ✅ N/A | — | (foundation only, solo sys_write) |
| cls | ✅ N/A | — | (foundation only, solo sys_write) |
| Issue | Binario | Syscall Legacy→Ob | Depende de | Prioridad |
|---|---|---|---|---|
| neoshell | readdir→ob_enum, pipe→ob_create(Pipe), readfile→ob_query_info, spawn→ob_create(Process)+ob_wait, chdir→ob_set_info(SetCwd) | OB-011, OB-014, OB-020 | ✅ COMPLETADO | |
| coredir, tree | readdir→ob_enum | OB-014 | ✅ COMPLETADO | |
| corecopy, coretype | readfile→ob_query_info, writefile→ob_set_info, unlink→ob_destroy | OB-012, OB-013 | ✅ COMPLETADO | |
| OB-046 | neoinit (PID 1) | spawn→ob_create(Process)+ob_wait | OB-011, OB-020 | CRÍTICA |
| coredel, coreren, coremd, corerd | unlink→ob_destroy, rename→ob_set_info, mkdir→ob_create(Directory), rmdir→ob_destroy | OB-011, OB-013 | ✅ COMPLETADO | |
| OB-044 | ndreg, loadnem, fsck, drives | driver_enum→ob_enum("\Driver"), fsck→ob_query_info(DriveInfo), get_drives→ob_enum("\Device") | OB-014 | MEDIA |
| OB-045 | datetime, ver, mem, cpuinfo | get_datetime→ob_open("\Global\Info\DateTime")+query, get_version→ob_query_info | OB-010, OB-012 | BAJA |