@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.
Files changed (101) hide show
  1. package/.env.example +53 -0
  2. package/CHANGELOG.md +67 -3
  3. package/CHARTER.md +19 -7
  4. package/README.md +106 -21
  5. package/docs/AUTHORSHIP.md +3 -3
  6. package/docs/BOTS.md +4 -0
  7. package/docs/COVERAGE.md +2 -2
  8. package/docs/DEPLOY.md +9 -4
  9. package/docs/GUARDRAILS-AND-MONORAILS.md +2 -1
  10. package/docs/GUIDED-SETUP.md +8 -3
  11. package/docs/PERMISSIONS.md +6 -3
  12. package/docs/ROADMAP.md +25 -22
  13. package/docs/SETUP.md +8 -2
  14. package/docs/SUBKEYS.md +59 -0
  15. package/gems/artifact-index.json +12 -0
  16. package/gems/bot-team-backup/floor.json +15 -0
  17. package/gems/bot-team-backup/gem.json +43 -0
  18. package/gems/bot-team-backup/guides/BOT_TEAM_BACKUP.md +27 -0
  19. package/gems/bot-team-backup/guides/BOT_TEAM_RECOVERY.md +23 -0
  20. package/gems/fieldnote/floor.json +14 -0
  21. package/gems/fieldnote/gem.json +70 -0
  22. package/gems/fieldnote/runes/fieldnote.js +4 -0
  23. package/gems/lean-six-sigma/CHANGELOG.md +10 -0
  24. package/gems/lean-six-sigma/README.md +92 -0
  25. package/gems/lean-six-sigma/floor.json +31 -0
  26. package/gems/lean-six-sigma/gem.json +1296 -0
  27. package/gems/lean-six-sigma/guides/ASSUMPTIONS.md +45 -0
  28. package/gems/lean-six-sigma/guides/BELTS.md +52 -0
  29. package/gems/lean-six-sigma/guides/DMADV.md +56 -0
  30. package/gems/lean-six-sigma/guides/DMAIC.md +127 -0
  31. package/gems/lean-six-sigma/guides/FORMULAS.md +330 -0
  32. package/gems/lean-six-sigma/guides/LEAN.md +97 -0
  33. package/gems/lean-six-sigma/guides/TEMPLATES.md +279 -0
  34. package/gems/lean-six-sigma/runes/lss_capability.js +132 -0
  35. package/gems/lean-six-sigma/runes/lss_control_limits.js +240 -0
  36. package/gems/lean-six-sigma/runes/lss_dpmo_sigma.js +81 -0
  37. package/gems/lean-six-sigma/runes/lss_hypothesis.js +298 -0
  38. package/gems/lean-six-sigma/runes/lss_sample_size.js +81 -0
  39. package/gems/neurendipity/floor.json +65 -0
  40. package/gems/neurendipity/gem.json +42 -0
  41. package/gems/neurendipity/guides/AUTISTIC_BURNOUT.md +81 -0
  42. package/{guides → gems/neurendipity/guides}/NEURODIVERGENT_SUPPORT.md +17 -8
  43. package/guides/README.md +3 -0
  44. package/package.json +11 -5
  45. package/server.json +44 -4
  46. package/src/aleph.js +4 -4
  47. package/src/annotations.js +38 -3
  48. package/src/atlas-role.js +1 -1
  49. package/src/attribution.js +555 -0
  50. package/src/conformance.js +2 -2
  51. package/src/database.js +6 -5
  52. package/src/dispatch.js +116 -13
  53. package/src/env.js +54 -9
  54. package/src/floor.js +82 -41
  55. package/src/gaps.js +39 -6
  56. package/src/gem-check.js +1359 -0
  57. package/src/guides.js +31 -4
  58. package/src/host-reach.js +23 -0
  59. package/src/http-remote.js +46 -2
  60. package/src/index.js +9 -2
  61. package/src/layers.js +1 -1
  62. package/src/lessons-to-checks.js +3 -3
  63. package/src/logger.js +2 -1
  64. package/src/mongo-connect.js +45 -2
  65. package/src/oauth-provider.js +2 -2
  66. package/src/owner-approvals.js +281 -0
  67. package/src/persons.js +20 -0
  68. package/src/redact.js +10 -4
  69. package/src/request-log.js +1 -1
  70. package/src/rune-dispatch.js +360 -0
  71. package/src/rune-registry.js +71 -0
  72. package/src/rune-scope.js +42 -0
  73. package/src/scopes.js +3 -0
  74. package/src/session-graph.js +25 -23
  75. package/src/session.js +9 -9
  76. package/src/setup.js +297 -30
  77. package/src/socket.js +545 -0
  78. package/src/startup-pages.js +23 -6
  79. package/src/startup-payload.js +9 -6
  80. package/src/subkey-store.js +357 -0
  81. package/src/subkeys.js +947 -0
  82. package/src/tools.js +299 -62
  83. package/src/transcript-session.js +1 -1
  84. package/src/validation.js +26 -2
  85. package/src/version.js +1 -1
  86. package/templates/BOARD.md +2 -2
  87. package/templates/BOTHANDOFF.md +2 -2
  88. package/templates/CHARACTER.md +1 -1
  89. package/templates/HANDOFF.md +1 -1
  90. package/templates/IDENTITY.md +1 -1
  91. package/templates/INDEX.md +19 -19
  92. package/templates/INSTALL.md +1 -1
  93. package/templates/PROCEDURE.md +1 -1
  94. package/templates/ROSTER.md +2 -2
  95. package/templates/SEED.md +2 -2
  96. package/templates/STAGING.md +2 -2
  97. package/templates/STANDARD.md +5 -5
  98. package/templates/THREAD.md +1 -1
  99. package/templates/USER.md +4 -1
  100. package/verification/load-gate/corpus.json +1765 -0
  101. package/verification/load-gate/load-gate.mjs +1246 -0
@@ -1,10 +1,11 @@
1
1
  /**
2
- * EMET - the session graph: the monorail under the guardrails (2026-09-29;
3
- * the practice is docs/GUARDRAILS-AND-MONORAILS.md).
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
- * The owner: "guardrails give a field of movement and execution to allow an AI to do
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" (a recorded lesson). The floor, the character and the served
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; the owner's decisions 1-7). The rule, stated once: a session written
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: the owner adds one id per bot, and removing it
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 reviewer's gate
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, a recorded lesson), else - for
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 second reader's nit 3 on an earlier draft, the reviewer's
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 second reader's re-check of
197
- * an earlier draft). Hosts send numbers as numbers or as text ("4"). The guard read "4"
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 second reader's blocker
355
- * and the reviewer's gate on an earlier draft). The closing exchange itself is written
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 second reader's nit 4). Unset or blank: 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 second reader's nit 5 on an earlier draft).
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 second reader's nit 2): none added, none dropped, none
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 second reader's blocker on
567
- // an earlier draft): a retry handed to the tool with the caller's arguments could
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 second reader's nit 3), never
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, the owner: "a 'lab results' location for storing the
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 second reader's nit 2 on an earlier draft, the reviewer's condition 2):
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 record's 31-33 against a 27-exchange session.
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. The owner's requirement (a decision record,
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-host): every artifact present,
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 (the owner 2026-09-26,
972
- // A decision record: receipts required from the first deploy; the former
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, {