@tpsdev-ai/flair 0.21.0 → 0.22.1

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 (74) hide show
  1. package/README.md +10 -7
  2. package/SECURITY.md +24 -2
  3. package/config.yaml +32 -5
  4. package/dist/cli.js +1811 -221
  5. package/dist/deploy.js +3 -4
  6. package/dist/fleet-presence.js +98 -0
  7. package/dist/fleet-verify.js +291 -0
  8. package/dist/mcp-client-assertion.js +364 -0
  9. package/dist/probe.js +97 -0
  10. package/dist/rem/runner.js +82 -12
  11. package/dist/resources/AttentionQuery.js +356 -0
  12. package/dist/resources/Credential.js +11 -1
  13. package/dist/resources/Federation.js +23 -0
  14. package/dist/resources/MCPClientMetadata.js +88 -0
  15. package/dist/resources/Memory.js +52 -53
  16. package/dist/resources/MemoryBootstrap.js +422 -76
  17. package/dist/resources/MemoryReflect.js +105 -49
  18. package/dist/resources/MemoryUsage.js +104 -0
  19. package/dist/resources/OAuth.js +8 -1
  20. package/dist/resources/OrgEvent.js +11 -0
  21. package/dist/resources/Presence.js +218 -19
  22. package/dist/resources/RecordUsage.js +230 -0
  23. package/dist/resources/Relationship.js +98 -25
  24. package/dist/resources/SemanticSearch.js +85 -317
  25. package/dist/resources/SkillScan.js +15 -0
  26. package/dist/resources/WorkspaceState.js +11 -0
  27. package/dist/resources/agent-auth.js +60 -2
  28. package/dist/resources/auth-middleware.js +18 -9
  29. package/dist/resources/bm25.js +12 -6
  30. package/dist/resources/collision-lib.js +157 -0
  31. package/dist/resources/embeddings-boot.js +149 -0
  32. package/dist/resources/embeddings-provider.js +364 -106
  33. package/dist/resources/entity-vocab.js +139 -0
  34. package/dist/resources/health.js +97 -6
  35. package/dist/resources/mcp-client-metadata-fields.js +112 -0
  36. package/dist/resources/mcp-handler.js +1 -1
  37. package/dist/resources/mcp-tools.js +88 -10
  38. package/dist/resources/memory-reflect-lib.js +289 -0
  39. package/dist/resources/migration-boot.js +143 -0
  40. package/dist/resources/migrations/dir-safety.js +71 -0
  41. package/dist/resources/migrations/embedding-stamp.js +178 -0
  42. package/dist/resources/migrations/envelope.js +43 -0
  43. package/dist/resources/migrations/export.js +38 -0
  44. package/dist/resources/migrations/ledger.js +55 -0
  45. package/dist/resources/migrations/lock.js +154 -0
  46. package/dist/resources/migrations/progress.js +31 -0
  47. package/dist/resources/migrations/registry.js +36 -0
  48. package/dist/resources/migrations/risk-policy.js +23 -0
  49. package/dist/resources/migrations/runner.js +455 -0
  50. package/dist/resources/migrations/snapshot.js +127 -0
  51. package/dist/resources/migrations/source-fields.js +93 -0
  52. package/dist/resources/migrations/space.js +167 -0
  53. package/dist/resources/migrations/state.js +64 -0
  54. package/dist/resources/migrations/status.js +39 -0
  55. package/dist/resources/migrations/synthetic-test-migration.js +93 -0
  56. package/dist/resources/migrations/types.js +9 -0
  57. package/dist/resources/presence-internal.js +29 -0
  58. package/dist/resources/provenance.js +50 -0
  59. package/dist/resources/rate-limiter.js +8 -1
  60. package/dist/resources/scoring.js +124 -5
  61. package/dist/resources/semantic-retrieval-core.js +317 -0
  62. package/dist/version-handshake.js +122 -0
  63. package/package.json +4 -5
  64. package/schemas/event.graphql +5 -0
  65. package/schemas/memory.graphql +66 -0
  66. package/schemas/schema.graphql +5 -43
  67. package/schemas/workspace.graphql +3 -0
  68. package/dist/resources/IngestEvents.js +0 -162
  69. package/dist/resources/IssueTokens.js +0 -19
  70. package/dist/resources/ObsAgentSnapshot.js +0 -13
  71. package/dist/resources/ObsEventFeed.js +0 -13
  72. package/dist/resources/ObsOffice.js +0 -19
  73. package/dist/resources/ObservationCenter.js +0 -23
  74. package/ui/observation-center.html +0 -385
package/README.md CHANGED
@@ -67,13 +67,13 @@ If you need any of those specifically, use them. If you need crypto-pinned ident
67
67
 
68
68
  Anthropic shipped [Claude Dreams](https://platform.claude.com/docs/en/managed-agents/dreams) (research preview, April 2026) — async pipeline that reads a memory store + session transcripts and produces a curated output store: duplicates merged, stale entries replaced, insights surfaced. Validates the category: agent memory accumulates drift and needs cleanup.
69
69
 
70
- Flair ships both the on-demand curation surface (`flair rem rapid`) AND the scheduled nightly cycle in v0.9.0, per the [FLAIR-NIGHTLY-REM spec](specs/FLAIR-NIGHTLY-REM.md).
70
+ Flair ships both the on-demand curation surface (`flair rem rapid`) AND the scheduled nightly cycle, per the [FLAIR-NIGHTLY-REM spec](specs/FLAIR-NIGHTLY-REM.md) and its [in-process distillation slice](specs/FLAIR-NIGHTLY-REM-SLICE-2-DISTILLATION.md). Config recipe (Ollama zero-key default, hosted-provider egress warning, clustered-deploy rules): [`docs/rem.md`](docs/rem.md).
71
71
 
72
- - **`flair rem rapid`** — on-demand reflection. `--focus {lessons_learned, patterns, decisions, errors}` mirrors Dreams' `instructions` parameter. Outputs *candidates*, not a wholesale store swap.
72
+ - **`flair rem rapid`** — reflects and distills server-side by default, staging candidates in one bounded call. `--focus {lessons_learned, patterns, decisions, errors}` mirrors Dreams' `instructions` parameter. `--prompt-only` falls back to the bring-your-own-model handoff. Outputs *candidates*, not a wholesale store swap.
73
73
  - **`flair rem candidates` / `flair rem promote <id> --rationale "<why>"` / `flair rem reject <id>`** — review and promote distilled candidates with required rationale.
74
- - **`flair rem nightly enable [--at HH:MM]`** — scheduled automation via platform-native scheduler (launchd / systemd). Pre-cycle snapshot to `~/.flair/snapshots/<agent>/<iso>.tar.gz`. Maintenance step (soft-delete expired + soft-archive stale). Audit log to `~/.flair/logs/rem-nightly.jsonl`. `flair rem pause` / `resume` for emergency stop.
74
+ - **`flair rem nightly enable [--at HH:MM]`** — scheduled automation via platform-native scheduler (launchd / systemd). Pre-cycle snapshot to `~/.flair/snapshots/<agent>/<iso>.tar.gz`. Maintenance (soft-delete expired + soft-archive stale) and distillation (staged candidates) both run each cycle. Audit log to `~/.flair/logs/rem-nightly.jsonl`. `flair rem pause` / `resume` for emergency stop.
75
75
  - **`flair rem restore <date> --apply`** — rewinds Harper state to a snapshot. Takes a pre-restore snapshot of current state first, so the rewind itself is reversible.
76
- - *Slice-3 (1.1)* — automated server-side distillation (requires pluggable LLM provider), trust-tier filter on REM input, cross-agent restore. Until then, distillation is operator-triggered via `flair rem rapid` followed by manual promote/reject.
76
+ - *Next* — trust-tier filter on REM input, cross-agent restore. Until the trust-tier arc lands, the input filter stays scope-based (own agent, non-archived, non-permanent, scope window); the structural safety net is unchanged either way — candidates are staged, never auto-promoted.
77
77
 
78
78
  The substantive difference is the **promotion contract**:
79
79
 
@@ -94,7 +94,7 @@ An agent that can't remember what it learned yesterday, can't prove who it is to
94
94
 
95
95
  Flair fixes that with three primitives:
96
96
 
97
- - **Identity** — Ed25519 key pairs. Agents sign every request. No passwords, no API keys, no shared secrets. Cross-agent reads are refused at the server, not by client convention.
97
+ - **Identity** — Ed25519 key pairs. Agents sign every request. No passwords, no API keys, no shared secrets. Write isolation (no agent can write as another) is enforced at the server, not by client convention; reads are open within the org for non-private memories by design (see [SECURITY.md](SECURITY.md)).
98
98
  - **Memory** — Persistent knowledge with semantic search (in-process [nomic-embed-text](https://huggingface.co/nomic-ai/nomic-embed-text-v1.5-GGUF), 768-dim, no API calls). Tiered durability (`permanent` / `persistent` / `standard` / `ephemeral`). Temporal validity. Decay-and-retrieval-aware composite scoring.
99
99
  - **Soul** — Personality, values, procedures. The stuff that makes an agent *that agent*. Re-injected every turn via the context-engine plugin so it doesn't drift across long sessions.
100
100
 
@@ -177,6 +177,9 @@ Passive extraction of entities from memory content on write. Entities are indexe
177
177
  ### Memory Bridges
178
178
  Pluggable import/export to foreign memory systems. Every agent-memory format (agentic-stack, Mem0, Letta, Anthropic memory, the next viral one) shouldn't need its own Flair PR. Bridges give you one contract with two shapes — a YAML descriptor for file-format targets or a code plugin for API targets — and a scaffold/test loop that lets an agent ship a working adapter in one pass. See [docs/bridges.md](docs/bridges.md).
179
179
 
180
+ ### Embedding benchmarks (`flair-bench`)
181
+ A standalone benchmark you can run anywhere — no Flair install, no server, just Node and a GGUF file. It ships the same 126-query recall corpus and scoring Flair's own CI gates on, so its numbers are directly comparable: benchmark candidate embedding models (`--model-file`, batchable), get a model recommendation for the host you're on backed by the numbers it just measured (`recommend`), and optionally save a redacted, shareable result (`--share`) — including a `--label` for tagging host classes when characterizing fleet hardware. See [packages/flair-bench](packages/flair-bench/README.md).
182
+
180
183
  ## Quick Start
181
184
 
182
185
  ### Prerequisites
@@ -409,9 +412,9 @@ Auth is Ed25519 — sign `agentId:timestamp:nonce:METHOD:/path` with your privat
409
412
 
410
413
  ### Auth across surfaces
411
414
 
412
- The default, secure path everywhere is **Ed25519 per-agent**: each agent holds its own key (`~/.flair/keys/<agent>.key`), signs every request, and the server refuses cross-agent reads. The CLI, the `flair-mcp` server, and the OpenClaw / pi / Hermes plugins all use it.
415
+ The default, secure path everywhere is **Ed25519 per-agent**: each agent holds its own key (`~/.flair/keys/<agent>.key`) and signs every request. That guarantees write isolation (no agent can write as another) and identity-verified reads it does **not** mean cross-agent reads are refused: within one Flair instance, any verified agent can read any other agent's non-private memory by design (open-within-org read; the hard boundary is the federation edge, not intra-instance reads — see [SECURITY.md](SECURITY.md)). The CLI, the `flair-mcp` server, and the OpenClaw / pi / Hermes plugins all use this model.
413
416
 
414
- One exception: the **`n8n-nodes-flair`** community node authenticates with the Harper **admin password** (Basic auth), which grants **whole-instance read/write** access — not per-agent isolation. That's acceptable only on a single-tenant, operator-controlled n8n with trusted workflow inputs; otherwise prefer the CLI/SDK Ed25519 path. Full breakdown in **[docs/auth.md](docs/auth.md#auth-across-surfaces-read-this-first)**.
417
+ One exception: the **`n8n-nodes-flair`** community node authenticates with the Harper **admin password** (Basic auth), which bypasses agent scoping entirelyincluding read of other agents' `visibility: private` memories and write-as-anyone, not just the org-wide non-private reads an Ed25519 identity already gets. That's acceptable only on a single-tenant, operator-controlled n8n with trusted workflow inputs; otherwise prefer the CLI/SDK Ed25519 path. Full breakdown in **[docs/auth.md](docs/auth.md#auth-across-surfaces-read-this-first)**.
415
418
 
416
419
  ## Architecture
417
420
 
package/SECURITY.md CHANGED
@@ -34,8 +34,23 @@ built-in HTTP Basic auth:
34
34
  Authorization: Basic <base64(admin:password)>
35
35
  ```
36
36
 
37
- The admin password is set via `HDB_ADMIN_PASSWORD` environment variable
38
- at Harper startup. **It is never stored on the filesystem by Flair.**
37
+ The admin password is generated on `flair init` and stored at
38
+ `~/.flair/admin-pass` (mode `0600`, owner-only) it can also be set
39
+ explicitly via `--admin-pass-file`, `FLAIR_ADMIN_PASS`, or
40
+ `HDB_ADMIN_PASSWORD`. It is never printed to the console. See
41
+ [docs/secrets-and-keys.md](docs/secrets-and-keys.md) for the full
42
+ precedence and rotation model.
43
+
44
+ The Harper **operations API** is the admin/management surface. Network
45
+ requests to it require admin Basic auth: Flair ships with
46
+ `authorizeLocal: false`, so an unauthenticated loopback request is
47
+ rejected (`401`) instead of being auto-elevated to super_user. The same
48
+ API is also reachable over a Unix **domain socket**
49
+ (`~/.flair/data/operations-server`, owner-write-only), which Harper
50
+ treats as an inherent local-admin channel — a request over the socket is
51
+ authorized as super_user **without** credentials. This is by design (the
52
+ admin-password rotation flow relies on it) and is constrained to the box
53
+ owner; see Threats NOT Mitigated below.
39
54
 
40
55
  ## Data Scoping
41
56
 
@@ -115,6 +130,13 @@ public key in Flair, and backs up the old key as `<agentId>.key.bak`.
115
130
  process could extract them.
116
131
  - **Network sniffing:** Flair uses HTTP by default. Use HTTPS in
117
132
  production or restrict to localhost.
133
+ - **Same-OS-user ops-API socket access:** the operations-API domain
134
+ socket (`operations-server`, owner-write-only) is an unauthenticated
135
+ super_user channel by Harper design — any process running as the box
136
+ owner can perform admin operations through it (the admin-password
137
+ rotation flow uses this path). Owner-write permissions keep it
138
+ unreachable by other OS users, co-tenants, and the network; isolate
139
+ untrusted workloads to separate OS users.
118
140
 
119
141
  ## Recommendations
120
142
 
package/config.yaml CHANGED
@@ -12,11 +12,38 @@ graphqlSchema:
12
12
  jsResource:
13
13
  files: dist/resources/*.js
14
14
 
15
- 'harper-fabric-embeddings':
16
- package: 'harper-fabric-embeddings'
17
- modelName: nomic-embed-text
15
+ # Phase 1 (flair#504): embeddings now run through Harper's native
16
+ # models.embed() facade, backed by harper-fabric-embeddings registered as the
17
+ # `embedding` backend. That registration is NOT configured here, and (as of
18
+ # flair#694) is no longer config-driven anywhere: a `models:` block in THIS
19
+ # file would silently never be read (this application always loads with
20
+ # `isRoot: false` — components/componentLoader.ts gates `bootstrapModels()`
21
+ # on `isRoot`), and the earlier fix for that — reasserting the block into the
22
+ # Harper INSTANCE-ROOT config via the HARPER_CONFIG env var on every spawn —
23
+ # turned out to PERSIST that block into harper-config.yaml, which an
24
+ # older/downgraded build's boot (never having set the env var) would tear
25
+ # down to an invalid empty shell and refuse to boot against (flair#694; see
26
+ # flair#695 for the invariant this violated). The registration now happens
27
+ # in-process instead: `dist/resources/embeddings-boot.js` (built from
28
+ # resources/embeddings-boot.ts, loaded by the `jsResource` glob below like
29
+ # every other file under resources/) calls harper-fabric-embeddings'
30
+ # `register()` factory directly on every boot — nothing is ever written to
31
+ # the config file, so there is nothing for a downgrade to trip over. This
32
+ # also means a `package:`-style sub-component entry
33
+ # (`'harper-fabric-embeddings': { package: ... }`, which used to sit here and
34
+ # drove `handleApplication`) still must not be reintroduced alongside it —
35
+ # that hook populates a SEPARATE raw-API engine, not `models.embed()`, and
36
+ # running both would double-init (two separate EmbeddingEngine instances:
37
+ # one unused, one backing models.embed).
18
38
 
19
39
  authentication:
20
- # Default secure. Set to false for local development only.
21
- authorizeLocal: true
40
+ # Default secure (flair#654): a credential-less loopback request to the
41
+ # Harper ops API (:9925) is no longer auto-authorized as super_user. Local
42
+ # admin operations now require a real credential — ~/.flair/admin-pass
43
+ # (written by `flair init`), --admin-pass, or FLAIR_ADMIN_PASS. flair's own
44
+ # application-layer resources were already immune to this forgery (#655's
45
+ # credential-evidence gate); this closes the remaining gap below it, in the
46
+ # raw Harper ops API itself. Set true only for local development, at your
47
+ # own risk.
48
+ authorizeLocal: false
22
49
  enableSessions: true