@happyvertical/smrt-ingestion 0.55.6 → 0.55.8

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 (77) hide show
  1. package/AGENTS.md +13 -3
  2. package/FEEDBACK.md +156 -0
  3. package/README.md +15 -3
  4. package/REVIEW.md +137 -0
  5. package/dist/chunks/{execution-C6HJvl9e.js → execution-C7sTFXFU.js} +375 -11
  6. package/dist/chunks/execution-C7sTFXFU.js.map +1 -0
  7. package/dist/chunks/execution-internal-DWteDHM2.js.map +1 -1
  8. package/dist/chunks/feedback-C3OHD4sA.js +625 -0
  9. package/dist/chunks/feedback-C3OHD4sA.js.map +1 -0
  10. package/dist/chunks/{extraction-bseWZuWN.js → proposal-errors-z24VKWnQ.js} +10 -2
  11. package/dist/chunks/proposal-errors-z24VKWnQ.js.map +1 -0
  12. package/dist/dto.d.ts +2 -0
  13. package/dist/dto.d.ts.map +1 -1
  14. package/dist/execution-internal.d.ts +3 -1
  15. package/dist/execution-internal.d.ts.map +1 -1
  16. package/dist/execution.d.ts +15 -1
  17. package/dist/execution.d.ts.map +1 -1
  18. package/dist/execution.js +1 -1
  19. package/dist/feedback-contracts.d.ts +51 -0
  20. package/dist/feedback-contracts.d.ts.map +1 -0
  21. package/dist/feedback-dto.d.ts +106 -0
  22. package/dist/feedback-dto.d.ts.map +1 -0
  23. package/dist/feedback-internal.d.ts +19 -0
  24. package/dist/feedback-internal.d.ts.map +1 -0
  25. package/dist/feedback.d.ts +54 -0
  26. package/dist/feedback.d.ts.map +1 -0
  27. package/dist/manifest.json +34 -1
  28. package/dist/models.js +1 -1
  29. package/dist/models.js.map +1 -1
  30. package/dist/proposal-contracts.d.ts +4 -0
  31. package/dist/proposal-contracts.d.ts.map +1 -1
  32. package/dist/proposal-dto.d.ts +4 -0
  33. package/dist/proposal-dto.d.ts.map +1 -1
  34. package/dist/proposal-errors.d.ts +5 -0
  35. package/dist/proposal-errors.d.ts.map +1 -0
  36. package/dist/proposal-sdk.d.ts.map +1 -1
  37. package/dist/proposals.d.ts +4 -1
  38. package/dist/proposals.d.ts.map +1 -1
  39. package/dist/proposals.js +114 -15
  40. package/dist/proposals.js.map +1 -1
  41. package/dist/review-dto.d.ts +115 -0
  42. package/dist/review-dto.d.ts.map +1 -0
  43. package/dist/server.d.ts +24 -0
  44. package/dist/server.d.ts.map +1 -1
  45. package/dist/server.js +146 -54
  46. package/dist/server.js.map +1 -1
  47. package/dist/smrt-knowledge.json +97 -14
  48. package/dist/svelte/components/ActionReview.svelte +232 -0
  49. package/dist/svelte/components/ActionReview.svelte.d.ts +15 -0
  50. package/dist/svelte/components/ActionReview.svelte.d.ts.map +1 -0
  51. package/dist/svelte/components/EvidenceViewer.svelte +31 -0
  52. package/dist/svelte/components/EvidenceViewer.svelte.d.ts +8 -0
  53. package/dist/svelte/components/EvidenceViewer.svelte.d.ts.map +1 -0
  54. package/dist/svelte/components/InboxView.svelte +119 -0
  55. package/dist/svelte/components/InboxView.svelte.d.ts +9 -0
  56. package/dist/svelte/components/InboxView.svelte.d.ts.map +1 -0
  57. package/dist/svelte/components/IntakeInbox.svelte +11 -0
  58. package/dist/svelte/components/IntakeInbox.svelte.d.ts +10 -0
  59. package/dist/svelte/components/IntakeInbox.svelte.d.ts.map +1 -0
  60. package/dist/svelte/components/IntakeReview.svelte +11 -0
  61. package/dist/svelte/components/IntakeReview.svelte.d.ts +10 -0
  62. package/dist/svelte/components/IntakeReview.svelte.d.ts.map +1 -0
  63. package/dist/svelte/components/ReviewView.svelte +243 -0
  64. package/dist/svelte/components/ReviewView.svelte.d.ts +9 -0
  65. package/dist/svelte/components/ReviewView.svelte.d.ts.map +1 -0
  66. package/dist/svelte/i18n.d.ts +72 -0
  67. package/dist/svelte/i18n.d.ts.map +1 -0
  68. package/dist/svelte/i18n.js +72 -0
  69. package/dist/svelte/index.d.ts +5 -0
  70. package/dist/svelte/index.d.ts.map +1 -0
  71. package/dist/svelte/index.js +3 -0
  72. package/dist/svelte/view-utils.d.ts +13 -0
  73. package/dist/svelte/view-utils.d.ts.map +1 -0
  74. package/dist/svelte/view-utils.js +96 -0
  75. package/package.json +49 -22
  76. package/dist/chunks/execution-C6HJvl9e.js.map +0 -1
  77. package/dist/chunks/extraction-bseWZuWN.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feedback-C3OHD4sA.js","names":["handler","candidate","digest","id"],"sources":["../../src/feedback.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\nimport type { DatabaseInterface } from '@happyvertical/sql';\nimport {\n intakeBindingDigest as digest,\n IntakeExecutionService,\n} from './execution.js';\nimport type { FeedbackConfiguration } from './feedback-contracts.js';\nimport type {\n AdoptRuleInput,\n FeedbackBinding,\n FeedbackExample,\n FeedbackReceipt,\n FeedbackReferences,\n FeedbackSelection,\n ObserveFeedbackInput,\n ReadRuleInput,\n RecordFeedbackInput,\n RoutingRule,\n RuleAdoption,\n RuleSuggestion,\n SuggestRuleInput,\n} from './feedback-dto.js';\nimport {\n type FeedbackActionContext,\n feedbackActionTransaction,\n feedbackDiscoveryContext,\n} from './feedback-internal.js';\nimport type { GenerationOutput } from './proposal-dto.js';\nimport type { IngestionOptions } from './server.js';\n\ntype Row = Record<string, unknown>;\nfunction object(value: unknown): Row {\n const result = typeof value === 'string' ? JSON.parse(value) : value;\n if (!result || typeof result !== 'object' || Array.isArray(result))\n throw new Error('Feedback unavailable');\n return result as Row;\n}\nfunction text(value: unknown, max = 512): asserts value is string {\n if (typeof value !== 'string' || !value.trim() || value.length > max)\n throw new Error('Invalid feedback');\n}\nfunction resultData(data: Row): Row {\n return {\n status: data.status,\n provider: data.provider,\n model: data.model,\n version: data.version,\n output: data.output,\n usage: data.usage,\n ...(Object.hasOwn(data, 'error') ? { error: data.error } : {}),\n ...(Object.hasOwn(data, 'confidence')\n ? { confidence: data.confidence }\n : {}),\n };\n}\nexport function feedbackTerms(value: string): string[] {\n return [\n ...new Set(value.toLowerCase().match(/[\\p{L}\\p{N}]+/gu) ?? []),\n ].sort();\n}\nexport function feedbackSimilarity(left: string, right: string): number {\n const a = new Set(feedbackTerms(left)),\n b = new Set(feedbackTerms(right));\n const union = new Set([...a, ...b]);\n return union.size\n ? [...a].filter((value) => b.has(value)).length / union.size\n : 0;\n}\nexport interface RetrieveFeedbackInput {\n itemId: string;\n query: string;\n offered: GenerationOutput['offered'];\n promptVersion: string;\n configurationVersion: string;\n model: { provider: string; model: string; version: string };\n providers?: string[];\n}\n/** Owning ingestion ledger. Generic LearningMemory's success/ancestor fallback semantics are deliberately not used. */\nexport class IntakeFeedbackService {\n private readonly execution: IntakeExecutionService;\n private readonly config: FeedbackConfiguration;\n private readonly lineage = new Set<string>();\n private exampleChecks = 0;\n constructor(\n private readonly options: IngestionOptions,\n execution?: IntakeExecutionService,\n ) {\n if (!options.execution || !options.feedback)\n throw new Error('Feedback not configured');\n this.config = { ...options.feedback };\n this.execution =\n execution ?? new IntakeExecutionService(options, options.execution);\n text(this.config.version);\n for (const [value, max] of [\n [this.config.maxExamples, 20],\n [this.config.maxScan, 1000],\n [this.config.maxBytes, 1000000],\n ])\n if (!Number.isSafeInteger(value) || value < 1 || value > max)\n throw new Error('Invalid feedback limits');\n if (\n !Number.isFinite(this.config.minimumSimilarity) ||\n this.config.minimumSimilarity < 0.2 ||\n this.config.minimumSimilarity > 1\n )\n throw new Error('Invalid feedback similarity');\n }\n private configurationDigest() {\n const { version, maxExamples, maxScan, maxBytes, minimumSimilarity } =\n this.config;\n return digest({\n version,\n maxExamples,\n maxScan,\n maxBytes,\n minimumSimilarity,\n });\n }\n private routing(\n ctx: FeedbackActionContext,\n ): Pick<RoutingRule, 'args' | 'projection'> {\n // Read live trusted configuration again at publication/replay boundaries.\n const declarations = this.options.feedback?.routing;\n if (declarations === undefined) return { args: ctx.args };\n if (!Array.isArray(declarations))\n throw new Error('Invalid routing projection');\n const seen = new Set<string>();\n for (const declaration of declarations) {\n const entry = object(declaration);\n text(entry.handlerId);\n text(entry.handlerVersion);\n text(entry.version);\n const key = digest([entry.handlerId, entry.handlerVersion]);\n const handler = this.options.execution!.handlers.find(\n (handler) =>\n handler.id === entry.handlerId &&\n handler.version === entry.handlerVersion,\n );\n if (!handler || seen.has(key))\n throw new Error('Invalid routing projection');\n seen.add(key);\n const properties = object(handler.argsSchema.properties);\n if (\n !Array.isArray(entry.fields) ||\n !entry.fields.length ||\n entry.fields.length > 64 ||\n new Set(entry.fields).size !== entry.fields.length\n )\n throw new Error('Invalid routing projection');\n for (const field of entry.fields) {\n text(field);\n if (\n ['__proto__', 'prototype', 'constructor'].includes(field) ||\n !Object.hasOwn(properties, field)\n )\n throw new Error('Invalid routing projection');\n }\n }\n const selected = declarations.find(\n (entry) =>\n entry.handlerId === ctx.handlerId &&\n entry.handlerVersion === ctx.handlerVersion,\n );\n if (!selected) return { args: ctx.args };\n const fields = [...selected.fields].sort();\n const args = Object.fromEntries(\n fields\n .filter((field) => Object.hasOwn(ctx.args, field))\n .map((field) => [field, structuredClone(ctx.args[field])]),\n );\n if (!Object.keys(args).length)\n throw new Error('Routing values unavailable');\n return { args, projection: { version: selected.version, fields } };\n }\n private scope() {\n return this.options.scope;\n }\n private async rows(\n db: DatabaseInterface,\n where: string,\n params: unknown[] = [],\n ): Promise<Row[]> {\n const scope = this.scope();\n return (\n await db.query(\n `SELECT * FROM intake_feedback WHERE tenant_id=? AND confidential_scope_id=? AND ${where}`,\n scope.tenantId,\n scope.confidentialScopeId,\n ...params,\n )\n ).rows;\n }\n private async authorize(\n ctx: FeedbackActionContext,\n operation: 'capture' | 'retrieve' | 'suggest' | 'adopt',\n ) {\n if (\n !(await this.config.authorize({\n db: ctx.db,\n scope: this.scope(),\n itemId: ctx.itemId,\n operation,\n }))\n )\n throw new Error('Feedback unavailable');\n }\n private checkBinding(input: FeedbackBinding, ctx: FeedbackActionContext) {\n if (\n input.itemId !== ctx.itemId ||\n input.actionId !== ctx.review.actionId ||\n input.expectedRevision !== ctx.review.revision ||\n input.expectedReviewVersion !== ctx.review.reviewVersion ||\n input.bindingHash !== ctx.review.bindingHash\n )\n throw new Error('Stale feedback binding');\n }\n private async insert(\n ctx: FeedbackActionContext,\n key: string,\n kind: string,\n data: Row,\n supersedesId: string | null = null,\n ): Promise<Row> {\n const serialized = JSON.stringify(data);\n if (\n Buffer.byteLength(serialized) >\n Math.min(this.config.maxBytes, ctx.context.policy.maxBytes)\n )\n throw new Error('Feedback limit');\n const scope = this.scope(),\n now = (this.options.now?.() ?? new Date()).toISOString();\n const row = {\n id: randomUUID(),\n slug: randomUUID(),\n context: '',\n created_at: now,\n updated_at: now,\n tenant_id: scope.tenantId,\n confidential_scope_id: scope.confidentialScopeId,\n item_id: ctx.itemId,\n request_key: key,\n supersedes_id: supersedesId,\n kind,\n data: serialized,\n };\n return (\n await ctx.db.query(\n `INSERT INTO intake_feedback (${Object.keys(row).join(',')}) VALUES (${Object.keys(\n row,\n )\n .map(() => '?')\n .join(',')}) RETURNING *`,\n ...Object.values(row),\n )\n ).rows[0];\n }\n private receipt(row: Row): FeedbackReceipt {\n return {\n id: String(row.id),\n digest: String(object(row.data).digest),\n kind: row.kind as FeedbackReceipt['kind'],\n };\n }\n private async provenance(ctx: FeedbackActionContext) {\n const output = object(ctx.result.output),\n generation = object(output.proposals),\n pin = object(generation.source),\n provenance = object(generation.provenance);\n if (provenance.feedback) {\n const inherited = object(provenance.feedback);\n const key = ctx.attemptId;\n if (this.lineage.has(key) || this.lineage.size >= 8)\n throw new Error('Feedback lineage unavailable');\n this.lineage.add(key);\n try {\n await this.assertSelection(\n {\n itemId: ctx.itemId,\n query: String(inherited.query),\n offered: generation.offered as GenerationOutput['offered'],\n promptVersion: String(provenance.promptVersion),\n configurationVersion: String(provenance.configurationVersion),\n model: provenance.generative as RetrieveFeedbackInput['model'],\n providers: [\n String(object(provenance.generative).provider),\n ...(object(provenance.decision).configured\n ? [String(object(provenance.decision).provider)]\n : []),\n ],\n },\n inherited.selection as unknown as FeedbackReferences,\n ctx.db,\n );\n } finally {\n this.lineage.delete(key);\n }\n }\n const scope = this.scope();\n const [source] = (\n await ctx.db.query(\n 'SELECT data,output_digest FROM intake_analysis_attempts WHERE tenant_id=? AND confidential_scope_id=? AND item_id=? AND id=?',\n scope.tenantId,\n scope.confidentialScopeId,\n ctx.itemId,\n pin.attemptId,\n )\n ).rows;\n if (!source || source.output_digest !== pin.outputDigest)\n throw new Error('Feedback source unavailable');\n const sourceResult = resultData(object(source.data));\n if (digest(sourceResult) !== pin.outputDigest)\n throw new Error('Feedback source integrity');\n const results = object(sourceResult.output).results;\n if (!Array.isArray(results))\n throw new Error('Feedback extraction unavailable');\n const query = results\n .flatMap((entry) => {\n const segments = object(entry).segments;\n return Array.isArray(segments)\n ? segments.map((segment) => String(object(segment).text ?? ''))\n : [];\n })\n .join('\\n')\n .slice(0, 4096);\n const model = object(provenance.generative);\n for (const field of ['provider', 'model', 'version']) text(model[field]);\n text(provenance.promptVersion);\n text(provenance.configurationVersion);\n return {\n query,\n model: {\n provider: String(model.provider),\n model: String(model.model),\n version: String(model.version),\n },\n promptVersion: String(provenance.promptVersion),\n configurationVersion: String(provenance.configurationVersion),\n attemptId: ctx.attemptId,\n evidence: object(ctx.analysis).inputs,\n source: pin,\n };\n }\n /** Internal saved-action gate; the execution owner supplies its transaction. */\n async assertActionLineage(\n actionId: string,\n db: DatabaseInterface,\n proposalId: string,\n ): Promise<void> {\n await this.execution[feedbackActionTransaction](\n actionId,\n false,\n async (ctx) => {\n await this.provenance(ctx);\n },\n db,\n undefined,\n proposalId,\n );\n }\n async record(input: RecordFeedbackInput): Promise<FeedbackReceipt> {\n digest(input);\n text(input.requestId);\n if (\n !['correct', 'incorrect'].includes(input.judgment) ||\n (input.comment !== undefined &&\n (typeof input.comment !== 'string' || input.comment.length > 4000))\n )\n throw new Error('Invalid feedback');\n const frozen = structuredClone(input);\n return this.execution[feedbackActionTransaction](\n input.actionId,\n true,\n async (ctx) => {\n await this.authorize(ctx, 'capture');\n this.checkBinding(frozen, ctx);\n const requestHash = digest(frozen),\n key = `judgment:${frozen.requestId}`;\n const [replay] = await this.rows(\n ctx.db,\n 'item_id=? AND request_key=?',\n [ctx.itemId, key],\n );\n if (replay) {\n const data = object(replay.data);\n if (\n data.requestHash !== requestHash ||\n data.reviewer !== this.scope().actorId\n )\n throw new Error('Feedback request conflict');\n return this.receipt(replay);\n }\n if (frozen.supersedesId) {\n const [old] = await this.rows(\n ctx.db,\n 'item_id=? AND id=? AND kind=?',\n [ctx.itemId, frozen.supersedesId, 'interpretation'],\n );\n if (\n !old ||\n object(old.data).actionId !== frozen.actionId ||\n (await this.rows(ctx.db, 'supersedes_id=?', [old.id])).length\n )\n throw new Error('Feedback supersession conflict');\n }\n const provenance = await this.provenance(ctx),\n routing = this.routing(ctx);\n const body = {\n version: 1,\n requestHash,\n reviewer: this.scope().actorId,\n actionId: ctx.review.actionId,\n revision: ctx.review.revision,\n reviewVersion: ctx.review.reviewVersion,\n bindingHash: ctx.review.bindingHash,\n handlerId: ctx.handlerId,\n handlerVersion: ctx.handlerVersion,\n args: ctx.args,\n ...(routing.projection ? { routing } : {}),\n judgment: frozen.judgment,\n comment: frozen.comment ?? '',\n ...provenance,\n };\n const row = await this.insert(\n ctx,\n key,\n 'interpretation',\n { ...body, digest: digest(body) },\n frozen.supersedesId ?? null,\n );\n await this.authorize(ctx, 'capture');\n if (digest(routing) !== digest(this.routing(ctx)))\n throw new Error('Routing projection changed');\n return this.receipt(row);\n },\n );\n }\n /** Consume a durable owner event idempotently. Never derive correctness from these signals. */\n async observe(input: ObserveFeedbackInput): Promise<FeedbackReceipt> {\n digest(input);\n text(input.eventId);\n if (!['action_decision', 'downstream_outcome'].includes(input.kind))\n throw new Error('Invalid feedback kind');\n return this.execution[feedbackActionTransaction](\n input.actionId,\n true,\n async (ctx) => {\n await this.authorize(ctx, 'capture');\n this.checkBinding(input, ctx);\n const scope = this.scope();\n const table =\n input.kind === 'action_decision'\n ? 'intake_review_decisions'\n : 'intake_executions';\n const [event] = (\n await ctx.db.query(\n `SELECT * FROM ${table} WHERE tenant_id=? AND confidential_scope_id=? AND item_id=? AND action_id=? AND id=?`,\n scope.tenantId,\n scope.confidentialScopeId,\n ctx.itemId,\n input.actionId,\n input.eventId,\n )\n ).rows;\n if (!event || event.binding_hash !== ctx.review.bindingHash)\n throw new Error('Feedback event unavailable');\n const state =\n input.kind === 'action_decision' ? event.decision : event.state;\n if (\n input.kind === 'downstream_outcome' &&\n !['succeeded', 'failed', 'outcome_unknown'].includes(String(state))\n )\n throw new Error('Outcome is not terminal');\n const body = {\n version: 1,\n eventId: input.eventId,\n actionId: input.actionId,\n revision: ctx.review.revision,\n reviewer:\n input.kind === 'action_decision'\n ? object(event.data).reviewer\n : null,\n observedBy: this.scope().actorId,\n principalId: object(event.data).principalId ?? null,\n signal: state,\n provenance: await this.provenance(ctx),\n };\n const key = `event:${input.kind}:${input.eventId}:${String(state)}`;\n const [existing] = await this.rows(\n ctx.db,\n 'item_id=? AND request_key=?',\n [ctx.itemId, key],\n );\n if (existing) return this.receipt(existing);\n const row = await this.insert(ctx, key, input.kind, {\n ...body,\n digest: digest(body),\n });\n await this.authorize(ctx, 'capture');\n return this.receipt(row);\n },\n );\n }\n private async example(\n row: Row,\n input: RetrieveFeedbackInput,\n executor?: DatabaseInterface,\n ): Promise<FeedbackExample | undefined> {\n if (++this.exampleChecks > this.config.maxScan) return undefined;\n try {\n const candidate = object(row.data);\n // Retention deliberately redacts ledger payloads. Reject tombstones before\n // issuing a UUID query: catching a PostgreSQL cast error cannot repair its transaction.\n if (\n typeof candidate.actionId !== 'string' ||\n !/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(\n candidate.actionId,\n )\n )\n return undefined;\n return await this.execution[feedbackActionTransaction](\n candidate.actionId,\n false,\n async (ctx) => {\n await this.authorize(ctx, 'retrieve');\n await this.provenance(ctx);\n const [current] = await this.rows(\n ctx.db,\n 'id=? AND kind=? AND NOT EXISTS (SELECT 1 FROM intake_feedback successor WHERE successor.tenant_id=intake_feedback.tenant_id AND successor.confidential_scope_id=intake_feedback.confidential_scope_id AND successor.supersedes_id=intake_feedback.id)',\n [row.id, 'interpretation'],\n );\n if (!current) return undefined;\n const data = object(current.data);\n const { digest: stored, ...body } = data;\n if (digest(body) !== stored) throw new Error('Feedback integrity');\n if (\n data.revision !== ctx.review.revision ||\n data.bindingHash !== ctx.review.bindingHash ||\n data.attemptId !== ctx.attemptId ||\n data.promptVersion !== input.promptVersion ||\n data.configurationVersion !== input.configurationVersion ||\n digest(data.model) !== digest(input.model)\n )\n return undefined;\n const offered = input.offered.find(\n (entry) =>\n entry.handler.id === data.handlerId &&\n entry.handler.version === data.handlerVersion,\n );\n if (!offered) return undefined;\n const args = object(data.args);\n for (const [field, reference] of Object.entries(\n offered.handler.references,\n )) {\n if (\n reference.kind === 'candidate' &&\n Object.hasOwn(args, field) &&\n !offered.candidates.some(\n (candidate) =>\n candidate.id === args[field] &&\n candidate.model === reference.model,\n )\n )\n return undefined;\n }\n return {\n feedbackId: String(current.id),\n digest: String(stored),\n itemId: ctx.itemId,\n actionId: ctx.review.actionId,\n revision: ctx.review.revision,\n handlerId: ctx.handlerId,\n handlerVersion: ctx.handlerVersion,\n judgment: data.judgment as 'correct' | 'incorrect',\n query: String(data.query),\n args,\n model: data.model as FeedbackExample['model'],\n promptVersion: String(data.promptVersion),\n configurationVersion: String(data.configurationVersion),\n };\n },\n executor,\n input.providers ?? [input.model.provider],\n );\n } catch {\n return undefined;\n }\n }\n private receivingContext(\n input: RetrieveFeedbackInput,\n executor: DatabaseInterface | undefined,\n work: (\n context: import('./execution-contracts.js').HandlerContext,\n ) => Promise<FeedbackSelection>,\n ): Promise<FeedbackSelection> {\n let limit = this.config.maxBytes;\n let bytes: number | undefined;\n const validate = async (\n context: import('./execution-contracts.js').HandlerContext,\n ) => {\n if (\n (input.providers ?? [input.model.provider]).some(\n (provider) => !context.policy.providers.includes(provider),\n )\n )\n throw new Error('Feedback recipient unavailable');\n limit = Math.min(limit, context.policy.maxBytes);\n if (bytes !== undefined && bytes > limit)\n throw new Error('Feedback limit');\n };\n const visit = (\n index: number,\n db: DatabaseInterface | undefined,\n ): Promise<FeedbackSelection> => {\n const entry = input.offered[index];\n return this.execution[feedbackDiscoveryContext](\n db,\n input.itemId,\n entry.handler.id,\n entry.handler.version,\n async (context) => {\n await validate(context);\n const selection =\n index + 1 < input.offered.length\n ? await visit(index + 1, context.db)\n : await work(context);\n bytes = Buffer.byteLength(JSON.stringify(selection));\n if (bytes > limit) throw new Error('Feedback limit');\n return selection;\n },\n validate,\n );\n };\n return visit(0, executor);\n }\n async retrieve(\n input: RetrieveFeedbackInput,\n executor?: DatabaseInterface,\n ): Promise<FeedbackSelection> {\n text(input.query, 4096);\n const offered = input.offered[0];\n if (!offered)\n return {\n version: this.config.version,\n configurationDigest: this.configurationDigest(),\n examples: [],\n };\n const work = async (\n context: import('./execution-contracts.js').HandlerContext,\n ) => {\n const authorize = async () => {\n if (\n !(await this.config.authorize({\n db: context.db,\n scope: this.scope(),\n itemId: input.itemId,\n operation: 'retrieve',\n }))\n )\n throw new Error('Feedback unavailable');\n };\n await authorize();\n const scope = this.scope();\n const rows = (\n await context.db.query(\n \"SELECT * FROM intake_feedback WHERE tenant_id=? AND confidential_scope_id=? AND kind='interpretation' ORDER BY id LIMIT ?\",\n scope.tenantId,\n scope.confidentialScopeId,\n this.config.maxScan,\n )\n ).rows;\n const ranked: Array<{ example: FeedbackExample; score: number }> = [];\n for (const row of rows) {\n const example = await this.example(row, input, context.db);\n if (!example) continue;\n const score = feedbackSimilarity(input.query, example.query);\n if (score >= this.config.minimumSimilarity)\n ranked.push({ example, score });\n }\n ranked.sort(\n (a, b) =>\n b.score - a.score ||\n a.example.feedbackId.localeCompare(b.example.feedbackId),\n );\n const selection = {\n version: this.config.version,\n configurationDigest: this.configurationDigest(),\n examples: ranked\n .slice(0, this.config.maxExamples)\n .map((entry) => entry.example),\n };\n await authorize();\n return selection;\n };\n return this.receivingContext(input, executor, work);\n }\n async assertSelection(\n input: RetrieveFeedbackInput,\n selection: FeedbackReferences,\n executor?: DatabaseInterface,\n ): Promise<void> {\n if (\n selection.version !== this.config.version ||\n selection.configurationDigest !== this.configurationDigest() ||\n !Array.isArray(selection.examples) ||\n selection.examples.length > this.config.maxExamples ||\n new Set(selection.examples.map((example) => example.feedbackId)).size !==\n selection.examples.length ||\n Buffer.byteLength(JSON.stringify(selection)) > this.config.maxBytes\n )\n throw new Error('Feedback eligibility changed');\n const offered = input.offered[0];\n if (!offered) {\n if (selection.examples.length)\n throw new Error('Feedback eligibility changed');\n return;\n }\n const work = async (\n context: import('./execution-contracts.js').HandlerContext,\n ) => {\n if (\n !(await this.config.authorize({\n db: context.db,\n scope: this.scope(),\n itemId: input.itemId,\n operation: 'retrieve',\n }))\n )\n throw new Error('Feedback unavailable');\n const examples: FeedbackExample[] = [];\n for (const expected of selection.examples) {\n const [row] = await this.rows(context.db, 'id=? AND kind=?', [\n expected.feedbackId,\n 'interpretation',\n ]);\n const current = row\n ? await this.example(row, input, context.db)\n : undefined;\n if (\n !current ||\n current.digest !== expected.digest ||\n feedbackSimilarity(input.query, current.query) <\n this.config.minimumSimilarity\n )\n throw new Error('Feedback eligibility changed');\n examples.push(current);\n }\n if (\n !(await this.config.authorize({\n db: context.db,\n scope: this.scope(),\n itemId: input.itemId,\n operation: 'retrieve',\n }))\n )\n throw new Error('Feedback unavailable');\n return { ...selection, examples };\n };\n await this.receivingContext(input, executor, work);\n }\n private async support(\n ctx: FeedbackActionContext,\n ids: string[],\n ): Promise<Array<{ id: string; digest: string; query: string }>> {\n if (\n !Array.isArray(ids) ||\n ids.length < 2 ||\n ids.length > this.config.maxExamples ||\n new Set(ids).size !== ids.length\n )\n throw new Error('Insufficient rule evidence');\n const provenance = await this.provenance(ctx),\n origins = new Set<string>(),\n result: Array<{ id: string; digest: string; query: string }> = [];\n for (const id of [...ids].sort()) {\n text(id);\n const [row] = await this.rows(ctx.db, 'id=? AND kind=?', [\n id,\n 'interpretation',\n ]);\n if (!row) throw new Error('Rule evidence unavailable');\n const data = object(row.data);\n await this.execution[feedbackActionTransaction](\n String(data.actionId),\n false,\n async (source) => {\n await this.authorize(source, 'retrieve');\n await this.provenance(source);\n if (origins.has(source.itemId))\n throw new Error('Independent rule evidence required');\n origins.add(source.itemId);\n const { digest: stored, ...body } = data;\n if (\n digest(body) !== stored ||\n data.judgment !== 'correct' ||\n data.revision !== source.review.revision ||\n data.bindingHash !== source.review.bindingHash ||\n data.attemptId !== source.attemptId ||\n data.handlerId !== source.handlerId ||\n data.handlerVersion !== source.handlerVersion ||\n data.handlerId !== ctx.handlerId ||\n data.handlerVersion !== ctx.handlerVersion ||\n digest(data.args) !== digest(source.args) ||\n digest(data.routing ?? { args: data.args }) !==\n digest(this.routing(source)) ||\n digest(this.routing(source)) !== digest(this.routing(ctx)) ||\n data.promptVersion !== provenance.promptVersion ||\n data.configurationVersion !== provenance.configurationVersion ||\n digest(data.model) !== digest(provenance.model) ||\n (await this.rows(ctx.db, 'supersedes_id=?', [id])).length\n )\n throw new Error('Rule evidence unavailable');\n result.push({\n id,\n digest: String(stored),\n query: String(data.query),\n });\n },\n ctx.db,\n );\n }\n return result;\n }\n async suggest(input: SuggestRuleInput): Promise<RuleSuggestion> {\n digest(input);\n text(input.requestId);\n if (!this.config.policy) throw new Error('Rule policy owner unavailable');\n return this.execution[feedbackActionTransaction](\n input.actionId,\n true,\n async (ctx) => {\n this.checkBinding(input, ctx);\n await this.authorize(ctx, 'suggest');\n const support = await this.support(ctx, input.supportingFeedbackIds);\n const terms = feedbackTerms(support[0].query).filter((term) =>\n support.every((example) =>\n feedbackTerms(example.query).includes(term),\n ),\n );\n if (!terms.length) throw new Error('No shared routing evidence');\n const rule: RoutingRule = {\n handlerId: ctx.handlerId,\n handlerVersion: ctx.handlerVersion,\n matchTerms: terms,\n ...this.routing(ctx),\n };\n const preview = await this.config.policy!.preview({\n db: ctx.db,\n scope: this.scope(),\n rule: structuredClone(rule),\n });\n text(preview.version);\n text(preview.preview, 4000);\n const body = {\n version: 1,\n actionId: input.actionId,\n revision: ctx.review.revision,\n bindingHash: ctx.review.bindingHash,\n rule,\n supportingFeedback: support.map(({ id, digest }) => ({ id, digest })),\n expectedPolicyVersion: preview.version,\n preview: preview.preview,\n reviewer: this.scope().actorId,\n requestHash: digest(input),\n };\n const key = `rule:${input.requestId}`;\n let [row] = await this.rows(ctx.db, 'item_id=? AND request_key=?', [\n ctx.itemId,\n key,\n ]);\n if (row) {\n if (object(row.data).requestHash !== body.requestHash)\n throw new Error('Rule request conflict');\n } else\n row = await this.insert(ctx, key, 'rule_suggestion', {\n ...body,\n digest: digest(body),\n });\n await this.authorize(ctx, 'suggest');\n await this.rule(ctx, String(row.id));\n return this.ruleDTO(row);\n },\n );\n }\n private ruleDTO(row: Row): RuleSuggestion {\n const data = object(row.data);\n return {\n id: String(row.id),\n digest: String(data.digest),\n itemId: String(row.item_id),\n rule: data.rule as unknown as RoutingRule,\n supportingFeedback:\n data.supportingFeedback as RuleSuggestion['supportingFeedback'],\n expectedPolicyVersion: String(data.expectedPolicyVersion),\n preview: String(data.preview),\n automaticActionEligible: false,\n };\n }\n private async rule(ctx: FeedbackActionContext, id: string): Promise<Row> {\n const [row] = await this.rows(ctx.db, 'item_id=? AND id=? AND kind=?', [\n ctx.itemId,\n id,\n 'rule_suggestion',\n ]);\n if (!row) throw new Error('Rule unavailable');\n const data = object(row.data),\n { digest: stored, ...body } = data;\n if (\n digest(body) !== stored ||\n data.actionId !== ctx.review.actionId ||\n data.revision !== ctx.review.revision ||\n data.bindingHash !== ctx.review.bindingHash\n )\n throw new Error('Stale rule');\n const rule = object(data.rule);\n if (\n rule.handlerId !== ctx.handlerId ||\n rule.handlerVersion !== ctx.handlerVersion ||\n digest({\n args: rule.args,\n ...(rule.projection ? { projection: rule.projection } : {}),\n }) !== digest(this.routing(ctx))\n )\n throw new Error('Rule routing projection changed');\n const support = data.supportingFeedback as Array<{\n id: string;\n digest: string;\n }>;\n const current = await this.support(\n ctx,\n support.map((entry) => entry.id),\n );\n if (\n digest(current.map(({ id, digest }) => ({ id, digest }))) !==\n digest(support)\n )\n throw new Error('Rule evidence changed');\n return row;\n }\n async readRule(input: ReadRuleInput): Promise<RuleSuggestion> {\n return this.execution[feedbackActionTransaction](\n input.actionId,\n true,\n async (ctx) => {\n this.checkBinding(input, ctx);\n await this.authorize(ctx, 'suggest');\n const suggestion = this.ruleDTO(\n await this.rule(ctx, input.suggestionId),\n );\n if (!this.config.policy)\n throw new Error('Rule policy owner unavailable');\n const current = await this.config.policy.preview({\n db: ctx.db,\n scope: this.scope(),\n rule: structuredClone(suggestion.rule),\n });\n if (\n current.version !== suggestion.expectedPolicyVersion ||\n current.preview !== suggestion.preview\n )\n throw new Error('Rule policy changed');\n await this.authorize(ctx, 'suggest');\n await this.rule(ctx, input.suggestionId);\n return suggestion;\n },\n );\n }\n async adopt(input: AdoptRuleInput): Promise<RuleAdoption> {\n digest(input);\n text(input.requestId);\n if (!this.config.policy) throw new Error('Rule policy owner unavailable');\n return this.execution[feedbackActionTransaction](\n input.actionId,\n true,\n async (ctx) => {\n this.checkBinding(input, ctx);\n await this.authorize(ctx, 'adopt');\n const row = await this.rule(ctx, input.suggestionId),\n suggestion = this.ruleDTO(row);\n if (\n input.expectedDigest !== suggestion.digest ||\n input.expectedPolicyVersion !== suggestion.expectedPolicyVersion\n )\n throw new Error('Stale rule');\n const requestHash = digest(input),\n key = `adopt:${input.requestId}`;\n const [replay] = await this.rows(\n ctx.db,\n 'item_id=? AND request_key=?',\n [ctx.itemId, key],\n );\n if (replay) {\n const data = object(replay.data);\n if (\n data.requestHash !== requestHash ||\n data.reviewer !== this.scope().actorId\n )\n throw new Error('Rule request conflict');\n return {\n id: String(replay.id),\n policyVersion: String(data.policyVersion),\n auditId: String(data.auditId),\n automaticActionEligible: false,\n };\n }\n const current = await this.config.policy!.preview({\n db: ctx.db,\n scope: this.scope(),\n rule: structuredClone(suggestion.rule),\n });\n if (current.version !== input.expectedPolicyVersion)\n throw new Error('Policy version changed');\n const applied = await this.config.policy!.adopt({\n db: ctx.db,\n scope: this.scope(),\n rule: structuredClone(suggestion.rule),\n expectedVersion: input.expectedPolicyVersion,\n requestId: input.requestId,\n });\n text(applied.version);\n text(applied.auditId);\n if (applied.version === input.expectedPolicyVersion)\n throw new Error('Policy version did not advance');\n const verified = await this.config.policy!.preview({\n db: ctx.db,\n scope: this.scope(),\n rule: structuredClone(suggestion.rule),\n });\n if (verified.version !== applied.version)\n throw new Error('Policy adoption mismatch');\n const body = {\n version: 1,\n requestHash,\n suggestionId: suggestion.id,\n suggestionDigest: suggestion.digest,\n previousPolicyVersion: input.expectedPolicyVersion,\n policyVersion: applied.version,\n auditId: applied.auditId,\n reviewer: this.scope().actorId,\n automaticActionEligible: false,\n };\n const saved = await this.insert(ctx, key, 'rule_adoption', {\n ...body,\n digest: digest(body),\n });\n await this.authorize(ctx, 'adopt');\n await this.rule(ctx, input.suggestionId);\n return {\n id: String(saved.id),\n policyVersion: applied.version,\n auditId: applied.auditId,\n automaticActionEligible: false,\n };\n },\n );\n }\n}\n"],"mappings":"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"}
@@ -288,6 +288,14 @@ function proposeDocumentSplits(result, revision, groups) {
288
288
  };
289
289
  }
290
290
  //#endregion
291
- export { extractAnalysis as n, proposeDocumentSplits as r, createSDKExtractionAdapter as t };
291
+ //#region src/proposal-errors.ts
292
+ var GenerationSnapshotStaleError = class extends Error {
293
+ constructor() {
294
+ super("Generation snapshot stale");
295
+ this.name = "GenerationSnapshotStaleError";
296
+ }
297
+ };
298
+ //#endregion
299
+ export { proposeDocumentSplits as i, createSDKExtractionAdapter as n, extractAnalysis as r, GenerationSnapshotStaleError as t };
292
300
 
293
- //# sourceMappingURL=extraction-bseWZuWN.js.map
301
+ //# sourceMappingURL=proposal-errors-z24VKWnQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proposal-errors-z24VKWnQ.js","names":[],"sources":["../../src/extraction.ts","../../src/proposal-errors.ts"],"sourcesContent":["import { fork } from 'node:child_process';\nimport { createHash } from 'node:crypto';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport type { GetAIOptions } from '@happyvertical/ai';\nimport type { PDFReaderOptions } from '@happyvertical/pdf';\nimport type { GetTranscriberOptions } from '@happyvertical/speech';\nimport type { AnalysisOutput } from './dto.js';\nimport {\n ExtractionFailure,\n emptyExtraction,\n validateExtractionRequest,\n} from './extraction-providers.js';\nimport type {\n ExtractionAdapter,\n ExtractionRequest,\n ExtractionResult,\n ProviderIdentity,\n} from './extraction-types.js';\nimport { providerIdentity } from './extraction-types.js';\nimport type { AnalysisLease, IngestionService } from './server.js';\n\nexport type * from './extraction-types.js';\n\n/** Trusted server configuration. Credentials never enter analysis provenance. */\nexport interface ExtractionSDKConfiguration {\n pdf?: {\n provider: NonNullable<PDFReaderOptions['provider']>;\n identity: ProviderIdentity;\n };\n ocr?: { identity: ProviderIdentity; options?: Record<string, unknown> };\n speech?: { identity: ProviderIdentity; options: GetTranscriberOptions };\n vision?: { identity: ProviderIdentity; options: GetAIOptions };\n imageMode?: 'ocr' | 'vision';\n /** Maximum concurrent child processes for this adapter instance (default 1). */\n maxConcurrentProcesses?: number;\n /** The deployment enforces a native-memory ceiling outside Node (e.g. container).\n * Required for native decoders: Node's heap cap does not bound native allocation. */\n nativeMemoryIsolation: 'host-enforced';\n}\n\n/** Production adapter: bounded per-evidence child, terminated on deadline/abort. */\nexport function createSDKExtractionAdapter(\n configuration: ExtractionSDKConfiguration,\n): ExtractionAdapter {\n try {\n configuration = structuredClone(configuration);\n } catch {\n throw new Error('Serializable SDK configuration required');\n }\n const maximum = configuration.maxConcurrentProcesses ?? 1;\n if (!Number.isSafeInteger(maximum) || maximum < 1 || maximum > 32)\n throw new Error('Invalid extraction concurrency');\n let running = 0;\n if (configuration.nativeMemoryIsolation !== 'host-enforced')\n throw new Error('Native memory isolation is required');\n for (const provider of [\n configuration.pdf,\n configuration.ocr,\n configuration.speech,\n configuration.vision,\n ]) {\n if (provider) provider.identity = providerIdentity(provider.identity);\n }\n if (\n configuration.pdf?.provider === 'auto' ||\n configuration.ocr?.identity.provider === 'auto'\n )\n throw new Error('Pin extraction providers');\n return {\n async extract(request) {\n let latest = emptyExtraction(request);\n try {\n validateExtractionRequest(request);\n } catch (caught) {\n if (!(caught instanceof ExtractionFailure)) throw caught;\n latest.errors.push({\n category: caught.category,\n location: { kind: 'source' },\n });\n return latest;\n }\n if (request.evidence.mediaType.toLowerCase().startsWith('video/')) {\n latest.status = 'unsupported';\n latest.errors.push({\n category: 'unsupported_type',\n location: { kind: 'source' },\n });\n return latest;\n }\n if (request.signal?.aborted) {\n latest.errors.push({\n category: 'cancelled',\n location: { kind: 'source' },\n });\n return latest;\n }\n if (running >= maximum) {\n latest.errors.push({ category: 'limit', location: { kind: 'source' } });\n return latest;\n }\n running++;\n return new Promise<ExtractionResult>((resolve) => {\n // A public entry can move shared code into chunks; resolve without loading it.\n const child = fork(\n join(\n dirname(\n fileURLToPath(\n import.meta.resolve('@happyvertical/smrt-ingestion/server'),\n ),\n ),\n 'extraction-worker.js',\n ),\n [],\n {\n serialization: 'advanced',\n stdio: ['ignore', 'ignore', 'ignore', 'ipc'],\n execArgv: [`--max-old-space-size=${request.limits.workerHeapMb}`],\n detached: process.platform !== 'win32',\n },\n );\n let done = false;\n const stop = () => {\n try {\n if (process.platform !== 'win32' && child.pid)\n process.kill(-child.pid, 'SIGKILL');\n else child.kill('SIGKILL');\n } catch {\n child.kill('SIGKILL');\n }\n };\n const finish = (\n category?: 'timeout' | 'cancelled' | 'unavailable' | 'limit',\n ) => {\n if (done) return;\n done = true;\n running--;\n clearTimeout(timer);\n request.signal?.removeEventListener('abort', abort);\n stop();\n if (category) {\n latest.errors.push({ category, location: { kind: 'source' } });\n latest.status = latest.segments.length ? 'partial' : 'failed';\n latest.truncated = true;\n latest.omitted.push({ kind: 'source' });\n }\n resolve(latest);\n };\n const abort = () => finish('cancelled');\n const timer = setTimeout(\n () => finish('timeout'),\n request.limits.timeoutMs,\n );\n request.signal?.addEventListener('abort', abort, { once: true });\n child.on('error', () => finish('unavailable'));\n child.on('exit', () => {\n if (!done) finish('unavailable');\n });\n child.on(\n 'message',\n async (message: {\n kind: string;\n id?: number;\n result?: ExtractionResult;\n }) => {\n if (done) return;\n if (\n message.kind === 'authorize' &&\n Number.isSafeInteger(message.id)\n ) {\n try {\n await request.beforeProviderCall?.();\n if (!done) child.send({ kind: 'authorized', id: message.id });\n } catch {\n finish('cancelled');\n }\n return;\n }\n if (\n (message.kind === 'progress' || message.kind === 'result') &&\n message.result\n ) {\n // The child is our trusted normalizer; bound serialized IPC output as well.\n if (\n Buffer.byteLength(JSON.stringify(message.result)) >\n request.limits.maxOutputBytes + 65536\n )\n return finish('limit');\n latest = message.result;\n if (message.kind === 'result') finish();\n } else finish('unavailable');\n },\n );\n const {\n signal: _signal,\n beforeProviderCall: _authorize,\n ...wireRequest\n } = request;\n child.send({ request: wireRequest, configuration }, (error) => {\n if (error) finish('unavailable');\n });\n if (request.signal?.aborted) abort();\n });\n },\n };\n}\n\nfunction validateAndNormalizeExtractionOutput(\n result: ExtractionResult,\n request: ExtractionRequest,\n): void {\n const numeric = (value: number) => Number.isFinite(value) && value >= 0;\n const location = (\n value: ExtractionResult['segments'][number]['location'],\n ) => {\n if (!value || typeof value !== 'object') return false;\n if (value.kind === 'source') return true;\n if (value.kind === 'page')\n return Number.isSafeInteger(value.page) && value.page > 0;\n if (value.kind === 'pages')\n return (\n Number.isSafeInteger(value.startPage) &&\n value.startPage > 0 &&\n Number.isSafeInteger(value.endPage) &&\n value.endPage >= value.startPage\n );\n return (\n value.kind === 'time' &&\n numeric(value.startMs) &&\n numeric(value.endMs) &&\n value.endMs >= value.startMs\n );\n };\n if (\n !result ||\n !['complete', 'partial', 'failed', 'unsupported'].includes(result.status) ||\n result.automaticActionEligible !== false ||\n result.configurationRevision !== request.configurationRevision ||\n !result.evidence ||\n Object.entries(request.evidence).some(\n ([key, value]) =>\n result.evidence[key as keyof typeof result.evidence] !== value,\n ) ||\n typeof result.truncated !== 'boolean' ||\n !Array.isArray(result.capabilities) ||\n result.capabilities.some(\n (capability) =>\n !capability ||\n typeof capability.confidence !== 'boolean' ||\n typeof capability.boxes !== 'boolean' ||\n !['source', 'page', 'time'].includes(capability.location) ||\n !['unknown', 'reported'].includes(capability.truncation) ||\n !['unknown', 'reported'].includes(capability.usage),\n ) ||\n !result.limits ||\n Object.entries(request.limits).some(\n ([key, value]) =>\n result.limits[key as keyof typeof result.limits] !== value,\n ) ||\n !Array.isArray(result.segments) ||\n !Array.isArray(result.errors) ||\n !Array.isArray(result.omitted) ||\n (result.status === 'complete' &&\n (result.truncated ||\n result.errors.length > 0 ||\n result.omitted.length > 0)) ||\n result.omitted.some((value) => !location(value)) ||\n result.segments.some(\n (segment) =>\n typeof segment.text !== 'string' ||\n !location(segment.location) ||\n segment.location.kind === 'pages' ||\n (segment.provenance?.provider === 'unlimited-ocr' &&\n (segment.confidence !== null || segment.boxes !== null)) ||\n !segment.provenance ||\n [\n segment.provenance.provider,\n segment.provenance.model,\n segment.provenance.version,\n ].some((value) => typeof value !== 'string' || !value) ||\n (segment.confidence !== null &&\n (!segment.confidence ||\n !numeric(segment.confidence.value) ||\n segment.confidence.value > 1 ||\n segment.confidence.scale !== '0-1' ||\n segment.confidence.calibration !== 'unknown')) ||\n (segment.boxes !== null &&\n (!Array.isArray(segment.boxes) ||\n segment.boxes.some(\n (box) =>\n typeof box.text !== 'string' ||\n ![box.x, box.y, box.width, box.height].every(numeric),\n ))),\n ) ||\n result.errors.some(\n (error) =>\n ![\n 'unsupported_type',\n 'malformed_output',\n 'limit',\n 'timeout',\n 'unavailable',\n 'authentication',\n 'cancelled',\n 'integrity',\n ].includes(error.category) || !location(error.location),\n ) ||\n !result.usage ||\n Object.values(result.usage).some((value) => !numeric(value))\n )\n throw new Error('Invalid extraction output');\n // Structural typing permits extra host fields. Never persist them as identity.\n for (const segment of result.segments)\n segment.provenance = providerIdentity(segment.provenance);\n result.capabilities = result.capabilities.map((capability) => ({\n ...providerIdentity(capability),\n confidence: capability.confidence,\n boxes: capability.boxes,\n location: capability.location,\n truncation: capability.truncation,\n usage: capability.usage,\n }));\n}\n\n/** Current access is rechecked on read and fenced publication by the foundation.\n * The host already allocated the immutable input/config revision and lease. */\nexport async function extractAnalysis(\n service: IngestionService,\n lease: AnalysisLease,\n adapter: ExtractionAdapter,\n options: Pick<\n ExtractionRequest,\n 'limits' | 'configurationRevision' | 'signal'\n >,\n): Promise<boolean> {\n const snapshot = await service.getAnalysisInput(lease);\n const persisted = snapshot.configuration.extraction as\n | { configurationRevision?: unknown; limits?: Record<string, unknown> }\n | undefined;\n if (\n !persisted ||\n persisted.configurationRevision !== options.configurationRevision ||\n !persisted.limits ||\n Object.keys(options.limits).some(\n (key) =>\n persisted.limits?.[key] !==\n options.limits[key as keyof typeof options.limits],\n ) ||\n Object.keys(persisted.limits).length !== Object.keys(options.limits).length\n )\n throw new Error('Extraction configuration mismatch');\n const evidence = snapshot.evidence;\n const boundOptions = { ...options, limits: structuredClone(options.limits) };\n const results: ExtractionResult[] = [];\n let limited = false;\n const publication = (reserve = false): AnalysisOutput => {\n const allComplete =\n !limited &&\n results.length === evidence.length &&\n results.every((result) => result.status === 'complete');\n const firstError =\n limited || reserve\n ? 'limit'\n : results.flatMap((result) => result.errors)[0]?.category;\n return {\n status: reserve\n ? 'needs_attention'\n : allComplete\n ? 'completed'\n : results.some((result) => result.segments.length)\n ? 'partial'\n : 'needs_attention',\n provider: 'smrt-ingestion-extraction',\n model: 'none',\n version: '1',\n output: {\n configurationRevision: options.configurationRevision,\n results,\n ...(limited || reserve\n ? {\n truncated: true,\n omittedEvidenceCount: evidence.length - results.length,\n }\n : {}),\n },\n usage: {},\n ...(firstError ? { error: firstError } : {}),\n };\n };\n // Canonical persistence sorts keys but uses identical JSON value encoding/size.\n const fits = (output: AnalysisOutput) =>\n Buffer.byteLength(JSON.stringify(output)) <= snapshot.maxOutputBytes;\n const minimum: AnalysisOutput = {\n status: 'needs_attention',\n provider: 'smrt-ingestion-extraction',\n model: 'none',\n version: '1',\n output: {},\n usage: {},\n error: 'limit',\n };\n if (!fits(minimum)) return service.failAnalysis(lease, 'limit');\n if (!fits(publication(true))) return service.completeAnalysis(lease, minimum);\n for (const part of evidence) {\n await service.getAnalysisInput(lease);\n const bytes = await service.readEvidence(lease.itemId, part.id);\n await service.getAnalysisInput(lease);\n const request = { ...boundOptions, evidence: part, bytes };\n const result = await adapter.extract({\n ...request,\n evidence: { ...part },\n limits: { ...request.limits },\n bytes: bytes.slice(),\n beforeProviderCall: async () => {\n await service.getAnalysisInput(lease);\n },\n });\n validateAndNormalizeExtractionOutput(result, request);\n results.push(result);\n if (!fits(publication(true))) {\n limited = true;\n // Preserve earlier parts and the largest prefix of complete segments that fits.\n result.status = 'partial';\n result.truncated = true;\n result.errors.push({ category: 'limit', location: { kind: 'source' } });\n while (result.segments.length && !fits(publication(true))) {\n const removed = result.segments.pop();\n if (removed) result.omitted.push(removed.location);\n }\n // Diagnostics are indivisible: omit this result rather than erase known gaps.\n if (!fits(publication(true))) results.pop();\n }\n // Revalidation after an external call prevents returning/publishing revoked evidence.\n await service.getAnalysisInput(lease);\n if (limited || options.signal?.aborted) break;\n }\n return service.completeAnalysis(lease, publication());\n}\n\n/** Side-effect-free, versioned split proposal. Original evidence is not replaced. */\nexport function proposeDocumentSplits(\n result: ExtractionResult,\n revision: number,\n groups: number[][],\n) {\n if (!Number.isSafeInteger(revision) || revision < 1 || !groups.length)\n throw new Error('Invalid split revision');\n const available = new Set(\n result.segments.flatMap((segment) =>\n segment.location.kind === 'page' ? [segment.location.page] : [],\n ),\n );\n const seen = new Set<number>();\n for (const group of groups) {\n if (!group.length) throw new Error('Empty split');\n for (const page of group) {\n if (!Number.isSafeInteger(page) || !available.has(page) || seen.has(page))\n throw new Error('Invalid split page');\n seen.add(page);\n }\n if (group.some((page, index) => index > 0 && page <= group[index - 1]))\n throw new Error('Unordered split');\n }\n const proposal = {\n revision,\n evidenceId: result.evidence.id,\n inputHash: result.evidence.contentHash,\n configurationRevision: result.configurationRevision,\n groups: groups.map((pages) => ({ pages: [...pages] })),\n status: 'proposed' as const,\n };\n return {\n ...proposal,\n digest: createHash('sha256').update(JSON.stringify(proposal)).digest('hex'),\n };\n}\n","/** Current generation is authorized, but its immutable candidate revisions are stale. */\nexport class GenerationSnapshotStaleError extends Error {\n constructor() {\n super('Generation snapshot stale');\n this.name = 'GenerationSnapshotStaleError';\n }\n}\n"],"mappings":"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"}
package/dist/dto.d.ts CHANGED
@@ -50,5 +50,7 @@ export interface AnalysisOutput {
50
50
  error?: IntakeFailure;
51
51
  confidence?: number;
52
52
  }
53
+ export type * from './feedback-dto.js';
53
54
  export type * from './proposal-dto.js';
55
+ export type * from './review-dto.js';
54
56
  //# sourceMappingURL=dto.d.ts.map
package/dist/dto.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"dto.d.ts","sourceRoot":"","sources":["../src/dto.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,YAAY,EACZ,gBAAgB,EAChB,YAAY,EACZ,UAAU,EACV,gBAAgB,EAChB,oBAAoB,EACpB,cAAc,EACd,eAAe,EACf,WAAW,GACZ,MAAM,oBAAoB,CAAC;AAE5B,oFAAoF;AACpF,MAAM,MAAM,aAAa,GACrB;IAAE,IAAI,EAAE,UAAU,GAAG,WAAW,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,GAC1E;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,CAAA;CAAE,GACnD;IACE,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE,UAAU,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;CACxD,CAAC;AAEN,kCAAkC;AAClC,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,gFAAgF;AAChF,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,2DAA2D;AAC3D,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,iFAAiF;AACjF,MAAM,MAAM,aAAa,GACrB,kBAAkB,GAClB,kBAAkB,GAClB,OAAO,GACP,SAAS,GACT,aAAa,GACb,gBAAgB,GAChB,WAAW,GACX,WAAW,CAAC;AAEhB,8EAA8E;AAC9E,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,WAAW,GAAG,SAAS,GAAG,QAAQ,GAAG,iBAAiB,CAAC;IAC/D,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,mBAAmB,mBAAmB,CAAC"}
1
+ {"version":3,"file":"dto.d.ts","sourceRoot":"","sources":["../src/dto.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,YAAY,EACZ,gBAAgB,EAChB,YAAY,EACZ,UAAU,EACV,gBAAgB,EAChB,oBAAoB,EACpB,cAAc,EACd,eAAe,EACf,WAAW,GACZ,MAAM,oBAAoB,CAAC;AAE5B,oFAAoF;AACpF,MAAM,MAAM,aAAa,GACrB;IAAE,IAAI,EAAE,UAAU,GAAG,WAAW,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,GAC1E;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,CAAA;CAAE,GACnD;IACE,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE,UAAU,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;CACxD,CAAC;AAEN,kCAAkC;AAClC,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,gFAAgF;AAChF,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,2DAA2D;AAC3D,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,iFAAiF;AACjF,MAAM,MAAM,aAAa,GACrB,kBAAkB,GAClB,kBAAkB,GAClB,OAAO,GACP,SAAS,GACT,aAAa,GACb,gBAAgB,GAChB,WAAW,GACX,WAAW,CAAC;AAEhB,8EAA8E;AAC9E,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,WAAW,GAAG,SAAS,GAAG,QAAQ,GAAG,iBAAiB,CAAC;IAC/D,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,mBAAmB,mBAAmB,CAAC;AACvC,mBAAmB,mBAAmB,CAAC;AACvC,mBAAmB,iBAAiB,CAAC"}
@@ -3,5 +3,7 @@ import type { HandlerContext } from './execution-contracts.js';
3
3
  export declare const discoveryTransaction: unique symbol;
4
4
  export declare const generationSnapshotRead: unique symbol;
5
5
  export type TransactionRunner<T> = (work: (db: DatabaseInterface) => Promise<T>) => Promise<T>;
6
- export type DiscoveryGate = <T>(handlerId: string, handlerVersion: string, work: (context: HandlerContext) => Promise<T>) => Promise<T>;
6
+ export type DiscoveryGate = <T>(handlerId: string, handlerVersion: string, work: (context: HandlerContext, currentTarget: (model: string, id: string) => Promise<{
7
+ revision: string;
8
+ }>) => Promise<T>) => Promise<T>;
7
9
  //# sourceMappingURL=execution-internal.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"execution-internal.d.ts","sourceRoot":"","sources":["../src/execution-internal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAG/D,eAAO,MAAM,oBAAoB,eAA2C,CAAC;AAC7E,eAAO,MAAM,sBAAsB,eAElC,CAAC;AACF,MAAM,MAAM,iBAAiB,CAAC,CAAC,IAAI,CACjC,IAAI,EAAE,CAAC,EAAE,EAAE,iBAAiB,KAAK,OAAO,CAAC,CAAC,CAAC,KACxC,OAAO,CAAC,CAAC,CAAC,CAAC;AAChB,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,EAC5B,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,MAAM,EACtB,IAAI,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,OAAO,CAAC,CAAC,CAAC,KAC1C,OAAO,CAAC,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"execution-internal.d.ts","sourceRoot":"","sources":["../src/execution-internal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAG/D,eAAO,MAAM,oBAAoB,eAA2C,CAAC;AAC7E,eAAO,MAAM,sBAAsB,eAElC,CAAC;AACF,MAAM,MAAM,iBAAiB,CAAC,CAAC,IAAI,CACjC,IAAI,EAAE,CAAC,EAAE,EAAE,iBAAiB,KAAK,OAAO,CAAC,CAAC,CAAC,KACxC,OAAO,CAAC,CAAC,CAAC,CAAC;AAChB,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,EAC5B,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,MAAM,EACtB,IAAI,EAAE,CACJ,OAAO,EAAE,cAAc,EACvB,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,KACxE,OAAO,CAAC,CAAC,CAAC,KACZ,OAAO,CAAC,CAAC,CAAC,CAAC"}
@@ -2,6 +2,8 @@ import type { JobExecutionContext } from '@happyvertical/smrt-jobs';
2
2
  import type { DatabaseInterface } from '@happyvertical/sql';
3
3
  import type { ActionResult, HandlerContext, IntakeExecutionOptions, PlanReview, PreviewPlanInput, PreviewProposalInput, ProposalReview, ReviewInput } from './execution-contracts.js';
4
4
  import { type DiscoveryGate, discoveryTransaction, type TransactionRunner } from './execution-internal.js';
5
+ import { type FeedbackActionContext, feedbackActionTransaction, feedbackDiscoveryContext } from './feedback-internal.js';
6
+ import type { ReviewPage } from './review-dto.js';
5
7
  import type { IngestionOptions } from './server.js';
6
8
  export type * from './execution-contracts.js';
7
9
  export type { IntakePolicy, IntakePolicyLayer } from './policy.js';
@@ -34,14 +36,26 @@ export declare class IntakeExecutionService {
34
36
  /** Current discovery authority. Trusted callbacks use context.db for bounded reads. */
35
37
  withDiscoveryContext<T>(itemId: string, handlerId: string, handlerVersion: string, work: (context: HandlerContext) => Promise<T>): Promise<T>;
36
38
  /** Keep retention restoration outside the supplied foundation transaction. */
37
- [discoveryTransaction]<T>(run: TransactionRunner<T>, itemId: string, work: (db: DatabaseInterface, authorize: DiscoveryGate) => Promise<T>): Promise<T>;
39
+ [discoveryTransaction]<T>(run: TransactionRunner<T>, itemId: string, work: (db: DatabaseInterface, authorize: DiscoveryGate) => Promise<T>, requireReview?: boolean): Promise<T>;
38
40
  private discoveryContext;
39
41
  private bound;
40
42
  private review;
43
+ /** Same-executor current review/evidence/target gate for the owning feedback ledger. */
44
+ /** Join an existing owning transaction; its outer boundary restores retention after rollback. */
45
+ [feedbackDiscoveryContext]<T>(db: DatabaseInterface | undefined, itemId: string, handlerId: string, handlerVersion: string, work: (context: HandlerContext) => Promise<T>, revalidate?: (context: HandlerContext) => Promise<void>): Promise<T>;
46
+ [feedbackActionTransaction]<T>(actionId: string, reviewer: boolean, work: (value: FeedbackActionContext) => Promise<T>, executor?: DatabaseInterface, requiredProviders?: string[], proposalId?: string): Promise<T>;
47
+ private feedbackLineage;
41
48
  getAction(actionId: string): Promise<ProposalReview>;
49
+ /** Bounded reload discovery. The cursor is an opaque action ID, never authority. */
50
+ listReviews(itemId: string, input?: {
51
+ cursor?: string;
52
+ limit?: number;
53
+ }): Promise<ReviewPage>;
42
54
  private buildBinding;
43
55
  private publish;
44
56
  previewProposal(input: PreviewProposalInput): Promise<ProposalReview>;
57
+ /** Capture owner facts in the same transaction; these are never correctness labels. */
58
+ private feedbackEvent;
45
59
  submitDecision(input: ReviewInput): Promise<ProposalReview>;
46
60
  private verifyEvidence;
47
61
  private approved;
@@ -1 +1 @@
1
- {"version":3,"file":"execution.d.ts","sourceRoot":"","sources":["../src/execution.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"execution.d.ts","sourceRoot":"","sources":["../src/execution.ts"],"names":[],"mappings":"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"}
package/dist/execution.js CHANGED
@@ -1,2 +1,2 @@
1
- import { i as resolveIntakePolicy, n as continueIntakeReview, r as intakeBindingDigest, t as IntakeExecutionService } from "./chunks/execution-C6HJvl9e.js";
1
+ import { i as resolveIntakePolicy, n as continueIntakeReview, r as intakeBindingDigest, t as IntakeExecutionService } from "./chunks/execution-C7sTFXFU.js";
2
2
  export { IntakeExecutionService, continueIntakeReview, intakeBindingDigest, resolveIntakePolicy };
@@ -0,0 +1,51 @@
1
+ import type { DatabaseInterface } from '@happyvertical/sql';
2
+ import type { RoutingRule } from './feedback-dto.js';
3
+ import type { IngestionScope } from './server.js';
4
+ /** Trusted server configuration, never a selector supplied by a feedback caller. */
5
+ export interface RoutingProjection {
6
+ handlerId: string;
7
+ handlerVersion: string;
8
+ /** Advance when the meaning of these routing preferences changes. */
9
+ version: string;
10
+ /** Nonempty allowlist of top-level handler argsSchema properties. */
11
+ fields: readonly string[];
12
+ }
13
+ export interface FeedbackConfiguration {
14
+ version: string;
15
+ maxExamples: number;
16
+ maxScan: number;
17
+ maxBytes: number;
18
+ minimumSimilarity: number;
19
+ /** Opt-in routing-only subsets. Omission retains exact full-argument matching. */
20
+ routing?: readonly RoutingProjection[];
21
+ /** Live permission, same executor; host serializes grant changes at this boundary. */
22
+ authorize(input: {
23
+ db: DatabaseInterface;
24
+ scope: Readonly<IngestionScope>;
25
+ itemId: string;
26
+ operation: 'capture' | 'retrieve' | 'suggest' | 'adopt';
27
+ }): Promise<boolean>;
28
+ policy?: {
29
+ /** Return current version and a human-readable routing preview; no mutation. */
30
+ preview(input: {
31
+ db: DatabaseInterface;
32
+ scope: Readonly<IngestionScope>;
33
+ rule: RoutingRule;
34
+ }): Promise<{
35
+ version: string;
36
+ preview: string;
37
+ }>;
38
+ /** Atomic same-executor CAS and audit. May store routing preferences only, never permissions or automation. */
39
+ adopt(input: {
40
+ db: DatabaseInterface;
41
+ scope: Readonly<IngestionScope>;
42
+ rule: RoutingRule;
43
+ expectedVersion: string;
44
+ requestId: string;
45
+ }): Promise<{
46
+ version: string;
47
+ auditId: string;
48
+ }>;
49
+ };
50
+ }
51
+ //# sourceMappingURL=feedback-contracts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feedback-contracts.d.ts","sourceRoot":"","sources":["../src/feedback-contracts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,oFAAoF;AACpF,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,qEAAqE;IACrE,OAAO,EAAE,MAAM,CAAC;IAChB,qEAAqE;IACrE,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;CAC3B;AACD,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,kFAAkF;IAClF,OAAO,CAAC,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACvC,sFAAsF;IACtF,SAAS,CAAC,KAAK,EAAE;QACf,EAAE,EAAE,iBAAiB,CAAC;QACtB,KAAK,EAAE,QAAQ,CAAC,cAAc,CAAC,CAAC;QAChC,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,EAAE,SAAS,GAAG,UAAU,GAAG,SAAS,GAAG,OAAO,CAAC;KACzD,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACrB,MAAM,CAAC,EAAE;QACP,gFAAgF;QAChF,OAAO,CAAC,KAAK,EAAE;YACb,EAAE,EAAE,iBAAiB,CAAC;YACtB,KAAK,EAAE,QAAQ,CAAC,cAAc,CAAC,CAAC;YAChC,IAAI,EAAE,WAAW,CAAC;SACnB,GAAG,OAAO,CAAC;YAAE,OAAO,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QAClD,+GAA+G;QAC/G,KAAK,CAAC,KAAK,EAAE;YACX,EAAE,EAAE,iBAAiB,CAAC;YACtB,KAAK,EAAE,QAAQ,CAAC,cAAc,CAAC,CAAC;YAChC,IAAI,EAAE,WAAW,CAAC;YAClB,eAAe,EAAE,MAAM,CAAC;YACxB,SAAS,EAAE,MAAM,CAAC;SACnB,GAAG,OAAO,CAAC;YAAE,OAAO,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KACnD,CAAC;CACH"}
@@ -0,0 +1,106 @@
1
+ /** Browser-safe feedback contracts. All provenance is resolved by the server. */
2
+ import type { IntakeValues } from './execution-dto.js';
3
+ export interface FeedbackBinding {
4
+ itemId: string;
5
+ actionId: string;
6
+ expectedRevision: number;
7
+ expectedReviewVersion: number;
8
+ bindingHash: string;
9
+ }
10
+ export interface RecordFeedbackInput extends FeedbackBinding {
11
+ judgment: 'correct' | 'incorrect';
12
+ comment?: string;
13
+ requestId: string;
14
+ supersedesId?: string;
15
+ }
16
+ export interface ObserveFeedbackInput extends FeedbackBinding {
17
+ kind: 'action_decision' | 'downstream_outcome';
18
+ eventId: string;
19
+ }
20
+ export interface FeedbackExample {
21
+ feedbackId: string;
22
+ digest: string;
23
+ itemId: string;
24
+ actionId: string;
25
+ revision: number;
26
+ handlerId: string;
27
+ handlerVersion: string;
28
+ judgment: 'correct' | 'incorrect';
29
+ query: string;
30
+ args: IntakeValues;
31
+ model: {
32
+ provider: string;
33
+ model: string;
34
+ version: string;
35
+ };
36
+ promptVersion: string;
37
+ configurationVersion: string;
38
+ }
39
+ export interface FeedbackReceipt {
40
+ id: string;
41
+ digest: string;
42
+ kind: 'interpretation' | 'action_decision' | 'downstream_outcome';
43
+ }
44
+ export interface FeedbackReferences {
45
+ version: string;
46
+ configurationDigest: string;
47
+ examples: Array<{
48
+ feedbackId: string;
49
+ digest: string;
50
+ }>;
51
+ }
52
+ export interface FeedbackSelection {
53
+ version: string;
54
+ configurationDigest: string;
55
+ examples: FeedbackExample[];
56
+ }
57
+ export interface RoutingRule {
58
+ handlerId: string;
59
+ handlerVersion: string;
60
+ /** Routing only; never grants, executable instructions or automation settings. */
61
+ matchTerms: string[];
62
+ /** Present only for a trusted versioned subset; bound to captured evidence. */
63
+ projection?: {
64
+ version: string;
65
+ fields: string[];
66
+ };
67
+ /** Full arguments by default; only allowlisted preferences with projection. */
68
+ args: IntakeValues;
69
+ }
70
+ export interface RuleSuggestion {
71
+ id: string;
72
+ digest: string;
73
+ itemId: string;
74
+ rule: RoutingRule;
75
+ supportingFeedback: Array<{
76
+ id: string;
77
+ digest: string;
78
+ }>;
79
+ expectedPolicyVersion: string;
80
+ preview: string;
81
+ automaticActionEligible: false;
82
+ }
83
+ export interface SuggestRuleInput extends FeedbackBinding {
84
+ supportingFeedbackIds: string[];
85
+ requestId: string;
86
+ }
87
+ export interface ReadRuleInput extends FeedbackBinding {
88
+ suggestionId: string;
89
+ }
90
+ export interface AdoptRuleInput extends FeedbackBinding {
91
+ suggestionId: string;
92
+ expectedDigest: string;
93
+ expectedPolicyVersion: string;
94
+ requestId: string;
95
+ }
96
+ export interface RuleAdoption {
97
+ id: string;
98
+ policyVersion: string;
99
+ auditId: string;
100
+ automaticActionEligible: false;
101
+ }
102
+ export interface RetrieveFeedbackInput {
103
+ itemId: string;
104
+ query: string;
105
+ }
106
+ //# sourceMappingURL=feedback-dto.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feedback-dto.d.ts","sourceRoot":"","sources":["../src/feedback-dto.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { DatabaseInterface } from '@happyvertical/sql';
2
+ import type { HandlerContext } from './execution-contracts.js';
3
+ import type { IntakeValues, ProposalReview } from './execution-dto.js';
4
+ /** Owning execution boundary; not exported from any public entry point. */
5
+ export declare const feedbackActionTransaction: unique symbol;
6
+ export interface FeedbackActionContext {
7
+ db: DatabaseInterface;
8
+ context: HandlerContext;
9
+ review: ProposalReview;
10
+ itemId: string;
11
+ attemptId: string;
12
+ args: IntakeValues;
13
+ analysis: IntakeValues;
14
+ result: IntakeValues;
15
+ handlerId: string;
16
+ handlerVersion: string;
17
+ }
18
+ export declare const feedbackDiscoveryContext: unique symbol;
19
+ //# sourceMappingURL=feedback-internal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feedback-internal.d.ts","sourceRoot":"","sources":["../src/feedback-internal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACvE,2EAA2E;AAC3E,eAAO,MAAM,yBAAyB,eAErC,CAAC;AACF,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,iBAAiB,CAAC;IACtB,OAAO,EAAE,cAAc,CAAC;IACxB,MAAM,EAAE,cAAc,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,YAAY,CAAC;IACnB,QAAQ,EAAE,YAAY,CAAC;IACvB,MAAM,EAAE,YAAY,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,eAAO,MAAM,wBAAwB,eAEpC,CAAC"}
@@ -0,0 +1,54 @@
1
+ import type { DatabaseInterface } from '@happyvertical/sql';
2
+ import { IntakeExecutionService } from './execution.js';
3
+ import type { AdoptRuleInput, FeedbackReceipt, FeedbackReferences, FeedbackSelection, ObserveFeedbackInput, ReadRuleInput, RecordFeedbackInput, RuleAdoption, RuleSuggestion, SuggestRuleInput } from './feedback-dto.js';
4
+ import type { GenerationOutput } from './proposal-dto.js';
5
+ import type { IngestionOptions } from './server.js';
6
+ export declare function feedbackTerms(value: string): string[];
7
+ export declare function feedbackSimilarity(left: string, right: string): number;
8
+ export interface RetrieveFeedbackInput {
9
+ itemId: string;
10
+ query: string;
11
+ offered: GenerationOutput['offered'];
12
+ promptVersion: string;
13
+ configurationVersion: string;
14
+ model: {
15
+ provider: string;
16
+ model: string;
17
+ version: string;
18
+ };
19
+ providers?: string[];
20
+ }
21
+ /** Owning ingestion ledger. Generic LearningMemory's success/ancestor fallback semantics are deliberately not used. */
22
+ export declare class IntakeFeedbackService {
23
+ private readonly options;
24
+ private readonly execution;
25
+ private readonly config;
26
+ private readonly lineage;
27
+ private exampleChecks;
28
+ constructor(options: IngestionOptions, execution?: IntakeExecutionService);
29
+ private configurationDigest;
30
+ private routing;
31
+ private scope;
32
+ private rows;
33
+ private authorize;
34
+ private checkBinding;
35
+ private insert;
36
+ private receipt;
37
+ private provenance;
38
+ /** Internal saved-action gate; the execution owner supplies its transaction. */
39
+ assertActionLineage(actionId: string, db: DatabaseInterface, proposalId: string): Promise<void>;
40
+ record(input: RecordFeedbackInput): Promise<FeedbackReceipt>;
41
+ /** Consume a durable owner event idempotently. Never derive correctness from these signals. */
42
+ observe(input: ObserveFeedbackInput): Promise<FeedbackReceipt>;
43
+ private example;
44
+ private receivingContext;
45
+ retrieve(input: RetrieveFeedbackInput, executor?: DatabaseInterface): Promise<FeedbackSelection>;
46
+ assertSelection(input: RetrieveFeedbackInput, selection: FeedbackReferences, executor?: DatabaseInterface): Promise<void>;
47
+ private support;
48
+ suggest(input: SuggestRuleInput): Promise<RuleSuggestion>;
49
+ private ruleDTO;
50
+ private rule;
51
+ readRule(input: ReadRuleInput): Promise<RuleSuggestion>;
52
+ adopt(input: AdoptRuleInput): Promise<RuleAdoption>;
53
+ }
54
+ //# sourceMappingURL=feedback.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feedback.d.ts","sourceRoot":"","sources":["../src/feedback.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAEL,sBAAsB,EACvB,MAAM,gBAAgB,CAAC;AAExB,OAAO,KAAK,EACV,cAAc,EAGd,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,oBAAoB,EACpB,aAAa,EACb,mBAAmB,EAEnB,YAAY,EACZ,cAAc,EACd,gBAAgB,EACjB,MAAM,mBAAmB,CAAC;AAM3B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AA2BpD,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAIrD;AACD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAOtE;AACD,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,gBAAgB,CAAC,SAAS,CAAC,CAAC;IACrC,aAAa,EAAE,MAAM,CAAC;IACtB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,KAAK,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5D,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AACD,uHAAuH;AACvH,qBAAa,qBAAqB;IAM9B,OAAO,CAAC,QAAQ,CAAC,OAAO;IAL1B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAyB;IACnD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAwB;IAC/C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;IAC7C,OAAO,CAAC,aAAa,CAAK;gBAEP,OAAO,EAAE,gBAAgB,EAC1C,SAAS,CAAC,EAAE,sBAAsB;IAsBpC,OAAO,CAAC,mBAAmB;IAW3B,OAAO,CAAC,OAAO;IAwDf,OAAO,CAAC,KAAK;YAGC,IAAI;YAeJ,SAAS;IAcvB,OAAO,CAAC,YAAY;YAUN,MAAM;IAwCpB,OAAO,CAAC,OAAO;YAOD,UAAU;IA+ExB,gFAAgF;IAC1E,mBAAmB,CACvB,QAAQ,EAAE,MAAM,EAChB,EAAE,EAAE,iBAAiB,EACrB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC;IAYV,MAAM,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,eAAe,CAAC;IA6ElE,+FAA+F;IACzF,OAAO,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,eAAe,CAAC;YAiEtD,OAAO;IAqFrB,OAAO,CAAC,gBAAgB;IA+ClB,QAAQ,CACZ,KAAK,EAAE,qBAAqB,EAC5B,QAAQ,CAAC,EAAE,iBAAiB,GAC3B,OAAO,CAAC,iBAAiB,CAAC;IA0DvB,eAAe,CACnB,KAAK,EAAE,qBAAqB,EAC5B,SAAS,EAAE,kBAAkB,EAC7B,QAAQ,CAAC,EAAE,iBAAiB,GAC3B,OAAO,CAAC,IAAI,CAAC;YA4DF,OAAO;IA+Df,OAAO,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,cAAc,CAAC;IA6D/D,OAAO,CAAC,OAAO;YAcD,IAAI;IAyCZ,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC;IA4BvD,KAAK,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,YAAY,CAAC;CAyF1D"}