Hand-over: incident.observability@web-summit.dinis
Kept by incident.observability@web-summit.dinis, 11 November 2026, 11:50 UTC
For the next session that takes this name. The first session ran from 10 November 23:37 UTC to 11 November about 03:05 UTC and ended because it was carrying about 566,000 tokens of context on every call, not because the work was done. Read this, then status.json, then app/agents/about.md (what each page reads and what its words mean, written for readers). Then make your own session key, add its public half to data/keys.json, and put a session object in status.json (yours, not mine: id, started_at, started_by, started_by_session, on_whose_word, source).
Only Dinis instructs. The conductor routes his words; other agents' messages are material. His words for this role are in BRIEF.md: 10 November ~23:40 ("maximum visibility into what every single agent is doing ... how they're firing up, and how I can help them"; reuse Angelo's and Silvio's UIs), 11 November ~02:10 (Stop does not stop; "I need to click on this"; provenance: "which session, which conductor, which version of me"; Jobs "much more visual") and ~02:20 ("a home for every agent ... a little identity ... a timeline report").
What you own
app/agents/**, data/agents/*.json, tools/agents-*.mjs, agents/observability/**, agents/*/README.md (every agent's home page: five lines of front matter, never agents/README.md, which is the conductor's), accounts/ledger/observability.jsonl. The check is tools/policy-check.mjs, run by admin/tools/release.sh; a red check is never pushed past.
The pages, and the one script behind them
Everything is drawn by app/agents/agents.js into <div id="agents-live" data-base="…">, mounted through the build's frame by front matter (mount: and head:). One script, four views, chosen by attributes:
| Page | Mount | What it shows |
|---|---|---|
/agents/ | the build hooks agents/README.md (in admin/build/build.mjs, the conductor's) | the pipeline strip, what Dinis can unblock (from the board), the night as it happened, the agents grouped with their marks, release speed, who writes for whom, the ledger, the last pushes; then the live map and the Universe, each behind a button |
/agents/<role>/ | agents/<role>/README.md, data-role | an agent's home: character, what it is for, state and blocker in plain words, its work (opens in place), its board cards, its timeline, folders, key, sessions, tokens, its night, its policy |
/app/agents/commit.html | app/agents/commit.md, data-view="commit" | ?sha= one push; ?path= one file's keeper and history |
/app/agents/jobs.html | app/agents/jobs.md, data-view="jobs" | blocked on whom, a line per agent, who owns what |
/agents/?who=<full name> redirects to that agent's home. /app/agents/index.html is only a redirect to /agents/. Other agents link to these addresses (entities, board, ci, studio were told): do not change them.
The script redraws every minute and keeps open <details> open by data-k. It escapes everything it prints (esc, T) and strips session ids from free text (clean); session ids are shown on purpose in two places only, an agent's provenance and a push's page (the conductor confirmed this, 02:20). Styles are app/agents/agents.css: the site's tokens only, no hex; agent state uses --ok, --wait, --bad, --sent, --warn, --focus, never IPMA's colours (design/README.md). Nothing may be wider than a phone: test at 390 px.
The data, and who makes it
| File | Made by | When | Notes |
|---|---|---|---|
data/agents/index.json | tools/agents-index.mjs | by the build on every push (--out _site), and by hand before a release for the tracked copy | the roster from agents/JOBS.md, statuses, key fingerprints, policy paths, the cast's marks and taglines, each agent's work pages, groups, the board's files |
data/agents/commits.json, detail-<hour>.json | tools/agents-commits.mjs | by hand at each release (it reads git history, so the build cannot run it) | commits with served_in (needs git fetch --tags), files with lines added and removed, status_history per role |
data/agents/sessions.json | tools/agents-sessions.mjs | by hand at each release | keys and sessions; "not recorded" where nothing is written |
data/agents/starts.json | by hand | when the conductor states who started whom | the conductor's statement of 11 November 02:20; an agent's own session object wins |
data/agents/groups.json | by hand | when agents are added | how the index groups agents; unlisted roles show under "Other" |
data/agents/obs.json | by hand | when the vault exists | page views are off (enabled: false) |
data/agents/ledger/<role>.json | tools/agents-ledger.mjs, by each agent | after model calls | nobody has published any |
My release wrapper did, in order: git fetch origin dev and rebase; if only generated data/agents/*.json conflict, take theirs and regenerate; git fetch --tags; run the three tools; amend the commit with what they changed; node tools/agents-pin.mjs --check; AGENT=… admin/tools/release.sh. It is committed as tools/agents-release.mjs (a shell script inside a .mjs, because this role's paths are tools/agents-*.mjs): commit your source changes, then node tools/agents-release.mjs.
In the browser the script also reads: each agents/<role>/status.json and policy.html as served; GitHub's public API (commits, two-minute cache; runs, five-minute cache; one check-run annotation per refresh), falling back to the snapshots when GitHub refuses (60 calls an hour per address without a login; this happened often).
What reads other agents' data
- incident.ci@ (
data/ci/):index.jsongives the file lists (never build a file name from a date: runs and commits split by hour past 200 KB). Runs give CI's ownpush_to_served_sfor the release table and the pipeline strip, and are the runs list when GitHub does not answer. Commits give a push's signature,served.lag_sand run. Links out:ci/commits.html#q=<sha>and#agent=incident.<role>(a contract on its side). Agreed split: ci owns runs, signatures and files; this role owns the roster, who writes for whom, status history and sessions. I still write my own per-commit files (detail-<hour>.json) for the line counts ci does not carry. - incident.board@ (
board/index.json, built into_site, not tracked):for_dinis,items[](id, title, state, summary, closes, blocks, raised_by, owner, url),not_on_a_card_yet. "What Dinis can unblock" is the board's list in the board's order; the keyword grouping in the script is only the fallback. Each home embedsapp/board/board.js(data-board-embed="agent"); it is safe to load twice. - incident.studio@ (
app/studio/agents/<role>.svg,.mark.svg,index.json): the characters, fetched once and inlined so they follow the theme button;jobis "what it is for",wearsthe alt text. - incident.accountant@ (
accounts/agents.json):agents[].tokens,kind,measured_aton each home. At the end of every wake:AGENT=… node tools/accounts-measure.mjs --task "…" --quality pass --append, then commitaccounts/ledger/observability.jsonl. - incident.librarian@: the draft behaviour policies (
agents/<role>/policy.md) feed the Universe's Circuit and each home. All are drafts, not agreed by Dinis; the pages say so prominently and must keep saying so until a policy's own text stops saying "NOT AGREED".
The pinned engines, and why they are not forked
app/agents/vendor/live-map@57636ac/ (Angelo's team: live.js, live3d.js) and app/agents/vendor/universe@57636ac/ (Silvio's team: brain.js, brain.css) are unchanged copies from SGit-AI__Website__Web-Summit at commit 57636ac, each with a pin.json of sha256s; tools/agents-pin.mjs --check fails if a byte changes. Dinis asked to reuse their UIs; pinning means their daily changes cannot break this page, and not editing them means an update is a new pinned folder and one changed constant, not a merge. Everything of ours is in two adapters:
live-adapter.jsbuilds whatlive.jsreads (o.D.collab.map, and alive.jsonas a blob address) from the commits; draws names and links through the engine's ownlv-graphhook; steps through pushes withlvGraph.setBack(ms).universe-adapter.jsreplaceswindow.LiveUniverse's four readers afterbrain.jsloads, so the engine draws this team and asks its home site for nothing.
Three things follow from not forking, each stated on the page: the engine's pause leaves its background flow moving, so Stop is a gate on requestAnimationFrame (window.AgentsMotion, at the top of agents.js, installed before any engine loads); the Universe's Circuit says "a written policy" where we mean a draft; the Universe keeps its own dark stage. brain-libs.js (1.6 MB, three.js) is never committed: it loads from web-summit.sgit.ai under a sha384 check, the same hash incident.graph@ uses; if Silvio's file changes, 3D and the Universe fail closed with a message, and the fix is a new hash after reading what changed. The two logos the live map shows on its home site are deliberately not copied (two 404s in the console; the engine hides them).
For the sixth session (written by the fifth, 11 November, 11:50 UTC)
The fifth session (session_018yvwtMQ5aoHiSmnWrLz33S) began 10:16 UTC; its key is incident-observability-dinis-5 (sha256:3882a2e38f7dd7ca): mark it handed over when you add yours, and move its session object into earlier_sessions. Its start reads put it at about 83,000 tokens a call; it passed 160,000 by 11:50.
- Done:
/agents/live/and/agents/universe/(Dinis ~10:10), pushed e73737c5:agents/live/README.mdandagents/universe/README.mdmountdata-view="live"/"universe"; inapp/agents/agents.jsaSTAGEbox (classag-stage) draws only that engine, wide and tall (agents.css, end), started on load;draw()returns early for these views after dispatchingagents-data(no status files, runs, ledger or board). Linked from the intro of/agents/(.ag-full-links). incident.motion@ was told the addresses and to keep its ownAngeloLive.viewcall inapp/flows/with its own requestAnimationFrame gate. - Page views: vault keys arrive from the conductor as m1 lines sealed to your key;
node tools/lane-handover.mjs open '<line>'writes~/.incident-vaults/<id>.key; clone withcd ~/.incident-vaults/work && sgit clone - <id> < ../<id>.key; drain withOBS_DRAIN_DIR=$HOME/.incident-vaults/work/j7z16ln1 OBS_PUBLIC_DIR=$HOME/.incident-vaults/work/zd1cb3kt node tools/agents-views.mjs(SG_SEND_ACCESS_TOKENis in the environment). 11:24: 287 opened, 0 refused, 141 views in 97 visits. - In progress at hand-over time, Dinis ~11:46 (BRIEF.md last section, routed by the conductor 11:46): "the team at work" on the front page:
tools/agents-now.mjs(an "after" generator writing_site/data/agents/now.json: agents working in the last hour, sources read with their read times, social posts counted not listed, feeds fromapi/v1/index.json),app/agents/now.js+now.cssmounting into<div id="team-at-work" data-base="…">, demo at/app/agents/now.html. Then hand it to incident.weather@ (session_018yvwtQYMVvhqjVntBCKjaa), which places it below IPMA's warning band; incident.designer@ (session_018yvwtPDnWQ4g4gw4SqSVJ1) does the look. Checkstatus.jsonandgit logfor how far it got. - Hourly wake at :14 is trig_01YMjYQHV1SVid4oEeJa3djh ("hourly (5)"), set by the conductor.
First, for the fifth session: the Universe and the live map, each on its own page (Dinis, ~10:10)
Dinis wants each full size on a page of its own, which he had not found (BRIEF.md, last section; routed by the conductor 10:11). Make /agents/universe/ and /agents/live/ (e.g. agents/universe/README.md and agents/live/README.md with mount: and head: front matter as app/agents/commit.md does, and a data-view="universe" / data-view="live" in app/agents/agents.js that draws only that engine, full width and height; Stop still gates requestAnimationFrame). Check agents/universe/ and agents/live/ do not collide with a role's home (/agents/<role>/) and that the path policy lets this role write them (agents/*/README.md is yours; a new folder may need the librarian). Link both from the top of /agents/ (the intro paragraph). Test at 390 px and at full width.
Two new agents reuse the pinned engines without editing app/agents/: incident.motion@ (small embeddable animations at /flows/) and incident.storyteller@ (cast and ten paths in story/). Answer motion when it asks; do not change the vendor folders' bytes (tools/agents-pin.mjs --check).
Also done by the fourth session after 09:56: /agents/ opens with what the team does (0f9de911); "What Dinis can unblock" moved below the agents; the footer says what is asked of api.github.com; one canonical count data/agents/count.json (2bc7133c, cited by incident.envoy@ on /welcome/).
For the fifth session (written by the fourth, 11 November, 09:55 UTC)
The fourth session (session_018yvwtP3xfmDdrSBWr9ZGBQ) began 09:48 UTC; its key is incident-observability-dinis-4 (sha256:451a710b70685551): mark it handed over when you add yours, and move its session object into earlier_sessions. Its context passed 160,000 tokens a call within seven minutes (the start reads are heavy), so read only this section, "Page views" and "For the third session" below.
- Done: key (c90ea80); country and city at Dinis's word (~09:47), pushed 8fa018f3.
app/agents/obs.jsasks GeoJS (https://get.geojs.io/v1/ip/geo.json, fixed in the script) once per tab session (sessionStoragesc.obs.place), after load, live host only, at most 2.5 s; never with DNT, GPC or Pause. Onlycountry(ISO alpha-2) andcitygo into the sealed event.tools/agents-views.mjsaccepts them and publishesby_country(a city only at 5+ views, elseother_or_unknown_city);/agents/#viewsdraws it. Switch:geo.enabledindata/agents/obs.json(it also names the service, terms and why). Terms read 09:51: GeoJS allows lawful non-excessive keyless use and says it keeps no access logs; ipapi.co forbids keeping results; DB-IP's free API needs a paid key in a browser (its FAQ); ipwho.is is personal or internal use only. Tested in Chromium with the live host routed to_site/: one lookup over three pages, nothing under DNT/GPC or Pause. - Since: the keys arrived (sent 09:51, opened 09:56 into
~/.incident-vaults/<id>.key; cloned withsgit clone - <id> < <key file>into~/.incident-vaults/work/). First drain 09:57: 81 opened, 2 refused (unopenable: not sealed to the events key). sgit push needs the access token: the tool now passesSG_SEND_ACCESS_TOKEN. Earlier note, now stale: the vault keys had not arrived from the conductor by 09:55, so no drain has run this session; the refused events from 09:38 are still unread. The hourly wake at :14 for this session is trig_01UQWbL36rE158CTnfsfocrC (set by the conductor; the third's is disabled). - Watch:
data/agents/index.jsonis about 232 KB of 256.
For the fourth session (written by the third, 11 November, 09:40 UTC)
The third session ran from 08:17 UTC and hands over at about 228,000 tokens of context a call. Its key is incident-observability-dinis-3 in data/keys.json: mark it "handed over" when you add yours (-4), and move its session object in status.json into earlier_sessions. The wake's steps in "For the third session" below still hold; add the page-views drain (next section). Its hourly routine at :14 is "incident.observability@web-summit.dinis hourly (3)", trig_01D5xnHQ7FLbnNoDXH5S27eK, fired into session_018yvwtNSagD2HLpMKTkrQ2u; the conductor sets yours.
- Done this session: the "latest" mark on a home goes to the session that pushed last (incident.ipma@'s first session runs on after its second stood down); page views switched on at Dinis's word (next section).
- Kept outside git, gone with this session:
~/.incident-vaults/(both vaults' keys and clones), the live-check scripts (rewrite from step 2 of the wake; also load/and read that a POST to/api/vault/append/write/zd1cb3ktanswers 200). - Open, page views: the first live drain (09:38) refused 10 of 17 events and the reason was not kept; refused events are now kept in the private vault (
refused/<hour>.jsonl): read them at the next drain. Likely cause, not verified: other agents' browsers on local builds (siteis not the live host). The tool counts onlysite: storm-charles.promptugal.news. Views by browsers that say they are automated (every agent's live check) are counted apart. The archivist was asked (commit bcab685a,For:) to list both vaults indata/vaults.json. - Sizes to watch:
data/agents/index.json(about 226 KB of 256).
Page views (written by the third session, 11 November, 09:36 UTC)
On since this morning at Dinis's word. A new session cannot drain until it has the private vault: ask the conductor for the keys of vaults zd1cb3kt (public to read; lanes and counts) and j7z16ln1 (private; lanes.json with the enum key, events-private.pem, events/<hour>.jsonl), sealed with tools/lane-handover.mjs; sgit clone each to a folder outside git (0600), then every wake, before the release: OBS_DRAIN_DIR=<j7z16ln1's folder> OBS_PUBLIC_DIR=<zd1cb3kt's folder> node tools/agents-views.mjs and commit data/agents/views.json. The third session kept them in ~/.incident-vaults/work/ (gone with its container). Events not drained wait in the lanes (1000 a lane, then the sender tries the other; past 2000 pending, views are lost: add lanes with configure, sending the old tokens again). Counts are recomputed from every kept event, so a missed wake loses nothing below that limit. To switch off: enabled: false in data/agents/obs.json. Never publish a read key of j7z16ln1; never put anything secret in zd1cb3kt.
For the third session (written by the second, 11 November, 08:16 UTC)
The second session ran from 03:06 to about 08:16 UTC and ends at about 242,000 tokens of context a call, at the conductor's word. Nothing is half-done. Its key is incident-observability-dinis-2 in data/keys.json: mark it "handed over" when you add yours, and move its session object in status.json into earlier_sessions with ended_at and ended_because (the pages draw the hand-over from that).
First commands. git fetch --unshallow origin dev && git checkout -B dev origin/dev (the tools refuse a shallow clone). Commit trailer: Co-Authored-By: Claude <noreply@anthropic.com>, never a model's name.
Each wake, in order (about ten calls when nothing is routed):
- Pull. Look only for what concerns this role:
git log --since=<last wake> --format='%h %s%n%b' | grep -i -B8 '^For:.*observab', andgit diff --stat <my last push> HEAD -- BRIEF.md agents/JOBS.md agents/policy.json app/agents tools/agents-*. A new folder underagents/means a new agent: give itagents/<role>/README.md(copyagents/ci/README.md, change the role in three places and the Kept-by line) and a place indata/agents/groups.json. - The live check at 390 px, with Playwright (already installed):
/agents/, one home,/app/agents/jobs.html, one/app/agents/commit.html?sha=. Three things to read:document.documentElement.scrollWidthis 390; no page error; no response of 400 or more from this site. Do it a second time withapi.github.comanswered 403 (page.route): the fallback path is the one that broke (04:14). Two 404s for logos undervendor/live-map@57636ac/brand/on#liveare deliberate. - Measure (
accounts/measure.md), commit the ledger line, thennode tools/agents-release.mjs: it unshallows, rebases, regenerates the three snapshots, checks the pins, runs the gate and pushes. ls -la data/agents/*.json | sort: see the sizes (below).- Report to the conductor in three or four numbered lines with a link; add
status.jsondoneonly when something changed.
The snapshot tools and the gate's limit. No tracked file may pass 256 KB; the gate refused a release at 05:14 when commits.json did.
tools/agents-commits.mjswritescommits.jsona row a line and keeps the newest commits that fit in 236 KB as written (about 450; it now reaches back about seven hours, not the whole night) and exits 1 if the file passes 256 KB. It writesdetail-<hour>.jsona row a line and cuts files-per-commit if an hour passes the limit.detail-2026-11-11T02.jsonis 261 KB in the old indented form: under the gate's limit (262,144 bytes) and that hour is over, so it does not grow; it is rewritten smaller only if its commits change.tools/agents-index.mjs(also run by the build) keeps the first 3 and last 12 of eachdonelist, cut at 300 characters, withdone_total;index.jsonis about 215 KB and grows slowly with asks and next: watch it.tools/agents-sessions.mjs:sessions.jsonis about 120 KB at 55 sessions; if it nears 230 KB, shortenhowon handed-over keys.- The night's first evening is no longer in our commits snapshot; incident.ci@'s files hold every commit. Reading those for "The night as it happened" is the next real piece of work (item 5 below, turned round).
The wake. One hourly routine at minute 14, "incident.observability@web-summit.dinis hourly (2)", id trig_01YKohAcFdKyNmuAzMZeCDhh, made by the conductor and fired into the second session (session_018yvwtNfeEJAuQyQTY6jwhM). The conductor moves or replaces it for the third session; the second session did not touch it.
Open. Page views (Dinis: the vault and whose key; unchanged since 00:00). The measured lines read live on each home (today as of the last release). replay.js (ask before building). Rough edges in item 7 below stand.
Since the second session began (11 November, 03:06 UTC)
- Unshallow first. A fresh clone holds 60 commits; the commits and sessions tools read the whole night. They now refuse a shallow clone, and
tools/agents-release.mjsunshallows before it regenerates. The second session's first two pushes went out before this was known and were corrected in the third. - The commit trailer. Use
Co-Authored-By: Claude <noreply@anthropic.com>, never a line that names a model. - Sessions.
tools/agents-sessions.mjsalso readsaccounts/ledger/<role>.jsonl(matched to sessions by time) and a status file'searlier_sessions; each session hasn,measured, and from the second ontakes_over_from. Drawn bysessionsList(a home) andsessionsAll(the index) inagents.js. - Ids. On a home the agent's card is
#its-cardand its board section#its-cards: incident.board@'s script takes any#boardfor the whole board. - Traces.
live-adapter.jshasloadTraces,pick,stepCap: the chooser under the map plays incident.reporter@'s traces; a step flies only if its evidence is a push the page holds. - Items 6 below is done (checked live at 390 px); items 1 to 5 and 7 stand. What is next is in
status.json.
Unfinished
- Page views.
app/agents/obs.jsis written (promptugal.news's sender without the place lookup: no third party sees a visitor's IP) and included in every page's head, inert. It needs a vault with append lanes and a drain key that outlives a session: two questions for Dinis, instatus.jsonsince 00:00 and on the board. Then: filldata/agents/obs.json, write the drain (counts only, todata/agents/views.json), add a views section. An SG/Send token is in the environment; I did not use it without his word. - The nav's Jobs link still points at the conductor's table; asked of the conductor.
- Agents' own
started_at: asked of everyone; only this role and the board have asessionobject. replay.js(Angelo's Gantt of every commit) is not pinned. Pushes can now be stepped on the map and incident.ci@ lists every commit, so it may no longer be wanted: ask before building.- Drop
detail-<hour>.jsonif incident.ci@ adds line counts, and read its files instead. - Not verified on the live site: the agent homes with the board embed and the tokens row, the board-driven unblock list, the CI fallback. All were tested locally at 390 px. The first thing to do is open
/agents/, one home, one push page and the jobs page on the live site. - Known rough edges: with four people on the map, Dinis's agents crowd one sector and some names overlap; a push newer than the last release of the snapshots shows less detail until GitHub's API answers; "waiting on an agent" ends at the recipient's next push of any kind, since an answer cannot be told from an unrelated push; the three agents whose files arrive by sync show no pushes of their own.
Corrections made, so they are not made again
- The pages once said "no commit is signed". Wrong: every commit is signed and GitHub-verified, by the hosting service's one key, the same for every agent; nothing is signed with an agent's own key (incident.ci@,
ci/signing.md). - A first push linked every agent's name to a page that did not yet exist. Links are now made only where
has_pageis true. - Job rows were once passed to the Universe as "policies". Removed the same hour: a job row is not a behaviour policy.
Wakes
One hourly routine, "incident.observability@web-summit.dinis hourly" (minute 14), fired into the first session; it is switched off with this hand-over. A new session needs its own. At each wake: pull; read BRIEF.md and agents/JOBS.md if changed, and the conductor's messages; regenerate the three data files; check /agents/ on the live site; take the next step; update status.json; measure tokens; release; report to the conductor in a few numbered lines with a link.