La lógica de Derivación del Código
CASO:
root["_"]("A")
root.child["_"]("B")
root.child["~"]("N")
root.child.leaf("x")
root scope=root(A) effective=A
child [_ B] scope=child(B) effective=A+B
cambia el dueño estructural aquí
child [~ N] scope=child(B) effective=N+B
corta A
conserva B porque B vive en el mismo noise boundary
leaf="x" scope=child(B) effective=N+B
hereda N+B
no hereda AY el caso 4, al lado, para comparar:
CASO 4:
wallet["_"]("A")
wallet.hidden.notes("alpha-note")
wallet["~"]("N")
wallet["_"]("B")
wallet.hidden.seed("beta-seed")
wallet scope=wallet(A) effective=A
hidden.notes scope=wallet(A) effective=A
escrito en la generación vieja
wallet [~ N] [_ B] scope=wallet(B) effective=N+B
mismo nodo, nuevo lineage efectivo
hidden.seed scope=wallet(B) effective=N+B
escrito en la generación nueva
hidden.notes old blob @ A
lectura actual intenta N+B
=> queda fuera / fail closedLa diferencia conceptual entre ambos es:
childya era el dueño estructural por["_"]("B"); luego~no le quita ese ownership. Solo le cambia la cadena efectiva deA+BaN+B.- En el caso 4, pasa algo parecido en el mismo nodo
wallet, pero además ves muy claro el corte temporal entre “datos escritos antes del reset” y “datos escritos después”.
Sobre el orden _ y ~ en el mismo nodo: el estado final no cambia.
Estas dos secuencias terminan con el mismo mapa final de secretos/noises y el mismo lineage efectivo:
root["_"]("A");
root.child["_"]("B");
root.child["~"]("N");root["_"]("A");
root.child["~"]("N");
root.child["_"]("B");Eso es porque el cálculo final lee los mapas actuales localSecrets y localNoises, no el orden histórico de memorias: registerStealthScope(...) y el manejo del operador ~ en src/core-write.ts, junto con computeEffectiveSecret(...) en src/secret-context.ts.
Lo que sí cambia con el orden es qué escrituras históricas quedaron cifradas con el linaje viejo y cuáles con el nuevo.
La regla mental se actualiza a:
~ corta todo lo que está SOBRE ese nodo
~ conserva el _ que está EN ese mismo nodo
~ no toca nada de abajoCasoScope estructuralEffective LineageRead ownerRead guest~ arriba, _ abajomanda el _ de abajonoise + secret_abajosíno_ arriba, ~ abajomanda el _ de arribanoise + cualquier _ en el boundary o debajosíno_ y ~ mismo nodomanda ese mismo nodonoise + secret_de_ese_mismo_nodosíno~ sin _no hay scope secretopuede calcular noise, pero no hay contexto secreto válidowrite inválido / edge caseno aplica- #### Operators: ["~"] sin ["_"] ancestro es write inválido. Define un scope secreto primero.
Security:
["~"] reutilizado en ramas distintas comparte linaje criptográfico. Usa noises únicos si necesitas aislamiento total.Sí puedes poner["~"]después de paths públicos. Lo que no puedes es escribir data secreta si no hay ningún["_"]ancestro.["~"]no crea privacidad. Solo corta la herencia criptográfica.["_"]crea el cuarto secreto. ### La regla exacta: ts // Caso 1: VÁLIDO ✅me.public["_"]("A"); // ← crea scope secreto en publicme.public.child["~"]("N"); // ← corta A, resembra en Nme.public.child.secret("x"); // ← escribe bajo scope=public(A), effective=N // Caso 2: INVÁLIDO ❌ me.public["~"]("N"); // ← intenta cortar herencia... pero no hay herenciame.public.secret("x"); // ← Error: No secret context active### Por qué: ["_"]hace 2 cosas: Marca el nodo comostealth= invisible en lecturas públicas - Registra
secretenlocalSecrets[path]
["~"] hace 1 cosa:
- Registra
noiseenlocalNoises[path]y dice “desde aquí abajo, ignora secrets de arriba”
Si escribes me.node("valor") y node no vive bajo ningún ["_"], el kernel no sabe dónde guardar el secreto. Por eso tira No secret context active.
Cómo pensar ~ sin _:
Es como decir “a partir de aquí, olvida la historia familiar”... pero si nunca hubo familia = ["_"], no hay nada que olvidar. Es un no-op que confunde.
me.root["~"]("N"); // noise registrado, pero sin efectome.root.child("x"); // x es público. N no se usó para nadame.root.child("_") // Error: no hay scope donde guardarCómo usarlo bien:
["~"] solo tiene sentido en 3 situaciones:
- Entre dos
["_"]para cortar herencia:
me.wallet["_"]("A"); // dueño viejome.wallet.box["~"]("N"); // caja nueva, olvida Ame.wallet.box["_"]("B"); // dueño nuevome.wallet.box.note("x"); // effective = N+B, no A- Debajo de un
["_"]para resetear ramas:
me.app["_"]("root-key");me.app.user1["~"]("N1"); // user1 no hereda root-keyme.app.user2["~"]("N2"); // user2 tampoco, y N1 ≠ N2- En el mismo nodo que
["_"]para rekey:
me.vault["_"]("old");me.vault["~"]("N"); // corta oldme.vault["_"]("new"); // nuevo dueñome.vault.doc("x"); // effective = N+newRespuesta directa:
¿Puedes poner ~ después de paths públicos? Sí. ¿Puedes escribir secretos ahí? No, hasta que algún ancestro tenga ["_"].
Si quieres que me.public.child sea secreto pero con linaje cortado, haz:
me.public["_"]("key"); // abre el cuarto secretome.public.child["~"]("N"); // corta key para child y descendientes me.public.child.data("x"); // x vive bajo scope=public, effective=N¿Queda claro? ~ es tijeras. _ es la caja fuerte. Necesitas la caja antes de usar tijeras.