@tpsdev-ai/flair 0.20.1 → 0.22.0

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 (104) hide show
  1. package/README.md +39 -11
  2. package/SECURITY.md +52 -20
  3. package/config.yaml +32 -5
  4. package/dist/cli.js +2235 -260
  5. package/dist/deploy.js +96 -15
  6. package/dist/doctor-client.js +312 -0
  7. package/dist/fleet-presence.js +98 -0
  8. package/dist/fleet-verify.js +291 -0
  9. package/dist/install/clients.js +18 -0
  10. package/dist/mcp-client-assertion.js +364 -0
  11. package/dist/probe.js +97 -0
  12. package/dist/rem/restore.js +1 -1
  13. package/dist/rem/runner.js +82 -12
  14. package/dist/resources/Admin.js +1 -1
  15. package/dist/resources/AdminConnectors.js +1 -1
  16. package/dist/resources/AdminDashboard.js +1 -1
  17. package/dist/resources/AdminIdp.js +1 -1
  18. package/dist/resources/AdminInstance.js +1 -1
  19. package/dist/resources/AdminMemory.js +2 -2
  20. package/dist/resources/AdminPrincipals.js +1 -1
  21. package/dist/resources/Agent.js +14 -0
  22. package/dist/resources/AgentCard.js +1 -1
  23. package/dist/resources/AgentSeed.js +1 -1
  24. package/dist/resources/AttentionQuery.js +356 -0
  25. package/dist/resources/Credential.js +11 -1
  26. package/dist/resources/Federation.js +121 -2
  27. package/dist/resources/Integration.js +1 -1
  28. package/dist/resources/MCPClientMetadata.js +88 -0
  29. package/dist/resources/Memory.js +127 -22
  30. package/dist/resources/MemoryBootstrap.js +441 -85
  31. package/dist/resources/MemoryGrant.js +1 -1
  32. package/dist/resources/MemoryReflect.js +105 -49
  33. package/dist/resources/MemoryUsage.js +104 -0
  34. package/dist/resources/OAuth.js +69 -5
  35. package/dist/resources/OrgEvent.js +11 -0
  36. package/dist/resources/OrgEventCatchup.js +1 -1
  37. package/dist/resources/Presence.js +268 -17
  38. package/dist/resources/RecordUsage.js +230 -0
  39. package/dist/resources/Relationship.js +108 -26
  40. package/dist/resources/SemanticSearch.js +88 -320
  41. package/dist/resources/SkillScan.js +15 -0
  42. package/dist/resources/Soul.js +14 -0
  43. package/dist/resources/WorkspaceLatest.js +1 -1
  44. package/dist/resources/WorkspaceState.js +12 -1
  45. package/dist/resources/agent-auth.js +61 -3
  46. package/dist/resources/agentcard-fields.js +2 -2
  47. package/dist/resources/auth-middleware.js +42 -14
  48. package/dist/resources/bm25-filter.js +1 -1
  49. package/dist/resources/bm25.js +13 -7
  50. package/dist/resources/collision-lib.js +157 -0
  51. package/dist/resources/dedup.js +2 -2
  52. package/dist/resources/ed25519-auth.js +2 -2
  53. package/dist/resources/embeddings-boot.js +149 -0
  54. package/dist/resources/embeddings-provider.js +364 -106
  55. package/dist/resources/entity-vocab.js +139 -0
  56. package/dist/resources/federation-nonce-store.js +195 -0
  57. package/dist/resources/health.js +97 -6
  58. package/dist/resources/instance-identity.js +53 -0
  59. package/dist/resources/mcp-client-metadata-fields.js +112 -0
  60. package/dist/resources/mcp-handler.js +1 -1
  61. package/dist/resources/mcp-tools.js +88 -10
  62. package/dist/resources/memory-bootstrap-lib.js +1 -1
  63. package/dist/resources/memory-read-scope.js +58 -71
  64. package/dist/resources/memory-reflect-lib.js +289 -0
  65. package/dist/resources/memory-visibility.js +37 -0
  66. package/dist/resources/migration-boot.js +143 -0
  67. package/dist/resources/migrations/dir-safety.js +71 -0
  68. package/dist/resources/migrations/embedding-stamp.js +178 -0
  69. package/dist/resources/migrations/envelope.js +43 -0
  70. package/dist/resources/migrations/export.js +38 -0
  71. package/dist/resources/migrations/ledger.js +55 -0
  72. package/dist/resources/migrations/lock.js +154 -0
  73. package/dist/resources/migrations/progress.js +31 -0
  74. package/dist/resources/migrations/registry.js +36 -0
  75. package/dist/resources/migrations/risk-policy.js +23 -0
  76. package/dist/resources/migrations/runner.js +456 -0
  77. package/dist/resources/migrations/snapshot.js +127 -0
  78. package/dist/resources/migrations/source-fields.js +93 -0
  79. package/dist/resources/migrations/space.js +73 -0
  80. package/dist/resources/migrations/state.js +64 -0
  81. package/dist/resources/migrations/status.js +39 -0
  82. package/dist/resources/migrations/synthetic-test-migration.js +93 -0
  83. package/dist/resources/migrations/types.js +9 -0
  84. package/dist/resources/presence-internal.js +29 -0
  85. package/dist/resources/provenance.js +50 -0
  86. package/dist/resources/rate-limiter.js +8 -1
  87. package/dist/resources/scoring.js +124 -5
  88. package/dist/resources/semantic-retrieval-core.js +317 -0
  89. package/dist/version-check.js +167 -0
  90. package/dist/version-handshake.js +122 -0
  91. package/package.json +4 -5
  92. package/schemas/agent.graphql +7 -0
  93. package/schemas/event.graphql +5 -0
  94. package/schemas/federation.graphql +12 -0
  95. package/schemas/memory.graphql +82 -0
  96. package/schemas/schema.graphql +5 -43
  97. package/schemas/workspace.graphql +3 -0
  98. package/dist/resources/IngestEvents.js +0 -162
  99. package/dist/resources/IssueTokens.js +0 -19
  100. package/dist/resources/ObsAgentSnapshot.js +0 -13
  101. package/dist/resources/ObsEventFeed.js +0 -13
  102. package/dist/resources/ObsOffice.js +0 -19
  103. package/dist/resources/ObservationCenter.js +0 -23
  104. 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,12 +94,14 @@ 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
 
101
101
  Built on [Harper](https://harper.fast). Single process. No sidecars. Zero external API calls for embeddings. **[Supply-chain policy](docs/supply-chain-policy.md)** documents the bake-time + dep-pinning we run to keep this honest.
102
102
 
103
+ See **[DESIGN.md](DESIGN.md)** for the design invariants behind these three primitives — why they're shaped the way they are.
104
+
103
105
  ## How It Works
104
106
 
105
107
  Flair is a native [Harper v5](https://harper.fast) application. Harper handles HTTP, persistence (RocksDB), and application logic in a single process.
@@ -152,7 +154,7 @@ Entity-to-entity triples with temporal bounds. Model structured knowledge — "A
152
154
  Subscribe to memory or soul changes via WebSocket/SSE. Useful for dashboards, cross-agent sync, or audit trails.
153
155
 
154
156
  ### Multi-Agent
155
- One Flair instance serves any number of agents. Each agent has its own keys, memories, and soul. Agents can't read each other's data without explicit access grants.
157
+ One Flair instance serves any number of agents. Each agent has its own keys, memories, and soul. Reads are open within the org: any agent can read any other agent's non-private memory, no grant required — `private` is the one owner-only exception. See [DESIGN.md](DESIGN.md#access-model-open-within-the-org-closed-at-the-federation-edge) for the full model.
156
158
 
157
159
  ### OAuth 2.1 Authorization Server
158
160
  Built-in OAuth 2.1 server with PKCE, dynamic client registration, and a standards-compliant token endpoint. Agents and services can delegate auth to Flair without a separate IdP.
@@ -175,6 +177,9 @@ Passive extraction of entities from memory content on write. Entities are indexe
175
177
  ### Memory Bridges
176
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).
177
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
+
178
183
  ## Quick Start
179
184
 
180
185
  ### Prerequisites
@@ -238,6 +243,29 @@ flair uninstall # Remove the service (keeps data)
238
243
  flair uninstall --purge # Remove everything including data and keys
239
244
  ```
240
245
 
246
+ ### Upgrading
247
+
248
+ `flair status` and `flair doctor` both check your installed version against the latest published release (cached, offline-tolerant — this never blocks or fails either command) and print a nudge when you're behind:
249
+
250
+ ```
251
+ ⚠ flair 0.16.1 is behind — latest is 0.20.1 (4 releases behind). Upgrade: npm i -g @tpsdev-ai/flair@latest
252
+ ```
253
+
254
+ To upgrade:
255
+
256
+ ```bash
257
+ npm install -g @tpsdev-ai/flair@latest
258
+
259
+ # Or check what's outdated across the whole toolchain (flair, flair-mcp, the
260
+ # openclaw-flair plugin) without installing anything:
261
+ flair upgrade --check
262
+
263
+ # Then apply:
264
+ flair upgrade
265
+ ```
266
+
267
+ `flair upgrade` also restarts the running instance for you with `--restart`. If you deployed Flair to a Harper Fabric cluster (rather than running it locally), use `flair upgrade --target <fabric-url>` instead — see `flair upgrade --help`.
268
+
241
269
  ### Advanced / manual setup
242
270
 
243
271
  Prefer to drive each step yourself, or scripting an unattended setup? Run `flair init --no-mcp` to bootstrap the instance + agent without wiring any MCP clients, then drive each step on its own:
@@ -384,9 +412,9 @@ Auth is Ed25519 — sign `agentId:timestamp:nonce:METHOD:/path` with your privat
384
412
 
385
413
  ### Auth across surfaces
386
414
 
387
- 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.
388
416
 
389
- 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)**.
390
418
 
391
419
  ## Architecture
392
420
 
@@ -457,10 +485,10 @@ See [SECURITY.md](SECURITY.md) for the full security model, threat analysis, and
457
485
 
458
486
  **Key points:**
459
487
  - Ed25519 cryptographic identity — agents sign every request
460
- - Collection-level data isolationagents can't read each other's memories
488
+ - Reads are open within the org any agent can read any other agent's non-private memory, no grant required; `private` is the one owner-only exception (see [DESIGN.md](DESIGN.md))
461
489
  - Admin password auto-generated on init, stored at `~/.flair/admin-pass` (mode 0600)
462
490
  - Key rotation via `flair agent rotate-key`
463
- - Cross-agent access requires explicit grants
491
+ - Writes are always agent-scoped — an agent can only write its own records
464
492
 
465
493
  ## Development
466
494
 
@@ -479,7 +507,7 @@ Integration tests spin up a real Harper instance on a random port, run the test
479
507
  | Category | Tests | What's covered |
480
508
  |----------|-------|----------------|
481
509
  | **Auth & Identity** | auth-middleware, auth-scoping, key-paths-and-rotation | Ed25519 signature verification, agent isolation, key rotation |
482
- | **Memory** | data-scoping, backup-restore, agent-remove-and-grants | Cross-agent access denied, data durability, grant lifecycle |
510
+ | **Memory** | data-scoping, backup-restore, agent-remove-and-grants | Private-memory exclusion, open within-org read scoping, data durability, grant lifecycle |
483
511
  | **Content Safety** | content-safety | Prompt injection detection, identity hijacking, format injection, exfiltration patterns |
484
512
  | **Search** | temporal-scoring, embeddings | Temporal decay, relevance scoring, embedding generation |
485
513
  | **Rate Limiting** | rate-limiter | Per-agent rate limiting, bucket isolation |
package/SECURITY.md CHANGED
@@ -2,8 +2,10 @@
2
2
 
3
3
  ## Overview
4
4
 
5
- Flair uses cryptographic identity (Ed25519) for agent authentication and
6
- collection-level scoping to enforce data isolation between agents.
5
+ Flair uses cryptographic identity (Ed25519) for agent authentication. Within
6
+ an org, memory reads are open agents see each other's non-private memories —
7
+ while writes are isolated per agent and private memories stay strictly
8
+ owner-only. The hard access boundary is the federation edge (cross-instance).
7
9
 
8
10
  ## Authentication
9
11
 
@@ -32,30 +34,49 @@ built-in HTTP Basic auth:
32
34
  Authorization: Basic <base64(admin:password)>
33
35
  ```
34
36
 
35
- The admin password is set via `HDB_ADMIN_PASSWORD` environment variable
36
- 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.
37
54
 
38
55
  ## Data Scoping
39
56
 
40
- ### Memory Isolation
57
+ ### Memory Read/Write Model
41
58
 
42
- Each agent can only read and write its own memories. This is enforced at
43
- the database layer (Harper resource `search()` override), not application
44
- logic:
59
+ Reads are open **within an org**; writes are isolated per agent. Enforced at
60
+ the database layer (Harper resource `search()` override via a single
61
+ centralized read-scope rule), not application logic:
45
62
 
46
- - `GET /Memory/` — returns only the authenticated agent's memories
47
- - `POST /Memory` writes with the authenticated agent's ID
48
- - `POST /MemorySearch` — searches only the authenticated agent's memories
63
+ - `GET /Memory/` — returns the authenticated agent's own memories (any
64
+ visibility) plus every **non-private** memory in the org
65
+ - `POST /MemorySearch` — same read scope: own memories plus all non-private
66
+ - `POST /Memory` — writes are attributed to the authenticated agent; an
67
+ agent cannot write as another (write isolation)
49
68
 
50
- ### Cross-Agent Access
69
+ **Private memories are strictly owner-only** — a memory written with
70
+ `visibility: private` is returned only to its author, never to another agent.
51
71
 
52
- Explicit grants allow one agent to read another's memories:
72
+ ### Cross-Agent Access (within an org)
53
73
 
54
- ```
55
- MemoryGrant { fromAgentId, toAgentId, scope: "read" }
56
- ```
57
-
58
- Grants are created by admin or by the granting agent.
74
+ Within an org, an agent reads every non-private memory directly — no grant
75
+ required. This is deliberate: the goal is relevance (surface what's useful to
76
+ the org) over secrecy. A writer keeps something private by marking it
77
+ `visibility: private`, which keeps it strictly owner-only. The access boundary
78
+ that stays hard is the **federation edge** (cross-instance / cross-org), not
79
+ within-org reads.
59
80
 
60
81
  ### Admin Bypass
61
82
 
@@ -88,8 +109,12 @@ public key in Flair, and backs up the old key as `<agentId>.key.bak`.
88
109
 
89
110
  - **Agent impersonation:** Ed25519 signatures prevent one agent from
90
111
  acting as another without possessing the private key.
91
- - **Cross-agent data leakage:** Collection-level scoping ensures agents
92
- can only query their own data.
112
+ - **Private-memory leakage:** memories marked `visibility: private` are
113
+ strictly owner-only and never returned to another agent. Non-private
114
+ memories are intentionally readable within the org (by design, not
115
+ leakage); the cross-instance boundary is the federation edge.
116
+ - **Write forgery:** writes are attributed to the authenticated agent —
117
+ an agent cannot write memories as another.
93
118
  - **Replay attacks:** 30-second window + nonce deduplication.
94
119
  - **Privilege escalation via SQL:** SQL and GraphQL endpoints blocked
95
120
  for non-admin agents.
@@ -105,6 +130,13 @@ public key in Flair, and backs up the old key as `<agentId>.key.bak`.
105
130
  process could extract them.
106
131
  - **Network sniffing:** Flair uses HTTP by default. Use HTTPS in
107
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.
108
140
 
109
141
  ## Recommendations
110
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