@tpsdev-ai/flair 0.29.0 → 0.30.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 (85) hide show
  1. package/dist/cli-shim.cjs +1 -1
  2. package/dist/cli.js +231 -104
  3. package/dist/deploy.js +29 -19
  4. package/dist/fabric-upgrade.js +61 -23
  5. package/dist/fleet-verify.js +3 -3
  6. package/dist/lib/mcp-enable.js +2 -2
  7. package/dist/rem/scheduler.js +226 -17
  8. package/dist/resources/A2AAdapter.js +1 -1
  9. package/dist/resources/Admin.js +1 -1
  10. package/dist/resources/AdminConnectors.js +1 -1
  11. package/dist/resources/AdminDashboard.js +1 -1
  12. package/dist/resources/AdminIdp.js +1 -1
  13. package/dist/resources/AdminInstance.js +1 -1
  14. package/dist/resources/AdminMemory.js +1 -1
  15. package/dist/resources/AdminPrincipals.js +1 -1
  16. package/dist/resources/Agent.js +1 -1
  17. package/dist/resources/AgentCard.js +1 -1
  18. package/dist/resources/AgentSeed.js +1 -1
  19. package/dist/resources/AttentionQuery.js +1 -1
  20. package/dist/resources/Credential.js +1 -1
  21. package/dist/resources/Federation.js +1 -1
  22. package/dist/resources/Instance.js +1 -1
  23. package/dist/resources/Integration.js +1 -1
  24. package/dist/resources/MCPClientMetadata.js +1 -1
  25. package/dist/resources/Memory.js +1 -1
  26. package/dist/resources/MemoryBootstrap.js +1 -1
  27. package/dist/resources/MemoryCandidate.js +168 -0
  28. package/dist/resources/MemoryConsolidate.js +1 -1
  29. package/dist/resources/MemoryDedupStats.js +1 -1
  30. package/dist/resources/MemoryFeed.js +1 -1
  31. package/dist/resources/MemoryGrant.js +1 -1
  32. package/dist/resources/MemoryMaintenance.js +1 -1
  33. package/dist/resources/MemoryReflect.js +2 -2
  34. package/dist/resources/MemoryReindex.js +1 -1
  35. package/dist/resources/MemoryUsage.js +1 -1
  36. package/dist/resources/OAuth.js +1 -1
  37. package/dist/resources/OAuthClient.js +1 -1
  38. package/dist/resources/OrgEvent.js +1 -1
  39. package/dist/resources/OrgEventCatchup.js +1 -1
  40. package/dist/resources/OrgEventMaintenance.js +1 -1
  41. package/dist/resources/PairingToken.js +1 -1
  42. package/dist/resources/Peer.js +1 -1
  43. package/dist/resources/Presence.js +3 -3
  44. package/dist/resources/RecordUsage.js +1 -1
  45. package/dist/resources/Relationship.js +1 -1
  46. package/dist/resources/SemanticSearch.js +1 -1
  47. package/dist/resources/SkillScan.js +1 -1
  48. package/dist/resources/Soul.js +1 -1
  49. package/dist/resources/SoulFeed.js +1 -1
  50. package/dist/resources/WorkspaceLatest.js +1 -1
  51. package/dist/resources/WorkspaceState.js +1 -1
  52. package/dist/resources/XAA.js +1 -1
  53. package/dist/resources/a2a-url.js +1 -1
  54. package/dist/resources/agent-auth.js +1 -1
  55. package/dist/resources/agentcard-fields.js +1 -1
  56. package/dist/resources/auth-middleware.js +1 -1
  57. package/dist/resources/embeddings-boot.js +4 -4
  58. package/dist/resources/embeddings-provider.js +5 -5
  59. package/dist/resources/federation-cleanup.js +5 -5
  60. package/dist/resources/federation-nonce-store.js +5 -5
  61. package/dist/resources/health.js +29 -6
  62. package/dist/resources/instance-identity.js +1 -1
  63. package/dist/resources/mcp-client-metadata-fields.js +1 -1
  64. package/dist/resources/mcp-handler.js +1 -1
  65. package/dist/resources/mcp-oauth.js +2 -2
  66. package/dist/resources/memory-read-scope.js +1 -1
  67. package/dist/resources/memory-reflect-lib.js +3 -3
  68. package/dist/resources/memory-visibility.js +3 -3
  69. package/dist/resources/migration-boot.js +1 -1
  70. package/dist/resources/migrations/embedding-stamp.js +3 -3
  71. package/dist/resources/migrations/graph-heal.js +2 -2
  72. package/dist/resources/migrations/ledger.js +1 -1
  73. package/dist/resources/migrations/registry.js +14 -5
  74. package/dist/resources/migrations/runner.js +64 -11
  75. package/dist/resources/migrations/synthetic-test-migration.js +1 -1
  76. package/dist/resources/migrations/visibility-backfill.js +232 -0
  77. package/dist/resources/record-types.js +28 -0
  78. package/dist/resources/semantic-retrieval-core.js +1 -1
  79. package/dist/resources/usage-recording.js +1 -1
  80. package/dist/src/rem/scheduler.js +449 -0
  81. package/docs/deployment.md +1 -0
  82. package/docs/supply-chain-policy.md +4 -4
  83. package/docs/upgrade.md +2 -2
  84. package/package.json +4 -4
  85. package/schemas/memory.graphql +9 -1
@@ -0,0 +1,168 @@
1
+ import { databases } from "harper";
2
+ import { resolveAgentAuth } from "./agent-auth.js";
3
+ import { makeAuthGate, makeReadScope, makeByIdReadGate, resolveAuthGate, stampAttribution, FORBIDDEN, UNAUTH, } from "./record-type-kit.js";
4
+ import { RECORD_TYPES } from "./record-types.js";
5
+ // Parameterized from RECORD_TYPES.MemoryCandidate (record-types slice 2,
6
+ // flair#520) rather than a hand-typed "owner-only" literal — the registry is
7
+ // the single source of truth this class draws its read-scope mode from.
8
+ // Exported solely so test/unit/record-types-registry.test.ts's drift
9
+ // tripwire can introspect the composed resolver's tagged `.mode`/
10
+ // `.ownerField` against RECORD_TYPES.MemoryCandidate — not for any other
11
+ // runtime consumer.
12
+ export const memoryCandidateReadScope = makeReadScope(RECORD_TYPES.MemoryCandidate.readScope, RECORD_TYPES.MemoryCandidate.ownerField);
13
+ const memoryCandidateByIdReadGate = makeByIdReadGate(memoryCandidateReadScope);
14
+ // See makeAuthGate's doc (record-type-kit.ts): must be wired as a genuine
15
+ // prototype method below, never a class-field assignment.
16
+ const memoryCandidateAuthGate = makeAuthGate();
17
+ /**
18
+ * MemoryCandidate resource — closes flair#849.
19
+ *
20
+ * The schema (schemas/memory.graphql) declared `@table` for this type with
21
+ * no `@export` and no resource file at all, so it had NO REST surface —
22
+ * `flair rem candidates`/`promote`/`reject` (src/cli.ts) all 404'd on every
23
+ * call, a clean-room dogfood blocker. Adding bare `@export` would have
24
+ * reopened the exact P0 leak the memory-soul-read-gate family fix closed for
25
+ * every other agent-facing table: Harper's `Resource` default is
26
+ * `allowRead/allowCreate/allowUpdate/allowDelete(user) { return
27
+ * user?.role.permission.super_user }` (test/unit/resource-allow-decision.test.ts
28
+ * enforces every exported resource makes an explicit allow-decision instead
29
+ * of falling through to that default), so an unguarded `@export` is reachable
30
+ * by `authorizeLocal`'s forged loopback super_user and, once the global gate
31
+ * stops rejecting a genuinely anonymous remote caller, by that caller too.
32
+ *
33
+ * Read: identity-gated (allowRead — verified agents, admins, and trusted
34
+ * internal calls pass; anonymous HTTP denied) AND per-agent scoped
35
+ * ("owner-only" — see RECORD_TYPES.MemoryCandidate's doc comment for why: a
36
+ * candidate is an unreviewed draft distillation, not yet promoted, and must
37
+ * not be org-readable). Same "owner-only" composition Relationship.ts uses,
38
+ * parameterized from the registry — this is NOT MemoryGrant.ts's bespoke
39
+ * owner-OR-grantee model (MemoryCandidate has no second-party field).
40
+ *
41
+ * Write: post()/put()/delete() all self-enforce inline (no allowCreate/
42
+ * allowUpdate/allowDelete wrapper — same deliberate omission Memory.ts's
43
+ * allowRead() doc explains: adding an unverified allow* gate on top of
44
+ * self-enforcing methods risks regressing owner writes). Non-admin agents
45
+ * may create/modify only their OWN candidates (`agentId` no-forge
46
+ * attribution, "validate-truthy" — present+mismatched agentId is rejected,
47
+ * absent passes through, matching Memory.post()/put()'s exact idiom for the
48
+ * same single-owner-field shape) and may delete only their own candidates
49
+ * (mirrors MemoryGrant.ts's delete() ownership check). Internal calls (the
50
+ * FLAIR-NIGHTLY-REM staging writer — resources/MemoryReflect.ts's
51
+ * `databases.flair.MemoryCandidate.put(row)` — and resources/health.ts's
52
+ * pending-count read) and admin agents pass every method unfiltered, exactly
53
+ * like every other table this pattern covers.
54
+ */
55
+ export class MemoryCandidate extends databases.flair.MemoryCandidate {
56
+ /**
57
+ * Self-authorize now that the global gate is non-rejecting (memory-soul-
58
+ * read-gate family fix — same pattern as Memory.ts/Relationship.ts/
59
+ * WorkspaceState.ts/OrgEvent.ts/Soul.ts/MemoryGrant.ts). Harper routes
60
+ * `GET /MemoryCandidate/<id>` to get() and the collection describe
61
+ * (`GET /MemoryCandidate`) outside search(), so both must be gated here,
62
+ * not just search(). Per-record owner scoping happens in get() below; the
63
+ * collection scope is still in search().
64
+ */
65
+ allowRead() { return memoryCandidateAuthGate.call(this); }
66
+ /**
67
+ * Override get() to scope by-id reads the same way search() scopes
68
+ * collection reads. Never distinguishes "doesn't exist" from "exists but
69
+ * not yours" — both return 404, never 403, so a denied caller can't use
70
+ * get() to enumerate other agents' candidate ids (same discipline
71
+ * makeByIdReadGate documents, and MemoryGrant.ts's get() hand-rolls
72
+ * identically). `flair rem promote`/`flair rem reject` (src/cli.ts) both
73
+ * fetch a candidate by id before writing back — this is their read path.
74
+ */
75
+ async get(target) {
76
+ // Collection / query reads arrive as a RequestTarget with
77
+ // `isCollection === true`, and are governed by search() (same owner
78
+ // scoping). Only a genuine by-id get is ownership-checked below.
79
+ if (!target || (typeof target === "object" && target.isCollection)) {
80
+ return this.search(target);
81
+ }
82
+ return memoryCandidateByIdReadGate.call(this, target, (t) => super.get(t));
83
+ }
84
+ /**
85
+ * Scope collection reads to the caller's own candidates. This is the
86
+ * handler `flair rem candidates` reaches via `POST
87
+ * /MemoryCandidate/search_by_conditions` (src/cli.ts) — the agentId
88
+ * condition is wrapped as the OUTERMOST `and` block (Relationship.ts's
89
+ * same "Security Critical" discipline) so a caller-supplied `operator:
90
+ * "or"` in the request body cannot boolean-inject past the owner scope.
91
+ */
92
+ async search(query) {
93
+ const ctx = this.getContext?.();
94
+ const gate = await resolveAuthGate(ctx, UNAUTH());
95
+ if (gate.kind === "denied")
96
+ return gate.response;
97
+ if (gate.kind === "unfiltered")
98
+ return super.search(query);
99
+ // Non-admin agent: scope to own candidates only.
100
+ const scope = await memoryCandidateReadScope(gate.agentId);
101
+ const agentCondition = scope.condition;
102
+ if (!query?.conditions) {
103
+ return super.search({ conditions: [agentCondition], ...(query || {}) });
104
+ }
105
+ return super.search({
106
+ ...query,
107
+ conditions: [agentCondition, { conditions: query.conditions, operator: query.operator || "and" }],
108
+ operator: "and",
109
+ });
110
+ }
111
+ /**
112
+ * No shipped CLI path calls POST today (the FLAIR-NIGHTLY-REM staging
113
+ * writer uses an internal `.put()`, not `.post()` — see MemoryReflect.ts).
114
+ * Guarded anyway, on the same "don't leave any exported verb unguarded"
115
+ * discipline the rest of this file follows: anonymous denied; a non-admin
116
+ * agent may only stage a candidate attributed to itself.
117
+ */
118
+ async post(content) {
119
+ const ctx = this.getContext?.();
120
+ const auth = await resolveAgentAuth(ctx);
121
+ if (auth.kind === "anonymous")
122
+ return UNAUTH();
123
+ const attr = stampAttribution(auth, content, RECORD_TYPES.MemoryCandidate.ownerField, RECORD_TYPES.MemoryCandidate.attribution.post, "forbidden: cannot stage a memory candidate for another agent");
124
+ if (attr.denied)
125
+ return attr.denied;
126
+ return super.post(content);
127
+ }
128
+ /**
129
+ * `flair rem promote`/`flair rem reject` (src/cli.ts) both PUT the
130
+ * candidate row back with an updated status/reviewerId/reviewRationale/
131
+ * decidedAt, spreading the existing record (agentId included, unchanged).
132
+ * Non-admin: the no-forge attribution check rejects a PRESENT, mismatched
133
+ * agentId (an agent can't repurpose this endpoint to rewrite another
134
+ * agent's candidate) but never stamps one in — the promote/reject flow
135
+ * always carries the original agentId forward untouched.
136
+ */
137
+ async put(content) {
138
+ const ctx = this.getContext?.();
139
+ const auth = await resolveAgentAuth(ctx);
140
+ if (auth.kind === "anonymous")
141
+ return UNAUTH();
142
+ const attr = stampAttribution(auth, content, RECORD_TYPES.MemoryCandidate.ownerField, RECORD_TYPES.MemoryCandidate.attribution.put, "forbidden: cannot modify a memory candidate owned by another agent");
143
+ if (attr.denied)
144
+ return attr.denied;
145
+ return super.put(content);
146
+ }
147
+ /**
148
+ * No shipped CLI path calls DELETE today. Guarded on the same discipline
149
+ * as post() above — mirrors MemoryGrant.ts's delete(): owner-only,
150
+ * admin/internal unfiltered, a genuinely-missing id is a clean no-op
151
+ * super.delete() rather than a FORBIDDEN (no existence oracle).
152
+ */
153
+ async delete(id, context) {
154
+ const ctx = this.getContext?.();
155
+ const gate = await resolveAuthGate(ctx, UNAUTH());
156
+ if (gate.kind === "denied")
157
+ return gate.response;
158
+ if (gate.kind === "unfiltered")
159
+ return super.delete(id, context);
160
+ const record = await super.get(id);
161
+ if (!record)
162
+ return super.delete(id, context);
163
+ if (record[RECORD_TYPES.MemoryCandidate.ownerField] !== gate.agentId) {
164
+ return FORBIDDEN("forbidden: cannot delete a memory candidate owned by another agent");
165
+ }
166
+ return super.delete(id, context);
167
+ }
168
+ }
@@ -15,7 +15,7 @@
15
15
  * candidates Array<{ memory, suggestion, reason }>
16
16
  * prompt string
17
17
  */
18
- import { Resource, databases } from "@harperfast/harper";
18
+ import { Resource, databases } from "harper";
19
19
  import { isAdmin, allowVerified } from "./agent-auth.js";
20
20
  import { evaluate, parseDuration } from "./memory-consolidate-lib.js";
21
21
  export class ConsolidateMemories extends Resource {
@@ -52,7 +52,7 @@
52
52
  * agent's own memories; this one is never scoped that way — it reads every
53
53
  * agent's embeddings — so it follows the admin-gated precedent instead.
54
54
  */
55
- import { Resource, databases } from "@harperfast/harper";
55
+ import { Resource, databases } from "harper";
56
56
  import { mkdirSync, writeFileSync } from "node:fs";
57
57
  import { dirname } from "node:path";
58
58
  import { allowAdmin } from "./agent-auth.js";
@@ -1,4 +1,4 @@
1
- import { Resource, databases } from "@harperfast/harper";
1
+ import { Resource, databases } from "harper";
2
2
  import { allowVerified } from "./agent-auth.js";
3
3
  import { computeContentHash, findExistingMemoryByContentHash } from "./memory-feed-lib.js";
4
4
  export class FeedMemories extends Resource {
@@ -1,4 +1,4 @@
1
- import { databases } from "@harperfast/harper";
1
+ import { databases } from "harper";
2
2
  import { resolveAgentAuth, allowVerified } from "./agent-auth.js";
3
3
  const FORBIDDEN = (msg) => new Response(JSON.stringify({ error: msg }), { status: 403, headers: { "Content-Type": "application/json" } });
4
4
  const UNAUTH = () => new Response(JSON.stringify({ error: "authentication required" }), { status: 401, headers: { "Content-Type": "application/json" } });
@@ -16,7 +16,7 @@
16
16
  * Migrated to the standard `extends Resource` shape with `allowCreate()`
17
17
  * to gate auth correctly.
18
18
  */
19
- import { Resource, databases } from "@harperfast/harper";
19
+ import { Resource, databases } from "harper";
20
20
  import { isAdmin } from "./agent-auth.js";
21
21
  export class MemoryMaintenance extends Resource {
22
22
  /** POST requires auth — either an agent acting on its own memories, or admin. */
@@ -36,7 +36,7 @@
36
36
  * Resource }` outright — see test/unit/resource-allow.test.ts). This
37
37
  * resource is a thin orchestrator over the lib's tested functions.
38
38
  */
39
- import { Resource, databases, models, logger } from "@harperfast/harper";
39
+ import { Resource, databases, models, logger } from "harper";
40
40
  import { randomBytes } from "node:crypto";
41
41
  import { isAdmin, allowVerified } from "./agent-auth.js";
42
42
  import { patchRecordSilent } from "./table-helpers.js";
@@ -143,7 +143,7 @@ export class ReflectMemories extends Resource {
143
143
  existingPendingClaims.push(c.claim);
144
144
  }
145
145
  const toStage = dedupeCandidates(outcome.candidates, existingPendingClaims);
146
- // generatedBy: GenerateResult in the pinned @harperfast/harper 5.1.17 has
146
+ // generatedBy: GenerateResult in the pinned harper 5.1.17 has
147
147
  // no model/backend-id field (content/finishReason/usage/toolCalls/trace
148
148
  // only) — the "from the generate result if available" branch is
149
149
  // unreachable in this version, so this always falls back to the
@@ -23,7 +23,7 @@
23
23
  *
24
24
  * This endpoint is idempotent: running it again finds zero drift.
25
25
  */
26
- import { Resource, databases } from "@harperfast/harper";
26
+ import { Resource, databases } from "harper";
27
27
  import { isAdmin, allowAdmin } from "./agent-auth.js";
28
28
  export class MemoryReindex extends Resource {
29
29
  // Admin-only: permit verified ADMIN agents (Basic-admin is super_user and
@@ -41,7 +41,7 @@
41
41
  * to expose "which agent used which memory" cross-agent, and narrowing this
42
42
  * costs nothing.
43
43
  */
44
- import { databases } from "@harperfast/harper";
44
+ import { databases } from "harper";
45
45
  import { resolveAgentAuth, allowVerified } from "./agent-auth.js";
46
46
  const FORBIDDEN = (msg) => new Response(JSON.stringify({ error: msg }), { status: 403, headers: { "Content-Type": "application/json" } });
47
47
  const UNAUTH = () => new Response(JSON.stringify({ error: "authentication required" }), { status: 401, headers: { "Content-Type": "application/json" } });
@@ -1,4 +1,4 @@
1
- import { Resource, databases } from "@harperfast/harper";
1
+ import { Resource, databases } from "harper";
2
2
  import { createHash, randomBytes } from "node:crypto";
3
3
  import { handleJwtBearerGrant } from "./XAA.js";
4
4
  import { resolveAgentAuth } from "./agent-auth.js";
@@ -1,4 +1,4 @@
1
- import { databases } from "@harperfast/harper";
1
+ import { databases } from "harper";
2
2
  import { allowAdmin } from "./agent-auth.js";
3
3
  /**
4
4
  * OAuthClient holds registered OAuth client records (incl. secrets) — admin/system
@@ -10,7 +10,7 @@
10
10
  * requests slipped through once the gate stopped rejecting. resolveAgentAuth
11
11
  * distinguishes internal/agent/anonymous explicitly.
12
12
  */
13
- import { databases } from "@harperfast/harper";
13
+ import { databases } from "harper";
14
14
  import { resolveAgentAuth } from "./agent-auth.js";
15
15
  import { invalidEntitiesResponse } from "./entity-vocab.js";
16
16
  import { makeAuthGate, resolveAuthGate, stampAttribution, FORBIDDEN, UNAUTH, } from "./record-type-kit.js";
@@ -9,7 +9,7 @@
9
9
  * Sorted by createdAt ascending (oldest first for in-order processing).
10
10
  * Limit 50 events max.
11
11
  */
12
- import { Resource, databases } from "@harperfast/harper";
12
+ import { Resource, databases } from "harper";
13
13
  import { allowVerified, resolveAgentAuth } from "./agent-auth.js";
14
14
  export class OrgEventCatchup extends Resource {
15
15
  // Self-authorize via the Ed25519 agent verify (auth reshape removes the gate's
@@ -4,7 +4,7 @@
4
4
  * POST /OrgEventMaintenance/ — deletes all records where expiresAt < now.
5
5
  * Auth: admin only.
6
6
  */
7
- import { Resource, databases } from "@harperfast/harper";
7
+ import { Resource, databases } from "harper";
8
8
  import { allowAdmin } from "./agent-auth.js";
9
9
  export class OrgEventMaintenance extends Resource {
10
10
  // Admin-only: permit verified ADMIN agents (Basic-admin is super_user and
@@ -1,4 +1,4 @@
1
- import { databases } from "@harperfast/harper";
1
+ import { databases } from "harper";
2
2
  import { allowAdmin } from "./agent-auth.js";
3
3
  /**
4
4
  * PairingToken holds one-time federation pairing secrets — admin/system only,
@@ -1,4 +1,4 @@
1
- import { databases } from "@harperfast/harper";
1
+ import { databases } from "harper";
2
2
  import { allowAdmin } from "./agent-auth.js";
3
3
  /**
4
4
  * Peer holds federation peer records (URLs + credentials) — system/admin data,
@@ -26,7 +26,7 @@
26
26
  * content. get() additionally gates currentTask itself to verified
27
27
  * in-org agents only; see get()'s inline comment.
28
28
  */
29
- import { databases } from "@harperfast/harper";
29
+ import { databases } from "harper";
30
30
  import { existsSync, readFileSync } from "node:fs";
31
31
  import { dirname, join } from "node:path";
32
32
  import { fileURLToPath } from "node:url";
@@ -80,7 +80,7 @@ function resolveVersion() {
80
80
  return process.env.npm_package_version ?? "dev";
81
81
  }
82
82
  /**
83
- * Resolve the running @harperfast/harper version. Unlike flair's own
83
+ * Resolve the running harper version. Unlike flair's own
84
84
  * package.json (readable via a plain relative path above), Harper's package
85
85
  * only exports "." → dist/index.js — there's no "./package.json" subpath, so
86
86
  * requiring it directly throws (Node's exports-map enforcement). Resolve the
@@ -93,7 +93,7 @@ function resolveVersion() {
93
93
  function resolveHarperVersion() {
94
94
  try {
95
95
  const req = createRequire(import.meta.url);
96
- const mainPath = req.resolve("@harperfast/harper");
96
+ const mainPath = req.resolve("harper");
97
97
  const pkgPath = join(dirname(mainPath), "..", "package.json");
98
98
  if (existsSync(pkgPath)) {
99
99
  const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
@@ -93,7 +93,7 @@
93
93
  * sanitized (control-character-stripped, length-capped) and stored as-is,
94
94
  * for audit/analytics only. Treat it as untrusted data, always.
95
95
  */
96
- import { Resource } from "@harperfast/harper";
96
+ import { Resource } from "harper";
97
97
  import { resolveAgentAuth } from "./agent-auth.js";
98
98
  import { checkRateLimit, rateLimitResponse } from "./rate-limiter.js";
99
99
  import { recordUsageContribution, MAX_USAGE_IDS_PER_CALL } from "./usage-recording.js";
@@ -1,4 +1,4 @@
1
- import { databases } from "@harperfast/harper";
1
+ import { databases } from "harper";
2
2
  import { resolveAgentAuth } from "./agent-auth.js";
3
3
  import { checkRateLimit, rateLimitResponse } from "./rate-limiter.js";
4
4
  import { localInstanceId } from "./instance-identity.js";
@@ -1,4 +1,4 @@
1
- import { Resource, databases } from "@harperfast/harper";
1
+ import { Resource, databases } from "harper";
2
2
  import { resolveAgentAuth, allowVerified } from "./agent-auth.js";
3
3
  import { getEmbedding, getMode } from "./embeddings-provider.js";
4
4
  import { patchRecord } from "./table-helpers.js";
@@ -1,4 +1,4 @@
1
- import { Resource } from "@harperfast/harper";
1
+ import { Resource } from "harper";
2
2
  import { allowVerified } from "./agent-auth.js";
3
3
  import { scanSkillContent } from "./scan/skill-scanner.js";
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { databases } from "@harperfast/harper";
1
+ import { databases } from "harper";
2
2
  import { resolveAgentAuth } from "./agent-auth.js";
3
3
  import { localInstanceId } from "./instance-identity.js";
4
4
  import { makeAuthGate, stampAttribution, UNAUTH } from "./record-type-kit.js";
@@ -1,4 +1,4 @@
1
- import { Resource, databases } from '@harperfast/harper';
1
+ import { Resource, databases } from 'harper';
2
2
  import { allowVerified } from './agent-auth.js';
3
3
  export class FeedSouls extends Resource {
4
4
  // Self-authorize the subscription via the Ed25519 agent verify (auth reshape
@@ -4,7 +4,7 @@
4
4
  * GET /WorkspaceLatest/{agentId} — returns most recent WorkspaceState record.
5
5
  * Auth: requesting agent must match agentId in path (or be admin).
6
6
  */
7
- import { Resource, databases } from "@harperfast/harper";
7
+ import { Resource, databases } from "harper";
8
8
  import { allowVerified, resolveAgentAuth } from "./agent-auth.js";
9
9
  export class WorkspaceLatest extends Resource {
10
10
  // Self-authorize via the Ed25519 agent verify (auth reshape removes the gate's
@@ -7,7 +7,7 @@
7
7
  * Note: Harper's static methods call instance methods with positional args only.
8
8
  * Use this.getContext() to access request context (tpsAgent, tpsAgentIsAdmin).
9
9
  */
10
- import { databases } from "@harperfast/harper";
10
+ import { databases } from "harper";
11
11
  import { resolveAgentAuth } from "./agent-auth.js";
12
12
  import { invalidEntitiesResponse } from "./entity-vocab.js";
13
13
  import { makeAuthGate, makeReadScope, makeByIdReadGate, resolveAuthGate, stampAttribution, FORBIDDEN, UNAUTH, } from "./record-type-kit.js";
@@ -1,4 +1,4 @@
1
- import { databases } from "@harperfast/harper";
1
+ import { databases } from "harper";
2
2
  import { allowAdmin } from "./agent-auth.js";
3
3
  import { createHash, randomBytes } from "node:crypto";
4
4
  import { createRemoteJWKSet, jwtVerify } from "jose";
@@ -6,7 +6,7 @@
6
6
  // reflect the REAL listening port, or a remote A2A peer that follows discovery
7
7
  // hits a dead port.
8
8
  //
9
- // Kept free of any @harperfast/harper import so the resolution logic is
9
+ // Kept free of any harper import so the resolution logic is
10
10
  // unit-testable without spinning up Harper (mirrors agentcard-fields.ts —
11
11
  // avoids the simulator-pattern drift that let the AdminInstance predicate be
12
12
  // reproduced-not-imported).
@@ -15,7 +15,7 @@
15
15
  * verified against the agent's stored Ed25519 public key. Replay is bounded by a
16
16
  * 30s timestamp window + a per-(agent,nonce) seen-set pruned to that window.
17
17
  */
18
- import { databases } from "@harperfast/harper";
18
+ import { databases } from "harper";
19
19
  import { WINDOW_MS, isNonceReplay, recordNonce, importEd25519Key, b64ToArrayBuffer, parseTpsEd25519Header } from "./ed25519-auth.js";
20
20
  /**
21
21
  * Shared Harper user that verified Ed25519 agents resolve to (least-privilege
@@ -7,7 +7,7 @@
7
7
  // fallback that could surface a private soul (an operator's internal note,
8
8
  // prompt fragment, or credential reminder) on the public endpoint.
9
9
  //
10
- // Kept free of any @harperfast/harper import so the real logic is unit-testable
10
+ // Kept free of any harper import so the real logic is unit-testable
11
11
  // without spinning up Harper (avoids the simulator-pattern that let the
12
12
  // description-fallback leak ship untested).
13
13
  export function readSoulKind(entry) {
@@ -1,5 +1,5 @@
1
1
  import { patchRecord } from "./table-helpers.js";
2
- import { server, databases } from "@harperfast/harper";
2
+ import { server, databases } from "harper";
3
3
  import { getEmbedding } from "./embeddings-provider.js";
4
4
  import { isAdmin, FLAIR_AGENT_USERNAME } from "./agent-auth.js";
5
5
  import { WINDOW_MS, isNonceReplay, recordNonce, importEd25519Key, b64ToArrayBuffer, parseTpsEd25519Header } from "./ed25519-auth.js";
@@ -7,7 +7,7 @@
7
7
  * The previous mechanism (removed by this change) delivered the registration
8
8
  * as a `models.embedding.default` block via the `HARPER_CONFIG` env var
9
9
  * (src/cli.ts's old `buildEmbeddingsHarperConfigEnv`) — a "merge layer" that
10
- * Harper's environment-manager (`@harperfast/harper`'s
10
+ * Harper's environment-manager (`harper`'s
11
11
  * `config/harperConfigEnvVars.js`) reasserts on every boot AND PERSISTS into
12
12
  * the instance-root `harper-config.yaml`. That file proved to be config-as-
13
13
  * STATE, not config-as-intent: `flair#694`'s downgrade-and-revert CI lane
@@ -28,14 +28,14 @@
28
28
  * to), leaving `models.embedding.default: {}` — an empty shell —
29
29
  * persisted to disk.
30
30
  * 3. The next boot's config schema validator
31
- * (`@harperfast/harper`'s `validation/configValidator.js`) resolves the
31
+ * (`harper`'s `validation/configValidator.js`) resolves the
32
32
  * entry's backend via `Joi.alternatives().conditional('.backend', {...,
33
33
  * otherwise: unknownBackendEntrySchema})`; with `backend` absent, that
34
34
  * falls through to `unknownBackendEntrySchema = Joi.object({backend:
35
35
  * string.required()})`, which throws exactly: "Harper config file
36
36
  * validation error: 'models.embedding.default.backend' is required" —
37
- * Harper refuses to boot. Confirmed byte-identical in both @harperfast/
38
- * harper 5.1.15 and 5.1.17 (this is upstream env-var-config behavior,
37
+ * Harper refuses to boot. Confirmed byte-identical in both harper
38
+ * 5.1.15 and 5.1.17 (this is upstream env-var-config behavior,
39
39
  * not a schema difference between versions), and reproduced locally by
40
40
  * replaying the exact downgrade-and-revert sequence.
41
41
  *
@@ -36,11 +36,11 @@
36
36
  * what this migration removes: `models.embed` is a process-wide singleton
37
37
  * Harper initializes at boot, off the first-call dynamic-import race.
38
38
  *
39
- * `@harperfast/harper` is dynamic-imported here (deferred to first actual
39
+ * `harper` is dynamic-imported here (deferred to first actual
40
40
  * getEmbedding()/getMode()/getStatus() call), NOT statically imported like
41
41
  * every other resource's `Resource`/`databases`/`server` — those work
42
42
  * unmocked-import-free only because every test that (transitively) imports
43
- * them already mocks `@harperfast/harper` first. Statically importing
43
+ * them already mocks `harper` first. Statically importing
44
44
  * `models` here would make *any* test that imports this file for
45
45
  * `resolveModelsDir()` alone (test/unit/embeddings-models-dir.test.ts, which
46
46
  * has no reason to know about Harper at all) also eagerly load Harper's real
@@ -186,7 +186,7 @@ function prefixesEnabled() {
186
186
  * Build the options object passed to `models.embed()`. Pulled out as its own
187
187
  * pure, harper-free function so the value-forwarding (and the reject-a-
188
188
  * wrong-value guard) is unit-testable without touching the deferred
189
- * `@harperfast/harper` import this file's header explains — see
189
+ * `harper` import this file's header explains — see
190
190
  * test/unit/embeddings-provider-input-type.test.ts.
191
191
  *
192
192
  * Gate ON (default): rejects anything other than the literal
@@ -217,7 +217,7 @@ let _modelsApi;
217
217
  /**
218
218
  * Resolve (and cache) Harper's `models` facade via a deferred import — see file header.
219
219
  *
220
- * NOTE for anyone using this as a reference: `models` (the `@harperfast/harper`
220
+ * NOTE for anyone using this as a reference: `models` (the `harper`
221
221
  * package export) and a component's `scope.models` are the SAME boot-time
222
222
  * singleton — Harper's jsLoader hands components `scope.models = <the global
223
223
  * models>` (two accessors, one object; the model registry lives on that singleton).
@@ -229,7 +229,7 @@ let _modelsApi;
229
229
  async function getModelsApi() {
230
230
  if (_modelsApi)
231
231
  return _modelsApi;
232
- const harper = await import("@harperfast/harper");
232
+ const harper = await import("harper");
233
233
  _modelsApi = harper.models;
234
234
  return _modelsApi;
235
235
  }
@@ -11,13 +11,13 @@ let cleanupTimer = null;
11
11
  * and performs housekeeping on expired/unconsumed token records.
12
12
  *
13
13
  * In test environments, callers pass mock serverOp/db via `opts` so this
14
- * module never imports @harperfast/harper at the top level (which would
14
+ * module never imports harper at the top level (which would
15
15
  * crash when STORAGE_PATH isn't set).
16
16
  */
17
17
  export async function initFederationCleanup(opts) {
18
18
  const immediate = opts?.immediateTick ?? true;
19
19
  // Resolve server / databases: use caller-supplied mocks when available,
20
- // otherwise lazy-import @harperfast/harper at call time.
20
+ // otherwise lazy-import harper at call time.
21
21
  let svr;
22
22
  let db;
23
23
  if (opts?.serverOp && opts?.db) {
@@ -26,12 +26,12 @@ export async function initFederationCleanup(opts) {
26
26
  }
27
27
  else {
28
28
  try {
29
- const harper = await import("@harperfast/harper");
29
+ const harper = await import("harper");
30
30
  svr = opts?.serverOp ?? harper.server.operation;
31
31
  db = opts?.db ?? harper.databases;
32
32
  }
33
33
  catch (err) {
34
- console.error("[federation-cleanup] failed to load @harperfast/harper:", err?.message ?? err);
34
+ console.error("[federation-cleanup] failed to load harper:", err?.message ?? err);
35
35
  return;
36
36
  }
37
37
  }
@@ -94,7 +94,7 @@ export async function runCleanupTick(opts = {}) {
94
94
  db = opts.db;
95
95
  }
96
96
  else {
97
- const harper = await import("@harperfast/harper");
97
+ const harper = await import("harper");
98
98
  svr = opts.serverOp ?? harper.server.operation;
99
99
  db = opts.db ?? harper.databases;
100
100
  }
@@ -44,7 +44,7 @@ async function resolveDb(opts, cache) {
44
44
  if (opts.db)
45
45
  return opts.db;
46
46
  if (!cache.db) {
47
- cache.db = import("@harperfast/harper").then((h) => h.databases);
47
+ cache.db = import("harper").then((h) => h.databases);
48
48
  }
49
49
  return cache.db;
50
50
  }
@@ -123,7 +123,7 @@ export async function runNonceCleanupTick(opts = {}) {
123
123
  db = opts.db;
124
124
  }
125
125
  else {
126
- const harper = await import("@harperfast/harper");
126
+ const harper = await import("harper");
127
127
  db = harper.databases;
128
128
  }
129
129
  const retentionMs = opts.retentionMs ?? DEFAULT_RETENTION_MS;
@@ -159,7 +159,7 @@ export async function runNonceCleanupTick(opts = {}) {
159
159
  * Initialise the periodic Nonce-table eviction sweep (5-min cadence).
160
160
  *
161
161
  * In test environments, callers pass a mock `db` via `opts` so this module
162
- * never imports @harperfast/harper at the top level (mirrors
162
+ * never imports harper at the top level (mirrors
163
163
  * federation-cleanup.ts's `initFederationCleanup`).
164
164
  */
165
165
  export async function initNonceStoreCleanup(opts) {
@@ -170,11 +170,11 @@ export async function initNonceStoreCleanup(opts) {
170
170
  }
171
171
  else {
172
172
  try {
173
- const harper = await import("@harperfast/harper");
173
+ const harper = await import("harper");
174
174
  db = harper.databases;
175
175
  }
176
176
  catch (err) {
177
- console.error("[federation-nonce-store] failed to load @harperfast/harper:", err?.message ?? err);
177
+ console.error("[federation-nonce-store] failed to load harper:", err?.message ?? err);
178
178
  return;
179
179
  }
180
180
  }