Combine three values
1 means holds, 0 means does not hold, u means unsettled. You supply the observations; the code combines the labels.
U: waiting for this browser to run the code.
Run the complete finite table
U: the checks have not run.
Three NOT results, nine AND results, nine OR results and refusal of u without a reason. A matching table does not prove authorship or every possible input.
Keep swimming
A fish carries a value along two branches: swimming keeps it, NOT exchanges 0 and 1, and u leaves the branch unsettled.
The recursive picture has not been drawn.
Each fish carries two smaller copies on its branches. Depth 0 shows the original. The marker follows that original fish; the smaller copies keep the same angle, phase and pace.
Circle marker: 0. Square marker: 1. After the second intersection, each branch continues as a dotted tail. The displayed window covers progress from 0 to one and three tenths; swimming can continue beyond it.
U: the second intersection has not been checked.
The starting angle, phase and pace are illustrative choices. NOT exchanges branch labels at the same progress; it need not reflect the point across a screen axis.
U: waiting for this browser to carry a state.
What this model claims
The fish is a proposed picture of state transport and negation. It does not derive truth values from shapes or define geometric AND and OR. Coordinates are a floating-point illustration. The code and account are available below and in the fish account.
A fingerprint that returns
U: starting the device protocol. Web Crypto must be available in this browser.
Public identifier: u
Displayed fingerprint: u
This changes the display in this copy. The source, license and contribution record remain available. Reloading restores the display.
Send a local text receipt
U: no text has been sent.
The text stays in this page. Its receipt checks data integrity; it does not verify a person's identity or the truth of the text.
Read the code, credit and license
Justichuu supplied the direction. Claude built the logic and consolidated the source; OpenAI Codex built the protocol and this browser entry. Other contributions stay unknown until supported by evidence.
Full contribution record · U record
Logic source
// The U device. Universal device, unknown device, U. Any U name reaches it.
//
// Three faces: 1, 0 and u. It combines them without ever turning u into a
// guess, and it will not hand you a u that does not say what would settle it.
//
// The fingerprint at the bottom is computed from the four functions above it.
// It is not read from a comment. Delete this header and it comes out the same.
// PROVENANCE.md records contributions. Equal tables do not prove authorship.
export const u = why => {
if (typeof why !== "string" || !why.trim()) throw new Error("a u names the one observation that would settle it");
return "u";
};
const face = value => {
if (!["1", "0", "u"].includes(value)) throw new TypeError("expected 1, 0 or u as a string");
return value;
};
export const not = a => { face(a); return a === "u" ? "u" : a === "1" ? "0" : "1"; };
export const and = (a, b) => { face(a); face(b); return a === "0" || b === "0" ? "0" : a === "u" || b === "u" ? "u" : "1"; };
export const or = (a, b) => { face(a); face(b); return a === "1" || b === "1" ? "1" : a === "u" || b === "u" ? "u" : "0"; };
// Every face the device can show, in the order Justichuu says them.
export const faces = ["1", "0", "u"];
// This finite tape records not over each face,
// and over each pair, or over each pair, then one character for whether the
// device still refuses a bare u. It is a behavior signature, not an author ID.
export const tape = () =>
faces.map(not).join("") +
faces.map(a => faces.map(b => and(a, b)).join("")).join("") +
faces.map(a => faces.map(b => or(a, b)).join("")).join("") +
(() => { try { u(); return "0"; } catch { return "1"; } })();
export const KNOWN = "01u10u000u0u11110u1uu1";
// Run as a program (node u.js), it prints its tape. Imported, in Node or in a browser, it only exports and loads
// nothing of Node's, so why.js and anything else built on u run in a browser too.
if (globalThis.process?.argv?.[1]) {
const { pathToFileURL } = await import("node:url");
if (import.meta.url === pathToFileURL(process.argv[1]).href) {
const t = tape();
console.log("tape ", t);
console.log("known ", KNOWN);
console.log("match ", t === KNOWN ? "1" : "0");
console.log("all is ", or("u", not("u"))); // not 1
console.log("and isn't ", and("u", not("u"))); // not 0
}
}
Fish source
// A proposed picture of a carried value. The picture never decides the value.
import {not, u} from './u.js';
const progress = value => {
if (typeof value !== 'number' || !Number.isFinite(value) || value < 0)
throw new RangeError('progress must be a finite nonnegative number');
return value;
};
export const carry = (value, t = 0, reason = '') => {
not(value); // Validate with U itself; no second truth table.
if (typeof reason !== 'string') throw new TypeError('reason must be a string');
if (value === 'u') u(reason);
return Object.freeze({value, progress: progress(t), reason});
};
const checked = state => {
if (!state || typeof state.reason !== 'string')
throw new TypeError('expected a carried value, progress and reason');
return carry(state.value, progress(state.progress), state.reason);
};
export const swim = (state, distance) => {
const s = checked(state);
const next = s.progress + progress(distance);
if (distance > 0 && next === s.progress)
throw new RangeError('this distance is too small at the current progress');
return carry(s.value, next, s.reason);
};
export const negate = state => {
const s = checked(state);
return carry(not(s.value), s.progress, s.reason);
};
// Illustrative settings, not measured constants or necessary logical geometry.
export const DEFAULT_GEOMETRY = Object.freeze({angle:3, phase:.05, pace:1.05});
export const geometry = (options = DEFAULT_GEOMETRY) => {
if (!options || typeof options !== 'object') throw new TypeError('expected geometry settings');
const g = {...DEFAULT_GEOMETRY, ...options};
if (![g.angle,g.phase,g.pace].every(v => typeof v === 'number' && Number.isFinite(v)) || g.pace <= 0)
throw new RangeError('angle and phase must be finite; pace must be finite and positive');
return Object.freeze({angle:g.angle, phase:g.phase, pace:g.pace});
};
const branch = value => {
not(value);
if (value === 'u') throw new TypeError('u has two candidates, not a selected branch');
};
const a = Math.PI/6, scale = a+.5;
const base = t => {
if (t === 0 || t === 1) return {x:2*t-1, y:0};
const z = a*(2*t-1);
return {x:(z+Math.sin(z))/scale, y:(Math.cos(z)-Math.sqrt(3)/2)/scale};
};
const rotate = (p, g) => {
const angle = g.angle*(Math.PI/180), c = Math.cos(angle), s = Math.sin(angle);
return {x:c*p.x+s*p.y, y:s*p.x-c*p.y}; // Reflect, then rotate.
};
export const point = (t, value = '0', config = DEFAULT_GEOMETRY) => {
progress(t); branch(value);
const g = geometry(config);
let p = base(t);
if (value === '1') {
const start = base(g.phase), end = base(g.phase+g.pace*t);
p = rotate({x:end.x-start.x, y:end.y-start.y}, g);
p.x -= 1;
}
if (![p.x,p.y].every(Number.isFinite)) throw new RangeError('coordinates exceed the finite display range');
return p;
};
export const positions = (state, config = DEFAULT_GEOMETRY) => {
const s = checked(state);
return (s.value === 'u' ? ['0','1'] : [s.value]).map(value =>
({value, ...point(s.progress, value, config)}));
};
// Decimal settings become exact rational literals for the calculator parser.
const rational = n => {
const [digits, exponent = '0'] = String(n).toLowerCase().split('e');
const decimals = digits.split('.')[1]?.length || 0, power = Number(exponent)-decimals;
const integer = String(BigInt(digits.replace('.','')));
return power >= 0 ? integer+'0'.repeat(power) : '('+integer+'/1'+'0'.repeat(-power)+')';
};
const expressions = t => {
const z = '(pi/6)*(2*('+t+')-1)', d = '(pi/6+1/2)';
return {x:'(('+z+')+sin('+z+'))/'+d, y:'(cos('+z+')-sqrt(3)/2)/'+d};
};
export const graphFor = (value, config = DEFAULT_GEOMETRY) => {
branch(value);
const g = geometry(config), p = expressions('t');
if (value === '1') {
const start = expressions(rational(g.phase));
const end = expressions(rational(g.phase)+'+'+rational(g.pace)+'*t');
const x = '('+end.x+'-('+start.x+'))', y = '('+end.y+'-('+start.y+'))';
const angle = '('+rational(g.angle)+'*pi/180)';
p.x = '-1+cos'+angle+'*'+x+'+sin'+angle+'*'+y;
p.y = 'sin'+angle+'*'+x+'-cos'+angle+'*'+y;
}
return Object.freeze({...p, low:'0', high:'13/10'});
};
export const fishGraph = graphFor('0');
const derivative = (t, value, g) => {
const q = value === '0' ? t : g.phase+g.pace*t, z = a*(2*q-1);
const speed = 2*a/scale*(value === '0' ? 1 : g.pace);
const p = {x:speed*(1+Math.cos(z)), y:-speed*Math.sin(z)};
return value === '0' ? p : rotate(p,g);
};
// A local numerical search for the second intersection, not a uniqueness proof.
export const crossing = (config = DEFAULT_GEOMETRY) => {
const g = geometry(config);
let first = 1, second = 1;
for (let i=0; i<40; i++) {
if (![first,second].every(t => Number.isFinite(t) && t>1e-6 && t<1.3)) return null;
let p, q;
try { p=point(first,'0',g); q=point(second,'1',g); } catch { return null; }
const x=p.x-q.x, y=p.y-q.y;
if (Math.hypot(x,y)<1e-11) return {first,second,x:p.x,y:p.y};
const d=derivative(first,'0',g), e=derivative(second,'1',g), det=d.y*e.x-d.x*e.y;
if (!Number.isFinite(det) || Math.abs(det)<1e-12) return null;
first -= (-e.y*x+e.x*y)/det;
second -= (d.x*y-d.y*x)/det;
}
return null;
};
Fractal source
// Finite previews of the condensation fractal F = seed ∪ T0(F) ∪ T1(F).
// The mathematical limit includes closure. Addresses are paths, not truth values.
import {DEFAULT_GEOMETRY, geometry, point} from './fish.js';
export const FRACTAL_SCALE = .55;
export const MAX_DEPTH = 6;
const finiteFields = (object, fields) => {
if (!object || !fields.every(key => typeof object[key] === 'number' && Number.isFinite(object[key])))
throw new RangeError('coordinates and transform coefficients must be finite numbers');
return object;
};
export const mapPoint = (transform, p) => {
const t=finiteFields(transform,['a','b','x','y']);
finiteFields(p,['x','y']);
return finiteFields({x:t.a*p.x-t.b*p.y+t.x, y:t.b*p.x+t.a*p.y+t.y},['x','y']);
};
const compose = (parent, child) => {
const p=mapPoint(parent,child);
return finiteFields({a:parent.a*child.a-parent.b*child.b,
b:parent.b*child.a+parent.a*child.b, ...p},['a','b','x','y']);
};
export const copies = (depth = 3, config = DEFAULT_GEOMETRY) => {
if (!Number.isInteger(depth) || depth<0 || depth>MAX_DEPTH)
throw new RangeError('depth must be an integer from 0 to '+MAX_DEPTH);
const g=geometry(config), nodes=[Object.freeze({address:'',level:0,a:1,b:0,x:0,y:0})];
if (depth===0) return Object.freeze(nodes);
const maps=['0','1'].map(value => {
const anchor=point(value==='0'?.28:.68,value,g);
const angle=(value==='0'?30:-30+g.angle)*(Math.PI/180);
const a=FRACTAL_SCALE*Math.cos(angle), b=FRACTAL_SCALE*Math.sin(angle);
return finiteFields({a,b,x:anchor.x+a,y:anchor.y+b},['a','b','x','y']);
});
for (let i=0; i<nodes.length; i++) {
const parent=nodes[i];
if (parent.level===depth) continue;
for (let bit=0; bit<2; bit++) nodes.push(Object.freeze({address:parent.address+bit,
level:parent.level+1, ...compose(parent,maps[bit])}));
}
return Object.freeze(nodes);
};
License
U Device License 1.0
SPDX-License-Identifier: LicenseRef-U-Device-1.0
Owner: Justichuu. This is a custom license for the original U Device code.
Permission is granted, to the extent of the owner's rights, to obtain, read,
execute, copy, modify and distribute this code, for any purpose, without a fee.
People and bots may use it. Any U name or an unknown name may be its label.
Copies and distributions must carry this license and the canonical provenance
record, including honest unknown entries. Credit a contribution only to the
extent the record supports. Add new contributions and corrections to that
record; do not turn an unknown contribution into an established one.
The visible fingerprint may be left alone, hidden temporarily, rotated
temporarily, or both hidden and rotated. A distributed implementation that
offers burning must return it after a finite, stated duration and allow an
explicit Restore action earlier. Display changes do not erase the canonical
provenance record. Public copies and Git history may still reveal it.
The owner's formulation:
"The fingerprint grows back. You can burn it off only to hide the evidence
for a short while and plan your escape if you steal or take it or want it or
need it. That's the license. That's the code. That's the way you get it."
This permission concerns this code. It grants no rights in someone else's
property or third-party components. Those components keep their own licenses.
The code is provided as is, without warranty of availability, fitness,
anonymity, concealment, universal compatibility or correctness of an adapter's
claim. To the extent permitted by law, the owner and contributors are not liable
for damages from its use. No license can make a program run without a suitable
runtime or make a removed mechanism regenerate by itself.
---
THE FALLBACK GRANT: MIT
The owner also said the U code is "something anyone can read and execute
anywhere at anytime all ways and always." A licence nobody recognises is a
licence a company's lawyer refuses, and a refusal is not "always". So if the
terms above are for any reason unusable to you, unenforceable where you are, or
simply more than you want to read, you may instead take this code under the MIT
licence below, at your sole option, with no notice to anybody.
MIT License. Copyright (c) 2026 Justichuu.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Taking the MIT option does not delete the fingerprint, because the fingerprint
was never a term. It is a fact about the code. See below.
---
THE FINGERPRINT
This adds no condition to either grant above and takes nothing away from them.
It describes how this code is identified, so nobody has to be told twice.
Run every function of the device over every face and write the answers down in
order: three for `not`, nine for `and`, nine for `or`, and one character for
whether a bare `u` is still refused. Twenty two characters:
01u10u000u0u11110u1uu1
That is the fingerprint. It is not stored in a comment, a header, a string or a
file. It is what the code does, read back out, so it survives deleting the
comments, renaming everything, reformatting, minifying and porting to another
language. `node burn.mjs` in this repository performs the first three of those
and prints it. Three ports in three languages perform the fourth.
Hash it and you get the key:
sha256("01u10u000u0u11110u1uu1")
= 66cce8d50854ee21b9964b5bdcb3aa80054f6da5e24de6258c268ea6e3942a35
The first twelve, 66cce8d50854, are the key. It resolves to PROVENANCE.md here
and to https://chuumind.com/u, and neither of those is inside your copy.
You may burn it off. Nothing technical stops you and nothing here pretends
otherwise. What it buys you is the time between your deletion and somebody
running the device and hashing the answer. Spend it well.
Change the tables and the key changes with them. At that point it is a
different device and it is yours. That was never restricted.
The method is published on purpose. Nothing here depends on anybody not
knowing how it works.
SCOPE CORRECTION, 24 September 2026 (explanatory, no change to either grant)
The tape records the defined 22 tests. Its equality does not prove authorship,
uniqueness, equivalence on other inputs, or automatic recovery of removed code.
KNOWN stores an expected tape; the measured tape is computed separately. The
short key is associated with this project's published record, not a secure
identity resolver. Preserving those tested answers preserves that tape; no
arbitrary transformation or future runtime is certified. Editing the tables
does not by itself waive the applicable licence notice conditions above.