ORACLE-OS-SETTINGS-GOAL.md (multi-tenant/settings), RELEASE-READINESS.md (multi-user), The KAI Codex.md |Read §6 "RESUME HERE" first if picking this up.
---
Turn the Oracle Lattice OS from an owner-only control dashboard into a **social
platform with a built-in AI ecosystem**: regular users create accounts, fill in a
profile (the stuff social apps ask for), and get a public feed of posts +
threads + groups (Facebook-style), all alongside the KAI AI fleet. The owner
remains admin/root.
---
command-center-server.mjs serves a self-contained,on-brand login page for any unauthenticated HTML request (the "ORACLE LATTICE OS
/ SECURE ACCESS / UNLOCK" screen). It POSTs to /api/login. **This is where the
login/Create-Account work goes — NOT oracle.html.**
sessions Map sid -> { exp, userId }, cookie cc_session (HttpOnly, SameSite=Strict), SESSION_TTL_MS = 12h absolute expiry
(L744-763). newSession(userId), sessionValid(sid) (checks exp only — NO idle
timeout yet). isAuthorized() accepts a valid session OR the x-cc-token/?token
control token.
state/cc_users.json, tokens sha256-hashed at rest (neverplaintext) (L563/595). Roles owner > admin > member > viewer > guest. Endpoints
/api/login, /api/logout, /api/me, /api/users (list), /api/users/mint
(owner creates a user). Gates requireOwner/Control/Member. Guest "cloud wall"
denies all but a few read routes.
no feed/posts/groups.
oracle.html — BLOCKED until the 106 KB oftrailing NUL bytes are stripped (Phase 0).
Safe write helpers already present: updateEnvKeys, atomic JSON writes
(temp+rename), newSession, the users file r/w.
---
Strip the trailing NUL padding from oracle.html (it makes the file read as binary,
breaking grep + risking further edits). Run once (PowerShell / IDE agent — the
Cowork mount CANNOT do it safely):
$p='c:\KAI\oracle.html'; $t=[IO.File]::ReadAllText($p); $i=$t.LastIndexOf('</html>'); [IO.File]::WriteAllText($p, $t.Substring(0,$i+7) + "`r`n")
Verify: Select-String -Path c:\KAI\oracle.html -Pattern 'agSend' should now match.
All in command-center-server.mjs (clean file). No oracle.html needed.
1. Idle / inactivity timeout. Add lastActive to each session; on each
authorized request, refresh it. Expire a session if `now - lastActive >
IDLE_TTL_MS (env CC_IDLE_TIMEOUT_MIN`, default e.g. 30 min) — sliding window,
in addition to the 12h absolute cap. On expiry -> the login page (re-login).
2. Session-time UI. The login/app shows a small "signed in / expires in" or a
live clock; on idle-expiry show "Signed out for inactivity — please sign in."
3. Create Account (open sign-up). Add a "Create Account" toggle on the login
page (second form) + POST /api/register:
(see Phase 2). Validate + rate-limit.
role: 'member' (or a new 'user' tier) record in cc_users.json, password hashed (extend the existing sha256 — add a
per-user random salt; bcrypt if a dep is acceptable). Never store plaintext.
newSession(userId) + set cookie -> straight into the app./api/users).handle, avatar (url/upload), bio/about, interests, location (optional), links,
and a free "about/research" block. Stored per-user (extend the user record or a
state/profiles.json).
GET/POST /api/profile (self), GET /api/profile/:handle (publicview). Owner/admin can edit/disable.
state/feed.json or the existing transcripts.db — posts `{id, author, text, media?, ts, replyTo?, reactions}. Threads = posts with replyTo`.
GET /api/feed (paged), POST /api/feed (create), `POST /api/feed/:id/reply, POST /api/feed/:id/react`, owner/admin delete.
threads + reactions). AI ecosystem tie-in: the KAI fleet agents can post /
reply in the feed (they already speak in Discord — mirror select posts), and
Antigravity/agents can be @mentioned in a post to answer inline.
state/groups.json — {id, name, desc, members[], visibility}; group posts carry groupId. Membership join/leave.
role/session (client never asserts role — matches current design); CSRF via
SameSite=Strict (already) + same-origin POSTs; rate-limit register/post/login.
(don't break isAuthorized/CC_CONTROL_TOKEN). New public users are a lower tier
layered on top of the existing RBAC.
---
cc_users.json: existing + new public users (role:'member'|'user', passHash, salt, createdAt, handle).
profiles.json (or inline): profile fields per user.feed.json: posts/threads/reactions.groups.json: groups + membership.sessions (in-memory): add lastActive for idle timeout.bcrypt/argon2 (dep).---
Confirmed: open sign-up, one shared platform, owner = admin.
Order (do top-down):
1. PHASE 0 — strip oracle.html NUL padding (native tool; command in §3). BLOCKS
any feed/groups UI. (Login/account work is NOT blocked — it's server-side.)
2. PHASE 1 — auth hardening + Create Account in command-center-server.mjs
(idle timeout + re-login + open registration). Unblocked; safe to start now.
CAUTION: this touches the login/session path — must not break the owner's
existing token/cookie login. Verify owner can still sign in after each change.
3. PHASE 2 profiles -> PHASE 3 feed (needs Phase 0 done for the oracle.html view)
-> PHASE 4 groups.
Hard rules (from CLAUDE.md): surgical edits only; never wholesale-rewrite
oracle.html/command-center-server.mjs; verify against the REAL Windows file (the
mount truncates + the NUL padding makes grep see binary); never print .env/token
secret values; keep the Codex + Cargo version synced.
Key files: command-center-server.mjs (login page + `/api/login|logout|me|users|
register, sessions, newSession, isAuthorized, SESSION_TTL_MS`),
state/cc_users.json, oracle.html (feed/groups views — after Phase 0),
RELEASE-READINESS.md, ORACLE-OS-SETTINGS-GOAL.md.