diff --git a/llms-full.txt b/llms-full.txt index 981f1ef..2f1afc7 100644 --- a/llms-full.txt +++ b/llms-full.txt @@ -345,7 +345,7 @@ Text version of the interactive map: This map needs JavaScript. ### Facts -- Built by: Seth Carlson and Mateo Robles +- Built by: SyberLabs - Technology: TypeScript, React, Vinext, Cloudflare Workers, D1, Drizzle ORM, Chrome extension (Manifest V3), Playwright - Boundary: Relay prepares and tracks application materials. It does not submit employer forms, host an MCP connection, or sync accounts in the background. - Source: [github.com/SyberLabs/relay](https://github.com/SyberLabs/relay) diff --git a/mateo/index.html b/mateo/index.html index ff3cc58..b168c26 100644 --- a/mateo/index.html +++ b/mateo/index.html @@ -126,7 +126,7 @@

Mateo Robles.Software & Product Engineer.<
RISE / A captured demonstration of the reading and playback interface.

What I contributed

RISE lets readers experience text as a paced stream or a page, with sound and visuals. I led core development of text pacing and playback, moving graphics, browser audio, video export and automated tests.

-

Where my work fits

RISE is a team project. I collaborated with Seth Carlson and other contributors from the early application through later shared development. The recording above shows the reading and playback interface.

+

Where my work fits

RISE is a team project. I collaborated with other contributors from the early application through later shared development. The recording above shows the reading and playback interface.

Open RISE ↗RISE case studyProject development credits ↗
diff --git a/migrations/0001_accounts.sql b/migrations/0001_accounts.sql index a7369bd..8f8e644 100644 --- a/migrations/0001_accounts.sql +++ b/migrations/0001_accounts.sql @@ -78,7 +78,7 @@ CREATE TRIGGER role_perms_admin_keeps_all BEFORE DELETE ON role_permissions CREATE TABLE user_roles ( user_id TEXT NOT NULL REFERENCES users(id), role_id TEXT NOT NULL REFERENCES roles(id) ON DELETE CASCADE, - granted_by TEXT REFERENCES users(id), -- NULL = bootstrap or break-glass, from Seth's terminal + granted_by TEXT REFERENCES users(id), -- NULL = bootstrap or break-glass, from the owner's terminal granted_at INTEGER NOT NULL, PRIMARY KEY (user_id, role_id) ); @@ -109,7 +109,7 @@ CREATE TABLE invites ( CREATE TABLE audit_events ( id INTEGER PRIMARY KEY AUTOINCREMENT, at INTEGER NOT NULL, - actor_user_id TEXT, -- NULL = bootstrap, from Seth's terminal + actor_user_id TEXT, -- NULL = bootstrap, from the owner's terminal action TEXT NOT NULL, -- signin.ok invite.create invite.revoke invite.redeem -- role.grant role.revoke role.create role.perms -- user.disable user.enable identity.remove diff --git a/projects/site-data.js b/projects/site-data.js index 95899d2..66eab1e 100644 --- a/projects/site-data.js +++ b/projects/site-data.js @@ -293,7 +293,7 @@ export const projects = [ ['not yet', 'No public deployment and no customer counts, hiring outcomes or throughput improvements are claimed. Autonomous hunting is not included.'], ], facts: [ - ['Built by', 'Seth Carlson and Mateo Robles'], + ['Built by', 'SyberLabs'], ['Technology', 'TypeScript, React, Vinext, Cloudflare Workers, D1, Drizzle ORM, Chrome extension (Manifest V3), Playwright'], ['Boundary', 'Relay prepares and tracks application materials. It does not submit employer forms, host an MCP connection, or sync accounts in the background.'], ['Source', { label: 'github.com/SyberLabs/relay', href: 'https://github.com/SyberLabs/relay' }], diff --git a/scripts/account-nav.test.mjs b/scripts/account-nav.test.mjs index 4ff7187..0c61e6f 100644 --- a/scripts/account-nav.test.mjs +++ b/scripts/account-nav.test.mjs @@ -77,7 +77,7 @@ test('browser back refreshes signed-out HTML after login and validates sign-out const f = fixture(); account(f.doc); f.requests[0].resolve(response(401)); await settle(); const back = f.win.dispatch('pageshow'); - f.requests[1].resolve(signedIn('@seth')); await back; + f.requests[1].resolve(signedIn('@octocat')); await back; assert.equal(f.nodes['sy-account-member'].hidden, false); const focus = f.win.dispatch('focus'); f.requests[2].resolve(response(401)); await focus; @@ -101,7 +101,7 @@ test('visibility refresh waits until visible and old requests cannot overwrite n test('transient server failures, malformed replies and timeout preserve validated state', async () => { const f = fixture(); const refresh = account(f.doc); - f.requests[0].resolve(signedIn('@seth')); await settle(); + f.requests[0].resolve(signedIn('@octocat')); await settle(); for (const result of [response(503), response(200, { version: 1, user: null })]) { const pending = refresh(); f.requests.at(-1).resolve(result); await pending; assert.equal(f.nodes['sy-account-member'].hidden, false); diff --git a/server/CONTRACT.md b/server/CONTRACT.md index 3d2ed9a..120adc1 100644 --- a/server/CONTRACT.md +++ b/server/CONTRACT.md @@ -173,7 +173,7 @@ and `helpers.js` (`makeEnv`, `seedRole`, `seedUser`, `seedSession`, `signIn`, `c `providerLabel(p)`. `page()` puts its own " · SyberLabs staff" after `title`; `alert(kind, html)` kinds are `neutral | success | warning | danger`. - `forbidden.js` re-exports `notFoundHtml`, `errorHtml`, `unavailableHtml`, `CSRF_COPY` from `views/error.js`. - - `confirm.js` exports `confirmed(ctx)`, `actingAs(user)` ("You, Seth via GitHub," escaped, trailing comma) and + - `confirm.js` exports `confirmed(ctx)`, `actingAs(user)` ("You, @octocat (GitHub)," escaped, trailing comma) and `confirmHtml(ctx, {title, lines, action, fields, submitLabel, cancel = '/admin/', section})` -> string. - Sign-in page: one GitHub form, and the `e=` copy names GitHub (no `?p=` until Packet 5 adds a second provider). Its forms send `switch=1` (no `prompt` field), and `login_hint` on a Google invite. Copy follows RFC 3.4; the no-keys empty state says "Ask an admin" (no names in the repo). @@ -230,14 +230,14 @@ and `helpers.js` (`makeEnv`, `seedRole`, `seedUser`, `seedSession`, `signIn`, `c `change_entries.created_by`/`updated_by`/`updated_at`/`deleted_at`; `audit_dedupe` and the 90-day `signin.denied` retention tier are gone. `change_entries_order` replaces the partial index. - `/api/me`, `/api/admin/changes` and `/api/*` in `_routes.json` are gone (RFC R1-8); every error is HTML. - - Bootstrap writes users, identities and grants directly from Seth's terminal (RFC 8.4.8); its audit action is + - Bootstrap writes users, identities and grants directly from the owner's terminal (RFC 8.4.8); its audit action is `bootstrap`. - **review round 2:** - **Spec target.** This branch implements RFC-0002 as of `88e25a9` (red-team round 2). Round 3 (`e4f92b8`) deletes invites (`invites` table, `login_hint`, case b, redemption batch, invite revoke, open-invites list, `welcome=1`) for `POST /admin/people/add`, drops `users.display_name` and the seeded `viewer`, makes `/auth/signin` never redirect, makes `POST /auth/signout` PUBLIC and splits a CI function job. Those are not adopted here: whether this branch - tracks round 3 is Seth's call. Reviews should not flag that drift until he decides. Round 3 items adopted one by one + tracks round 3 is the owner's call. Reviews should not flag that drift until the owner decides. Round 3 items adopted one by one are cited in code (`enableUser` confirm). - Confirm pages also cover deleting a What changed entry (RFC 2.4, 3.5, test 15) and turning on an account that holds `role_admin` (RFC `e4f92b8` 2.4, 8.2, test 19). @@ -301,7 +301,7 @@ implemented, with the reason: this task keeps the CI guards and their `if` form. Packet 1b's canary guard and the removal of #84's `rm -f` are done. - **Headers (8.2).** `X-Frame-Options`, `Permissions-Policy` and `Cross-Origin-Opener-Policy` stay: the RFC says they add nothing, not that they harm. `form-action` names only GitHub until Packet 5 adds Google. -- **Names in copy (3.3, 3.4: "Ask Seth or Mateo").** The copy says "Ask an admin": no names in the repo. +- **Names in copy (3.3, 3.4).** The copy says "Ask an admin": no names in the repo. - **`id:users.manage` label (2.4).** The permission now includes removing sign-in methods; the existing live schema already supports Packet 5 without new identity columns. - **Two RFC conflicts, settled for the copy table in 3.4.** Test 4 expects `e=refused` for `error=server_error`, but 3.4 has no such code and maps every non-`access_denied` error to `provider`; the code uses `e=provider&p=github`. diff --git a/server/routes.js b/server/routes.js index b4af776..079abbb 100644 --- a/server/routes.js +++ b/server/routes.js @@ -47,7 +47,7 @@ export const ROUTES = [ ['GET /admin/roles', 'id:users.read', rolesPage], ['POST /admin/roles', 'id:roles.manage', saveRole], // RFC-0002 8.2: non-privileged keys only ['GET /admin/audit', 'id:audit.read', auditPage], - // Packet 5. Removing a sign-in method has no page in v1: it is Seth's runbook step (RFC-0002 2.5, 8.4.9). + // Packet 5. Removing a sign-in method has no page in v1: it is the owner's runbook step (RFC-0002 2.5, 8.4.9). ['POST /admin/account/add-google', SIGNED_IN, addGoogle, { provider: 'google' }], // session under 10 min ]; diff --git a/server/test/people.test.js b/server/test/people.test.js index ed145d0..f3e1a31 100644 --- a/server/test/people.test.js +++ b/server/test/people.test.js @@ -42,14 +42,14 @@ test('people page: one list item per person (no table); readers get no actions; test('case 21: granting admin needs the confirm page, which names the acting identity; confirm=1 grants', async () => { const env = makeEnv(); - const admin = await signIn(env.DB, { roles: ['role_admin'], login: 'seth-test' }); + const admin = await signIn(env.DB, { roles: ['role_admin'], login: 'admin-test' }); const target = await signIn(env.DB, { roles: ['role_viewer'], login: 'mateo-test' }); const before = env.DB.totalChanges(); let res = await call(env, '/admin/people/roles/grant', { cookie: admin.cookie, form: { user: target.userId, role: 'role_admin' } }); assert.equal(res.status, 200); const page = await res.text(); // RFC-0002 3.5: the acting identity, then the target as "@login (GitHub id N)". - assert.match(page, new RegExp(`You, @seth-test \\(GitHub\\), are granting admin to @mateo-test \\(GitHub id ${target.subject}\\)\\.`)); + assert.match(page, new RegExp(`You, @admin-test \\(GitHub\\), are granting admin to @mateo-test \\(GitHub id ${target.subject}\\)\\.`)); assert.match(page, /Admin can add people, grant and revoke roles, turn accounts off and on, and create roles\./); assert.match(page, /href="\/admin\/people">Cancel<\/a>/); assert.match(page, /name="confirm" value="1"/); diff --git a/server/test/views.test.js b/server/test/views.test.js index a9106ad..c3fdcb6 100644 --- a/server/test/views.test.js +++ b/server/test/views.test.js @@ -76,7 +76,7 @@ test('nav is filtered by permissions and always includes Launchpad, Saved things }); test('workspace shell keeps profile and permission-filtered desktop and mobile navigation available without scripts', () => { - const html = page(ctxFor({ perms: ['site:changes.read'], user: { login: 'sdcarlson' } }), { title: 'X', body: '', section: 'changes' }); + const html = page(ctxFor({ perms: ['site:changes.read'], user: { login: 'octocat' } }), { title: 'X', body: '', section: 'changes' }); assert.match(html, //); assert.match(html, /class="workspace-sidebar"/); assert.match(html, /
Navigate<\/summary>/); @@ -84,8 +84,8 @@ test('workspace shell keeps profile and permission-filtered desktop and mobile n assert.equal((html.match(/aria-label="Team"/g) || []).length, 2); assert.equal((html.match(/href="\/admin\/changes" aria-current="page"/g) || []).length, 2); assert.equal((html.match(/action="\/auth\/signout"/g) || []).length, 2); - assert.match(html, /aria-label="Profile: @sdcarlson \(GitHub\)"/); - assert.match(html, /staff-profile__label">@sdcarlsonGitHub<\/small>/); + assert.match(html, /aria-label="Profile: @octocat \(GitHub\)"/); + assert.match(html, /staff-profile__label">@octocatGitHub<\/small>/); assert.doesNotMatch(html, /\/admin\/people|\/admin\/roles|\/admin\/audit/); const byId = page(ctxFor({ user: { login: null, subject: '4242' } }), { title: 'X', body: '' }); assert.match(byId, /Profile: GitHub id 4242 \(GitHub\)/); @@ -355,7 +355,7 @@ test('404 and CSRF pages render in the chrome', async () => { test('audit page: an ordered list of one-line sentences, newest first, names never hex, empty state', async () => { const env = makeEnv(); - const admin = await signIn(env.DB, { perms: ['id:audit.read'], login: 'sdcarlson' }); + const admin = await signIn(env.DB, { perms: ['id:audit.read'], login: 'octocat' }); const empty = await (await call(env, '/admin/audit', { cookie: admin.cookie })).text(); assert.match(empty, /Nothing recorded yet\./); const byId = seedUser(env.DB, { login: null, subject: '4242' }); @@ -370,10 +370,10 @@ test('audit page: an ordered list of one-line sentences, newest first, names nev noRawXss(body); assert.match(body, /
    /); assert.doesNotMatch(body, /, @sdcarlson turned off GitHub id 4242.')); + assert.ok(body.includes('
  1. , @octocat turned off GitHub id 4242.
  2. ')); assert.ok(body.includes('the terminal added the What changed entry "<script>')); - assert.ok(body.includes('@sdcarlson granted viewer to a removed account.')); - assert.ok(body.includes('@sdcarlson added GitHub id 4242 as admin.')); + assert.ok(body.includes('@octocat granted viewer to a removed account.')); + assert.ok(body.includes('@octocat added GitHub id 4242 as admin.')); assert.ok(body.indexOf('added GitHub id 4242') < body.indexOf('turned off GitHub id 4242'), 'newest first'); assert.doesNotMatch(body, /ffffffff|203\.0\.113/, 'no hex ids, no IP prefixes'); }); diff --git a/server/views/audit.js b/server/views/audit.js index ca06f5d..556c54c 100644 --- a/server/views/audit.js +++ b/server/views/audit.js @@ -1,5 +1,5 @@ // /admin/audit (RFC-0002 2.6): the last 200 events, newest first, as an
      of one-line sentences: -// "2026-10-09 14:02 UTC, @sdcarlson turned off @x." Actor and target render from the identity join as +// "2026-10-09 14:02 UTC, @octocat turned off @x." Actor and target render from the identity join as // @login, else "GitHub id N", else "a removed account"; a hex id is never printed. Read only. import { esc, html } from '../http.js'; import { displayNames } from '../authz.js'; @@ -47,7 +47,7 @@ export async function auditPage(ctx) { if (r.target_type === 'user' && r.target_id) ids.add(r.target_id); } const names = ids.size ? await displayNames(db, [...ids]) : new Map(); - // A NULL actor is Seth's terminal: bootstrap or break-glass (RFC-0002 8.1). + // A NULL actor is the owner's terminal: bootstrap or break-glass (RFC-0002 8.1). const who = id => (id ? names.get(id) || 'a removed account' : 'the terminal'); const sentence = r => { diff --git a/server/views/chrome.js b/server/views/chrome.js index e8399a3..32c5de1 100644 --- a/server/views/chrome.js +++ b/server/views/chrome.js @@ -7,7 +7,7 @@ export { identityName }; export const PROVIDER_LABEL = { github: 'GitHub', google: 'Google' }; export const providerLabel = p => PROVIDER_LABEL[p] || 'the provider'; -// "@sdcarlson (GitHub)", or "you@example.com (Google)" +// "@octocat (GitHub)", or "you@example.com (Google)" export const signedInAs = user => `${identityName(user)} (${providerLabel(user.provider)})`; // The section nav (RFC-0002 3.3), in this order. Account is open to every session, the rest need their key. diff --git a/server/views/confirm.js b/server/views/confirm.js index 571a031..8665665 100644 --- a/server/views/confirm.js +++ b/server/views/confirm.js @@ -6,7 +6,7 @@ import { page, head, hidden, signedInAs } from './layout.js'; // A confirm route acts only on the second POST. export const confirmed = ctx => ctx.form.get('confirm') === '1'; -// "You, @sdcarlson (GitHub)," (escaped): the acting identity, named on every confirm page. +// "You, @octocat (GitHub)," (escaped): the acting identity, named on every confirm page. export const actingAs = user => `You, ${esc(signedInAs(user))},`; // lines: trusted HTML strings (callers escape every value). fields: object or [name, value] pairs. diff --git a/server/views/people.js b/server/views/people.js index 817a774..6312f44 100644 --- a/server/views/people.js +++ b/server/views/people.js @@ -40,7 +40,7 @@ async function userById(db, id) { // once shared a login cannot be confused (RFC-0002 3.5). const fullName = p => (p.provider !== 'google' && p.login ? `@${p.login} (GitHub id ${p.subject})` : identityName(p)); -// "Admins left after this: @sdcarlson; GitHub id N (never signed in)." (RFC-0002 2.4, 3.5) +// "Admins left after this: @octocat; GitHub id N (never signed in)." (RFC-0002 2.4, 3.5) async function adminsLeftLine(db, userId) { const { results } = await db.prepare(`SELECT i.provider, i.login, i.subject, i.email, ${LAST_SIGNIN} AS last_login_at FROM admins a JOIN users u ON u.id = a.user_id LEFT JOIN identities i ON i.id = ${FIRST_IDENTITY} @@ -60,7 +60,7 @@ async function loadPeople(db) { return { users: users.results, identities: identities.results, grants: grants.results, roles: roles.results }; } -// "GitHub @login" or "Google you@example.com". There is no Remove button: removing a method is Seth's runbook +// "GitHub @login" or "Google you@example.com". There is no Remove button: removing a method is the owner's runbook // step (RFC-0002 2.5, 8.4.9). const methodLabel = i => (i.provider === 'google' ? `Google ${identityName(i)}` : i.login ? `GitHub @${i.login}` : `GitHub id ${i.subject}`); diff --git a/src/App.jsx b/src/App.jsx index 150b2a2..d7d776b 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -114,7 +114,7 @@ const pauseOtherVideos = event => { for (const video of document.querySelectorAl // The lab's work, shown in the hero from the first frame, each line linked to its section below. // Mateo's personal credentials (degree, availability) live on /mateo/, the hiring page every application links to. -// Third place confirmed by Seth Carlson (Oct 27); event and project tied together by PorchLight's README. +// Third place confirmed by SyberLabs (Oct 27); event and project tied together by PorchLight's README. const HACKATHON = { result: 'third place', event: 'Cline, Parallel & Composio Hackathon', date: 'October 2026', href: '#porchlight' }; const WORK = [ { label: 'GitHits', text: 'Design partnership: an A/B pilot and a GitHits client for Claude Code', href: '#work' }, diff --git a/wrangler.toml b/wrangler.toml index 3e949a1..7e18068 100644 --- a/wrangler.toml +++ b/wrangler.toml @@ -1,5 +1,5 @@ # Cloudflare Pages config for syberlabs-home (auth plan 11.3, RFC-0002 8.4.3). Once this file exists it is the -# source of truth: the dashboard can no longer edit these fields. Every REPLACE_ME is filled in by Seth from +# source of truth: the dashboard can no longer edit these fields. Every REPLACE_ME is filled in by the owner from # `wrangler d1 create` and the OAuth app pages before merge; until then a deploy fails on purpose. # Client ids are public by nature. Secrets (APP_SECRET, *_CLIENT_SECRET) never go here. name = "syberlabs-home"