@happyvertical/smrt-ingestion 0.57.45 → 0.57.46

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 (79) hide show
  1. package/FEEDBACK.md +30 -0
  2. package/PROPOSALS.md +29 -0
  3. package/REVIEW.md +79 -0
  4. package/agents/execution.md +3 -1
  5. package/dist/chunks/{execution-DKWz2cz0.js → execution-Clcmi0sj.js} +2 -2
  6. package/dist/chunks/{execution-DKWz2cz0.js.map → execution-Clcmi0sj.js.map} +1 -1
  7. package/dist/chunks/{feedback-DHcSKgVU.js → feedback-hDSMYjiG.js} +94 -34
  8. package/dist/chunks/feedback-hDSMYjiG.js.map +1 -0
  9. package/dist/chunks/{proposal-contracts-CPH3ckgH.js → proposal-contracts-DREPLG56.js} +75 -2
  10. package/dist/chunks/proposal-contracts-DREPLG56.js.map +1 -0
  11. package/dist/chunks/{reviewer-instruction-Deoe4NPv.js → reviewer-instruction-BeOYVCVk.js} +2 -2
  12. package/dist/chunks/{reviewer-instruction-Deoe4NPv.js.map → reviewer-instruction-BeOYVCVk.js.map} +1 -1
  13. package/dist/execution-contracts.d.ts +7 -0
  14. package/dist/execution-contracts.d.ts.map +1 -1
  15. package/dist/execution.js +1 -1
  16. package/dist/feedback-contracts.d.ts +32 -3
  17. package/dist/feedback-contracts.d.ts.map +1 -1
  18. package/dist/feedback.d.ts +28 -0
  19. package/dist/feedback.d.ts.map +1 -1
  20. package/dist/generation-retry.d.ts +45 -0
  21. package/dist/generation-retry.d.ts.map +1 -0
  22. package/dist/manifest.json +1 -1
  23. package/dist/models.js +1 -1
  24. package/dist/models.js.map +1 -1
  25. package/dist/proposal-contracts.d.ts +15 -0
  26. package/dist/proposal-contracts.d.ts.map +1 -1
  27. package/dist/proposal-dto.d.ts +6 -0
  28. package/dist/proposal-dto.d.ts.map +1 -1
  29. package/dist/proposals.d.ts +7 -0
  30. package/dist/proposals.d.ts.map +1 -1
  31. package/dist/proposals.js +61 -18
  32. package/dist/proposals.js.map +1 -1
  33. package/dist/review-dto.d.ts +56 -0
  34. package/dist/review-dto.d.ts.map +1 -1
  35. package/dist/review-host.d.ts +14 -1
  36. package/dist/review-host.d.ts.map +1 -1
  37. package/dist/server.d.ts +27 -1
  38. package/dist/server.d.ts.map +1 -1
  39. package/dist/server.js +127 -5
  40. package/dist/server.js.map +1 -1
  41. package/dist/smrt-knowledge.json +16 -16
  42. package/dist/svelte/argument-fields.d.ts +48 -0
  43. package/dist/svelte/argument-fields.d.ts.map +1 -0
  44. package/dist/svelte/argument-fields.js +96 -0
  45. package/dist/svelte/components/ActionReview.svelte +81 -11
  46. package/dist/svelte/components/ActionReview.svelte.d.ts +30 -1
  47. package/dist/svelte/components/ActionReview.svelte.d.ts.map +1 -1
  48. package/dist/svelte/components/ArgumentFields.svelte +176 -0
  49. package/dist/svelte/components/ArgumentFields.svelte.d.ts +27 -0
  50. package/dist/svelte/components/ArgumentFields.svelte.d.ts.map +1 -0
  51. package/dist/svelte/components/InboxView.svelte +137 -17
  52. package/dist/svelte/components/InboxView.svelte.d.ts +17 -0
  53. package/dist/svelte/components/InboxView.svelte.d.ts.map +1 -1
  54. package/dist/svelte/components/IntakeInbox.svelte +26 -2
  55. package/dist/svelte/components/IntakeInbox.svelte.d.ts +10 -1
  56. package/dist/svelte/components/IntakeInbox.svelte.d.ts.map +1 -1
  57. package/dist/svelte/components/IntakeWorkspace.svelte +23 -1
  58. package/dist/svelte/components/IntakeWorkspace.svelte.d.ts +13 -1
  59. package/dist/svelte/components/IntakeWorkspace.svelte.d.ts.map +1 -1
  60. package/dist/svelte/components/ReviewView.svelte +88 -10
  61. package/dist/svelte/components/ReviewView.svelte.d.ts.map +1 -1
  62. package/dist/svelte/components/TriageView.svelte +43 -3
  63. package/dist/svelte/components/TriageView.svelte.d.ts +10 -1
  64. package/dist/svelte/components/TriageView.svelte.d.ts.map +1 -1
  65. package/dist/svelte/i18n.d.ts +33 -0
  66. package/dist/svelte/i18n.d.ts.map +1 -1
  67. package/dist/svelte/i18n.js +36 -0
  68. package/dist/svelte/index.d.ts +2 -1
  69. package/dist/svelte/index.d.ts.map +1 -1
  70. package/dist/svelte/index.js +1 -0
  71. package/dist/svelte/upload-refusal.d.ts +25 -0
  72. package/dist/svelte/upload-refusal.d.ts.map +1 -0
  73. package/dist/svelte/upload-refusal.js +40 -0
  74. package/dist/svelte/view-utils.d.ts +8 -0
  75. package/dist/svelte/view-utils.d.ts.map +1 -1
  76. package/dist/svelte/view-utils.js +36 -0
  77. package/package.json +13 -13
  78. package/dist/chunks/feedback-DHcSKgVU.js.map +0 -1
  79. package/dist/chunks/proposal-contracts-CPH3ckgH.js.map +0 -1
package/FEEDBACK.md CHANGED
@@ -18,6 +18,15 @@ judgment. A second successor conflicts. Revised actions make old bindings
18
18
  ineligible. Approval and successful execution never imply that extracted fields
19
19
  are correct.
20
20
 
21
+ Optional `feedback.onRecorded({ db, scope, receipt, input })` (#4522) runs
22
+ inside the transaction that stores an explicit judgment, on the same executor,
23
+ after the judgment row (and its `supersedesId` link) is written and before the
24
+ final `capture` recheck. Write the host's own activity entry there: it commits
25
+ or rolls back with the judgment, and a throw rolls the judgment back and
26
+ rejects `recordFeedback` with that error. `receipt` and `input` are copies. It
27
+ is not called for an idempotent replay (already committed) or for
28
+ `observeFeedback`; like `policy.adopt`, it must write only host-owned rows.
29
+
21
30
  Decision and downstream execution facts are captured inside their owning
22
31
  transaction, keyed by immutable event ID and signal, when the configured capture
23
32
  authority allows the optional memory projection and it fits the configured byte
@@ -290,6 +299,15 @@ displayed binding is current again. Hosts must authenticate that callback and co
290
299
  maintained browser fixture demonstrates this transport with CSRF protection and
291
300
  rejects substituted revisions.
292
301
 
302
+ With `enableFeedback`, `createIntakeReviewHost` also loads each action's
303
+ `ReviewAction.feedback` (#4503): this reviewer's own current (not superseded)
304
+ judgment at the displayed revision and binding (`id`, `judgment`, `comment`,
305
+ `recordedAt`), read through `IngestionService.listOwnFeedback`. The chosen
306
+ button is `aria-pressed`, `ingestion.feedbackSent` shows after a judgment, and
307
+ a further judgment sends `supersedesId` (the loaded id, else the receipt id the
308
+ callback returned). Another reviewer's judgment is never shown as pressed; a
309
+ failed read only leaves the pressed state off.
310
+
293
311
  See [the behavior matrix](../../docs/test-matrix/3676-ingestion-feedback.md) for
294
312
  validation and the frozen learning protocol, and the
295
313
  [routing projection matrix](../../docs/test-matrix/3732-ingestion-routing-projection.md)
@@ -299,6 +317,18 @@ production improvement. Real-provider evaluation belongs to #3677. There are no
299
317
  sampled automatic outcomes in this feature; reporting that stratum as unavailable
300
318
  avoids inventing correctness labels from successful jobs.
301
319
 
320
+ `authorize` distinguishes two read operations (#4504). `retrieve` covers
321
+ picking new examples and revalidating a selection at the provider boundary.
322
+ `verify` covers re-checking the stored lineage of an existing generation (the
323
+ examples it was produced with) whenever its actions are read, reviewed,
324
+ labelled or applied, including `getAction`/`listReviews`, and whenever the
325
+ stored generation snapshot is read (`getCompletedAnalysis`, the review host's
326
+ `load`, instructions, splits and Try again). A host that switches
327
+ learning off refuses `retrieve` and keeps allowing `verify`, so items analysed
328
+ while learning was on still load. Fail-safe for authorizers that predate
329
+ `verify`: when `verify` returns `false` the same check is asked as `retrieve`,
330
+ and only a refusal of both fails closed ("Feedback unavailable") as before.
331
+
302
332
  When interpretation requests optional examples, an explicit denial of feedback
303
333
  retrieval degrades to generation without examples or feedback provenance. Direct
304
334
  `retrieveFeedback` calls still reject denied reads. Other authorization errors
package/PROPOSALS.md CHANGED
@@ -468,6 +468,35 @@ Like `failureCapture`, the hook is not public read configuration and never enter
468
468
  frozen configuration or digests. Hosts keep it synchronous-cheap: it runs inside
469
469
  the generation lease.
470
470
 
471
+ ### Retry and concurrency (opt-in, #4504)
472
+
473
+ ```ts
474
+ proposals: {
475
+ // ...
476
+ retry: {
477
+ attempts: 3, // total calls, 1..10; default 1
478
+ backoffMs: (attempt) => 500 * 2 ** (attempt - 2), // or a number, 0..60000; default 0
479
+ retryable: (error) => (error as { status?: number }).status === 529,
480
+ },
481
+ concurrency: 4, // 1..1000; default unlimited
482
+ },
483
+ ```
484
+
485
+ `retry` retries a rejected `generator.generate` call; absent (or
486
+ `attempts: 1`) keeps one call as before. `retryable(error, attempt)` sees the
487
+ generator's rejection (default: retry every rejection; a throwing predicate
488
+ means no). Each call gets its own `limits.timeoutMs` deadline; a timeout is
489
+ final, as are validation failures of a returned reply. A retry is skipped when
490
+ the analysis lease could not cover the backoff plus another full deadline, and
491
+ a malformed `backoffMs` answer ends the retries. Only the final rejection is
492
+ recorded (`provider_error`, category `unavailable`, value-free reason).
493
+ `concurrency` bounds `generate` calls in flight across every service built
494
+ from the same configuration object (FIFO); a queued call's deadline starts
495
+ when it gets a slot. Both are validated at `IngestionService` construction and,
496
+ like `reviewSuggestion`, never enter frozen configuration, digests or
497
+ `proposalReadConfiguration`. A reviewer can still re-run a finally failed item
498
+ with "Try again" (REVIEW.md, `retryInterpretation`).
499
+
471
500
  ### Failed-attempt capture (opt-in, #4285)
472
501
 
473
502
  The value-free reason cannot show what the model actually sent. A host that
package/REVIEW.md CHANGED
@@ -363,6 +363,24 @@ streaming channel; status is read through the existing item/analysis APIs. The
363
363
  maintained fixture records the instruction durably and then runs the stages in
364
364
  the background so the browser proof exercises the in-place update.
365
365
 
366
+ **Try again (#4504).** `retryInterpretation({itemId, attemptId,
367
+ expectedRevision, requestId})` re-runs an item whose interpretation failed (the
368
+ displayed generation is `provider_error`, or later work failed or never
369
+ started) with no new instruction. It uses the same anchor, guards, `process`
370
+ authority and fresh extraction plus interpretation as an instruction, carries
371
+ the item's current configuration (an instruction or split already in effect
372
+ included) unchanged, and records nothing in the instruction history. Superseded
373
+ anchors, work in flight and items that did not fail throw
374
+ `ReviewerInstructionStaleError`. A replay of the same intent (item, anchor,
375
+ revision, `requestId`, actor) returns the first append under current `process`
376
+ authority; the same `requestId` with another intent is a request conflict.
377
+ `createIntakeReviewHost` exposes it as `IntakeReviewHost.retry` (stale resolves
378
+ `{ stale: true }`) and wakes the worker through `onRetry`, else `onInstruct`.
379
+ `ReviewView` draws a "Try again" button (`ingestion.tryAgain`) beside the
380
+ instruction box when `host.retry` exists, the item is open, nothing is in
381
+ flight and the interpretation failed; it binds like the instruction
382
+ (`instruction.binding`, else the displayed generation).
383
+
366
384
  `feedback` is an optional explicit correctness callback, separate from approval
367
385
  choice and execution success. No learning, feedback storage or rule promotion is
368
386
  implemented by these components; #3676 owns those services. Do not pass feedback
@@ -451,6 +469,45 @@ provider. The UI picker shows the offered catalog, so a handler hidden from it i
451
469
  only reachable by a reviewer who already holds `review` authority for it. The maintained
452
470
  browser fixture serves both operations behind CSRF and the same session scope.
453
471
 
472
+ ## Review screen presentation (#4503)
473
+
474
+ All presentation only; no new authority.
475
+
476
+ - **Handler labels.** A handler registration may declare `label`. It is carried
477
+ on the reviewer catalog only (`listHandlers`, `ItemReviewView.catalog`), never
478
+ on generation input, catalog digests or bindings, so adding one never stales
479
+ existing work. The proposal heading, action heading and "Start action as…"
480
+ select draw it, falling back to the handler id.
481
+ - **State labels.** Review states draw `ingestion.reviewState.<state>` and
482
+ generation outcomes `ingestion.outcome.<outcome>`; an unknown value is drawn
483
+ as is.
484
+ - **Arguments as fields.** Where a handler `argsSchema` declares top-level
485
+ `string` (plain, `date`, `date-time`), `number`, `integer`, `boolean` or
486
+ enum properties, or `references` declares a candidate/evidence field, the
487
+ suggestion draft, the action's arguments and the start form draw those as
488
+ fields (`title` as the label, `*` when required). A candidate reference is a
489
+ search box over `host.candidates`, filtered to the reference's model, showing
490
+ the candidate's label (the generation's offered candidates label the current
491
+ value); an evidence reference picks among the item's originals. The JSON text
492
+ stays the source of truth: fields rewrite it, and it remains editable under a
493
+ collapsed "Advanced" disclosure for everything else (objects, arrays,
494
+ unions). Without such properties the plain JSON textarea (and the
495
+ destination picker) are drawn as before. Server validation is unchanged.
496
+ - **Effects.** `action.review.display` is drawn as a `<dl>`: the handler's
497
+ preview fields (`display.preview`, or `display.step.preview` for a plan step;
498
+ a flat record as is), then non-empty `dependencies`/`plan` metadata as JSON,
499
+ named `metadata.<key>` when a preview field already has that name
500
+ (`displayEntries` in `view-utils`).
501
+ - **Assignees.** An optional `IntakeReviewHost.assignees(query)` (adapter
502
+ option `assignees`) answers `{ id, label }[]`; the inbox then draws a search
503
+ picker for the filter and each row instead of the free-text "Assignee ID".
504
+ `assign` still receives the id and still authorizes. A failed search offers
505
+ nothing.
506
+ - **Feedback state.** `ReviewAction.feedback` (see FEEDBACK.md) presses the
507
+ current judgment; a further judgment supersedes it and
508
+ `ingestion.feedbackSent` confirms it.
509
+ - **Confidence.** Nothing is drawn when the provider reports no confidence.
510
+
454
511
  ## Single-page triage workspace
455
512
 
456
513
  `IntakeWorkspace` (#4215) composes the existing pieces so a reviewer works the
@@ -586,6 +643,16 @@ model only, exactly as in `IntakeReview`.
586
643
  goes through the item pane and advances.
587
644
 
588
645
 
646
+ **List following and refresh (#4504).** Every listed row (other than the open
647
+ item) whose entry shows a stage in flight is followed like an item left
648
+ mid-stage, up to `WATCH_CAP` rows, `WATCH_LIMIT` reads per tick on the pane's
649
+ backoff, so rows no longer keep "Interpreting…" until Refresh. Opt-in
650
+ `listPollMs` on `IntakeWorkspace`/`IntakeInbox` also re-reads the listed page
651
+ under its listed filter while any row is processing (skipped while a read or
652
+ operation is pending or Load more appended pages). Both components export
653
+ `refresh()` (`bind:this`), which re-reads the first page like the Refresh
654
+ button and resolves `{ items, result: 'shown' | 'failed' | 'pending' }`.
655
+
589
656
  ## Maintained browser proof
590
657
 
591
658
  `pnpm test:components` runs real Svelte component tests; `pnpm test:e2e` runs the
@@ -811,6 +878,18 @@ The factory unwraps this into `ItemReviewView.generation`. Stale generation is
811
878
  omitted while authorized saved reviews remain available; access denials propagate.
812
879
  The reference application still owns its fixture provisioning and HTTP transport.
813
880
 
881
+ ## Upload refusals and accepted types (#4502)
882
+
883
+ `IntakeWorkspace`/`IntakeInbox` take `accept` (an `<input accept>` value)
884
+ for their file picker, defaulting to `IntakeReviewHost.uploadAccept` (adapter
885
+ option `uploadAccept`); it is a hint only, `upload` still enforces the host's
886
+ allowlist. When `upload` throws `IntakeUploadRefusedError` (from `/svelte`) or
887
+ any error with a string `userMessage` (or an error named
888
+ `IntakeUploadRefusedError` / with `code: 'INTAKE_UPLOAD_REFUSED'`, whose
889
+ `message` is then shown), the inbox shows that reason (trimmed, at most 500
890
+ characters) and keeps its rows; `uploadRefusalMessage(error)` applies the same
891
+ rule. Any other error still fails the list closed with `ingestion.error`.
892
+
814
893
  ## Explicit upload retries
815
894
 
816
895
  The inbox retains selected original files and the receive request identity when
@@ -11,7 +11,9 @@ service surface and create `IngestionScope` from the session.
11
11
  ## Catalog and authority
12
12
 
13
13
  Applications supply a trusted `IntakeExecutionOptions.handlers` catalog.
14
- `OperationHandler` has qualified ID, immutable version, description, object JSON
14
+ `OperationHandler` has qualified ID, immutable version, description, optional
15
+ reviewer-facing `label` (presentation only, carried on the reviewer catalog and
16
+ never on generation input or digests; REVIEW.md), object JSON
15
17
  schemas for arguments/results, allowlisted `resultModels`, `validate`, `preview`,
16
18
  a registered `{model, action, version}` operation and explicit effect/idempotency/
17
19
  open-world capability declaration. Preview returns display, exact normalized
@@ -7144,7 +7144,7 @@ var IntakeExecutionService = class IntakeExecutionService {
7144
7144
  if (!Array.isArray(references)) throw new Error("Feedback lineage unavailable");
7145
7145
  if (references.length === 0) return;
7146
7146
  if (!this.options.feedback) throw new Error("Feedback configuration unavailable");
7147
- const { IntakeFeedbackService } = await import("./feedback-DHcSKgVU.js").then((n) => n.r);
7147
+ const { IntakeFeedbackService } = await import("./feedback-hDSMYjiG.js").then((n) => n.r);
7148
7148
  await new IntakeFeedbackService(this.options, this).assertActionLineage(String(bound.action.id), db, String(bound.proposal.id));
7149
7149
  }
7150
7150
  async getAction(actionId) {
@@ -8729,4 +8729,4 @@ async function continueIntakeReview(service, actionId, task) {
8729
8729
  //#endregion
8730
8730
  export { __toESM as A, storedFailureCapture as C, generationSnapshotRead as D, discoveryTransaction as E, listReadGate as O, prepareFailureCapture as S, completeWithFailureCapture as T, HandlerArgumentsInvalidError as _, resolveIntakePolicy as a, FAILURE_CAPTURE_MAX_BYTES as b, HANDLER_ARGUMENT_ISSUE_LIMIT as c, schemaOwnedPath as d, require_ajv as f, GenerationSourceStaleError as g, GenerationSnapshotStaleError as h, intakeBindingDigest as i, __exportAll as k, HANDLER_ARGUMENT_PATH_LIMIT as l, redactedCeiling as m, IntakeExecutionService as n, feedbackActionTransaction as o, UNFINISHED_ACTION_STATES as p, continueIntakeReview as r, feedbackDiscoveryContext as s, IntakeAccessDeniedError as t, describeArgumentRefusal as u, ProposalsNotConfiguredError as v, analysisLeaseRemaining as w, assertFailureCapture as x, FAILURE_CAPTURE_DEFAULT_MAX_BYTES as y };
8731
8731
 
8732
- //# sourceMappingURL=execution-DKWz2cz0.js.map
8732
+ //# sourceMappingURL=execution-Clcmi0sj.js.map