@chude/memory 4.0.0 → 4.0.2

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 (60) hide show
  1. package/README.md +58 -11
  2. package/dist/application/services/embedding-service.d.ts +8 -1
  3. package/dist/application/services/friction-service.d.ts +18 -2
  4. package/dist/application/services/index.d.ts +11 -1
  5. package/dist/application/services/memory-governance-service.d.ts +65 -0
  6. package/dist/application/services/memory-ranking-service.d.ts +65 -0
  7. package/dist/application/services/persona-profile-service.d.ts +29 -0
  8. package/dist/application/services/projection-registry.d.ts +18 -0
  9. package/dist/application/services/remote-event-sync-service.d.ts +76 -0
  10. package/dist/application/services/smart-context-service.d.ts +34 -1
  11. package/dist/application/services/temporal-graph-service.d.ts +30 -0
  12. package/dist/domain/entities/graph-edge.d.ts +87 -0
  13. package/dist/domain/entities/index.d.ts +5 -0
  14. package/dist/domain/entities/memory-event.d.ts +101 -0
  15. package/dist/domain/entities/memory-governance.d.ts +100 -0
  16. package/dist/domain/entities/memory-utility-metric.d.ts +65 -0
  17. package/dist/domain/entities/persona-entry.d.ts +67 -0
  18. package/dist/domain/ports/capability.d.ts +35 -0
  19. package/dist/domain/ports/embedding.d.ts +21 -0
  20. package/dist/domain/ports/index.d.ts +1 -0
  21. package/dist/domain/ports/redactor.d.ts +3 -0
  22. package/dist/domain/ports/repositories.d.ts +155 -1
  23. package/dist/domain/ports/sources.d.ts +1 -1
  24. package/dist/domain/services/path-decoder.d.ts +1 -1
  25. package/dist/domain/value-objects/project-path.d.ts +2 -2
  26. package/dist/index.d.ts +2 -2
  27. package/dist/index.js +774 -328
  28. package/dist/infrastructure/capabilities/capability-status.d.ts +10 -0
  29. package/dist/infrastructure/capabilities/index.d.ts +1 -0
  30. package/dist/infrastructure/database/event-log.d.ts +40 -8
  31. package/dist/infrastructure/database/health-checker.d.ts +22 -1
  32. package/dist/infrastructure/database/index.d.ts +3 -3
  33. package/dist/infrastructure/database/repositories/embedding-repository.d.ts +18 -4
  34. package/dist/infrastructure/database/repositories/friction-repository.d.ts +2 -1
  35. package/dist/infrastructure/database/repositories/graph-repository.d.ts +17 -0
  36. package/dist/infrastructure/database/repositories/index.d.ts +4 -0
  37. package/dist/infrastructure/database/repositories/memory-governance-repository.d.ts +21 -0
  38. package/dist/infrastructure/database/repositories/memory-utility-repository.d.ts +15 -0
  39. package/dist/infrastructure/database/repositories/persona-repository.d.ts +16 -0
  40. package/dist/infrastructure/database/schema.d.ts +40 -0
  41. package/dist/infrastructure/embedding/embedding-provider-factory.d.ts +3 -2
  42. package/dist/infrastructure/embedding/ollama-provider.d.ts +1 -0
  43. package/dist/infrastructure/hooks/config-manager.d.ts +17 -0
  44. package/dist/infrastructure/providers/provider-egress-policy.d.ts +21 -0
  45. package/dist/infrastructure/providers/provider-registry.d.ts +8 -4
  46. package/dist/infrastructure/remote/git-remote-event-transport.d.ts +40 -0
  47. package/dist/infrastructure/security/pattern-redactor.d.ts +3 -0
  48. package/dist/infrastructure/security/secret-audit-service.d.ts +57 -0
  49. package/dist/infrastructure/sources/project-name-resolver.d.ts +2 -2
  50. package/dist/presentation/cli/commands/audit-secrets.d.ts +54 -0
  51. package/dist/presentation/cli/commands/friction/types.d.ts +13 -0
  52. package/dist/presentation/cli/commands/governance.d.ts +27 -0
  53. package/dist/presentation/cli/commands/index.d.ts +6 -0
  54. package/dist/presentation/cli/commands/profile.d.ts +23 -0
  55. package/dist/presentation/cli/commands/remote.d.ts +21 -3
  56. package/dist/presentation/cli/commands/sync/ambient.d.ts +7 -0
  57. package/dist/presentation/cli/commands/sync/types.d.ts +8 -12
  58. package/dist/presentation/cli/formatters/envelope.d.ts +2 -2
  59. package/dist/presentation/cli/index.js +918 -351
  60. package/package.json +9 -6
package/README.md CHANGED
@@ -51,11 +51,19 @@ memory show <session-id>
51
51
  # Find related sessions
52
52
  memory related <session-id>
53
53
 
54
- # Browse sessions interactively
55
- memory browse
56
- ```
57
-
58
- ## How It Works
54
+ # Browse sessions interactively
55
+ memory browse
56
+
57
+ # Audit durable memory surfaces for suspected secrets
58
+ memory audit-secrets
59
+
60
+ # Query durable friction signals for first-party tooling
61
+ memory friction list --tool aidev --since 2026-06-01 --count --min 3
62
+ ```
63
+
64
+ Machine consumers should use `memory friction list --json`; see [Friction Query Contract](docs/reference/friction-query-contract.md) for the versioned envelope, filter semantics, privacy behavior, and exit codes.
65
+
66
+ ## How It Works
59
67
 
60
68
  1. Claude Code stores sessions as JSONL files in `~/.claude/projects/`
61
69
  2. `memory sync` extracts messages, topics, and entities into a SQLite database with FTS5
@@ -114,6 +122,19 @@ Known secret patterns in newly synced transcript content, tool inputs/results, e
114
122
  memory export backup.json --include-sensitive
115
123
  ```
116
124
 
125
+ Run a read-only scan of the database and event logs before publishing, syncing to a remote, or reviewing older data:
126
+
127
+ ```bash
128
+ memory audit-secrets
129
+ memory audit-secrets --json
130
+ ```
131
+
132
+ Remediation is explicit. Database redaction rewrites mutable stored fields and rebuilds FTS indexes; event-log quarantine moves raw logs aside and writes sanitized active replacements:
133
+
134
+ ```bash
135
+ memory audit-secrets --redact-db --quarantine-events --report audit-report.json
136
+ ```
137
+
117
138
  ## Provider Support
118
139
 
119
140
  Provider support is explicit and registry-backed. Built-in embedding providers are `local`, `openai`, `ollama`, and `openai-compatible`. Built-in extraction providers are `claude-cli`, `anthropic`, `openai`, `ollama`, and `openai-compatible`.
@@ -132,6 +153,20 @@ Use `openai-compatible` for gateways or providers that expose OpenAI-compatible
132
153
 
133
154
  `LLM_PROVIDER` selects the extraction provider. `LLM_MODEL` overrides the extraction model without changing embedding configuration.
134
155
 
156
+ Remote provider egress is deny-by-default until the config grants consent and the target provider or host is allowlisted. Local providers do not require egress consent.
157
+
158
+ ```json
159
+ {
160
+ "providerEgress": {
161
+ "consent": "granted",
162
+ "allowedHosts": ["api.openai.com", "api.anthropic.com"],
163
+ "allowedProviders": ["openai", "anthropic", "claude-cli"]
164
+ }
165
+ }
166
+ ```
167
+
168
+ `memory status` and `memory doctor` report provider egress readiness without printing secrets. The experimental Git remote-sync path also runs an event-log secret preflight before any push and blocks remote sync until active logs are clean or quarantined.
169
+
135
170
  ## AI-First Design
136
171
 
137
172
  This tool is designed for Claude to use via the Bash tool:
@@ -196,9 +231,10 @@ const contextResult = await executeContextCommand("my-project", {
196
231
  | `executeBrowseCommand` | `options: BrowseCommandOptions` | `Promise<CommandResult>` |
197
232
  | `executeInstallCommand` | `options: InstallOptions` | `Promise<CommandResult>` |
198
233
  | `executeUninstallCommand` | `options: UninstallOptions` | `Promise<CommandResult>` |
199
- | `executeStatusCommand` | `options: StatusOptions` | `Promise<CommandResult>` |
200
- | `executeDoctorCommand` | `options: DoctorOptions` | `Promise<CommandResult>` |
201
- | `executePurgeCommand` | `options: PurgeCommandOptions` | `Promise<CommandResult>` |
234
+ | `executeStatusCommand` | `options: StatusOptions` | `Promise<CommandResult>` |
235
+ | `executeDoctorCommand` | `options: DoctorOptions` | `Promise<CommandResult>` |
236
+ | `executeAuditSecretsCommand` | `options: AuditSecretsOptions` | `Promise<CommandResult>` |
237
+ | `executePurgeCommand` | `options: PurgeCommandOptions` | `Promise<CommandResult>` |
202
238
  | `executeExportCommand` | `outputPath: string, options: ExportOptions` | `Promise<CommandResult>` |
203
239
  | `executeImportCommand` | `inputPath: string, options: ImportOptions` | `Promise<CommandResult>` |
204
240
  | `executeCompletionCommand` | `shell: string` | `CommandResult` |
@@ -206,9 +242,9 @@ const contextResult = await executeContextCommand("my-project", {
206
242
  ### CommandResult
207
243
 
208
244
  ```typescript
209
- interface CommandResult {
210
- exitCode: number; // 0 = success, 1 = error/not found
211
- }
245
+ interface CommandResult {
246
+ exitCode: number; // 0 = success, 1 = error/not found/findings, 2 = operational/remediation failure where used
247
+ }
212
248
  ```
213
249
 
214
250
  All functions handle their own database initialization and teardown. They never call `process.exit()`.
@@ -264,10 +300,21 @@ bun test --timeout 15000
264
300
  bun run test:isolation
265
301
  bun run test:coverage
266
302
  bun audit
303
+ gitleaks detect --no-banner --redact --source .
267
304
  ```
268
305
 
269
306
  `bun run quality` runs the release gate sequence. `bun run test:coverage` uses an Istanbul-backed Bun harness and is intentionally strict: statements, branches, functions, and lines must each be available and at least 95%. Missing metrics fail the gate.
270
307
 
308
+ ### Published package smoke
309
+
310
+ After publishing, verify registry metadata plus npm and Bun global installs:
311
+
312
+ ```bash
313
+ bun run verify:published @chude/memory@4.0.2
314
+ ```
315
+
316
+ On Windows, Bun global install creates `memory.exe` in `bun pm bin -g`. Do not assume an npm-style `memory.cmd` shim exists.
317
+
271
318
  ### Running tests on Windows
272
319
 
273
320
  Current 2026-05-28 verification has `bun test --timeout 15000` passing on Windows 11 with Bun 1.3.5. A previous full-suite run crashed with Bun's `panic(main thread): integer overflow` signature at ~6.8GB peak memory pressure; keep the subdirectory workaround available if that upstream runtime crash returns.
@@ -10,7 +10,7 @@
10
10
  * Sits between the presentation layer (sync command) and infrastructure
11
11
  * (repository + provider). Respects hexagonal architecture boundaries.
12
12
  */
13
- import type { IEmbeddingProvider } from "../../domain/ports/embedding.js";
13
+ import { type IEmbeddingProvider } from "../../domain/ports/embedding.js";
14
14
  import type { IRedactor } from "../../domain/ports/redactor.js";
15
15
  import type { IEmbeddingRepository, EmbeddingServiceConfig } from "../../domain/ports/repositories.js";
16
16
  /**
@@ -88,6 +88,7 @@ export declare class EmbeddingService {
88
88
  private readonly repository;
89
89
  private readonly provider;
90
90
  private readonly batchSize;
91
+ private readonly maxBatchBytes;
91
92
  private readonly modelHash;
92
93
  private readonly modelName;
93
94
  private readonly redactor;
@@ -128,4 +129,10 @@ export declare class EmbeddingService {
128
129
  * @returns Summary of the re-embedding operation
129
130
  */
130
131
  clearAndReembed(options?: EmbedOptions): Promise<EmbedResult>;
132
+ private prepareBatch;
133
+ private chunkByPayloadBytes;
134
+ private estimatePayloadBytes;
135
+ private embedChunk;
136
+ private markPayloadTooLargeSkip;
137
+ private getSkippedCountForCurrentModel;
131
138
  }
@@ -12,8 +12,9 @@
12
12
  * - wontFix flow: resolve() then updateStatus() for correct final state
13
13
  * - Auto-ingest: reads friction.jsonl fallback file, saves entries, deletes file
14
14
  */
15
- import type { IFrictionRepository, FrictionStats, FrictionPattern } from "../../domain/ports/repositories.js";
15
+ import type { IFrictionRepository, FrictionStats, FrictionPattern, FrictionQueryResult } from "../../domain/ports/repositories.js";
16
16
  import { FrictionEntry, type FrictionSeverity, type FrictionCategory } from "../../domain/entities/friction-entry.js";
17
+ import type { IRedactor } from "../../domain/ports/redactor.js";
17
18
  /**
18
19
  * Parameters for logging a new friction entry.
19
20
  */
@@ -32,9 +33,13 @@ export interface LogFrictionParams {
32
33
  export interface ListFrictionOptions {
33
34
  all?: boolean | undefined;
34
35
  status?: string | undefined;
36
+ severity?: string | undefined;
35
37
  category?: string | undefined;
36
38
  tool?: string | undefined;
37
39
  sourceProject?: string | undefined;
40
+ since?: Date | undefined;
41
+ descriptionContains?: string | undefined;
42
+ contextContains?: string | undefined;
38
43
  limit?: number | undefined;
39
44
  }
40
45
  /**
@@ -45,7 +50,8 @@ export interface ListFrictionOptions {
45
50
  */
46
51
  export declare class FrictionService {
47
52
  private readonly repository;
48
- constructor(repository: IFrictionRepository);
53
+ private readonly redactor;
54
+ constructor(repository: IFrictionRepository, redactor?: IRedactor);
49
55
  /**
50
56
  * Log a new friction entry.
51
57
  *
@@ -66,6 +72,16 @@ export declare class FrictionService {
66
72
  * @returns Array of matching friction entries
67
73
  */
68
74
  list(options?: ListFrictionOptions): Promise<FrictionEntry[]>;
75
+ /**
76
+ * Query friction entries using the durable friction contract.
77
+ *
78
+ * Default behavior remains open-only. Explicit status wins; `all: true`
79
+ * removes the default status filter when no status is provided.
80
+ *
81
+ * @param options Query options
82
+ * @returns Matching entries and total count before limit is applied
83
+ */
84
+ query(options?: ListFrictionOptions): Promise<FrictionQueryResult>;
69
85
  /**
70
86
  * Resolve a friction entry.
71
87
  *
@@ -29,6 +29,16 @@ export type { BackfillResult, BackfillProgress, DryRunResult, BackfillOptions, I
29
29
  export { allocateBudget } from "./budget-allocator.js";
30
30
  export type { BudgetSection, AllocatedSection, BudgetAllocationResult, } from "./budget-allocator.js";
31
31
  export { SmartContextService } from "./smart-context-service.js";
32
- export type { SmartContextOptions, SmartContextResult, ContextSection, IProjectResolver, SmartContextDeps, } from "./smart-context-service.js";
32
+ export type { SmartContextOptions, SmartContextResult, ContextSection, IProjectResolver, IContextGovernancePolicy, SmartContextDeps, } from "./smart-context-service.js";
33
33
  export { AmbientContextService } from "./ambient-context-service.js";
34
34
  export type { AmbientContextOptions, AmbientContextResult, } from "./ambient-context-service.js";
35
+ export { ProjectionRegistry } from "./projection-registry.js";
36
+ export { PersonaProfileService, personaEntryFromFactEvent } from "./persona-profile-service.js";
37
+ export { TemporalGraphService, graphEdgesFromFact, governanceEntryForGraphEdge, } from "./temporal-graph-service.js";
38
+ export { MemoryRankingService, candidateFromFact, candidateFromGraphEdge, candidateFromPersonaEntry, } from "./memory-ranking-service.js";
39
+ export type { MemoryRankCandidate, MemoryRankKind, MemoryRankingPolicy, MemoryRankingServiceDeps, RankedMemory, RankedMemoryComponents, } from "./memory-ranking-service.js";
40
+ export type { EventProjection, ProjectionReplayResult, } from "./projection-registry.js";
41
+ export { MemoryGovernanceService } from "./memory-governance-service.js";
42
+ export type { GovernanceControlCommand, MemoryEventWriter, MemoryGovernanceServiceDeps, RegisterDerivedMemoryParams, } from "./memory-governance-service.js";
43
+ export { RemoteEventSyncService, validateMachineIdentity, validateRemoteRef, validateRemoteRepositoryUrl, } from "./remote-event-sync-service.js";
44
+ export type { RemoteEventSyncRequest, RemoteEventSyncResult, RemoteEventSyncServiceDeps, RemoteEventTransport, RemoteGitIdentity, RemotePrivacyPreflightPort, RemoteProjectionRebuilderPort, RemoteTransportCommandResult, } from "./remote-event-sync-service.js";
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Memory governance service.
3
+ *
4
+ * Application-layer orchestration for durable consent/provenance controls.
5
+ * It emits canonical memory events and updates the governance projection.
6
+ */
7
+ import { MemoryEventEnvelope, type ConsentStatus, type RedactionState } from "../../domain/entities/memory-event.js";
8
+ import { MemoryGovernanceEntry, type MemoryGovernanceSurface } from "../../domain/entities/memory-governance.js";
9
+ import type { IMemoryGovernanceRepository, MemoryGovernanceListOptions } from "../../domain/ports/repositories.js";
10
+ export interface MemoryEventWriter {
11
+ (event: MemoryEventEnvelope): Promise<void>;
12
+ }
13
+ export interface RegisterDerivedMemoryParams {
14
+ surface: MemoryGovernanceSurface;
15
+ targetId: string;
16
+ project?: string | undefined;
17
+ sourceEventIds: string[];
18
+ transformationMethod: string;
19
+ actor?: string | undefined;
20
+ confidence?: number | undefined;
21
+ redactionState?: RedactionState | undefined;
22
+ consentStatus?: ConsentStatus | undefined;
23
+ consentScopes?: string[] | undefined;
24
+ visibility?: "project" | "workspace" | "global" | undefined;
25
+ expiresAt?: Date | null | undefined;
26
+ }
27
+ export interface GovernanceControlCommand {
28
+ surface: MemoryGovernanceSurface;
29
+ targetId: string;
30
+ actor?: string | undefined;
31
+ reason?: string | undefined;
32
+ expiresAt?: Date | null | undefined;
33
+ consentStatus?: ConsentStatus | undefined;
34
+ consentScopes?: string[] | undefined;
35
+ }
36
+ export interface MemoryGovernanceServiceDeps {
37
+ repository: IMemoryGovernanceRepository;
38
+ writeEvent?: MemoryEventWriter | undefined;
39
+ machineId?: string | undefined;
40
+ now?: (() => Date) | undefined;
41
+ nextSequence?: (() => number) | undefined;
42
+ }
43
+ export declare class MemoryGovernanceService {
44
+ private readonly repository;
45
+ private readonly writeEvent?;
46
+ private readonly machineId;
47
+ private readonly now;
48
+ private readonly nextSequence;
49
+ constructor(deps: MemoryGovernanceServiceDeps);
50
+ registerDerivedMemory(params: RegisterDerivedMemoryParams): Promise<MemoryGovernanceEntry>;
51
+ suppress(params: GovernanceControlCommand): Promise<MemoryGovernanceEntry>;
52
+ unsuppress(params: GovernanceControlCommand): Promise<MemoryGovernanceEntry>;
53
+ invalidate(params: GovernanceControlCommand): Promise<MemoryGovernanceEntry>;
54
+ expire(params: GovernanceControlCommand): Promise<MemoryGovernanceEntry>;
55
+ review(params: GovernanceControlCommand): Promise<MemoryGovernanceEntry>;
56
+ grantConsent(params: GovernanceControlCommand): Promise<MemoryGovernanceEntry>;
57
+ revokeConsent(params: GovernanceControlCommand): Promise<MemoryGovernanceEntry>;
58
+ list(options?: MemoryGovernanceListOptions): Promise<MemoryGovernanceEntry[]>;
59
+ show(surface: MemoryGovernanceSurface, targetId: string): Promise<MemoryGovernanceEntry | null>;
60
+ isAllowed(surface: MemoryGovernanceSurface, targetId: string): Promise<boolean>;
61
+ filterAllowed<T>(surface: MemoryGovernanceSurface, items: T[], getTargetId: (item: T) => string): Promise<T[]>;
62
+ private applyControl;
63
+ private createEvent;
64
+ private persistEvent;
65
+ }
@@ -0,0 +1,65 @@
1
+ import type { Fact, FactType } from "../../domain/entities/fact.js";
2
+ import type { GraphEdge } from "../../domain/entities/graph-edge.js";
3
+ import type { MemoryGovernanceStatus } from "../../domain/entities/memory-governance.js";
4
+ import type { MemoryUtilityMetric, MemoryUtilitySurface } from "../../domain/entities/memory-utility-metric.js";
5
+ import type { PersonaEntry, PersonaEntryKind } from "../../domain/entities/persona-entry.js";
6
+ export type MemoryRankKind = MemoryUtilitySurface;
7
+ export interface MemoryRankCandidate {
8
+ id: string;
9
+ kind: MemoryRankKind;
10
+ memoryType?: string | undefined;
11
+ content: string;
12
+ project?: string | undefined;
13
+ observedAt?: Date | undefined;
14
+ validFrom?: Date | undefined;
15
+ validTo?: Date | null | undefined;
16
+ supersededAt?: Date | null | undefined;
17
+ confidence?: number | undefined;
18
+ importance?: number | undefined;
19
+ utility?: number | undefined;
20
+ evergreen?: boolean | undefined;
21
+ pinned?: boolean | undefined;
22
+ recencyNoisePenalty?: number | undefined;
23
+ governanceStatus?: MemoryGovernanceStatus | "reviewed" | undefined;
24
+ metric?: MemoryUtilityMetric | undefined;
25
+ }
26
+ export interface RankedMemoryComponents {
27
+ importance: number;
28
+ utility: number;
29
+ confidence: number;
30
+ accessBoost: number;
31
+ accessCount: number;
32
+ halfLifeDays: number;
33
+ ageDays: number;
34
+ decayMultiplier: number;
35
+ recencyNoisePenalty: number;
36
+ baseScore: number;
37
+ finalScore: number;
38
+ }
39
+ export interface RankedMemory extends MemoryRankCandidate {
40
+ score: number;
41
+ whyIncluded: string;
42
+ components: RankedMemoryComponents;
43
+ }
44
+ export interface MemoryRankingPolicy {
45
+ defaultHalfLifeDays?: number | undefined;
46
+ halfLifeByKind?: Partial<Record<MemoryRankKind, number>> | undefined;
47
+ halfLifeByFactType?: Partial<Record<FactType, number>> | undefined;
48
+ halfLifeByPersonaKind?: Partial<Record<PersonaEntryKind, number>> | undefined;
49
+ }
50
+ export interface MemoryRankingServiceDeps {
51
+ now?: (() => Date) | undefined;
52
+ policy?: MemoryRankingPolicy | undefined;
53
+ }
54
+ export declare class MemoryRankingService {
55
+ private readonly now;
56
+ private readonly policy;
57
+ constructor(deps?: MemoryRankingServiceDeps);
58
+ rank(candidates: MemoryRankCandidate[]): RankedMemory[];
59
+ private isEligible;
60
+ private scoreCandidate;
61
+ private resolveHalfLifeDays;
62
+ }
63
+ export declare function candidateFromFact(fact: Fact, metric?: MemoryUtilityMetric | undefined): MemoryRankCandidate;
64
+ export declare function candidateFromPersonaEntry(entry: PersonaEntry, metric?: MemoryUtilityMetric | undefined): MemoryRankCandidate;
65
+ export declare function candidateFromGraphEdge(edge: GraphEdge, metric?: MemoryUtilityMetric | undefined): MemoryRankCandidate;
@@ -0,0 +1,29 @@
1
+ import { Fact } from "../../domain/entities/fact.js";
2
+ import { PersonaEntry } from "../../domain/entities/persona-entry.js";
3
+ import type { IFactRepository, IFrictionRepository, IMemoryGovernanceRepository, IPersonaRepository } from "../../domain/ports/repositories.js";
4
+ export interface PersonaProfileServiceDeps {
5
+ factRepo: IFactRepository;
6
+ frictionRepo: IFrictionRepository;
7
+ personaRepo: IPersonaRepository;
8
+ governanceRepo: IMemoryGovernanceRepository;
9
+ now?: () => Date;
10
+ }
11
+ export interface PersonaRebuildOptions {
12
+ project?: string | undefined;
13
+ }
14
+ export interface PersonaRebuildResult {
15
+ entries: PersonaEntry[];
16
+ factCount: number;
17
+ frictionPatternCount: number;
18
+ }
19
+ export declare class PersonaProfileService {
20
+ private readonly deps;
21
+ private readonly now;
22
+ constructor(deps: PersonaProfileServiceDeps);
23
+ rebuildProfile(options?: PersonaRebuildOptions): Promise<PersonaRebuildResult>;
24
+ private entryFromFact;
25
+ private entryFromFrictionPattern;
26
+ private governanceEntryFor;
27
+ }
28
+ export declare function personaEntriesFromFact(fact: Fact, now?: Date): PersonaEntry[];
29
+ export declare function personaEntryFromFactEvent(fact: Fact, now?: Date): PersonaEntry | null;
@@ -0,0 +1,18 @@
1
+ import type { MemoryEventEnvelope, MemoryEventKind } from "../../domain/entities/memory-event.js";
2
+ export interface EventProjection<TContext> {
3
+ name: string;
4
+ consumedKinds: readonly MemoryEventKind[];
5
+ reset?: (context: TContext) => void | Promise<void>;
6
+ apply: (event: MemoryEventEnvelope, context: TContext) => void | boolean | Promise<void | boolean>;
7
+ }
8
+ export interface ProjectionReplayResult {
9
+ processedEvents: number;
10
+ skippedDuplicateEvents: number;
11
+ appliedProjections: string[];
12
+ }
13
+ export declare class ProjectionRegistry<TContext> {
14
+ private readonly projections;
15
+ constructor(projections: EventProjection<TContext>[]);
16
+ getConsumedKinds(projectionName: string): MemoryEventKind[];
17
+ replay(events: Iterable<MemoryEventEnvelope>, context: TContext): Promise<ProjectionReplayResult>;
18
+ }
@@ -0,0 +1,76 @@
1
+ export interface RemoteValidationResult {
2
+ valid: boolean;
3
+ error?: string;
4
+ }
5
+ export interface RemoteTransportCommandResult {
6
+ success: boolean;
7
+ error?: string;
8
+ skipped?: boolean;
9
+ }
10
+ export interface RemoteGitIdentity {
11
+ machineId: string;
12
+ userName: string;
13
+ userEmail: string;
14
+ }
15
+ export interface RemoteEventTransport {
16
+ isRepository(): Promise<boolean>;
17
+ initRepository(identity: RemoteGitIdentity): Promise<RemoteTransportCommandResult>;
18
+ getRemoteUrl(): Promise<string | null>;
19
+ setRemoteUrl(remoteUrl: string): Promise<RemoteTransportCommandResult>;
20
+ listEventLogFingerprints(): Promise<Record<string, string>>;
21
+ hasEventLog(machineId: string): Promise<boolean>;
22
+ commitEventLog(machineId: string, message: string): Promise<RemoteTransportCommandResult>;
23
+ fetch(remoteName: string): Promise<RemoteTransportCommandResult>;
24
+ hasRemoteRef(remoteName: string, ref: string): Promise<boolean>;
25
+ pullRebase(remoteName: string, ref: string): Promise<RemoteTransportCommandResult>;
26
+ abortRebase(): Promise<RemoteTransportCommandResult>;
27
+ push(remoteName: string, ref: string): Promise<RemoteTransportCommandResult>;
28
+ }
29
+ export interface RemotePrivacyPreflightPort {
30
+ audit(): Promise<{
31
+ eventLogFindings: number;
32
+ }>;
33
+ }
34
+ export interface RemoteProjectionRebuilderPort {
35
+ rebuild(): Promise<void>;
36
+ }
37
+ export interface RemoteEventSyncServiceDeps {
38
+ transport: RemoteEventTransport;
39
+ privacyPreflight?: RemotePrivacyPreflightPort;
40
+ projectionRebuilder?: RemoteProjectionRebuilderPort;
41
+ now?: () => Date;
42
+ }
43
+ export interface RemoteEventSyncRequest {
44
+ machineId: string;
45
+ repositoryUrl: string;
46
+ branch?: string;
47
+ remoteName?: string;
48
+ autoPull?: boolean;
49
+ autoPush?: boolean;
50
+ allowLocalPathRemote?: boolean;
51
+ }
52
+ export interface RemoteEventSyncResult {
53
+ success: boolean;
54
+ status: "synced" | "blocked" | "failed";
55
+ rebuildNeeded: boolean;
56
+ projectionRebuilt: boolean;
57
+ pulled: boolean;
58
+ pushed: boolean;
59
+ configuredRemote: boolean;
60
+ initializedRepository: boolean;
61
+ error: string | undefined;
62
+ }
63
+ export declare function validateRemoteRepositoryUrl(value: string, options?: {
64
+ allowLocalPathRemote?: boolean;
65
+ }): RemoteValidationResult;
66
+ export declare function validateRemoteRef(ref: string): RemoteValidationResult;
67
+ export declare function validateMachineIdentity(machineId: string): RemoteValidationResult;
68
+ export declare class RemoteEventSyncService {
69
+ private readonly transport;
70
+ private readonly privacyPreflight;
71
+ private readonly projectionRebuilder;
72
+ private readonly now;
73
+ constructor(deps: RemoteEventSyncServiceDeps);
74
+ sync(request: RemoteEventSyncRequest): Promise<RemoteEventSyncResult>;
75
+ private rebuildIfNeeded;
76
+ }
@@ -17,7 +17,9 @@
17
17
  * Dependencies injected via constructor for hexagonal architecture.
18
18
  * Zero imports from infrastructure layer.
19
19
  */
20
- import type { IFactRepository, IFrictionRepository } from "../../domain/ports/repositories.js";
20
+ import type { IFactRepository, IFrictionRepository, IPersonaRepository, IGraphRepository, IMemoryUtilityRepository } from "../../domain/ports/repositories.js";
21
+ import type { MemoryGovernanceSurface } from "../../domain/entities/memory-governance.js";
22
+ import { type MemoryRankingService } from "./memory-ranking-service.js";
21
23
  /**
22
24
  * Options for smart context retrieval.
23
25
  */
@@ -77,6 +79,13 @@ export interface IProjectResolver {
77
79
  */
78
80
  resolveProjectName(projectFilter: string): string | null;
79
81
  }
82
+ /**
83
+ * Optional governance policy used to suppress/expire/invalidate derived memory
84
+ * before it reaches context assembly or AI-facing output.
85
+ */
86
+ export interface IContextGovernancePolicy {
87
+ filterAllowed<T>(surface: MemoryGovernanceSurface, items: T[], getTargetId: (item: T) => string): Promise<T[]>;
88
+ }
80
89
  /**
81
90
  * Dependencies for SmartContextService (constructor injection).
82
91
  */
@@ -84,6 +93,11 @@ export interface SmartContextDeps {
84
93
  projectResolver: IProjectResolver;
85
94
  factRepo: IFactRepository;
86
95
  frictionRepo: IFrictionRepository;
96
+ personaRepo?: IPersonaRepository | undefined;
97
+ graphRepo?: IGraphRepository | undefined;
98
+ governancePolicy?: IContextGovernancePolicy | undefined;
99
+ rankingService?: MemoryRankingService | undefined;
100
+ utilityRepo?: IMemoryUtilityRepository | undefined;
87
101
  /** Optional legacy session summary provider */
88
102
  getSessionSummary?: (projectFilter: string, days?: number) => Promise<string | null>;
89
103
  now?: () => Date;
@@ -98,7 +112,13 @@ export declare class SmartContextService {
98
112
  private readonly projectResolver;
99
113
  private readonly factRepo;
100
114
  private readonly frictionRepo;
115
+ private readonly personaRepo?;
116
+ private readonly graphRepo?;
117
+ private readonly governancePolicy?;
118
+ private readonly rankingService?;
119
+ private readonly utilityRepo?;
101
120
  private readonly getSessionSummary?;
121
+ private readonly now;
102
122
  constructor(deps: SmartContextDeps);
103
123
  /**
104
124
  * Get structured context for a project.
@@ -119,6 +139,19 @@ export declare class SmartContextService {
119
139
  * Returns null if no friction entries exist.
120
140
  */
121
141
  private buildFrictionContent;
142
+ private buildPersonaContent;
143
+ private buildGraphContent;
144
+ private rankFacts;
145
+ private rankPersona;
146
+ private rankGraph;
147
+ private lookupMetrics;
148
+ /**
149
+ * Remove derived facts blocked by governance controls. Ungoverned facts are
150
+ * allowed for backward compatibility with pre-governance databases.
151
+ */
152
+ private filterAllowedFacts;
153
+ private filterAllowedPersona;
154
+ private filterAllowedGraph;
122
155
  /**
123
156
  * Apply budget allocation and return result with truncation info.
124
157
  */
@@ -0,0 +1,30 @@
1
+ import { Fact } from "../../domain/entities/fact.js";
2
+ import { GraphEdge } from "../../domain/entities/graph-edge.js";
3
+ import { MemoryGovernanceEntry } from "../../domain/entities/memory-governance.js";
4
+ import type { GraphEdgeQueryOptions, IFactRepository, IGraphRepository, IMemoryGovernanceRepository } from "../../domain/ports/repositories.js";
5
+ import type { IContextGovernancePolicy } from "./smart-context-service.js";
6
+ export interface TemporalGraphServiceDeps {
7
+ graphRepo: IGraphRepository;
8
+ factRepo?: IFactRepository | undefined;
9
+ governanceRepo?: IMemoryGovernanceRepository | undefined;
10
+ governancePolicy?: IContextGovernancePolicy | undefined;
11
+ now?: (() => Date) | undefined;
12
+ }
13
+ export interface GraphRebuildOptions {
14
+ project?: string | undefined;
15
+ }
16
+ export interface GraphRebuildResult {
17
+ edges: GraphEdge[];
18
+ edgeCount: number;
19
+ factCount: number;
20
+ }
21
+ export declare class TemporalGraphService {
22
+ private readonly deps;
23
+ private readonly now;
24
+ constructor(deps: TemporalGraphServiceDeps);
25
+ rebuildGraph(options?: GraphRebuildOptions): Promise<GraphRebuildResult>;
26
+ findContextEdges(options: GraphEdgeQueryOptions): Promise<GraphEdge[]>;
27
+ formatContextLines(edges: GraphEdge[]): string[];
28
+ }
29
+ export declare function graphEdgesFromFact(fact: Fact, now?: Date): GraphEdge[];
30
+ export declare function governanceEntryForGraphEdge(edge: GraphEdge, transformationMethod: string): MemoryGovernanceEntry;
@@ -0,0 +1,87 @@
1
+ import type { MemoryEventScope, MemoryEventVisibility } from "./memory-event.js";
2
+ export declare const GRAPH_NODE_TYPES: readonly ["project", "tool", "person", "decision", "error", "plan", "file", "command", "capability"];
3
+ export type GraphNodeType = (typeof GRAPH_NODE_TYPES)[number];
4
+ export interface GraphNodeRef {
5
+ type: GraphNodeType;
6
+ id: string;
7
+ label: string;
8
+ }
9
+ export interface GraphEdgeParams {
10
+ id?: number | undefined;
11
+ edgeId?: string | undefined;
12
+ source: GraphNodeRef;
13
+ target: GraphNodeRef;
14
+ relationship: string;
15
+ project?: string | undefined;
16
+ visibility: MemoryEventVisibility;
17
+ sourceEventIds: string[];
18
+ sourceKinds: string[];
19
+ confidence: number;
20
+ validFrom: Date;
21
+ validTo?: Date | null | undefined;
22
+ why: string;
23
+ metadata?: Record<string, unknown> | undefined;
24
+ createdAt: Date;
25
+ updatedAt: Date;
26
+ }
27
+ export interface GraphEdgeJson {
28
+ id?: number | undefined;
29
+ edge_id: string;
30
+ source: GraphNodeRef;
31
+ target: GraphNodeRef;
32
+ relationship: string;
33
+ project?: string | undefined;
34
+ visibility: MemoryEventVisibility;
35
+ source_event_ids: string[];
36
+ source_kinds: string[];
37
+ confidence: number;
38
+ valid_from: string;
39
+ valid_to: string | null;
40
+ why: string;
41
+ scope: MemoryEventScope;
42
+ metadata?: Record<string, unknown> | undefined;
43
+ controls: string[];
44
+ created_at: string;
45
+ updated_at: string;
46
+ }
47
+ export declare class GraphEdge {
48
+ private readonly _id?;
49
+ private readonly _edgeId;
50
+ private readonly _source;
51
+ private readonly _target;
52
+ private readonly _relationship;
53
+ private readonly _project?;
54
+ private readonly _visibility;
55
+ private readonly _sourceEventIds;
56
+ private readonly _sourceKinds;
57
+ private readonly _confidence;
58
+ private readonly _validFrom;
59
+ private readonly _validTo;
60
+ private readonly _why;
61
+ private readonly _metadata?;
62
+ private readonly _createdAt;
63
+ private readonly _updatedAt;
64
+ private constructor();
65
+ static create(params: GraphEdgeParams): GraphEdge;
66
+ get id(): number | undefined;
67
+ get edgeId(): string;
68
+ get source(): GraphNodeRef;
69
+ get target(): GraphNodeRef;
70
+ get relationship(): string;
71
+ get project(): string | undefined;
72
+ get visibility(): MemoryEventVisibility;
73
+ get sourceEventIds(): string[];
74
+ get sourceKinds(): string[];
75
+ get confidence(): number;
76
+ get validFrom(): Date;
77
+ get validTo(): Date | null;
78
+ get why(): string;
79
+ get metadata(): Record<string, unknown> | undefined;
80
+ get createdAt(): Date;
81
+ get updatedAt(): Date;
82
+ get scope(): MemoryEventScope;
83
+ get controls(): string[];
84
+ isCurrent(asOf: Date, minConfidence?: number): boolean;
85
+ withId(id: number): GraphEdge;
86
+ toJSON(): GraphEdgeJson;
87
+ }
@@ -13,3 +13,8 @@ export { MemoryFile, type MemoryFileType } from "./memory-file.js";
13
13
  export { FrictionEntry, type FrictionSeverity, type FrictionCategory, type FrictionStatus, } from "./friction-entry.js";
14
14
  export { BackfillState } from "./backfill-state.js";
15
15
  export { Fact, type FactType, type FactParams, type CandidateFact } from "./fact.js";
16
+ export { MemoryEventEnvelope, MEMORY_EVENT_SCHEMA_VERSION, type ConsentStatus, type MemoryEventCausality, type MemoryEventConsent, type MemoryEventCreateParams, type MemoryEventEnvelopeJson, type MemoryEventIntegrity, type MemoryEventKind, type MemoryEventOperation, type MemoryEventPrivacy, type MemoryEventProvenance, type MemoryEventScope, type MemoryEventVisibility, type RedactionState, } from "./memory-event.js";
17
+ export { MemoryGovernanceEntry, MEMORY_GOVERNANCE_CONTROLS, MEMORY_GOVERNANCE_STATUSES, MEMORY_GOVERNANCE_SURFACES, assertMemoryGovernanceControl, assertMemoryGovernanceSurface, type GovernanceControlParams, type MemoryGovernanceControl, type MemoryGovernanceEntryJson, type MemoryGovernanceEntryParams, type MemoryGovernanceStatus, type MemoryGovernanceSurface, } from "./memory-governance.js";
18
+ export { PersonaEntry, PERSONA_ENTRY_CONTROLS, PERSONA_ENTRY_KINDS, type PersonaEntryJson, type PersonaEntryKind, type PersonaEntryParams, type PersonaReviewStatus, } from "./persona-entry.js";
19
+ export { GraphEdge, GRAPH_NODE_TYPES, type GraphEdgeJson, type GraphEdgeParams, type GraphNodeRef, type GraphNodeType, } from "./graph-edge.js";
20
+ export { MemoryUtilityMetric, MEMORY_UTILITY_CONTROLS, MEMORY_UTILITY_SURFACES, type MemoryUtilityControl, type MemoryUtilityMetricJson, type MemoryUtilityMetricParams, type MemoryUtilitySurface, } from "./memory-utility-metric.js";