@dreamforgestudiollc/emet 0.2.4 → 0.2.6
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/.env.example +53 -0
- package/CHANGELOG.md +67 -3
- package/CHARTER.md +19 -7
- package/README.md +106 -21
- package/docs/AUTHORSHIP.md +3 -3
- package/docs/BOTS.md +4 -0
- package/docs/COVERAGE.md +2 -2
- package/docs/DEPLOY.md +9 -4
- package/docs/GUARDRAILS-AND-MONORAILS.md +2 -1
- package/docs/GUIDED-SETUP.md +8 -3
- package/docs/PERMISSIONS.md +6 -3
- package/docs/ROADMAP.md +25 -22
- package/docs/SETUP.md +8 -2
- package/docs/SUBKEYS.md +59 -0
- package/gems/artifact-index.json +12 -0
- package/gems/bot-team-backup/floor.json +15 -0
- package/gems/bot-team-backup/gem.json +43 -0
- package/gems/bot-team-backup/guides/BOT_TEAM_BACKUP.md +27 -0
- package/gems/bot-team-backup/guides/BOT_TEAM_RECOVERY.md +23 -0
- package/gems/fieldnote/floor.json +14 -0
- package/gems/fieldnote/gem.json +70 -0
- package/gems/fieldnote/runes/fieldnote.js +4 -0
- package/gems/lean-six-sigma/CHANGELOG.md +10 -0
- package/gems/lean-six-sigma/README.md +92 -0
- package/gems/lean-six-sigma/floor.json +31 -0
- package/gems/lean-six-sigma/gem.json +1296 -0
- package/gems/lean-six-sigma/guides/ASSUMPTIONS.md +45 -0
- package/gems/lean-six-sigma/guides/BELTS.md +52 -0
- package/gems/lean-six-sigma/guides/DMADV.md +56 -0
- package/gems/lean-six-sigma/guides/DMAIC.md +127 -0
- package/gems/lean-six-sigma/guides/FORMULAS.md +330 -0
- package/gems/lean-six-sigma/guides/LEAN.md +97 -0
- package/gems/lean-six-sigma/guides/TEMPLATES.md +279 -0
- package/gems/lean-six-sigma/runes/lss_capability.js +132 -0
- package/gems/lean-six-sigma/runes/lss_control_limits.js +240 -0
- package/gems/lean-six-sigma/runes/lss_dpmo_sigma.js +81 -0
- package/gems/lean-six-sigma/runes/lss_hypothesis.js +298 -0
- package/gems/lean-six-sigma/runes/lss_sample_size.js +81 -0
- package/gems/neurendipity/floor.json +65 -0
- package/gems/neurendipity/gem.json +42 -0
- package/gems/neurendipity/guides/AUTISTIC_BURNOUT.md +81 -0
- package/{guides → gems/neurendipity/guides}/NEURODIVERGENT_SUPPORT.md +17 -8
- package/guides/README.md +3 -0
- package/package.json +11 -5
- package/server.json +44 -4
- package/src/aleph.js +4 -4
- package/src/annotations.js +38 -3
- package/src/atlas-role.js +1 -1
- package/src/attribution.js +555 -0
- package/src/conformance.js +2 -2
- package/src/database.js +6 -5
- package/src/dispatch.js +116 -13
- package/src/env.js +54 -9
- package/src/floor.js +82 -41
- package/src/gaps.js +39 -6
- package/src/gem-check.js +1359 -0
- package/src/guides.js +31 -4
- package/src/host-reach.js +23 -0
- package/src/http-remote.js +46 -2
- package/src/index.js +9 -2
- package/src/layers.js +1 -1
- package/src/lessons-to-checks.js +3 -3
- package/src/logger.js +2 -1
- package/src/mongo-connect.js +45 -2
- package/src/oauth-provider.js +2 -2
- package/src/owner-approvals.js +281 -0
- package/src/persons.js +20 -0
- package/src/redact.js +10 -4
- package/src/request-log.js +1 -1
- package/src/rune-dispatch.js +360 -0
- package/src/rune-registry.js +71 -0
- package/src/rune-scope.js +42 -0
- package/src/scopes.js +3 -0
- package/src/session-graph.js +25 -23
- package/src/session.js +9 -9
- package/src/setup.js +297 -30
- package/src/socket.js +545 -0
- package/src/startup-pages.js +23 -6
- package/src/startup-payload.js +9 -6
- package/src/subkey-store.js +357 -0
- package/src/subkeys.js +947 -0
- package/src/tools.js +299 -62
- package/src/transcript-session.js +1 -1
- package/src/validation.js +26 -2
- package/src/version.js +1 -1
- package/templates/BOARD.md +2 -2
- package/templates/BOTHANDOFF.md +2 -2
- package/templates/CHARACTER.md +1 -1
- package/templates/HANDOFF.md +1 -1
- package/templates/IDENTITY.md +1 -1
- package/templates/INDEX.md +19 -19
- package/templates/INSTALL.md +1 -1
- package/templates/PROCEDURE.md +1 -1
- package/templates/ROSTER.md +2 -2
- package/templates/SEED.md +2 -2
- package/templates/STAGING.md +2 -2
- package/templates/STANDARD.md +5 -5
- package/templates/THREAD.md +1 -1
- package/templates/USER.md +4 -1
- package/verification/load-gate/corpus.json +1765 -0
- package/verification/load-gate/load-gate.mjs +1246 -0
package/src/session-graph.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* EMET - the session graph: the monorail under the guardrails (2026-09-29
|
|
3
|
-
*
|
|
2
|
+
* EMET - the session graph: the monorail under the guardrails (2026-09-29,
|
|
3
|
+
* board board 120, design staging/emet-session-graph.md; the practice is
|
|
4
|
+
* docs/GUARDRAILS-AND-MONORAILS.md).
|
|
4
5
|
*
|
|
5
|
-
*
|
|
6
|
+
* Alex: "guardrails give a field of movement and execution to allow an AI to do
|
|
6
7
|
* processes where rails guide the AI through a process flow without it
|
|
7
|
-
* processing" (
|
|
8
|
+
* processing" (semantic ref 297). The floor, the character and the served
|
|
8
9
|
* instructions are the guardrails. This file is the monorail - the car cannot
|
|
9
10
|
* leave the beam; where a flow forks, a small switch owned by the track (never
|
|
10
11
|
* the model) picks the branch (designed 2026-09-29, not yet built): the next step of a
|
|
@@ -68,18 +69,19 @@ export const HANDOFF_DOC = 'HANDOFF.md';
|
|
|
68
69
|
export const BOARD_DOC = 'STATE.md';
|
|
69
70
|
|
|
70
71
|
/**
|
|
71
|
-
* Per-bot close records (C1, 2026-10-01;
|
|
72
|
+
* Per-bot close records (C1, 2026-10-01; review note "C1: per-bot close
|
|
73
|
+
* records", the owner's decisions 1-7). The rule, stated once: a session written
|
|
72
74
|
* under a bot's source tag closes against that bot's own records
|
|
73
75
|
* (bots/<tag>/HANDOFF.md); only that tag's own revisions in the session window
|
|
74
76
|
* count; a bot tag never writes or cites the main HANDOFF.md or STATE.md.
|
|
75
77
|
*
|
|
76
78
|
* A tag T is a BOT TAG when bots/T/HANDOFF.md is listed in EMET_RECORD_DOCS,
|
|
77
79
|
* the list that already marks ids as supersede-only records (tools.js
|
|
78
|
-
* recordDocIds). No new setting:
|
|
80
|
+
* recordDocIds). No new setting: Alex adds one id per bot, and removing it
|
|
79
81
|
* puts that tag back on the host rules. Bot records are named by the source
|
|
80
82
|
* tag itself (decision 1), so no tag-to-name mapping exists. These are pure
|
|
81
83
|
* reads of settings - no database - so the graph can key its bot-handoff gate
|
|
82
|
-
* on a write's `source` without an extra read.
|
|
84
|
+
* on a write's `source` without an extra read (review note section 5).
|
|
83
85
|
*/
|
|
84
86
|
export function botRecordDir(tag) { return `bots/${tag}/`; }
|
|
85
87
|
export function botHandoffDoc(tag) { return `bots/${tag}/HANDOFF.md`; }
|
|
@@ -101,7 +103,7 @@ export function mainRecordIds() {
|
|
|
101
103
|
* The source tag a write names, read as dispatch.js sourceOf reads it
|
|
102
104
|
* (`source`, then the older aliases). Repeated here because dispatch imports
|
|
103
105
|
* this module. No default: a write with no source takes the host path in the
|
|
104
|
-
* graph.
|
|
106
|
+
* graph (review note section 5).
|
|
105
107
|
*/
|
|
106
108
|
export function writeSourceOf(args = {}) {
|
|
107
109
|
const v = args.source ?? args.updated_by ?? args.retired_by ?? args.accepted_by ?? args.channel ?? null;
|
|
@@ -136,7 +138,7 @@ export function echoId(id) {
|
|
|
136
138
|
* Every session base an id could belong to, the way the close check groups a
|
|
137
139
|
* session's documents (session.js inspectSession: ^base(_.*)?$). An id like
|
|
138
140
|
* `<base>_extra` is counted by the close as part of `<base>`, so the closed-
|
|
139
|
-
* session guard must treat it as `<base>` too (2026-10-01, the
|
|
141
|
+
* session guard must treat it as `<base>` too (2026-10-01, the tester's gate
|
|
140
142
|
* (a)). Longest first: the id itself, then each prefix ending before a `_`.
|
|
141
143
|
*/
|
|
142
144
|
export function candidateBases(sessionId) {
|
|
@@ -163,13 +165,13 @@ export function groupedUnder(sessionId, base) {
|
|
|
163
165
|
/**
|
|
164
166
|
* The session a call names: `session_id`, else the transcript span in
|
|
165
167
|
* `metadata.derived_from` (revise_memory refuses metadata.session_id and names
|
|
166
|
-
* its session there - live-caught 2026-09-29,
|
|
168
|
+
* its session there - live-caught 2026-09-29, semantic ref 295), else - for
|
|
167
169
|
* emet_session_close, the only tool that takes `receipts` -
|
|
168
170
|
* `receipts.transcript_session_id`. The close tool's description documents
|
|
169
171
|
* that shape ("receipts.transcript_session_id is used when this is omitted")
|
|
170
172
|
* and sessionClose checks that session; until 2026-10-01 the graph read only
|
|
171
173
|
* `session_id`, so a close naming its session only in the receipts was never
|
|
172
|
-
* recorded and the session stayed open (the
|
|
174
|
+
* recorded and the session stayed open (the reviewer's nit 3 on commit-df21117, the tester's
|
|
173
175
|
* condition 1). Receipts sent as JSON text are read as sessionClose reads
|
|
174
176
|
* them (session.js parseReceipts).
|
|
175
177
|
*/
|
|
@@ -193,8 +195,8 @@ function receiptsOf(value) {
|
|
|
193
195
|
}
|
|
194
196
|
|
|
195
197
|
/**
|
|
196
|
-
* An exchange number as sent, normalized ONCE (2026-10-01, the
|
|
197
|
-
*
|
|
198
|
+
* An exchange number as sent, normalized ONCE (2026-10-01, the reviewer's re-check of
|
|
199
|
+
* commit-2a361fd). Hosts send numbers as numbers or as text ("4"). The guard read "4"
|
|
198
200
|
* as 4 while emet_transcript_append only took real numbers, so a text "4" was a
|
|
199
201
|
* "retry" to the guard and "the next exchange" to the tool. dispatch now runs
|
|
200
202
|
* every exchange_index through this before the graph, the guard and the tool,
|
|
@@ -351,8 +353,8 @@ export async function isSessionClosed(base, dbManager) {
|
|
|
351
353
|
* once the window passes, the session is locked. A retry of that same
|
|
352
354
|
* exchange number is answered as already saved, never as a second write:
|
|
353
355
|
* the guard answers it itself and the tool is not called, at any time after
|
|
354
|
-
* the close, so a retry can write nothing anywhere (2026-10-01, the
|
|
355
|
-
* and the
|
|
356
|
+
* the close, so a retry can write nothing anywhere (2026-10-01, the reviewer's blocker
|
|
357
|
+
* and the tester's gate on commit-2a361fd). The closing exchange itself is written
|
|
356
358
|
* into the session's last live part, whatever part or base id the caller sent.
|
|
357
359
|
*
|
|
358
360
|
* graceDecision is pure: state is the session row, declared the exchange the
|
|
@@ -368,7 +370,7 @@ export const DEFAULT_CLOSE_GRACE_MINUTES = 5;
|
|
|
368
370
|
export const MAX_CLOSE_GRACE_MINUTES = 60;
|
|
369
371
|
|
|
370
372
|
/**
|
|
371
|
-
* The window setting, checked (2026-10-01, the
|
|
373
|
+
* The window setting, checked (2026-10-01, the reviewer's nit 4). Unset or blank: the
|
|
372
374
|
* default, 5. A number from 0 to 60: that many minutes (0 turns the window
|
|
373
375
|
* off). Anything else is NOT silently accepted: a negative or non-numeric value
|
|
374
376
|
* falls back to the default 5, and a value over 60 is capped at 60; both come
|
|
@@ -390,7 +392,7 @@ function closeGraceName() {
|
|
|
390
392
|
export function closeGraceSetting(raw = setting('CLOSE_GRACE_MINUTES'), name = closeGraceName()) {
|
|
391
393
|
if (raw === undefined || raw === null || String(raw).trim() === '') return { minutes: DEFAULT_CLOSE_GRACE_MINUTES, note: null };
|
|
392
394
|
// Decimal only: Number() also reads hex, octal and binary ("0x10" is 16),
|
|
393
|
-
// which no one means for minutes (the
|
|
395
|
+
// which no one means for minutes (the reviewer's nit 5 on commit-df21117).
|
|
394
396
|
const text = String(raw).trim();
|
|
395
397
|
const n = /^[+-]?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i.test(text) ? Number(text) : NaN;
|
|
396
398
|
if (!Number.isFinite(n) || n < 0) {
|
|
@@ -517,7 +519,7 @@ export async function closedSessionGuard(tool, args = {}, dbManager, now = new D
|
|
|
517
519
|
} catch (e) { throw await unreadable(tool, base, 'the transcript part to be revised', e); }
|
|
518
520
|
if (!part) return null; // the tool itself refuses a revision of a part that does not exist
|
|
519
521
|
// A correction of a closed session keeps EXACTLY the exchange numbers the
|
|
520
|
-
// part holds (2026-10-01, the
|
|
522
|
+
// part holds (2026-10-01, the reviewer's nit 2): none added, none dropped, none
|
|
521
523
|
// duplicated. Numbers sent as text are stored as numbers; the corrected
|
|
522
524
|
// part is stored in exchange order.
|
|
523
525
|
const held = [...new Set((part.exchanges || []).map((e) => Number(e && e.exchange_index)))].sort((a, b) => a - b);
|
|
@@ -563,8 +565,8 @@ export async function closedSessionGuard(tool, args = {}, dbManager, now = new D
|
|
|
563
565
|
const d = graceDecision(row, declared, highest, now, minutes);
|
|
564
566
|
|
|
565
567
|
if (d === 'retry') {
|
|
566
|
-
// Answered HERE, and the tool is never called (2026-10-01, the
|
|
567
|
-
//
|
|
568
|
+
// Answered HERE, and the tool is never called (2026-10-01, the reviewer's blocker on
|
|
569
|
+
// commit-2a361fd): a retry handed to the tool with the caller's arguments could
|
|
568
570
|
// land in another part id, the base id, or - with the number sent as text -
|
|
569
571
|
// as a new exchange, while the reply said nothing was written.
|
|
570
572
|
return { retry: true, base, index: row.grace_index,
|
|
@@ -572,7 +574,7 @@ export async function closedSessionGuard(tool, args = {}, dbManager, now = new D
|
|
|
572
574
|
}
|
|
573
575
|
if (d === 'grace') {
|
|
574
576
|
const index = highest + 1;
|
|
575
|
-
// Pinned to the session's last live part (2026-10-01, the
|
|
577
|
+
// Pinned to the session's last live part (2026-10-01, the reviewer's nit 3), never
|
|
576
578
|
// the part or base id the caller named. If that part is full, the append
|
|
577
579
|
// rolls to the next part number exactly as a live append does.
|
|
578
580
|
let part = typeof pos.last_part === 'string' && pos.last_part ? pos.last_part : null;
|
|
@@ -767,7 +769,7 @@ export async function graphBefore(tool, args, dbManager, now = new Date()) {
|
|
|
767
769
|
}
|
|
768
770
|
|
|
769
771
|
// ---------------------------------------------------------------------------
|
|
770
|
-
// Lab results (2026-09-29,
|
|
772
|
+
// Lab results (2026-09-29, Alex: "a 'lab results' location for storing the
|
|
771
773
|
// results in real time with time stamps so we can have a resource to look at
|
|
772
774
|
// after the probationary period"). Every check the monorail makes - ok,
|
|
773
775
|
// refuse, unknown (would_refuse in rows from before enforce-only) - is one timestamped row in
|
|
@@ -901,7 +903,7 @@ export function graphBlock(g) {
|
|
|
901
903
|
/**
|
|
902
904
|
* After a successful call: record the step. Never throws - a failed record is
|
|
903
905
|
* logged, not fatal. Returns what happened, so the close can say so
|
|
904
|
-
* (2026-10-01, the
|
|
906
|
+
* (2026-10-01, the reviewer's nit 2 on commit-df21117, the tester's condition 2):
|
|
905
907
|
* null nothing to record (no session, or no step)
|
|
906
908
|
* {recorded: true, base} the step was written
|
|
907
909
|
* {recorded: false, base, error} the write failed (logged as a warning)
|
package/src/session.js
CHANGED
|
@@ -322,7 +322,7 @@ export async function corroborateCoverage(db, baseId) {
|
|
|
322
322
|
// correction makes the check permanently worse, and the flag can never
|
|
323
323
|
// clear because superseded entries cannot be edited. Found live at the
|
|
324
324
|
// 2026-09-11 close: nine entries superseded with correct spans, and the
|
|
325
|
-
// check still read the old
|
|
325
|
+
// check still read the old ref 314's 31-33 against a 27-exchange session.
|
|
326
326
|
// Every other read in EMET hides superseded entries by default; this one
|
|
327
327
|
// now does too - and says how many it set aside, because dropping
|
|
328
328
|
// evidence silently is the other half of the same mistake.
|
|
@@ -354,7 +354,7 @@ export async function corroborateCoverage(db, baseId) {
|
|
|
354
354
|
* The store check above answers "do the artifacts exist". It could not answer
|
|
355
355
|
* "did the host actually do each step", and a host that skipped a step, or
|
|
356
356
|
* never read the transcript back, could still walk away with `complete`
|
|
357
|
-
* because the store happened to look fine.
|
|
357
|
+
* because the store happened to look fine. the owner's requirement (procedural ref 388,
|
|
358
358
|
* 389, 391): the wrap steps HAVE TO BE FOLLOWED, whichever model is hosting,
|
|
359
359
|
* and a skipped step blocks the close the same way a skipped opening is caught
|
|
360
360
|
* at initialize.
|
|
@@ -387,7 +387,7 @@ export const RECEIPT_FIELDS = Object.freeze({
|
|
|
387
387
|
});
|
|
388
388
|
|
|
389
389
|
/**
|
|
390
|
-
* A bot session's receipts (C1, 2026-10-01).
|
|
390
|
+
* A bot session's receipts (C1, 2026-10-01; review note section 3.3).
|
|
391
391
|
* Seven: no board is required - a bot that keeps one lists it under
|
|
392
392
|
* bots/<tag>/ as board_doc (checked when given) or as a working document - and
|
|
393
393
|
* handoff_doc names the bot's own handoff. Host receipts stay at the eight
|
|
@@ -403,7 +403,7 @@ export const BOT_RECEIPT_FIELDS = Object.freeze({
|
|
|
403
403
|
handoff_version: RECEIPT_FIELDS.handoff_version
|
|
404
404
|
});
|
|
405
405
|
|
|
406
|
-
/** The message every bot-records refusal carries. */
|
|
406
|
+
/** The message every bot-records refusal carries (review note section 3.5). */
|
|
407
407
|
export function hubRecordsMessage(tag) {
|
|
408
408
|
return `a bot session closes against ${botRecordDir(tag)} records; the main handoff and board are the hub's`;
|
|
409
409
|
}
|
|
@@ -429,7 +429,7 @@ export function sessionTagOf(rows = []) {
|
|
|
429
429
|
* Hosts do not all pass an object argument the same way. A client working from
|
|
430
430
|
* a cached tool list that predates `receipts` - or a host that serialises every
|
|
431
431
|
* nested argument - sends the receipts as JSON TEXT. Found live at the first
|
|
432
|
-
* close under the new rule (2026-09-26, cloud
|
|
432
|
+
* close under the new rule (2026-09-26, cowork-cloud): every artifact present,
|
|
433
433
|
* receipts sent, and the server saw none. Consistent execution across hosts
|
|
434
434
|
* means accepting both forms. Text that does not parse is treated as absent,
|
|
435
435
|
* so it still blocks - it is never guessed at.
|
|
@@ -485,7 +485,7 @@ export function checkReceipts(receipts, observed) {
|
|
|
485
485
|
|
|
486
486
|
const docs = new Map((observed.documents || []).map((d) => [d.doc_id, d]));
|
|
487
487
|
|
|
488
|
-
// A bot session never names the main records: any
|
|
488
|
+
// A bot session never names the main records (review note section 3.5): any
|
|
489
489
|
// receipt that does is refused here, and those ids get no other check.
|
|
490
490
|
const mainIds = bot ? (bot.main_records || []) : [];
|
|
491
491
|
const isMain = (id) => mainIds.includes(id);
|
|
@@ -852,7 +852,7 @@ export async function sessionClose(options = {}) {
|
|
|
852
852
|
if (row && ms !== null && ms >= startMs) {
|
|
853
853
|
receiptEpisodicSource = parseMetadata(row.metadata).source || null;
|
|
854
854
|
if (bot) {
|
|
855
|
-
// A bot's session record is its own and cites this session.
|
|
855
|
+
// A bot's session record is its own and cites this session (review note 3.2).
|
|
856
856
|
const cited = typeof row.source_session_id === 'string' && row.source_session_id ? row.source_session_id : null;
|
|
857
857
|
if (receiptEpisodicSource !== bot.tag) {
|
|
858
858
|
episodicRejected = `its metadata.source is ${receiptEpisodicSource || '(none)'}, not ${bot.tag}`;
|
|
@@ -968,8 +968,8 @@ export async function sessionClose(options = {}) {
|
|
|
968
968
|
}
|
|
969
969
|
|
|
970
970
|
// Store-level gaps make the session incomplete. Receipt problems, and a
|
|
971
|
-
// transcript nothing independently corroborates, BLOCK it (
|
|
972
|
-
//
|
|
971
|
+
// transcript nothing independently corroborates, BLOCK it (Alex 2026-09-26,
|
|
972
|
+
// procedural ref 391: receipts required from the first deploy; the former
|
|
973
973
|
// `unconfirmed` state is blocked, not passed).
|
|
974
974
|
const storeMissing = [...missing];
|
|
975
975
|
const receiptCheck = checkReceipts(receipts, {
|