seisin 0.6.3 → 0.6.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +143 -686
- package/package.json +2 -2
- package/src/canary.js +1 -1
- package/src/cli.js +47 -3
- package/src/commands/check.js +68 -12
- package/src/commands/hook.js +1 -1
- package/src/commands/log.js +21 -14
- package/src/commands/requests.js +10 -15
- package/src/commands/review.js +2 -1
- package/src/commands/run.js +331 -245
- package/src/commands/walls.js +12 -5
- package/src/config-fields.js +305 -0
- package/src/config.js +114 -534
- package/src/controls.js +1 -1
- package/src/decide-request.js +37 -0
- package/src/denial-attribution.js +338 -0
- package/src/grants.js +1 -1
- package/src/help.js +6 -4
- package/src/index.js +1 -1
- package/src/inspect/enforce.js +1 -1
- package/src/inspect/files.js +1 -1
- package/src/inspect/home.js +1 -1
- package/src/inspect/inject.js +1 -1
- package/src/intake.js +3 -2
- package/src/keys.js +2 -2
- package/src/kinds.js +19 -0
- package/src/layout.js +1 -1
- package/src/log.js +3 -2
- package/src/mcp.js +1 -1
- package/src/notify-config.js +58 -0
- package/src/notify.js +4 -52
- package/src/owners.js +2 -2
- package/src/requests.js +9 -4
- package/src/rundir.js +2 -2
- package/src/runs.js +29 -10
- package/src/sandboxes/command.js +0 -2
- package/src/sandboxes/index.js +15 -2
- package/src/sandboxes/srt.js +1 -1
- package/src/sandboxes/tartaros.js +34 -6
- package/src/serve.js +11 -22
- package/src/spool.js +1 -1
- package/src/{srt.js → srt-settings.js} +5 -2
- package/src/state.js +25 -0
- package/src/suggest.js +26 -1
- package/src/surface.js +3 -2
- package/src/territory.js +20 -1
- package/src/toml.js +250 -0
- package/src/violations.js +16 -315
- package/src/walls.js +4 -2
- package/ui/index.html +35 -9
package/ui/index.html
CHANGED
|
@@ -2088,9 +2088,9 @@ table.runs tr.sys td{color:var(--dim)}
|
|
|
2088
2088
|
* that was gone or had a new token. After two failed polls in a row the page
|
|
2089
2089
|
* says which of the two it is, since when, and turns the writes off. */
|
|
2090
2090
|
var FAILS = 0, OFFLINE = null;
|
|
2091
|
-
function setOffline(kind){
|
|
2092
|
-
if (kind && OFFLINE && OFFLINE.kind === kind) return;
|
|
2093
|
-
OFFLINE = kind ? { kind: kind, since: (OFFLINE && OFFLINE.since) || new Date() } : null;
|
|
2091
|
+
function setOffline(kind, why){
|
|
2092
|
+
if (kind && OFFLINE && OFFLINE.kind === kind && OFFLINE.why === why) return;
|
|
2093
|
+
OFFLINE = kind ? { kind: kind, why: why || null, since: (OFFLINE && OFFLINE.since) || new Date() } : null;
|
|
2094
2094
|
var label = document.getElementById("source");
|
|
2095
2095
|
var ban = document.getElementById("off-banner");
|
|
2096
2096
|
if (!OFFLINE) {
|
|
@@ -2099,7 +2099,11 @@ table.runs tr.sys td{color:var(--dim)}
|
|
|
2099
2099
|
} else {
|
|
2100
2100
|
var t = pad(OFFLINE.since.getHours()) + ":" + pad(OFFLINE.since.getMinutes());
|
|
2101
2101
|
label.style.color = "var(--amber)";
|
|
2102
|
-
if (kind === "
|
|
2102
|
+
if (kind === "policy") {
|
|
2103
|
+
label.textContent = "seisin.toml cannot be read";
|
|
2104
|
+
ban.innerHTML = "<b>seisin.toml cannot be read</b> (since " + t + "): " + esc(OFFLINE.why) + " " +
|
|
2105
|
+
"What is on screen is the last policy that loaded. Decisions and saves are off until the file is fixed.";
|
|
2106
|
+
} else if (kind === "expired") {
|
|
2103
2107
|
label.textContent = "link expired — open the new one";
|
|
2104
2108
|
ban.innerHTML = "<b>This tab's link has expired</b> (since " + t + "): the console was restarted with a new one. " +
|
|
2105
2109
|
"Open the new link — run <code>seisin ui --link</code> in the repository. Decisions and saves are off in this tab.";
|
|
@@ -2184,7 +2188,13 @@ table.runs tr.sys td{color:var(--dim)}
|
|
|
2184
2188
|
if (!fresh && LAST.etag && LAST.url === url) h["if-none-match"] = LAST.etag;
|
|
2185
2189
|
var r = await fetch(url, { cache: "no-store", headers: h });
|
|
2186
2190
|
if (r.status === 304) return { same: true };
|
|
2187
|
-
|
|
2191
|
+
// A refusal carries the server's reason (a seisin.toml that no longer
|
|
2192
|
+
// parses): kept, so it is shown instead of reading as the server gone.
|
|
2193
|
+
if (!r.ok) {
|
|
2194
|
+
var why = null;
|
|
2195
|
+
try { why = (await r.json()).error || null; } catch (_) { /* no body */ }
|
|
2196
|
+
return { status: r.status, error: why };
|
|
2197
|
+
}
|
|
2188
2198
|
var s = await r.json();
|
|
2189
2199
|
if (s.error) return { status: r.status, error: s.error };
|
|
2190
2200
|
LAST = { url: url, etag: r.headers.get("etag") };
|
|
@@ -2311,6 +2321,16 @@ table.runs tr.sys td{color:var(--dim)}
|
|
|
2311
2321
|
'passes the example policy off as yours.</p></div>';
|
|
2312
2322
|
return;
|
|
2313
2323
|
}
|
|
2324
|
+
if (!s && got && got.error) {
|
|
2325
|
+
label.textContent = "seisin.toml cannot be read";
|
|
2326
|
+
label.style.color = "var(--amber)";
|
|
2327
|
+
document.querySelector("main").innerHTML =
|
|
2328
|
+
'<div class="box" style="padding:22px 24px;max-width:640px">' +
|
|
2329
|
+
'<h2 style="margin:0 0 8px;font-size:17px">The console cannot read this repository\'s policy</h2>' +
|
|
2330
|
+
'<p style="margin:0 0 8px" class="err">' + esc(got.error) + '</p>' +
|
|
2331
|
+
'<p style="margin:0;color:var(--mid)">Fix the file and reload. <code>seisin check</code> says the same in a terminal.</p></div>';
|
|
2332
|
+
return;
|
|
2333
|
+
}
|
|
2314
2334
|
if (!s) {
|
|
2315
2335
|
label.textContent = location.protocol.startsWith("http") && !TOKEN
|
|
2316
2336
|
? "no token — showing an example"
|
|
@@ -2403,15 +2423,18 @@ table.runs tr.sys td{color:var(--dim)}
|
|
|
2403
2423
|
if (w.text) bits.push('started <span title="' + escA(w.title) + '">' + esc(w.text) + "</span>");
|
|
2404
2424
|
return bits.join(" · ");
|
|
2405
2425
|
}
|
|
2406
|
-
function outcomeTag(o){
|
|
2426
|
+
function outcomeTag(o, dropped){
|
|
2407
2427
|
var says = { clean: "clean", denied: "denied", refused: "canary failed", unread: "policy unreadable" };
|
|
2408
|
-
|
|
2428
|
+
// A run whose system log dropped kernel messages: its walls may be missing some.
|
|
2429
|
+
var lost = dropped ? ' <span class="oc refused" title="the system log dropped ' + escA(String(dropped)) +
|
|
2430
|
+
' batch(es) of kernel messages during this run: denials may be missing from its record">record incomplete</span>' : "";
|
|
2431
|
+
return '<span class="oc ' + escA(o) + '">' + esc(says[o] || o) + "</span>" + lost;
|
|
2409
2432
|
}
|
|
2410
2433
|
|
|
2411
2434
|
function drawRunBanner(){
|
|
2412
2435
|
var b = document.getElementById("run-banner");
|
|
2413
2436
|
var r = RUNINFO || { id: RUN };
|
|
2414
|
-
b.innerHTML = "<b>Run " + esc(r.run_id || r.id) + "</b> " + outcomeTag(r.outcome || "") +
|
|
2437
|
+
b.innerHTML = "<b>Run " + esc(r.run_id || r.id) + "</b> " + outcomeTag(r.outcome || "", r.dropped) +
|
|
2415
2438
|
' · <a href="./">all runs</a>' +
|
|
2416
2439
|
'<div class="meta">' + (runMeta(r) || "no run.json: only what its policy and log say") +
|
|
2417
2440
|
" · read only: nothing is granted from here</div>";
|
|
@@ -2442,6 +2465,7 @@ table.runs tr.sys td{color:var(--dim)}
|
|
|
2442
2465
|
document.getElementById("rn-kpis").innerHTML =
|
|
2443
2466
|
card("b", "runs", t.runs, (t.outcome.denied || 0) + " denied something · " + (t.outcome.clean || 0) + " clean") +
|
|
2444
2467
|
card(t.outcome.refused ? "a" : "g", "canary failed", t.outcome.refused || 0, "runs that never started") +
|
|
2468
|
+
(t.incomplete ? card("a", "record incomplete", t.incomplete, "runs whose system log dropped kernel messages") : "") +
|
|
2445
2469
|
card(t.denied ? "a" : "g", "denied", t.denied, (k.file || 0).toLocaleString() + " files · " + (k.network || 0).toLocaleString() + " network") +
|
|
2446
2470
|
card(t.retried ? "a" : "g", "spent retrying", t.retried, "calls after the first denial of the same thing");
|
|
2447
2471
|
|
|
@@ -2463,7 +2487,7 @@ table.runs tr.sys td{color:var(--dim)}
|
|
|
2463
2487
|
var w = when(r.started_at || "");
|
|
2464
2488
|
return "<tr><td><a href=\"./?run=" + encodeURIComponent(r.id) + "#requests\"><code>" + esc(r.run_id || r.id) + "</code></a></td>" +
|
|
2465
2489
|
'<td title="' + escA(w.title || "") + '">' + esc(w.text || "") + "</td><td>" + esc(r.team || "") + "</td><td>" + esc(r.role || "") +
|
|
2466
|
-
"</td><td>" + esc(r.work_item || "") + "</td><td>" + esc(r.status || "") + "</td><td>" + outcomeTag(r.outcome) +
|
|
2490
|
+
"</td><td>" + esc(r.work_item || "") + "</td><td>" + esc(r.status || "") + "</td><td>" + outcomeTag(r.outcome, r.dropped) +
|
|
2467
2491
|
"</td><td class=num>" + r.denied + "</td><td class=num>" + r.retried + "</td><td>" +
|
|
2468
2492
|
(r.hosts || []).slice(0, 3).map(function(h){ return "<code>" + esc(h.target) + "</code>"; }).join(" ") + "</td></tr>";
|
|
2469
2493
|
}).join("") + "</tbody>"
|
|
@@ -2628,6 +2652,8 @@ table.runs tr.sys td{color:var(--dim)}
|
|
|
2628
2652
|
if (got.s) applyState(got.s);
|
|
2629
2653
|
return;
|
|
2630
2654
|
}
|
|
2655
|
+
// The server answered, with the reason it cannot: said at once, not as an outage.
|
|
2656
|
+
if (got.error && got.status !== 401 && got.status !== 403) { FAILS = 0; setOffline("policy", got.error); return; }
|
|
2631
2657
|
FAILS++;
|
|
2632
2658
|
if (FAILS >= 2) setOffline(got.status === 401 || got.status === 403 ? "expired" : "down");
|
|
2633
2659
|
}
|