@inixiative/foundry-core 0.5.8 → 0.5.10

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 (50) hide show
  1. package/package.json +4 -4
  2. package/src/action-prompt.ts +11 -2
  3. package/src/adapters/file-memory.ts +5 -0
  4. package/src/adapters/http-memory.ts +5 -0
  5. package/src/adapters/markdown-docs.ts +5 -0
  6. package/src/adapters/markdown-hierarchy.ts +7 -2
  7. package/src/adapters/sqlite-memory.ts +21 -6
  8. package/src/base-agent.ts +5 -0
  9. package/src/bounded-set.ts +5 -0
  10. package/src/cache-lifecycle.ts +5 -0
  11. package/src/capability.ts +5 -0
  12. package/src/clarifier.ts +5 -0
  13. package/src/classifier.ts +5 -0
  14. package/src/context-layer.ts +10 -0
  15. package/src/context-stack.ts +5 -0
  16. package/src/credentials.ts +5 -0
  17. package/src/decider.ts +5 -0
  18. package/src/delivery-evidence.ts +5 -0
  19. package/src/event-stream.ts +5 -0
  20. package/src/executor.ts +17 -4
  21. package/src/feedback/archive-turns.ts +25 -4
  22. package/src/feedback/correction.ts +13 -1
  23. package/src/feedback/experiment-gate.ts +5 -0
  24. package/src/feedback/review-findings.ts +5 -0
  25. package/src/feedback/warden-labels.ts +5 -0
  26. package/src/feedback/warden-prefilter.ts +5 -0
  27. package/src/feedback/warden-probes.ts +5 -0
  28. package/src/harness.ts +7 -2
  29. package/src/hydrator.ts +5 -0
  30. package/src/id.ts +5 -0
  31. package/src/index.ts +23 -11
  32. package/src/intervention.ts +5 -0
  33. package/src/messages.ts +5 -0
  34. package/src/middleware.ts +5 -0
  35. package/src/model-registry.ts +92 -2
  36. package/src/native-evidence.ts +18 -0
  37. package/src/native-tools.ts +5 -0
  38. package/src/retry.ts +5 -0
  39. package/src/router.ts +5 -0
  40. package/src/scope.ts +5 -0
  41. package/src/serialized-queue.ts +35 -0
  42. package/src/session-delivery.ts +5 -0
  43. package/src/signal.ts +5 -0
  44. package/src/thread.ts +196 -6
  45. package/src/token-counts.ts +5 -0
  46. package/src/token-tracker.ts +49 -24
  47. package/src/tools.ts +6 -1
  48. package/src/trace.ts +5 -0
  49. package/src/types.ts +5 -0
  50. package/src/hooks.ts +0 -133
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inixiative/foundry-core",
3
- "version": "0.5.8",
3
+ "version": "0.5.10",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "types": "src/index.ts",
@@ -30,10 +30,10 @@
30
30
  "access": "public"
31
31
  },
32
32
  "engines": {
33
- "bun": ">=1.4.2"
33
+ "bun": ">=1.4.4"
34
34
  },
35
35
  "peerDependencies": {
36
- "@inixiative/archive": "^0.24.0"
36
+ "@inixiative/archive": "^0.32.0"
37
37
  },
38
38
  "peerDependenciesMeta": {
39
39
  "@inixiative/archive": {
@@ -41,6 +41,6 @@
41
41
  }
42
42
  },
43
43
  "devDependencies": {
44
- "@inixiative/archive": "^0.24.0"
44
+ "@inixiative/archive": "^0.32.0"
45
45
  }
46
46
  }
@@ -1,3 +1,9 @@
1
+ /**
2
+ * @atlas
3
+ * @kind service
4
+ * @partOf primitive:signals
5
+ */
6
+ import { newId } from './id';
1
7
  // ---------------------------------------------------------------------------
2
8
  // ActionPrompt — blocking agent→human interaction primitive
3
9
  // ---------------------------------------------------------------------------
@@ -30,6 +36,8 @@ export interface ActionResolution {
30
36
  readonly by: 'human' | 'policy' | 'timeout';
31
37
  readonly action: string; // "approved", "rejected", or an option ID
32
38
  readonly input?: string; // for "input" kind prompts
39
+ /** Context the user typed in the message box and sent with this answer. */
40
+ readonly note?: string;
33
41
  readonly timestamp: number;
34
42
  }
35
43
 
@@ -129,7 +137,7 @@ export class ActionQueue {
129
137
  * Returns the resolution (human choice, policy decision, or timeout).
130
138
  */
131
139
  async prompt(opts: PromptOpts): Promise<ActionResolution> {
132
- const id = `prompt-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
140
+ const id = newId('prompt');
133
141
 
134
142
  const prompt: ActionPrompt = {
135
143
  id,
@@ -197,7 +205,7 @@ export class ActionQueue {
197
205
  resolve(
198
206
  promptId: string,
199
207
  action: string,
200
- opts?: { by?: 'human' | 'policy'; input?: string },
208
+ opts?: { by?: 'human' | 'policy'; input?: string; note?: string },
201
209
  ): boolean {
202
210
  const prompt = this._prompts.get(promptId);
203
211
  if (!prompt || prompt.status !== 'pending') return false;
@@ -206,6 +214,7 @@ export class ActionQueue {
206
214
  by: opts?.by ?? 'human',
207
215
  action,
208
216
  input: opts?.input,
217
+ ...(opts?.note ? { note: opts.note } : {}),
209
218
  timestamp: Date.now(),
210
219
  };
211
220
 
@@ -1,3 +1,8 @@
1
+ /**
2
+ * @atlas
3
+ * @kind adapter
4
+ * @partOf primitive:memory
5
+ */
1
6
  import { existsSync, mkdirSync } from 'node:fs';
2
7
  import { join, relative, resolve } from 'node:path';
3
8
  import {
@@ -1,3 +1,8 @@
1
+ /**
2
+ * @atlas
3
+ * @kind adapter
4
+ * @partOf primitive:memory
5
+ */
1
6
  import type { ContextSource } from '../context-layer';
2
7
  import type { ContextRef, HydrationAdapter } from '../hydrator';
3
8
  import type { Signal } from '../signal';
@@ -1,3 +1,8 @@
1
+ /**
2
+ * @atlas
3
+ * @kind adapter
4
+ * @partOf primitive:memory
5
+ */
1
6
  import { existsSync, realpathSync } from 'node:fs';
2
7
  import { realpath, stat } from 'node:fs/promises';
3
8
  import { homedir } from 'node:os';
@@ -1,6 +1,11 @@
1
- import { createHash } from 'node:crypto';
1
+ /**
2
+ * @atlas
3
+ * @kind adapter
4
+ * @partOf feature:composition
5
+ */
2
6
  import { readFileSync, realpathSync, statSync } from 'node:fs';
3
7
  import { basename, dirname, isAbsolute, join, resolve, sep } from 'node:path';
8
+ import { sha256Hex } from '../context-layer';
4
9
  import {
5
10
  fenceSegments,
6
11
  INSTRUCTION_FILE_LIMIT,
@@ -685,7 +690,7 @@ export async function discoverHierarchy(
685
690
  return { files, duplicates, refused, probes: [...probes] };
686
691
  }
687
692
 
688
- const digest = (text: string) => createHash('sha256').update(text).digest('hex');
693
+ const digest = sha256Hex;
689
694
 
690
695
  /**
691
696
  * Blank lines, trailing whitespace, line endings and runs of spaces inside a line do not make two
@@ -1,3 +1,8 @@
1
+ /**
2
+ * @atlas
3
+ * @kind adapter
4
+ * @partOf primitive:memory
5
+ */
1
6
  import { Database } from 'bun:sqlite';
2
7
  import type { ContextSource } from '../context-layer';
3
8
  import type { ContextRef, HydrationAdapter } from '../hydrator';
@@ -71,7 +76,7 @@ export class SqliteMemory {
71
76
 
72
77
  /** Read by id. */
73
78
  get(id: string): SqliteEntry | undefined {
74
- const row = this.db.query('SELECT * FROM entries WHERE id = ?').get(id) as any;
79
+ const row = this.db.query('SELECT * FROM entries WHERE id = ?').get(id) as SqliteRow | null;
75
80
  return row ? this._rowToEntry(row) : undefined;
76
81
  }
77
82
 
@@ -81,7 +86,7 @@ export class SqliteMemory {
81
86
  ? this.db.query('SELECT * FROM entries WHERE kind = ? ORDER BY timestamp DESC')
82
87
  : this.db.query('SELECT * FROM entries ORDER BY timestamp DESC');
83
88
  const rows = kind ? query.all(kind) : query.all();
84
- return (rows as any[]).map(this._rowToEntry);
89
+ return (rows as SqliteRow[]).map(this._rowToEntry);
85
90
  }
86
91
 
87
92
  /** Full-text search. */
@@ -91,7 +96,7 @@ export class SqliteMemory {
91
96
  `SELECT entries.* FROM entries_fts JOIN entries ON entries_fts.id = entries.id WHERE entries_fts MATCH ? ORDER BY rank LIMIT ?`,
92
97
  )
93
98
  .all(query, limit);
94
- return (rows as any[]).map(this._rowToEntry);
99
+ return (rows as SqliteRow[]).map(this._rowToEntry);
95
100
  }
96
101
 
97
102
  /** Delete by id. */
@@ -105,7 +110,7 @@ export class SqliteMemory {
105
110
  const query = kind
106
111
  ? this.db.query('SELECT COUNT(*) as c FROM entries WHERE kind = ?')
107
112
  : this.db.query('SELECT COUNT(*) as c FROM entries');
108
- const row = (kind ? query.get(kind) : query.get()) as any;
113
+ const row = (kind ? query.get(kind) : query.get()) as { c: number };
109
114
  return row.c;
110
115
  }
111
116
 
@@ -115,7 +120,7 @@ export class SqliteMemory {
115
120
  ? this.db.query('SELECT * FROM entries WHERE kind = ? ORDER BY timestamp DESC LIMIT ?')
116
121
  : this.db.query('SELECT * FROM entries ORDER BY timestamp DESC LIMIT ?');
117
122
  const rows = kind ? query.all(kind, limit) : query.all(limit);
118
- return (rows as any[]).map(this._rowToEntry);
123
+ return (rows as SqliteRow[]).map(this._rowToEntry);
119
124
  }
120
125
 
121
126
  /** Create a ContextSource that loads entries as context. */
@@ -168,7 +173,7 @@ export class SqliteMemory {
168
173
  this.db.close();
169
174
  }
170
175
 
171
- private _rowToEntry(row: any): SqliteEntry {
176
+ private _rowToEntry(row: SqliteRow): SqliteEntry {
172
177
  return {
173
178
  id: row.id,
174
179
  kind: row.kind,
@@ -180,6 +185,16 @@ export class SqliteMemory {
180
185
  }
181
186
  }
182
187
 
188
+ /** A row of the `entries` table as bun:sqlite returns it. */
189
+ interface SqliteRow {
190
+ id: string;
191
+ kind: string;
192
+ content: string;
193
+ source: string | null;
194
+ timestamp: number;
195
+ meta: string | null;
196
+ }
197
+
183
198
  export interface SqliteEntry {
184
199
  readonly id: string;
185
200
  readonly kind: string;
package/src/base-agent.ts CHANGED
@@ -1,3 +1,8 @@
1
+ /**
2
+ * @atlas
3
+ * @kind agent
4
+ * @partOf primitive:agents
5
+ */
1
6
  import { computeHash } from './context-layer';
2
7
  import type { AssembledContext, ContextStack, LayerFilter } from './context-stack';
3
8
  import type { TokenCounts } from './token-counts';
@@ -1,3 +1,8 @@
1
+ /**
2
+ * @atlas
3
+ * @kind utils
4
+ * @partOf primitive:signals
5
+ */
1
6
  /**
2
7
  * A set with bounded capacity that evicts oldest entries when full.
3
8
  * Used for message deduplication at harness ingress.
@@ -1,3 +1,8 @@
1
+ /**
2
+ * @atlas
3
+ * @kind service
4
+ * @partOf primitive:contextLayers
5
+ */
1
6
  import type { ContextLayer, LayerState } from './context-layer';
2
7
  import type { ContextStack } from './context-stack';
3
8
 
package/src/capability.ts CHANGED
@@ -1,3 +1,8 @@
1
+ /**
2
+ * @atlas
3
+ * @kind helper
4
+ * @partOf primitive:agents, primitive:tools
5
+ */
1
6
  // ---------------------------------------------------------------------------
2
7
  // Capability — permission flags and gating for dangerous operations
3
8
  // ---------------------------------------------------------------------------
package/src/clarifier.ts CHANGED
@@ -1,3 +1,8 @@
1
+ /**
2
+ * @atlas
3
+ * @kind agent
4
+ * @partOf primitive:agents
5
+ */
1
6
  import type { AgentConfig } from './base-agent';
2
7
  import type { Classification } from './classifier';
3
8
  import type { ContextStack } from './context-stack';
package/src/classifier.ts CHANGED
@@ -1,3 +1,8 @@
1
+ /**
2
+ * @atlas
3
+ * @kind agent
4
+ * @partOf primitive:agents
5
+ */
1
6
  import type { AgentConfig } from './base-agent';
2
7
  import type { ContextStack } from './context-stack';
3
8
  import { Decider, type DeciderConfig, type Decision } from './decider';
@@ -1,3 +1,8 @@
1
+ /**
2
+ * @atlas
3
+ * @kind service
4
+ * @partOf primitive:contextLayers
5
+ */
1
6
  import type { OwnershipScope } from './scope';
2
7
 
3
8
  /**
@@ -354,6 +359,11 @@ export function computeHash(content: string): string {
354
359
  return Bun.hash(content).toString(16).slice(0, 16);
355
360
  }
356
361
 
362
+ /** SHA-256 as hex: for content addresses and digests that are persisted or compared across processes (computeHash is a fast in-memory cache key, not this). */
363
+ export function sha256Hex(content: string | Uint8Array): string {
364
+ return new Bun.CryptoHasher('sha256').update(content).digest('hex');
365
+ }
366
+
357
367
  export class ContextLayer {
358
368
  readonly id: string;
359
369
  readonly owner?: OwnershipScope;
@@ -1,3 +1,8 @@
1
+ /**
2
+ * @atlas
3
+ * @kind service
4
+ * @partOf primitive:contextLayers
5
+ */
1
6
  import { type ContextLayer, computeHash, type LayerState } from './context-layer';
2
7
  import type { OwnershipScope } from './scope';
3
8
 
@@ -1,3 +1,8 @@
1
+ /**
2
+ * @atlas
3
+ * @kind helper
4
+ * @partOf primitive:secrets
5
+ */
1
6
  /** Credential references belong in configuration; secrets stay behind the resolver. */
2
7
  /** `kingdom-signet` names the Signet a paired Kingdom granted, by the destination's origin plus the owner it was paired as. */
3
8
  export type CredentialReference =
package/src/decider.ts CHANGED
@@ -1,3 +1,8 @@
1
+ /**
2
+ * @atlas
3
+ * @kind agent
4
+ * @partOf primitive:agents
5
+ */
1
6
  import { type AgentConfig, BaseAgent, type ExecutionResult } from './base-agent';
2
7
  import { computeHash } from './context-layer';
3
8
  import type { ContextStack, LayerFilter } from './context-stack';
@@ -1,3 +1,8 @@
1
+ /**
2
+ * @atlas
3
+ * @kind helper
4
+ * @partOf primitive:nativeSessions
5
+ */
1
6
  /** Portable SHA-256 for public evidence, shared by Bun and the historical browser.
2
7
  * This is an integrity join, not a signature or native delivery acknowledgment. */
3
8
  export function evidenceDigest(text: string): string {
@@ -1,3 +1,8 @@
1
+ /**
2
+ * @atlas
3
+ * @kind service
4
+ * @partOf primitive:signals
5
+ */
1
6
  import type { ActionPrompt } from './action-prompt';
2
7
  import type { LifecycleEvent } from './cache-lifecycle';
3
8
  import type { DispatchContext } from './middleware';
package/src/executor.ts CHANGED
@@ -1,6 +1,11 @@
1
+ /**
2
+ * @atlas
3
+ * @kind agent
4
+ * @partOf primitive:agents
5
+ */
1
6
  import { type AgentConfig, BaseAgent, type ExecutionResult } from './base-agent';
2
7
  import { computeHash, REQUIRED_CONTEXT_BLOCKED } from './context-layer';
3
- import type { AssembledContext, ContextStack, LayerFilter } from './context-stack';
8
+ import type { AssembledContext, ContextStack, LayerFilter, PromptBlock } from './context-stack';
4
9
  import { buildInjectionArtifact, type InjectionArtifact, type MessageDecoration } from './messages';
5
10
  import type { NativeEvidence, NativeObservation } from './native-evidence';
6
11
  import {
@@ -52,6 +57,16 @@ export interface ExecuteMeta {
52
57
  images?: readonly ImageInput[];
53
58
  }
54
59
 
60
+ /**
61
+ * The user's message as a turn sends it: the after-message notes (Wardens chiming in) appended to
62
+ * its end below a rule, each note's text in order. No notes: the message as typed.
63
+ */
64
+ export function withAfterMessageNotes(message: string, notes: readonly PromptBlock[]): string {
65
+ return notes.length
66
+ ? `${message}\n\n---\n\n${notes.map((note) => note.text).join('\n\n')}`
67
+ : message;
68
+ }
69
+
55
70
  export type ExecuteHandler<TPayload, TResult> = (
56
71
  context: string,
57
72
  payload: TPayload,
@@ -214,9 +229,7 @@ export class Executor<TPayload = unknown, TResult = unknown> extends BaseAgent<T
214
229
  let recording = true;
215
230
  try {
216
231
  const sent = (
217
- notes.length && typeof payload === 'string'
218
- ? `${payload}\n\n---\n\n${notes.map((note) => note.text).join('\n\n')}`
219
- : payload
232
+ typeof payload === 'string' ? withAfterMessageNotes(payload, notes) : payload
220
233
  ) as TPayload;
221
234
  output = await this._handler(context, sent, {
222
235
  ...meta,
@@ -1,3 +1,8 @@
1
+ /**
2
+ * @atlas
3
+ * @kind transformer
4
+ * @partOf feature:feedback, integration:archive
5
+ */
1
6
  import type { ArchiveSnapshot } from '@inixiative/archive';
2
7
  import { typedPrompt } from '@inixiative/archive/import';
3
8
  import type { TranscriptTurn } from './correction';
@@ -6,15 +11,31 @@ import type { TranscriptTurn } from './correction';
6
11
  // `foundry repeats` and Oracle's session miner; its own export, so the core root never loads Archive.
7
12
 
8
13
  const INTERRUPTED = /^\s*\[Request interrupted by user/;
9
- const COMMIT_BRACKET = /\[[^[\]\n]+\s([0-9a-f]{7,40})\]/g;
14
+ const COMMIT_BRACKET = /\[([^[\]\n]+?)\s([0-9a-f]{7,40})\]/g;
15
+ /** `git commit` adds this to the branch on a repository's first commit. */
16
+ const ROOT_COMMIT = /\s+\(root-commit\)$/;
10
17
  const COMMIT_LINE = /^commit ([0-9a-f]{40})/gm;
11
18
 
12
- /** Commits a tool result says were made: `git commit`'s `[branch sha]` line only. */
13
- export const commitsMade = (text: string) => [...text.matchAll(COMMIT_BRACKET)].map((m) => m[1]!);
19
+ /** A commit a session made, as `git commit` printed it: the branch it was on, and its short SHA. */
20
+ export interface MadeCommit {
21
+ /** As git printed it: `main`, `feat/x`, `detached HEAD`; `(root-commit)` dropped. */
22
+ readonly branch: string;
23
+ readonly sha: string;
24
+ }
25
+
26
+ /**
27
+ * Commits a tool result says were made: `git commit`'s `[branch sha]` line only, with the branch,
28
+ * so a reader can tell work on a PR's own branch (amended or rebased away later) from other work.
29
+ */
30
+ export const commitsMade = (text: string): MadeCommit[] =>
31
+ [...text.matchAll(COMMIT_BRACKET)].map((m) => ({
32
+ branch: m[1]!.replace(ROOT_COMMIT, ''),
33
+ sha: m[2]!,
34
+ }));
14
35
 
15
36
  /** Commit SHAs a tool result printed: `git commit`'s `[branch sha]` line, `git log`'s `commit <sha>`. */
16
37
  export const commitsIn = (text: string) => [
17
- ...commitsMade(text),
38
+ ...commitsMade(text).map((made) => made.sha),
18
39
  ...[...text.matchAll(COMMIT_LINE)].map((m) => m[1]!),
19
40
  ];
20
41
 
@@ -1,3 +1,8 @@
1
+ /**
2
+ * @atlas
3
+ * @kind service
4
+ * @partOf feature:feedback
5
+ */
1
6
  import { createHash } from 'node:crypto';
2
7
 
3
8
  // The Prospector's correction detection (moved from Oracle's session miner), shared by Oracle's
@@ -217,7 +222,7 @@ export function extractCorrections(
217
222
  }
218
223
 
219
224
  const SECRET_PATTERNS: ReadonlyArray<readonly [RegExp, string]> = [
220
- [/sk-ant-[A-Za-z0-9_-]{8,}/g, '[REDACTED:anthropic-key]'],
225
+ [/sk-ant-[A-Za-z0-9_-]{20,}/g, '[REDACTED:anthropic-key]'],
221
226
  [/sk-[A-Za-z0-9_-]{20,}/g, '[REDACTED:api-key]'],
222
227
  [/gh[pousr]_[A-Za-z0-9]{20,}/g, '[REDACTED:github-token]'],
223
228
  [/github_pat_[A-Za-z0-9_]{20,}/g, '[REDACTED:github-token]'],
@@ -231,6 +236,13 @@ const SECRET_PATTERNS: ReadonlyArray<readonly [RegExp, string]> = [
231
236
  [/eyJ[A-Za-z0-9_-]{10,}\.eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}/g, '[REDACTED:jwt]'],
232
237
  [/\b[a-z]+_(?:live|test|prod|runtime)_[A-Za-z0-9]{16,}/g, '[REDACTED:token]'],
233
238
  [/\b(?:npm_|glpat-|hf_)[A-Za-z0-9_-]{20,}/g, '[REDACTED:token]'],
239
+ // Kingdom's run, refresh and Signet access tokens: the prefix and exactly 43 base64url characters.
240
+ [/\bkingdom_(?:run_|refresh_)?[A-Za-z0-9_-]{43}(?![A-Za-z0-9_-])/g, '[REDACTED:kingdom-token]'],
241
+ // API tokens Kingdom, template and Tribe issue: `<environment>_<owner model>_<48 hex>`.
242
+ [
243
+ /\b(?:local|pr|staging|prod|test)_(?:user|org|orgUser|space|spaceUser|integration)_[0-9a-f]{48}\b/g,
244
+ '[REDACTED:api-token]',
245
+ ],
234
246
  [/hooks\.slack\.com\/services\/[A-Za-z0-9/]+/g, '[REDACTED:slack-webhook]'],
235
247
  [/\bASIA[A-Z0-9]{16}/g, '[REDACTED:aws-key]'],
236
248
  [/\b(Bearer|Basic|DPoP)\s+[A-Za-z0-9._~+/=-]{16,}/g, '$1 [REDACTED:credential]'],
@@ -1,3 +1,8 @@
1
+ /**
2
+ * @atlas
3
+ * @kind helper
4
+ * @partOf feature:evals
5
+ */
1
6
  /**
2
7
  * The experiment gate (`.claude/skills/experiment/SKILL.md`), shared by Foundry's eval scripts and
3
8
  * Oracle's replay runner: a wide run (more than TINY_MOMENTS moments, or whatever else the caller
@@ -1,3 +1,8 @@
1
+ /**
2
+ * @atlas
3
+ * @kind service
4
+ * @partOf feature:feedback
5
+ */
1
6
  import {
2
7
  type Authorship,
3
8
  CONCEPT_CLUSTERS,
@@ -1,3 +1,8 @@
1
+ /**
2
+ * @atlas
3
+ * @kind type
4
+ * @partOf feature:evals
5
+ */
1
6
  import type { WardenProbe } from './warden-probes';
2
7
 
3
8
  /** One Warden of the roster as the labeler sees it. */
@@ -1,3 +1,8 @@
1
+ /**
2
+ * @atlas
3
+ * @kind service
4
+ * @partOf feature:wardens
5
+ */
1
6
  // The Warden pre-filter: one cheap local yes/no per Warden before it is asked. Data and pure
2
7
  // functions only, so Oracle scores runs the same way; Foundry's provider makes the call. It fails
3
8
  // open: a Warden is skipped only on a confident no, and anything else (an unsure score, an error, no
@@ -1,3 +1,8 @@
1
+ /**
2
+ * @atlas
3
+ * @kind service
4
+ * @partOf feature:evals
5
+ */
1
6
  // Warden probes: the offline measurement of how well a Warden charter keeps the chorus quiet, in
2
7
  // scope and right. Data and pure functions only, so Oracle can score runs on a core-only dependency;
3
8
  // callers bring the probes, the Warden calls and the judge call.
package/src/harness.ts CHANGED
@@ -1,3 +1,8 @@
1
+ /**
2
+ * @atlas
3
+ * @kind service
4
+ * @partOf primitive:agents
5
+ */
1
6
  import type { ExecutionResult } from './base-agent';
2
7
  import { BoundedSet } from './bounded-set';
3
8
  import type { ClarificationResult, ClarifyPayload } from './clarifier';
@@ -512,7 +517,7 @@ export class Harness {
512
517
  const layerFilter = this.buildLayerFilter(undefined, undefined, requestedLayers);
513
518
  const settled = await Promise.allSettled(
514
519
  decisionStages.map(async (stage) => {
515
- const span = trace.startDetached(`${stage.role}:${stage.agentId}`, stage.role as any, {
520
+ const span = trace.startDetached(`${stage.role}:${stage.agentId}`, stage.role, {
516
521
  agentId: stage.agentId,
517
522
  threadId: this.thread.id,
518
523
  input: message.payload,
@@ -638,7 +643,7 @@ export class Harness {
638
643
  }
639
644
 
640
645
  // Trace and dispatch (foreground — blocks pipeline)
641
- const stageSpan = trace.start(`${stage.role}:${agentId}`, stage.role as any, {
646
+ const stageSpan = trace.start(`${stage.role}:${agentId}`, stage.role, {
642
647
  agentId,
643
648
  threadId: this.thread.id,
644
649
  input: message.payload,
package/src/hydrator.ts CHANGED
@@ -1,3 +1,8 @@
1
+ /**
2
+ * @atlas
3
+ * @kind service
4
+ * @partOf primitive:contextLayers
5
+ */
1
6
  import type { ContextSource } from './context-layer';
2
7
 
3
8
  /**
package/src/id.ts CHANGED
@@ -1,3 +1,8 @@
1
+ /**
2
+ * @atlas
3
+ * @kind utils
4
+ * @partOf primitive:thread
5
+ */
1
6
  import { uuidv7 } from 'uuidv7';
2
7
 
3
8
  /**
package/src/index.ts CHANGED
@@ -140,6 +140,7 @@ export {
140
140
  type SourceSegment,
141
141
  type SourceSelectionReport,
142
142
  segmentsText,
143
+ sha256Hex,
143
144
  type VersionEntry,
144
145
  type VersionLog,
145
146
  } from './context-layer';
@@ -166,7 +167,13 @@ export {
166
167
  } from './delivery-evidence';
167
168
  // Observability
168
169
  export { EventStream, type SessionEvent, type StreamEvent } from './event-stream';
169
- export { type ExecuteHandler, type ExecuteMeta, Executor, type ExecutorConfig } from './executor';
170
+ export {
171
+ type ExecuteHandler,
172
+ type ExecuteMeta,
173
+ Executor,
174
+ type ExecutorConfig,
175
+ withAfterMessageNotes,
176
+ } from './executor';
170
177
  // Feedback: correction detection (the Prospector's), shared by Oracle, live capture and `foundry repeats`
171
178
  export {
172
179
  AGAIN_CORRECTION,
@@ -292,16 +299,6 @@ export {
292
299
  type PipelineStep,
293
300
  type RequestContext,
294
301
  } from './harness';
295
- // Lifecycle Hooks (registry only — built-in hooks in @inixiative/foundry)
296
- export {
297
- type HookContext,
298
- type HookHandler,
299
- type HookPoint,
300
- HookRegistry,
301
- type HookResult,
302
- type PlanModeConfig,
303
- type PlanModeTrigger,
304
- } from './hooks';
305
302
  export {
306
303
  type ContextRef,
307
304
  type HydrationAdapter,
@@ -357,17 +354,20 @@ export {
357
354
  type ModelVendor,
358
355
  mainThreadLab,
359
356
  modelCapabilities,
357
+ modelEfforts,
360
358
  modelHasCapability,
361
359
  modelOptionsByCapability,
362
360
  type ProviderCredential,
363
361
  type ProviderMode,
364
362
  type ProviderType,
365
363
  providersWithCapability,
364
+ REASONING_EFFORTS,
366
365
  type ReasoningEffort,
367
366
  type RuntimeKind,
368
367
  registryModel,
369
368
  resolveDecisionModel,
370
369
  SUBSCRIPTION_DECISION_MODELS,
370
+ SUBSCRIPTION_WORKER_MODELS,
371
371
  vendorModeProvider,
372
372
  vendorOfProvider,
373
373
  } from './model-registry';
@@ -390,6 +390,7 @@ export { type RetryConfig, retryMiddleware } from './retry';
390
390
  export { type Route, type RouteHandler, Router, type RouterConfig } from './router';
391
391
  // Ownership scope — which thread/project owns a source read or tool call
392
392
  export { normalizeScope, type OwnershipScope } from './scope';
393
+ export { createSerializedQueue, type SerializedQueue } from './serialized-queue';
393
394
  export {
394
395
  type DeliveredPart,
395
396
  layerPart,
@@ -408,12 +409,22 @@ export {
408
409
  type DispatchOptions,
409
410
  type FanResult,
410
411
  Thread,
412
+ type ThreadAgentStatus,
413
+ type ThreadCheckout,
411
414
  type ThreadConfig,
412
415
  type ThreadContext,
416
+ type ThreadDone,
417
+ type ThreadFork,
418
+ type ThreadLoop,
419
+ type ThreadLoopRound,
420
+ type ThreadMachine,
413
421
  type ThreadMeta,
414
422
  type ThreadName,
423
+ type ThreadPlan,
424
+ type ThreadPlanItem,
415
425
  type ThreadReference,
416
426
  type ThreadSetup,
427
+ type ThreadSnooze,
417
428
  type ThreadSpawn,
418
429
  type ThreadStatus,
419
430
  threadTitle,
@@ -428,6 +439,7 @@ export {
428
439
  DEFAULT_COST_TABLE,
429
440
  estimateTokens,
430
441
  type ModelPricing,
442
+ modelPricing,
431
443
  TokenTracker,
432
444
  type TokenUsage,
433
445
  type UsageAttribution,
@@ -1,3 +1,8 @@
1
+ /**
2
+ * @atlas
3
+ * @kind service
4
+ * @partOf primitive:signals
5
+ */
1
6
  import { newId } from './id';
2
7
  import type { Signal, SignalBus } from './signal';
3
8
  import type { Span, Trace } from './trace';
package/src/messages.ts CHANGED
@@ -1,3 +1,8 @@
1
+ /**
2
+ * @atlas
3
+ * @kind helper
4
+ * @partOf primitive:nativeSessions
5
+ */
1
6
  import type {
2
7
  CompositionSnapshot,
3
8
  LayerInstanceState,