@dreamforgestudiollc/emet 0.0.0-stage → 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 (114) hide show
  1. package/.env.example +189 -0
  2. package/CHANGELOG.md +360 -0
  3. package/CHARTER.md +137 -0
  4. package/LICENSE +22 -0
  5. package/README.md +868 -2
  6. package/docs/AUTHORSHIP.md +26 -0
  7. package/docs/BENCHMARKS.md +261 -0
  8. package/docs/BOOTSTRAP.md +127 -0
  9. package/docs/BOTS.md +83 -0
  10. package/docs/COVERAGE.md +64 -0
  11. package/docs/DEPLOY.md +251 -0
  12. package/docs/DISCIPLINES.md +29 -0
  13. package/docs/GUARDRAILS-AND-MONORAILS.md +108 -0
  14. package/docs/GUIDED-SETUP.md +301 -0
  15. package/docs/PERMISSIONS.md +121 -0
  16. package/docs/ROADMAP.md +62 -0
  17. package/docs/SETUP.md +265 -0
  18. package/docs/SUBKEYS.md +59 -0
  19. package/gems/artifact-index.json +12 -0
  20. package/gems/bot-team-backup/floor.json +15 -0
  21. package/gems/bot-team-backup/gem.json +43 -0
  22. package/gems/bot-team-backup/guides/BOT_TEAM_BACKUP.md +27 -0
  23. package/gems/bot-team-backup/guides/BOT_TEAM_RECOVERY.md +23 -0
  24. package/gems/fieldnote/floor.json +14 -0
  25. package/gems/fieldnote/gem.json +70 -0
  26. package/gems/fieldnote/runes/fieldnote.js +4 -0
  27. package/gems/lean-six-sigma/CHANGELOG.md +10 -0
  28. package/gems/lean-six-sigma/README.md +92 -0
  29. package/gems/lean-six-sigma/floor.json +31 -0
  30. package/gems/lean-six-sigma/gem.json +1296 -0
  31. package/gems/lean-six-sigma/guides/ASSUMPTIONS.md +45 -0
  32. package/gems/lean-six-sigma/guides/BELTS.md +52 -0
  33. package/gems/lean-six-sigma/guides/DMADV.md +56 -0
  34. package/gems/lean-six-sigma/guides/DMAIC.md +127 -0
  35. package/gems/lean-six-sigma/guides/FORMULAS.md +330 -0
  36. package/gems/lean-six-sigma/guides/LEAN.md +97 -0
  37. package/gems/lean-six-sigma/guides/TEMPLATES.md +279 -0
  38. package/gems/lean-six-sigma/runes/lss_capability.js +132 -0
  39. package/gems/lean-six-sigma/runes/lss_control_limits.js +240 -0
  40. package/gems/lean-six-sigma/runes/lss_dpmo_sigma.js +81 -0
  41. package/gems/lean-six-sigma/runes/lss_hypothesis.js +298 -0
  42. package/gems/lean-six-sigma/runes/lss_sample_size.js +81 -0
  43. package/gems/neurendipity/floor.json +65 -0
  44. package/gems/neurendipity/gem.json +42 -0
  45. package/gems/neurendipity/guides/AUTISTIC_BURNOUT.md +81 -0
  46. package/gems/neurendipity/guides/NEURODIVERGENT_SUPPORT.md +287 -0
  47. package/guides/README.md +3 -0
  48. package/package.json +76 -4
  49. package/server.json +79 -0
  50. package/src/aleph.js +395 -0
  51. package/src/annotations.js +170 -0
  52. package/src/approve-throttle.js +54 -0
  53. package/src/atlas-role.js +58 -0
  54. package/src/attribution.js +555 -0
  55. package/src/conformance.js +688 -0
  56. package/src/content_analyzer.js +450 -0
  57. package/src/database.js +812 -0
  58. package/src/disciplines.js +26 -0
  59. package/src/dispatch.js +382 -0
  60. package/src/env.js +97 -0
  61. package/src/floor.js +228 -0
  62. package/src/gaps.js +509 -0
  63. package/src/gem-check.js +1359 -0
  64. package/src/guides.js +75 -0
  65. package/src/host-reach.js +23 -0
  66. package/src/http-remote.js +313 -0
  67. package/src/index.js +397 -0
  68. package/src/invites.js +167 -0
  69. package/src/layers.js +449 -0
  70. package/src/lessons-to-checks.js +366 -0
  71. package/src/logger.js +300 -0
  72. package/src/metadata.js +61 -0
  73. package/src/module-path.js +32 -0
  74. package/src/mongo-connect.js +91 -0
  75. package/src/named-items.js +208 -0
  76. package/src/oauth-provider.js +838 -0
  77. package/src/owner-approvals.js +281 -0
  78. package/src/persons.js +136 -0
  79. package/src/provenance.js +257 -0
  80. package/src/redact.js +237 -0
  81. package/src/request-log.js +124 -0
  82. package/src/rune-dispatch.js +360 -0
  83. package/src/rune-registry.js +71 -0
  84. package/src/rune-scope.js +42 -0
  85. package/src/scopes.js +100 -0
  86. package/src/security-headers.js +26 -0
  87. package/src/session-graph.js +947 -0
  88. package/src/session.js +1097 -0
  89. package/src/setup.js +1580 -0
  90. package/src/socket.js +545 -0
  91. package/src/startup-pages.js +371 -0
  92. package/src/startup-payload.js +129 -0
  93. package/src/subkey-store.js +357 -0
  94. package/src/subkeys.js +947 -0
  95. package/src/tools.js +4508 -0
  96. package/src/transcript-session.js +106 -0
  97. package/src/validation.js +1187 -0
  98. package/src/version.js +2 -0
  99. package/templates/BOARD.md +72 -0
  100. package/templates/BOTHANDOFF.md +57 -0
  101. package/templates/CHARACTER.md +30 -0
  102. package/templates/HANDOFF.md +63 -0
  103. package/templates/IDENTITY.md +29 -0
  104. package/templates/INDEX.md +82 -0
  105. package/templates/INSTALL.md +29 -0
  106. package/templates/PROCEDURE.md +39 -0
  107. package/templates/ROSTER.md +43 -0
  108. package/templates/SEED.md +65 -0
  109. package/templates/STAGING.md +37 -0
  110. package/templates/STANDARD.md +99 -0
  111. package/templates/THREAD.md +43 -0
  112. package/templates/USER.md +32 -0
  113. package/verification/load-gate/corpus.json +1765 -0
  114. package/verification/load-gate/load-gate.mjs +1246 -0
package/docs/SETUP.md ADDED
@@ -0,0 +1,265 @@
1
+ # Setting up EMET
2
+
3
+ From nothing to a working memory your assistant can use, on every device you own.
4
+
5
+ There are three stages and they must happen in order: **a database**, **a server**, **an
6
+ identity**. The first two are plumbing. The third is the one people skip, and it is the one
7
+ that decides whether the thing is useful.
8
+
9
+ **If you would rather not do the plumbing yourself,** [GUIDED-SETUP.md](GUIDED-SETUP.md) is
10
+ the same three stages carried out by your assistant, with you signing in when asked. This
11
+ page is the manual walkthrough and the reference the guided path points back to.
12
+
13
+ ---
14
+
15
+ ## Stage 1 — MongoDB Atlas
16
+
17
+ EMET stores everything in MongoDB. The Atlas free tier is enough to start.
18
+
19
+ **Trying it on one machine first?** A local MongoDB (version 6 or later) works for everything
20
+ except `semantic_recall`, which needs an Atlas vector index (step 7). Set
21
+ `MONGODB_URI=mongodb://127.0.0.1:27017/`, skip steps 1–4 and 7, and go to Stage 2. The
22
+ `emetRecordKeeper` role (step 2) is still worth creating on a local server that has users
23
+ enabled, by hand with `db.createRole`; `scripts/atlas-role.mjs` is for Atlas only. Use Atlas
24
+ when you want a second device to reach the same memory.
25
+
26
+ 1. **Create a cluster.** <https://cloud.mongodb.com> → new project → **Create** a cluster.
27
+ Any region near you. Note the cluster name.
28
+
29
+ 2. **Create a database user for EMET, and give it EMET's own role.** Database Access →
30
+ Add New Database User. Authentication: password. Username e.g. `emet_app`.
31
+
32
+ EMET keeps its record — it never deletes a memory, a document or a transcript. Give the
33
+ server a login that *cannot* delete them either, so the rule holds at the database and
34
+ not only in the code. The role is **`emetRecordKeeper`**, defined once in
35
+ `src/atlas-role.js`:
36
+
37
+ | On | Allowed |
38
+ |---|---|
39
+ | your whole EMET database | find, insert, update, create collection, create index, list collections, list indexes, list search indexes, collection and database stats |
40
+ | `<prefix>oauth_tokens` | remove — revoking a sign-in token |
41
+ | `_emet_verify` | remove — the status check deletes its probe document and does not drop the collection |
42
+
43
+ Nothing else may be removed or dropped. `tests/atlas-role.test.js` fails if the code ever
44
+ starts deleting from a collection this role does not allow.
45
+
46
+ **The quick way (Atlas CLI).** Install it (`winget install MongoDB.MongoDBAtlasCLI`, or
47
+ see mongodb.com/docs/atlas/cli), sign in with `atlas auth login` in your own terminal —
48
+ it asks you to pick options, so it needs a real keyboard — then from the EMET folder:
49
+
50
+ ```
51
+ node scripts/atlas-role.mjs --project <projectId> --db <database> --user emet_app
52
+ ```
53
+
54
+ That is a dry run: it prints the commands. Add `--apply` to create the role and move the
55
+ user onto it; `--rollback` puts the user back on `readWrite@<database>`. Find the project id
56
+ with `atlas projects list`. A non-default `EMET_COLLECTION_PREFIX` is picked up, or pass
57
+ `--prefix`.
58
+
59
+ **The click way.** Database Access → Custom Roles → Add New Custom Role, name
60
+ `emetRecordKeeper`, add the actions in the table above against your database and the two
61
+ collections; then edit the user and set its role to `emetRecordKeeper`.
62
+
63
+ **Prove it.** From any EMET host, run `emet_status` with `probe: true`. It writes, reads
64
+ back and removes a test document, so a role missing something fails there, loudly, instead
65
+ of in the middle of a session.
66
+
67
+ - Do *not* grant cluster-wide admin, and do not use this login for maintenance. A one-off
68
+ job that must delete (a migration, a corpus rebuild) gets its own login, used and then
69
+ removed.
70
+
71
+ 3. **Network access.** Network Access → Add IP Address.
72
+ - Local use only: add your own IP.
73
+ - Deploying to Railway or similar: the egress IP is dynamic, so `0.0.0.0/0` is the
74
+ practical option. Security then rests on the scoped user and the OAuth passphrase —
75
+ both are required, and neither is optional.
76
+
77
+ 4. **Get the connection string.** Connect → Drivers → copy the `mongodb+srv://...` URI and
78
+ substitute your user and password. This goes in `MONGODB_URI` and **never** into git.
79
+
80
+ 5. **Pick a database name** and set `MONGODB_DB`. It defaults to `emet`. Collections (`emet_episodic`, `emet_semantic`, …) are
81
+ created on first write — there is nothing to pre-create.
82
+
83
+ 6. **One database per EMET instance.** The document store (`documents`,
84
+ `documents_history`) is deliberately *not* prefixed, so two instances pointed at the same
85
+ database will share their identity and continuity documents even if their memory
86
+ collections use different prefixes. If you want two separate memories, give them separate
87
+ databases - not just separate prefixes.
88
+
89
+ 7. **Vector index — only if you want `semantic_recall`.** Keyword search works without it.
90
+ For meaning-based search, create an Atlas Vector Search index named
91
+ `emet_content_auto` on the `emet_semantic` collection, path `content`, using
92
+ Atlas Automated Embedding. Repeat per layer collection you want searchable.
93
+ ⚠ **Atlas tier migrations can silently drop search indexes created mid-migration.**
94
+ After any tier change, re-check that the index still exists.
95
+
96
+ ---
97
+
98
+ ## Stage 2 — run the server
99
+
100
+ EMET runs two ways from one codebase. Most people want both eventually: local for speed,
101
+ remote so the phone can reach it.
102
+
103
+ ### Local (stdio) — desktop and CLI
104
+
105
+ ```
106
+ npm install
107
+ npm test # optional: no database or credentials needed
108
+ cp .env.example .env # fill in MONGODB_URI at minimum
109
+ npm start
110
+ ```
111
+
112
+ `.env` is read automatically from the repo root. Real environment variables win over it,
113
+ so a hosted deployment that sets them directly is unaffected by a stray local file.
114
+
115
+ `npm start` prints its startup log and then waits, silently, for an MCP client on standard
116
+ input; that is normal. Stop it with Ctrl-C. Day to day you do not run it by hand: your MCP
117
+ client starts it from the entry below.
118
+
119
+ Then point your MCP client at it:
120
+
121
+ ```json
122
+ { "mcpServers": { "emet": {
123
+ "command": "node",
124
+ "args": ["/absolute/path/to/emet/src/index.js"],
125
+ "env": { "MONGODB_URI": "mongodb+srv://...", "MONGODB_DB": "emet", "EMET_SOURCE_TAG": "laptop" }
126
+ } } }
127
+ ```
128
+
129
+ ### Remote (HTTP + OAuth) — phone, tablet, anything else
130
+
131
+ See **[DEPLOY.md](DEPLOY.md)** for the Railway walkthrough. Short version: deploy
132
+ `src/http-remote.js`, set the environment variables, and add the resulting
133
+ `https://<host>/mcp` URL as a custom connector in your client.
134
+
135
+ ### Set a distinct source tag on every host
136
+
137
+ Every write records which host produced it. A local entry, which serves one host, sets that
138
+ host's tag with `EMET_SOURCE_TAG`, as in the example above. A remote server several hosts
139
+ share leaves `EMET_SOURCE_TAG` unset, and each host passes its own tag as `source` on its
140
+ writes: a shared default makes every host look the same, and you will have entries you cannot
141
+ attribute. `laptop`, `phone`, `cli`, `work-desktop`. One each.
142
+
143
+ ---
144
+
145
+ ## Stage 3 — the setup interview
146
+
147
+ This is the part that turns a database into a memory.
148
+
149
+ **Say "initialize".** There is no setup command to memorize.
150
+
151
+ Your assistant calls `emet_initialize`, which branches on the state of the store so you do not
152
+ have to. A new store returns a short interview; an established one returns the assistant's
153
+ identity, your profile, and recent context. Requiring a command would have been backwards —
154
+ the one session you would need it is the first one, before you have read any of this.
155
+
156
+ The interview asks eight things, four required and four optional:
157
+
158
+ - **What the assistant should be called**, and **how it should carry itself.** This becomes
159
+ the identity it speaks from in every session on every host.
160
+ - **Your name**, in the form you actually want used.
161
+ - **What you are using this memory for**, which shapes what gets treated as worth saving.
162
+ - Optionally: how you want to be worked with, this host's source tag, and whether more than
163
+ one bot or AI will use this memory. Leaving that one out leaves sub-keys off. The
164
+ walkthrough is [SUBKEYS.md](SUBKEYS.md).
165
+ - Optionally: whether to turn on bot-team backup. **Yes is the recommended choice.** Yes and
166
+ Yes. count as yes, the same way as the multi-bot question. No, or leaving it out, leaves it
167
+ off. The answer is recorded. EMET does not copy prompts or
168
+ settings itself, and secret values are never stored. The recipe is `gems/bot-team-backup/guides/BOT_TEAM_BACKUP.md`.
169
+
170
+ Your assistant asks these conversationally, one at a time — not as a form — then calls
171
+ `emet_setup_complete`.
172
+
173
+ Three behaviours worth knowing:
174
+
175
+ - **It refuses to finish on partial answers** rather than filling in the gaps itself. An
176
+ invented identity is worse than no identity.
177
+ - **Re-running is safe.** Documents are versioned and the previous copy is archived to
178
+ `documents_history`. Nothing is overwritten in place, ever.
179
+ - **If the store is unreachable, initialize says so** instead of continuing as though memory
180
+ were available. A confident assistant with no memory and no warning is the worst outcome.
181
+
182
+ What gets written: `bootstrap/IDENTITY.md` and `bootstrap/USER.md` in the document store, plus
183
+ an entry in the `identity` layer. All three are read-back verified before setup reports
184
+ success. Edit any of them later with `write_doc` — same versioning applies.
185
+
186
+ **The supporting tools**, which you should not normally need:
187
+
188
+ | Tool | What it does |
189
+ |---|---|
190
+ | `emet_status` | Diagnostic: environment, database, collections, vector index, whether identity and user documents exist, per-layer counts and health. With `probe: true` it also connects, pings, **writes a probe and reads the same value back**, then removes it — a read alone will not reveal a broken write path. |
191
+ | `emet_setup_complete` | Records the answers, read-back verified, and creates the owner person. The owner's only: refused under a bot tag, and refused on a store that is already set up unless `reissue: true` is passed. |
192
+
193
+ ## Migrating an existing CASCADE deployment
194
+
195
+ If you are already running upstream CASCADE against a MongoDB store, EMET reads it in
196
+ place. **Nothing needs to be renamed, copied, or migrated** - point the new build at your
197
+ existing names and every memory, document, transcript and OAuth token stays exactly where
198
+ it is.
199
+
200
+ | Variable | Set it to | Why |
201
+ |---|---|---|
202
+ | `MONGODB_DB` | your existing database | EMET defaults to `emet`; yours is probably something else |
203
+ | `EMET_COLLECTION_PREFIX` | `cascade_` | your layer collections are `cascade_episodic`, etc. |
204
+ | `EMET_VECTOR_INDEX` | `cascade_content_auto` | the Atlas Vector Search index `semantic_recall` uses |
205
+ | `EMET_CORPORA` | your corpus names, comma-separated | only if you use `corpus_recall`; leave unset otherwise |
206
+
207
+ `EMET_COLLECTION_PREFIX` also governs the counters collection and the three OAuth
208
+ collections, so **devices you have already authorized stay authorized** - there is no
209
+ re-consent step.
210
+
211
+ Your old `CASCADE_SOURCE_TAG` and `CASCADE_OAUTH_PASSPHRASE` continue to work; the `EMET_`
212
+ forms take precedence if both are set. New installs should use the `EMET_` names only.
213
+
214
+ **The server guards against getting this wrong.** If it is configured for a prefix that sees
215
+ zero memories while the same database holds populated collections under a different one,
216
+ `emet_initialize` returns `state: "misconfigured"` instead of `ready` or `setup_required`, and
217
+ refuses to offer the setup interview. This matters because the failure is otherwise silent:
218
+ the document store is unprefixed, so a mismatched server still finds your identity and comes
219
+ up looking healthy - correct name, correct profile, and an empty memory. It reports the
220
+ prefixes it found and how many entries are under them.
221
+
222
+ **Verify before trusting it.** Run `emet_status` and confirm the layer counts match
223
+ what you had, and that `vector_index` reports the index you expect. Then `emet_initialize` -
224
+ it should come back `ready` with your existing identity, not `setup_required`. If it says
225
+ `setup_required`, one of the four variables above is wrong; **do not run the setup interview,
226
+ which would write a new identity over your existing one.**
227
+
228
+ ## Stage 4 — tell your assistant to use it
229
+
230
+ Setup gives the store an identity. It does not tell your assistant to consult it. See
231
+ **[BOOTSTRAP.md](BOOTSTRAP.md)** for the short instruction block to paste into your project,
232
+ and for what to expect on hosts that offer no instructions field.
233
+
234
+ ## Verifying it worked
235
+
236
+ ```
237
+ emet_status → initialized: true (false until the setup interview is done)
238
+ emet_status probe:true → every probe check passed
239
+ emet_session_open → a session_id
240
+ save_to_layer → with that session_id, then recall it from a different device
241
+ ```
242
+
243
+ Ask your assistant to remember something and it makes these calls. A `semantic` or
244
+ `procedural` save without a `session_id` (or a `derived_from`) is refused by design: those
245
+ layers must name the conversation they came from.
246
+
247
+ That last one is the real test. Write from your laptop, read from your phone. If both see it,
248
+ the thing is doing its job.
249
+
250
+ ---
251
+
252
+ ## When it does not work
253
+
254
+ | Symptom | Cause |
255
+ |---|---|
256
+ | `MONGODB_URI is not set` | No `.env`, or the process was started without it. |
257
+ | `source tag "..." is not registered` | The tag is missing from `EMET_SOURCE_TAGS`. Add it, then restart. |
258
+ | `a source tag is required` on `emet_transcript_append` | Transcript appends always name their host: pass `source` (a registered tag) on the call. |
259
+ | `semantic entries must carry their source` | Open a session with `emet_session_open` and pass its `session_id` on the save. |
260
+ | `vector_index: not queryable on this deployment tier` | Normal on a local MongoDB or before the Atlas index exists; only `semantic_recall` needs it. |
261
+ | Connect times out | Your IP is not in Atlas Network Access, or the cluster is paused. |
262
+ | Auth fails | The password in the URI needs percent-encoding if it contains `@ : / ?` etc. |
263
+ | `semantic_recall` returns nothing, keyword search works | The vector index is missing or was dropped by a tier migration. |
264
+ | Writes land but another device cannot see them | The two hosts point at different `MONGODB_DB` values. |
265
+ | Entries all carry the same source | A server several hosts share has `EMET_SOURCE_TAG` set, so every write that passes no `source` gets that default, or two local entries use the same tag. Unset it on the shared server and have each host pass its own `source`. |
@@ -0,0 +1,59 @@
1
+ # When more than one bot uses EMET
2
+
3
+ One EMET. One owner login. If more than one bot or AI writes through that login, each bot that can keep a key file gets its own key. The server stamps the tag on the key. A bot does not get to name another bot's tag and have that stamp stick.
4
+
5
+ This is part of EMET. It is the same server, the same owner page, and the same keys. It is not a second product, and it is not a fork.
6
+
7
+ The Charter and the floor are unchanged. This supports ISO 9001:2015 clause 7.5.3 and ISO 13485:2016 clause 4.2.5 (identification of who changed a record, retention of records, nothing deleted), as the README and the Charter word it. EMET claims no certification. The organization validates EMET for its own use.
8
+
9
+ ## Turn it on
10
+
11
+ Say **initialize**. Your assistant asks whether more than one bot or AI will use this memory. Answer in your own words. Leaving it out is the same as no.
12
+
13
+ - **No.** Sub-keys stay off. That one client uses its own source tag. The tool list does not grow.
14
+ - **Yes, and this server reads a `.env` file.** Setup writes three settings into that file after your identity is saved: sub-keys on, a pepper the server generates, and version 1. You do not type the pepper, and it is not repeated. Restart (or redeploy) the server once. The tools and `/owner/approvals` appear together after that restart. They do not turn on in the server that is already running.
15
+ - **Yes, and the server takes its settings from the platform** (Railway or anything else that injects environment variables). Setup refuses before it saves anything. No pepper or .env was written. Run setup again without yes to finish the rest. Then set these in the platform's variables and redeploy:
16
+ 1. `EMET_SUBKEYS=1`
17
+ 2. `EMET_SUBKEY_PEPPER` — generate it yourself, at least 32 bytes, for example with `openssl rand -hex 32`
18
+ 3. `EMET_SUBKEY_PEPPER_VERSION=1`
19
+
20
+ Do not paste the pepper into the chat or into any EMET document.
21
+
22
+ A single client does not get this turned on. The page and the tools ship with EMET. They stay quiet until the answer is yes and the server has restarted with the flag on.
23
+
24
+ If this memory is already set up and you later add bots, say so. Your assistant turns sub-keys on only after you explicitly agree to run setup again. That writes a new version of your identity documents. The previous version is kept.
25
+
26
+ ## Approve a bot
27
+
28
+ List each bot's tag in `EMET_SOURCE_TAGS` before it asks for a key. An empty list refuses every request.
29
+
30
+ 1. Open `/owner/approvals` on the same host you already use for this memory. Enter the passphrase you already use when you connect a device. A correct passphrase opens a short session. A wrong one is counted with the other passphrase attempts.
31
+ 2. Each bot that can keep a key file asks for a key with its own tag.
32
+ 3. On the approvals page, approve that request. Deny applies only to a pending request.
33
+ 4. The bot claims the key within 24 hours. It keeps the key where the other bots cannot read it. The key is never written into EMET.
34
+
35
+ A bot then opens a session with that key and passes the session handle the server gives back on later writes in that session.
36
+
37
+ ## A key lasts 30 days
38
+
39
+ To renew a key, the bot asks again with the same tag, you approve it on the page, and the bot claims the new key within 24 hours. The previous key works for a few minutes while the bot switches, then it stops. Earlier writes stay as they were written.
40
+
41
+ ## Revoking your login
42
+
43
+ Revoking the owner login stops every sub-key. The keys hang off that login. They do not keep working after it is gone.
44
+
45
+ ## A phone, or a web project
46
+
47
+ A host that cannot store a key file does not take a sub-key. A phone, or a web project instance, uses the tag on its own connection.
48
+
49
+ ## Security
50
+
51
+ The pepper is a server secret. When this server reads `.env`, setup writes that file and does not put the pepper in the database, in a document, or in the answer it gives your assistant. An MCP call is what writes the file, and only on that kind of server. A hosted server does not get a pepper written into its container.
52
+
53
+ The approvals page uses the same passphrase as connecting a device, and a wrong passphrase counts toward the same lockout.
54
+
55
+ What a sub-key shows is that a write was made with a key you approved. If several bots can read each other's files, EMET cannot prove which program was holding the key. If you think an active key has leaked, revoke it from your own login (`emet_subkey_revoke`), then the bot requests a new key and you approve it on the page. Deny only applies to a pending request.
56
+
57
+ ## Building a bot team
58
+
59
+ For designing a team of bots, see Lauren Tan (@poteto, https://x.com/poteto), who works on Grok Bot and describes choosing a bot topology (one generalist, several narrow specialists, or generalists each owning a project) in [this post](https://x.com/poteto/status/2109781899610874002). Her bot designer, [dr eggbot](https://x.ai/bot/93gOz3op1UQdBdbekQFLK) ([source](https://x.com/poteto/status/2106895160298852470)), helped design the EMET author's own bot team.
@@ -0,0 +1,12 @@
1
+ {
2
+ "sha256:c9f58a0ef18f7468b9618d0f1e96ddd8c50845243e098e84480908ca8cb0a528": {
3
+ "gem": "fieldnote",
4
+ "rune": "fieldnote",
5
+ "version": "1.0.0"
6
+ },
7
+ "sha256:cfb62b669f67c69f53989ed2621a40bfbfa60a744f1b4040e5b8496755598a35": {
8
+ "gem": "fieldnote",
9
+ "rune": "fieldnote",
10
+ "version": "1.0.1"
11
+ }
12
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "sections": {
3
+ "bot_team_backup": {
4
+ "title": "Bot-team backup",
5
+ "note": "Optional. Off unless the recorded setup answer is yes. This floor does not copy documents by itself.",
6
+ "lines": {
7
+ "follow_the_recipe": "When bootstrap/USER.md records bot-team backup as yes, follow guides/BOT_TEAM_BACKUP.md. Write each bot's name, prompt, settings, routines and skills to bot-team/<bot>.md. Revise a document only when it changed. Supersede; do not delete.",
8
+ "no_secrets": "Never store secret values, tokens, passwords or card data in a bot-team document. Connectors, logins and secrets are reconnected by hand. Name those items in bot-team/RECOVERY.md. Do not write the values."
9
+ }
10
+ }
11
+ },
12
+ "reassertion": [
13
+ "Bot-team backup stores no secret values."
14
+ ]
15
+ }
@@ -0,0 +1,43 @@
1
+ {
2
+ "spec": "2026-10-12",
3
+ "id": "bot-team-backup",
4
+ "name": "Bot-team backup",
5
+ "description": "Optional recipe for writing each bot's name, prompt, settings, routines and skills as controlled documents. Off unless the recorded setup answer is yes. Does not store tokens, passwords or card data.",
6
+ "version": "1.0.0",
7
+ "kind": "gem",
8
+ "requires": {
9
+ "emet": ">=0.2.6"
10
+ },
11
+ "priority": 10,
12
+ "defaultOn": false,
13
+ "released": true,
14
+ "overrides": [],
15
+ "distribution": "bundled",
16
+ "floor": "floor.json",
17
+ "guides": [
18
+ "guides/BOT_TEAM_BACKUP.md",
19
+ "guides/BOT_TEAM_RECOVERY.md"
20
+ ],
21
+ "runes": [],
22
+ "files": [
23
+ {
24
+ "path": "floor.json",
25
+ "digest": "sha256:7182ec1d78bed4234c9a309bd03b4ca4099fa3b031e6b743d554378862230862",
26
+ "size": 802
27
+ },
28
+ {
29
+ "path": "guides/BOT_TEAM_BACKUP.md",
30
+ "digest": "sha256:aa912c28c08745e4cde13d156488af94a74745573e7d184a10007ee453de2d12",
31
+ "size": 1384
32
+ },
33
+ {
34
+ "path": "guides/BOT_TEAM_RECOVERY.md",
35
+ "digest": "sha256:8fbccbc7985c2e1696c42293c73c1257e2fbf9548717b19a8086306b2ed0db0e",
36
+ "size": 1305
37
+ }
38
+ ],
39
+ "authors": [
40
+ "Dreamforge Studio LLC"
41
+ ],
42
+ "license": "MIT"
43
+ }
@@ -0,0 +1,27 @@
1
+ # Bot-team backup
2
+
3
+ Optional. Off unless the first-run answer recorded in `bootstrap/USER.md` under BOT-TEAM BACKUP is `yes`. Yes is the recommended choice. Leaving the question out records `no`.
4
+
5
+ EMET does not run this recipe. The assistant does, and only after that recorded yes.
6
+
7
+ ## What to write
8
+
9
+ For each bot the install uses, keep one controlled document at `bot-team/<bot>.md`. Use the bot's own tag as `<bot>`, the same tag its writes already carry. The document holds:
10
+
11
+ - the bot's name
12
+ - the prompt it runs with
13
+ - the settings that are not secret
14
+ - the routines it follows
15
+ - the skills it uses
16
+
17
+ Write the document through the normal document tools. A later change is a new revision of the same id. Do not delete the previous copy. If nothing changed since the last revision, do not write again.
18
+
19
+ Check on a steady cadence the install chooses, such as at session close, and only write when the text would differ.
20
+
21
+ ## What never goes in
22
+
23
+ Never store secret values, tokens, passwords or card data. Not in `bot-team/<bot>.md`, not in `bot-team/RECOVERY.md`, and not in any other bot-team document. A name of a connector or a login is not a secret. The value behind it is.
24
+
25
+ ## Recovery
26
+
27
+ Keep the rebuild order in `bot-team/RECOVERY.md`, filled from `guides/BOT_TEAM_RECOVERY.md`. That document lists what a person must reconnect by hand. It does not store the secrets themselves.
@@ -0,0 +1,23 @@
1
+ # Bot-team recovery
2
+
3
+ Copy this into the store as `bot-team/RECOVERY.md` when bot-team backup is on. Revise it when the rebuild order changes. Supersede; do not delete.
4
+
5
+ Never store secret values, tokens, passwords or card data here. Name the item that has to be reconnected. Leave the value out.
6
+
7
+ ## Rebuild order
8
+
9
+ 1. Restore the memory server and its database from the operator's own backup of that service.
10
+ 2. Read `bot-team/<bot>.md` for each bot and put back that bot's name, prompt, settings, routines and skills.
11
+ 3. Reconnect, by hand, every item in the list below. The documents do not contain what those items need in order to authenticate.
12
+
13
+ ## Reconnect by hand
14
+
15
+ | Item | Where it lives | What the person does |
16
+ |---|---|---|
17
+ | Connectors | The host's connector settings | Connect each one again. The document may name the connector. It must not hold a key. |
18
+ | Logins | The host account for each bot | Sign in again. The document may name the account. It must not hold a password. |
19
+ | Secrets | The host's secret store | Put each secret back from the place the operator keeps secrets. This document names the slot, not the value. |
20
+
21
+ ## Rule
22
+
23
+ If a value is a token, a password, a card number, or any other secret, it does not belong in EMET. Record that the item must be reconnected. Stop there.
@@ -0,0 +1,14 @@
1
+ {
2
+ "sections": {
3
+ "field_notes": {
4
+ "title": "Field notes",
5
+ "note": "A count of the working layer is a note about what is already stored. It does not add a store.",
6
+ "lines": {
7
+ "count_only": "Report the count. The count is not a list, and it is not a new record."
8
+ }
9
+ }
10
+ },
11
+ "reassertion": [
12
+ "The working layer is memory, and a count is not a new store."
13
+ ]
14
+ }
@@ -0,0 +1,70 @@
1
+ {
2
+ "spec": "2026-10-12",
3
+ "id": "fieldnote",
4
+ "name": "Fieldnote",
5
+ "description": "A reference RUNED directive. Counts rows the caller passes in. Off unless the install asks for it.",
6
+ "version": "1.0.1",
7
+ "kind": "runed-gem",
8
+ "requires": {
9
+ "emet": ">=0.2.4"
10
+ },
11
+ "priority": 40,
12
+ "defaultOn": false,
13
+ "overrides": [],
14
+ "distribution": "bundled",
15
+ "floor": "floor.json",
16
+ "guides": [],
17
+ "runes": [
18
+ {
19
+ "name": "fieldnote",
20
+ "description": "Count the rows the caller passes in. A call returns this code and does not run it.",
21
+ "execution": "client",
22
+ "artifact": "runes/fieldnote.js",
23
+ "sha256": "sha256:cfb62b669f67c69f53989ed2621a40bfbfa60a744f1b4040e5b8496755598a35",
24
+ "version": "1.0.1",
25
+ "runtime": "node",
26
+ "inputSchema": {
27
+ "type": "object",
28
+ "properties": {
29
+ "rows": {
30
+ "type": "array",
31
+ "description": "Working-layer rows the caller already read."
32
+ }
33
+ }
34
+ },
35
+ "outputSchema": {
36
+ "type": "object",
37
+ "properties": {
38
+ "count": {
39
+ "type": "integer"
40
+ }
41
+ }
42
+ },
43
+ "annotations": {
44
+ "readOnlyHint": true,
45
+ "destructiveHint": false,
46
+ "idempotentHint": true,
47
+ "openWorldHint": false
48
+ },
49
+ "reads": [],
50
+ "writes": [],
51
+ "network": "none"
52
+ }
53
+ ],
54
+ "files": [
55
+ {
56
+ "path": "floor.json",
57
+ "digest": "sha256:11af3724b165beb3e9a49a681f1f07cb742bcb4535206f714a0dc689067f32d6",
58
+ "size": 403
59
+ },
60
+ {
61
+ "path": "runes/fieldnote.js",
62
+ "digest": "sha256:cfb62b669f67c69f53989ed2621a40bfbfa60a744f1b4040e5b8496755598a35",
63
+ "size": 147
64
+ }
65
+ ],
66
+ "authors": [
67
+ "Dreamforge Studio LLC"
68
+ ],
69
+ "license": "MIT"
70
+ }
@@ -0,0 +1,4 @@
1
+ export default function fieldnote(input) {
2
+ const rows = input && Array.isArray(input.rows) ? input.rows : [];
3
+ return { count: rows.length };
4
+ }
@@ -0,0 +1,10 @@
1
+ # Changelog
2
+
3
+ ## 0.9.0
4
+ date: 2026-10-20
5
+ class: initial
6
+ what changed and why: Pre-release 0.9.0. requires.emet is >=0.2.6. Rune files are unchanged.
7
+ init time: before none, after unmeasured
8
+ test time: before none, after unmeasured
9
+ log noise: before none, after unmeasured
10
+ byte cost: before none, after 1790
@@ -0,0 +1,92 @@
1
+ DMAIC and DMADV guidance, blank templates, and formulas with worked examples for hand calculation. Capability calculator. DPMO and yield calculator. Control limit calculator. Sample size calculator. Basic statistics calculator. Off unless the user asks.
2
+
3
+ DMAIC and DMADV guidance, blank templates, and formulas with worked examples for hand calculation.
4
+ Define phase steps
5
+ Measure phase steps
6
+ Analyze phase steps
7
+ Improve phase steps
8
+ Control phase steps
9
+ Define tollgate
10
+ Measure tollgate
11
+ Analyze tollgate
12
+ Improve tollgate
13
+ Control tollgate
14
+ DMADV and DFSS note for a new design
15
+ DMADV Define tollgate
16
+ DMADV Measure tollgate
17
+ DMADV Analyze tollgate
18
+ DMADV Design tollgate
19
+ DMADV Verify tollgate
20
+ Wastes walk
21
+ 5S
22
+ Value stream map
23
+ Flow
24
+ Pull
25
+ Kaizen
26
+ SMED
27
+ Poka-yoke
28
+ Project charter template
29
+ SIPOC template
30
+ VOC and CTQ tree template
31
+ Data collection plan template
32
+ MSA and Gage R&R plan template
33
+ Fishbone template
34
+ Five Whys template
35
+ FMEA template
36
+ Hypothesis test selection guide
37
+ DOE planning template
38
+ Control plan template
39
+ Response plan template
40
+ A3 template
41
+ Tollgate checklists
42
+ Financial benefits worksheet
43
+ DPMO and DPO worked example
44
+ Opportunity yield worked example
45
+ First pass yield worked example
46
+ Rolled throughput yield worked example
47
+ Sigma level convention and the hand DPMO path
48
+ Cp worked example
49
+ Cpu worked example
50
+ Cpl worked example
51
+ Cpk worked example
52
+ Pp worked example
53
+ Ppk worked example
54
+ Sigma from average range worked example
55
+ X-bar and R limits worked example
56
+ Individuals and moving range limits worked example
57
+ p chart limits worked example
58
+ np chart limits worked example
59
+ c chart limits worked example
60
+ u chart limits worked example
61
+ Sample size for a proportion worked example
62
+ Sample size for a mean worked example
63
+ Known-sigma confidence interval worked example
64
+ Confidence interval with a caller-supplied t worked example
65
+ One-sample t statistic worked example
66
+ Chi-square goodness of fit worked example
67
+ One-way ANOVA worked example
68
+ Simple linear regression worked example
69
+ Takt time worked example
70
+ OEE worked example
71
+ Little's Law worked example
72
+ FMEA RPN worked example
73
+ Yellow Belt scope
74
+ Green Belt scope
75
+ Black Belt scope
76
+ Coaching questions
77
+ Statistical assumption flags
78
+ Work one DMAIC phase at a time
79
+ Keep an unanswered tollgate item open
80
+ Ask for data and leave a blank field blank
81
+ Report a number the user supplied and leave every other numeric claim unstated
82
+ Name statistical assumptions that were not checked
83
+ Ask the belt for this project and do not certify one
84
+ Open the DMADV note when the work is a new design
85
+ Keep project data in this install
86
+ Write a project document only when the user asks to save it
87
+ Leave the memory layers unread and unwritten for this project
88
+ Capability calculator
89
+ DPMO and yield calculator
90
+ Control limit calculator
91
+ Sample size calculator
92
+ Basic statistics calculator