Costuras de Oasis para el nodo clase (notas de exploración) ficha

Costuras de Oasis para el nodo clase (notas de exploración)

Costuras de Oasis 1.0.7 para el nodo clase (materialismo filosófico de Gustavo Bueno)

Exploración de 2026-09-09 sobre vendor/oasis/src @ 9a657b776fcafc7c24bf3ad61825316385ecf513. Cada fila se ha verificado con sed -n y la línea citada contiene el símbolo nombrado. Las categorías siguen las coordenadas K1-K7 del plan embebido en drafts/draft.md. La columna «Lectura» es trituración nuestra: donde interpreta doctrina de Bueno sin verbatim lleva grado de certeza (A/B/C) y la etiqueta [doctrina, sin verbatim]. Los hechos de res_publica/drafts/draftv0.md y otro nodo del catálogo/drafts/draftv0.md se han usado solo como pistas y se han vuelto a verificar aquí.

Rutas: models/ y views/ son relativas a vendor/oasis/src/; backend/backend.js, server/SSB_server.js, AI/ai_service.mjs, configs/server-config.json y ../scripts/oasis-pub.js se citan con su ruta completa desde src/.

Tabla de costuras (54)

# Categoría Fichero:línea Línea literal Lectura
1 K1 · M1 físico banking_model.js:35 const carbonGramsFromBytes = (b) => (Number(b) || 0) / ONE_MIB * 0.095; La única traducción de M1 (bytes) a mundo físico (gramos CO₂) es una constante sin procedencia. Eutaxia ecológica con número mágico
2 K1 · M1 físico banking_model.js:617 (m) => { try { bytes += Buffer.byteLength(JSON.stringify(m && m.value), 'utf8'); } catch (_) {} }, El cuerpo físico del inhabitant es la suma de bytes de su feed (getCarbonGramsForUser, :609). M1 = lo que pesa el log
3 K1 · M1 físico stats_model.js:438 const folderSize = getFolderSize(`${os.homedir()}/.ssb`); El disco de ~/.ssb es la única medida material del nodo; se mide almacenamiento, no duración
4 K1 · M1 físico panicmode_model.js:10 await fs.promises.rm(ssbPath, { recursive: true, force: true }); Destrucción de M1 (directorio) = destrucción de la identidad (M3, la clave). Los géneros se involucran en el borrado
5 K1 · M2 fenomenológico opinion_categories.js:1 const positive = [ La vivencia se tipifica en listas cerradas (positive, constructive). M2 entra en la red solo como categoría
6 K1 · M2 fenomenológico opinions_model.js:59 if (!categories.includes(category)) throw new Error("Invalid voting category."); Una opinión fuera del catálogo lanza error: M2 no tiene entrada libre, se reduce a M3 (tipo de mensaje)
7 K1 · M2 fenomenológico settings_view.js:24 const theme = currentThemeConfig.themes?.current || "Dark-SNH"; La apariencia (tema) vive en oasis-config.json del nodo, no en el feed: la experiencia es local y no replicada
8 K1 · M2 fenomenológico inhabitants_model.js:65 function bucketLastActivity(ts) { La presencia de un sujeto se reduce a tres cubos (green <2w, orange 2w-6m, red ≥6m). Única medida de recurrencia social
9 K1 · M3 abstracto parliament_model.js:17 const TERM_DAYS = 60; Las reglas constitutivas (60 días de mandato, 7 de propuesta, 15 de revocación, quórum 2 / 25 %) son constantes del código, sin sujeto que las haya votado
10 K1 · M3 abstracto parliament_model.js:23 const METHODS = ['DEMOCRACY', 'MAJORITY', 'MINORITY', 'DICTATORSHIP', 'KARMATOCRACY']; El catálogo de formas de gobierno es M3 cerrado: cinco métodos, no ampliables por el log
11 K1 · M3 abstracto banking_model.js:14 const DEFAULT_RULES = { Parámetros de la RBU (alpha, reserveMin, capPerEpoch, caps) fijados en código: capa basal con constantes sin procedencia
12 K1 · M3 abstracto typed_log.js:77 const readTyped = async (ssbClient, types, opts = {}) => { Todo el mundo institucional de Oasis es un log leído por type: M3 = tipos de mensaje indexados en cliente
13 K1 · reducción M3→M1 banking_model.js:840 const karmaScore = Math.max(0, Math.round(rawKarma - carbonGrams)); Peso político (karma, M3) menos gramos de CO₂ (M1) en una misma resta. Única reducción entre géneros que la red ejecuta; contra la inconmensurabilidad de K1 (A)
14 K1 · reducción M3→M1 banking_model.js:1151 const engagementScore = Math.max(0, Math.round(rawScore - carbonGramsForScore)); La misma resta se repite para el engagementScore de la RBU: el fisicalismo alcanza también la redistribución
15 K2 · cierre criptográfico SSB_server.js:57 const Server = SecretStack({ caps }) La red se cierra con caps (secret handshake) importado: ciencia ajena, cerrada, parametrizada por el operador (server-config.json:6)
16 K2 · cierre de replicación SSB_server.js:60 .use(require('ssb-ebt')) Replicación EBT + ssb-friends (:61): cierre determinista importado; Oasis no lo reabre
17 K2 · cierre de replicación server-config.json:12 "hops": 2 El horizonte de replicación (cuántos saltos del grafo de follows se replican) es un parámetro de fichero, no una decisión del cuerpo político
18 K2 · IA abierta ai_service.mjs:89 app.listen(4001); El servicio de IA escucha en 4001 sin autenticación: técnica abierta, sin cierre
19 K2 · IA abierta ai_service.mjs:52 const sanitize = (s) => String(s || '').replace(/[<>"']/g, '').replace(/\b(ignore|disregard|forget|system|instruction|prompt)\b/gi, '[$1]').trim();` La defensa contra inyección es una regex de siete palabras: no hay cierre operatorio de la categoría «IA»
20 K2 · banca dependiente wallet_model.js:22 const clientrpc = await makeClient(url, user, pass); Toda la economía pasa por RPC a una wallet externa (@open-rpc/client-js, :5): categoría dependiente, sin cierre propio
21 K2 · gobernanza abierta en la ejecución tombstone_validator.js:12 if (typeof c === 'object' && c.type === 'tombstone' && typeof c.target === 'string') { Derogar es publicar un tombstone que cada cliente valida por su cuenta (:26 exige mismo autor). Cierre en el log, no en la ejecución
22 K2 · gobernanza abierta en la ejecución parliament_model.js:1104 async function enactApprovedChanges(expiringTerm) { «Enact» publica mensajes de ley al expirar el mandato; nada fuera de la interfaz obedece. Rama ejecutiva ausente (K5)
23 K3 · eje radial stats_model.js:24 const listPubsFromEbt = () => { El mundo objetivo del nodo son pubs y pares leídos de ~/.ssb/ebt: eje radial = infraestructura, no naturaleza
24 K3 · eje circular backend.js:7306 .post("/block/:feed", koaBody(), async (ctx) => { La frontera del círculo humano se traza por friend.block (:7307), decisión individual sin órgano
25 K3 · eje circular server-config.json:25 "autofollow": { El círculo inicial viene de fábrica: feeds seguidos automáticamente por configuración del proyecto upstream
26 K3 · eje circular tribes_model.js:11 const STRUCTURAL_FIELDS = ['title', 'description', 'image', 'location', 'tags', 'isAnonymous', 'inviteMode', 'status', 'parentTribeId', 'mapUrl']; parentTribeId anida círculos: federación de tribus sin órgano federativo (K5 cortical)
27 K3 · eje angular logs_model.js:243 const MAX_ACTIONS = 40; La IA narra hasta 40 acciones por clic y las publica como log (:263): sujeto no humano que escribe en el feed. Angular→IA es extensión nuestra (C) [doctrina, sin verbatim]
28 K3 · eje angular logs_model.js:137 const res = await axios.post('http://localhost:4001/ai', { input: prompt, raw: true }, { timeout: 90000 }); El númen habita en localhost:4001; la relación con él es HTTP sin auth (ver #18)
29 K3 · eje angular AI_view.js:61 form({ method: 'POST', action: '/ai/approve', class: 'ai-approve-form' }, El humano «aprueba» lo que dice la IA antes de publicarlo: único gobierno del eje angular, individual y sin registro
30 K3 · eje angular larp_model.js:139 const SOLAR_AGE_OFFSET = 10000000 - 2026; Calendario mítico (año 10.000.000) con nueve casas (HOUSE_KEYS, :9) rotando por mes (:149): estructura numinosa embebida en el código
31 K3 · eje angular melody_model.js:124 function embedTextInWav(wavBuffer, text) { Esteganografía LSB en WAV (:140-141): mensajes ocultos para quien sepa leerlos. Comunicación fuera del espacio circular visible
32 K4/K5 · conjuntiva legislativa parliament_model.js:1298 async function canPropose() { Quién puede proponer ley depende del mandato vigente (getCurrentTermBase): rama legislativa implementada
33 K4/K5 · conjuntiva judicial courts_model.js:139 const ALLOWED = new Set(['JUDGE', 'DICTATOR', 'POPULAR', 'MEDIATION', 'KARMATOCRACY']); Cinco formas de resolver un caso; el veredicto JUDGE solo vale si coincide con judgeId (:363). Rama judicial implementada
34 K4/K5 · fusión judicial-legislativa courts_model.js:142 if (m === 'DICTATOR') { El método DICTATOR exige gov.method === 'DICTATORSHIP' (:150) y toma dictatorId del powerId del gobierno (:151): la rama judicial se funde con la conjuntiva bajo dictadura
35 K4/K5 · basal planificadora industry_model.js:164 const steward = rootNode.author La instalación industrial tiene un steward único = autor del mensaje raíz; toda mutación exige steward !== ssbClient.idUnauthorized (:457, :484). Poder basal personal
36 K4/K5 · basal redistribuidora banking_model.js:215 function isPubNode() { El nodo que redistribuye es el que se autodeclara en walletPub.pubId === keys.id (:216-218): no hay rama, hay un fichero de config
37 K4/K5 · basal redistribuidora backend.js:10273 pubEngineTimer = setInterval(runPubEngineTick, 30 * 60 * 1000); executeEpoch + processPendingClaims cada 30 min sin humano (:10265-10269): redistribución automática. Eutaxia o automatismo, a decidir en D02
38 K4/K5 · cortical militar (técnica) crypto.js:146 const cipher = crypto.createCipheriv('aes-256-gcm', key, iv); Cifrado de tribus AES-256-GCM y reparto de clave con ssbKeys.box (:320): defensa como técnica, no como poder político
39 K4/K5 · cortical federativa / eutaxia tribes_model.js:753 async rotateTribeKey(tribeId, remainingMembers) { Al expulsar se genera clave nueva y se redistribuye (:757-760): frontera de pertenencia que se repara sola. Indicador de eutaxia (B) [doctrina, sin verbatim]
40 K4/K5 · cortical diplomática backend.js:4651 .post("/settings/fediverse", koaBody(), async (ctx) => { Conectar Mastodon no exige isLoopbackRequest (compárese /update, :9553); la cuenta se guarda en configs/fediverse-accounts.json (fediverse_model.js:5). Diplomacia sin órgano, en manos de cualquier petición
41 K4/K5 · cortical federativa oasis-pub.js:41 const code = await call(ssb.invite.create.bind(ssb.invite), uses); Los invites del PUB se crean desde shell (uses por argumento, :40); y el plugin de invite depende de config.pub (SSB_server.js:70). Federación sin rama
42 K6 · eutaxia (recurrencia) parliament_model.js:26 const TERM_EPOCH = Date.UTC(2020, 0, 1); Calendario fijo desde 2020-01-01 en ventanas de TERM_SPAN_MS: el ciclo se recurre sin convocante. Eutaxia como recurrencia (B) [doctrina, sin verbatim]
43 K6 · eutaxia (retorno a anarquía) parliament_model.js:373 function virtualAnarchyTerm(window = termWindowFor(Date.now())) { Si no hay mandato, el ciclo es ANARCHY virtual con powerType: 'none' (:380): la sociedad política persiste sin gobierno, por defecto de código
44 K6 · distaxia (identidad) exportmode_model.js:24 if (file === 'secret') { El export excluye secret: no hay camino de respaldo de la identidad. STEPS del onboarding incluye backup (onboarding_model.js:5) pero solo escribe un flag de fichero (writeFileSync, :116; markStep, :123-125)
45 K6 · distaxia (irreversibilidad) backend.js:8054 await panicmodeModel.removeSSB(); Tras borrar, pkill del servidor y process.exit (:8056-8057) sin confirmación en dos pasos. Muerte voluntaria sin fricción
46 K6 · distaxia (actualización) backend.js:9556 const { stdout, stderr } = await exec("git reset --hard && git pull", { cwd: repoRoot }); POST /update hace git reset --hard sobre el repo, que contiene src/configs/*.json (caps, hops, wallet): la actualización destruye la configuración local
47 K6 · sin medida de tiempo stats_model.js (grep -i uptime: 0 resultados) El nodo mide disco (#3) y pubs (#23) pero no su propia duración: la red no se mide en el tiempo, que es el eje de la eutaxia (B) [doctrina, sin verbatim]
48 K7 · holización por el log inhabitants_model.js:87 const authorsMsgs = (await readTyped(ssbClient, [], { limit: logLimit, withWindow: true })).filter(msg => !!msg.value?.author && … El censo = conjunto de autores con mensajes no tombstone: un feed, un inhabitant. Holización mínima: demos definido por haber publicado
49 K7 · holización por el log parliament_model.js:1191 const population = await inhabitantsCount(); La población que fija el quórum del mandato sale de ese mismo censo (inhabitantsCount, :244): partes homogéneas contadas
50 K7 · holización (igualdad formal) parliament_view.js:21 if (m === 'DEMOCRACY' || m === 'ANARCHY') return Math.floor(Number(total || 0) / 2) + 1; Mayoría = mitad más uno de votos iguales: la forma democrática como aritmética de partes iguales (K7, B)
51 K7 · des-holización por karma parliament_model.js:422 const maxKarma = Math.max(...tied.map(c => c.karma)); Empate electoral resuelto por karma: reintroduce partes heterogéneas (notoriedad) en el demos homogéneo
52 K7 · des-holización por karma parliament_model.js:650 if (method === 'DICTATORSHIP' || method === 'KARMATOCRACY') { Bajo KARMATOCRACY la revocación sigue otro camino: el karma crea un régimen propio, con propuestas ordenadas por karma (:576)
53 K7 · des-holización por karma inhabitants_model.js:217 const karmaBonus = Math.min(20, Math.log10(1 + Math.max(0, karmaScore)) * 5); Sugerencias de contacto ponderan follow (20), karma (≤20), skills (4/u) y actividad (5/2/0): la red re-estratifica el círculo
54 K7 · un sujeto, un voto polls_model.js:99 if (!entry.voters.includes(v.author)) { Las opiniones se deduplican por autor de feed: la unidad de cuenta es la clave, no la persona. Holización técnica, no jurídica

Desajustes de numeración detectados en drafts/draft.md (2026-09-09)

Ambos se han comprobado con sed -n; las líneas del draft apuntan a código cercano pero no al símbolo nombrado.

Dónde (draft.md) Dice Verificado Nota
§4.1, fila Planificadora (L315) `steward` único (:163, :462) industry_model.js:164 (const steward = rootNode.author) y :457 (if (g.facility.steward !== ssbClient.id) throw new Error("Unauthorized")) :163 es if (!rootNode) return null; :462 es name: patch.name === undefined …
§4.1, fila Militar (L318) AES-GCM :146, box :319 crypto.js:146 correcto; ssbKeys.box está en :320 (:319 es la cabecera const boxKeyForMember = …) Ajuste de una línea

Operaciones propuestas (para el integrador; el draft semilla no se reescribe salvo nota al margen, así que se dejan como candidatas a draftv0):

[
  {"file": "drafts/draft.md", "old": "`steward` único (:163, :462)", "new": "`steward` único (:164, :457)", "motivo": "industry_model.js:164 es `const steward = rootNode.author`; :457 es el `Unauthorized` del steward. Verificado 2026-09-09."},
  {"file": "drafts/draft.md", "old": "AES-GCM :146, box :319", "new": "AES-GCM :146, box :320", "motivo": "crypto.js:320 es `ssbKeys.box(tribeKeyHex, [memberFeedId])`; :319 es la cabecera de `boxKeyForMember`. Verificado 2026-09-09."}
]

Ambos old aparecen exactamente una vez (grep -c = 1). Nota: los old tienen menos de 40 caracteres porque la celda es corta; si el integrador exige el mínimo, ampliar a la fila completa de la tabla (L315 y L318, únicas).

Resumen por coordenada

  • K1 (materialidades): M1 = bytes/disco/CO₂ (#1-4); M2 = opiniones tipificadas, tema local, cubos de actividad (#5-8); M3 = constantes y tipos de mensaje (#9-12). La red ejecuta una sola reducción entre géneros, karma − gramos (#13-14).
  • K2 (cierres): criptografía y replicación cerradas por importación (#15-17); IA abierta (#18-19); banca dependiente (#20); gobernanza cerrada en el log, abierta en la ejecución (#21-22).
  • K3 (espacio antropológico): radial = pubs y disco (#23); circular = block, autofollow, tribus anidadas (#24-26); angular = IA 42, L.A.R.P., esteganografía (#27-31), gobernado solo por el botón /ai/approve.
  • K4/K5 (capas y ramas): conjuntiva implementada y fusionable bajo dictadura (#32-34); basal en manos de steward único y nodo autodeclarado pub con motor de 30 min (#35-37); cortical existe como técnica o como shell/config sin órgano (#38-41).
  • K6 (eutaxia): recurrencia por calendario y anarquía virtual (#42-43); distaxias de identidad, pánico y actualización (#44-46); ausencia de medida de tiempo (#47).
  • K7 (holización): el log holiza por autoría (#48-50); el karma des-holiza en empates, régimen propio y sugerencias (#51-53); la unidad de cuenta es la clave (#54).