@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.
- package/.env.example +189 -0
- package/CHANGELOG.md +360 -0
- package/CHARTER.md +137 -0
- package/LICENSE +22 -0
- package/README.md +868 -2
- package/docs/AUTHORSHIP.md +26 -0
- package/docs/BENCHMARKS.md +261 -0
- package/docs/BOOTSTRAP.md +127 -0
- package/docs/BOTS.md +83 -0
- package/docs/COVERAGE.md +64 -0
- package/docs/DEPLOY.md +251 -0
- package/docs/DISCIPLINES.md +29 -0
- package/docs/GUARDRAILS-AND-MONORAILS.md +108 -0
- package/docs/GUIDED-SETUP.md +301 -0
- package/docs/PERMISSIONS.md +121 -0
- package/docs/ROADMAP.md +62 -0
- package/docs/SETUP.md +265 -0
- 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/gems/neurendipity/guides/NEURODIVERGENT_SUPPORT.md +287 -0
- package/guides/README.md +3 -0
- package/package.json +76 -4
- package/server.json +79 -0
- package/src/aleph.js +395 -0
- package/src/annotations.js +170 -0
- package/src/approve-throttle.js +54 -0
- package/src/atlas-role.js +58 -0
- package/src/attribution.js +555 -0
- package/src/conformance.js +688 -0
- package/src/content_analyzer.js +450 -0
- package/src/database.js +812 -0
- package/src/disciplines.js +26 -0
- package/src/dispatch.js +382 -0
- package/src/env.js +97 -0
- package/src/floor.js +228 -0
- package/src/gaps.js +509 -0
- package/src/gem-check.js +1359 -0
- package/src/guides.js +75 -0
- package/src/host-reach.js +23 -0
- package/src/http-remote.js +313 -0
- package/src/index.js +397 -0
- package/src/invites.js +167 -0
- package/src/layers.js +449 -0
- package/src/lessons-to-checks.js +366 -0
- package/src/logger.js +300 -0
- package/src/metadata.js +61 -0
- package/src/module-path.js +32 -0
- package/src/mongo-connect.js +91 -0
- package/src/named-items.js +208 -0
- package/src/oauth-provider.js +838 -0
- package/src/owner-approvals.js +281 -0
- package/src/persons.js +136 -0
- package/src/provenance.js +257 -0
- package/src/redact.js +237 -0
- package/src/request-log.js +124 -0
- 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 +100 -0
- package/src/security-headers.js +26 -0
- package/src/session-graph.js +947 -0
- package/src/session.js +1097 -0
- package/src/setup.js +1580 -0
- package/src/socket.js +545 -0
- package/src/startup-pages.js +371 -0
- package/src/startup-payload.js +129 -0
- package/src/subkey-store.js +357 -0
- package/src/subkeys.js +947 -0
- package/src/tools.js +4508 -0
- package/src/transcript-session.js +106 -0
- package/src/validation.js +1187 -0
- package/src/version.js +2 -0
- package/templates/BOARD.md +72 -0
- package/templates/BOTHANDOFF.md +57 -0
- package/templates/CHARACTER.md +30 -0
- package/templates/HANDOFF.md +63 -0
- package/templates/IDENTITY.md +29 -0
- package/templates/INDEX.md +82 -0
- package/templates/INSTALL.md +29 -0
- package/templates/PROCEDURE.md +39 -0
- package/templates/ROSTER.md +43 -0
- package/templates/SEED.md +65 -0
- package/templates/STAGING.md +37 -0
- package/templates/STANDARD.md +99 -0
- package/templates/THREAD.md +43 -0
- package/templates/USER.md +32 -0
- package/verification/load-gate/corpus.json +1765 -0
- 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`. |
|
package/docs/SUBKEYS.md
ADDED
|
@@ -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,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
|