@sema-agent/core 5.45.0 → 5.47.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/CHANGELOG.md +97 -0
  2. package/dist/agents/subagent.js +130 -3
  3. package/dist/core/checkpoint-store.d.ts +12 -0
  4. package/dist/core/governance-codes.d.ts +13 -0
  5. package/dist/core/governance-codes.js +33 -0
  6. package/dist/core/hooks.d.ts +9 -2
  7. package/dist/core/hooks.js +6 -5
  8. package/dist/core/memory-engine/content-origin.d.ts +3 -1
  9. package/dist/core/memory-engine/delegation-settlement.d.ts +318 -0
  10. package/dist/core/memory-engine/delegation-settlement.js +661 -0
  11. package/dist/core/memory-engine/engine.d.ts +209 -4
  12. package/dist/core/memory-engine/engine.js +885 -39
  13. package/dist/core/memory-engine/export-bundle.d.ts +10 -1
  14. package/dist/core/memory-engine/export-bundle.js +21 -0
  15. package/dist/core/memory-engine/file-backend.d.ts +34 -4
  16. package/dist/core/memory-engine/file-backend.js +168 -40
  17. package/dist/core/memory-engine/frontmatter.d.ts +69 -1
  18. package/dist/core/memory-engine/frontmatter.js +156 -2
  19. package/dist/core/memory-engine/header-hints.d.ts +17 -0
  20. package/dist/core/memory-engine/header-hints.js +6 -0
  21. package/dist/core/memory-engine/index.d.ts +7 -5
  22. package/dist/core/memory-engine/index.js +5 -3
  23. package/dist/core/memory-engine/layout.d.ts +39 -2
  24. package/dist/core/memory-engine/layout.js +27 -14
  25. package/dist/core/memory-engine/memory-backend-contract.js +108 -0
  26. package/dist/core/memory-engine/origin-clearance.d.ts +66 -0
  27. package/dist/core/memory-engine/origin-clearance.js +84 -0
  28. package/dist/core/memory-engine/provenance-wording.d.ts +50 -0
  29. package/dist/core/memory-engine/provenance-wording.js +15 -0
  30. package/dist/core/memory-engine/sync-client.d.ts +1 -1
  31. package/dist/core/memory-engine/sync-client.js +33 -1
  32. package/dist/core/memory-engine/tools.d.ts +64 -3
  33. package/dist/core/memory-engine/tools.js +37 -9
  34. package/dist/core/memory-engine/types.d.ts +145 -3
  35. package/dist/core/memory-engine/types.js +1 -1
  36. package/dist/core/reminder-mint.d.ts +70 -0
  37. package/dist/core/reminder-mint.js +25 -0
  38. package/dist/core/runner/git-status-frame.d.ts +3 -14
  39. package/dist/core/runner/git-status-frame.js +39 -14
  40. package/dist/core/runner/prepare-config-doors.d.ts +4 -0
  41. package/dist/core/runner/prepare-config-doors.js +15 -0
  42. package/dist/core/runner/prepare-hands-readface.d.ts +5 -11
  43. package/dist/core/runner/prepare-hands-readface.js +26 -0
  44. package/dist/core/runner/prepare-memory.d.ts +11 -0
  45. package/dist/core/runner/prepare-memory.js +61 -24
  46. package/dist/core/runner/prepare-task.d.ts +46 -1
  47. package/dist/core/runner/prepare-task.js +128 -23
  48. package/dist/core/runner/runtask.js +62 -55
  49. package/dist/core/session-reconcile.js +3 -2
  50. package/dist/core/side-query.d.ts +11 -1
  51. package/dist/core/side-query.js +3 -0
  52. package/dist/core/types.d.ts +85 -10
  53. package/dist/core/types.js +3 -0
  54. package/dist/engine/harness/types.d.ts +46 -1
  55. package/dist/engine/harness/types.js +11 -0
  56. package/dist/engine/session/import-validate.js +6 -1
  57. package/dist/engine/session/session.d.ts +20 -0
  58. package/dist/engine/session/session.js +26 -1
  59. package/dist/index.d.ts +3 -1
  60. package/dist/index.js +3 -1
  61. package/dist/orchestration/run-workflow-tool.d.ts +16 -0
  62. package/dist/orchestration/run-workflow-tool.js +23 -3
  63. package/dist/orchestration/workflow-governance.d.ts +8 -1
  64. package/dist/prompt-assembly/epoch.js +2 -0
  65. package/dist/prompt-assembly/types.d.ts +6 -0
  66. package/dist/prompts/default.d.ts +13 -1
  67. package/dist/prompts/default.js +5 -1
  68. package/dist/tools/fs/fs-bash.d.ts +4 -0
  69. package/dist/tools/fs/fs-bash.js +1 -1
  70. package/dist/tools/fs/fs-read.d.ts +1 -1
  71. package/dist/tools/fs/fs-read.js +8 -7
  72. package/dist/tools/fs/fs-shared.d.ts +10 -4
  73. package/dist/tools/fs/fs-shared.js +6 -3
  74. package/dist/tools/fs/gh-rate-limit.d.ts +4 -1
  75. package/dist/tools/fs/gh-rate-limit.js +3 -2
  76. package/dist/tools/fs/index.d.ts +10 -2
  77. package/dist/tools/fs/index.js +2 -1
  78. package/dist/tools/task-list.d.ts +5 -1
  79. package/package.json +1 -1
  80. package/test/export-surface.snapshot.json +21 -2
@@ -1,8 +1,10 @@
1
1
  import type { EngineNotice } from "../types.js";
2
+ import { foreignDanglingSessionAccounts, type EffectiveSettlement, type HoldRow } from "./delegation-settlement.js";
3
+ import { type OriginClearanceRow } from "./origin-clearance.js";
2
4
  import { type CommittedBinding, type EraseMemoryEntriesInput, type MemoryErasureAttestation, type TransferEvidence } from "./file-backend.js";
3
5
  import { type MemoryExportBundle, type MemoryImportReport } from "./export-bundle.js";
4
6
  import { type ChallengeAssignment, type ChallengeEvent, type ControlPlaneRebuildReceipt, type StrictControlPlaneLedger, type ChallengedHistoryRow, type LineagePendingTxn, type LineagePromotion, type MemoryPartitionIncidentSink, type RetrievedAccountRow, type SessionPollutionMarkOutcome, type SessionPollutionRecord } from "./layout.js";
5
- import type { HarvestReport, MemoryAnnouncement, MemoryBackend, MemorySessionHandle, ScanFinding } from "./types.js";
7
+ import type { HarvestReport, MemoryAnnouncement, MemoryBackend, MemoryEntryOrigin, MemorySessionHandle, ScanFinding } from "./types.js";
6
8
  /**
7
9
  * The CC `# Memory` instruction section — VERBATIM from the live capture
8
10
  * (bench/cc-parity-toolsuite/reminders/live-capture-main-session-2026-07-08.md §12), with the
@@ -34,6 +36,34 @@ export declare function buildMemoryInstruction(memoryDir: string, instructionFil
34
36
  * dual-root instruction merge ("the write plane's instruction wins") never sees a second candidate.
35
37
  */
36
38
  export declare const MEMORY_RECALL_DISCIPLINE = "Before answering questions about earlier work, decisions, dates, people, or the user's preferences, look them up: `memory_search` finds entries by keyword and `memory_get` reads a full entry \u2014 the injected memory index only lists what exists. When a lookup comes up empty, say that you checked memory and found nothing instead of guessing.";
39
+ /**
40
+ * design/336 §5.4 — the recall-discipline SEGMENT as the runner composes (and, on a retracted tool
41
+ * pair, strips) it: the base paragraph, plus — under `provenance: "carry"` only — the
42
+ * label-semantics sentence ({@link MEMORY_PROVENANCE_RECALL_SENTENCE}: what a `⚠ext` handle row /
43
+ * external-origin note means, "stays usable, verify before acting"). ONE function on purpose:
44
+ * prepare-memory appends this exact string and prepare-task's pair-retraction removes this exact
45
+ * string — two compositions would drift the moment either mode's wording moved. Under "off" this
46
+ * is byte-identical to {@link MEMORY_RECALL_DISCIPLINE} (the pre-336 segment).
47
+ */
48
+ export declare function memoryRecallDisciplineSegment(provenance: "off" | "carry"): string;
49
+ /**
50
+ * design/336 §5.5 (file-face half) — does the entry file at `absPath` carry a committed
51
+ * external-origin marker? A BOUNDED head read (default 64 KiB — an engine-projected frontmatter
52
+ * block sits at the head and is orders of magnitude smaller; the per-file store cap is 100 KB) +
53
+ * the one marker normalization ({@link committedOriginOf}: typed field or extra-form carrier).
54
+ * Consumed by the runner's Read-tool recall-taint judgment: a model that bypasses `memory_get` and
55
+ * Reads a marked entry file straight off a zero-copy plane takes up the same content, so the same
56
+ * derived mark must follow the delivery.
57
+ *
58
+ * FAIL-OPEN by design (`false` on any read/parse failure): this is a taint-propagation widening
59
+ * over a disclosure the file bytes already make themselves (the origin block is IN the file the
60
+ * model just read), not a gate — a refusal here would break ordinary reads on I/O hiccups. Named
61
+ * residuals (§5.5's standing bypass-channel class, disclosed): a frontmatter block larger than the
62
+ * bound reads as unmarked, and a file swapped between the tool's read and this one is judged on
63
+ * the swapped bytes (either direction; a spurious derived mark is the safe side — marks are
64
+ * over-approximations by law, and a missed one is exactly the residual Bash reads already carry).
65
+ */
66
+ export declare function entryFileHeadCarriesOrigin(absPath: string, maxBytes?: number): boolean;
37
67
  /**
38
68
  * design/180 B-3 — the preference-header discipline paragraph. Same carriage as
39
69
  * {@link MEMORY_RECALL_DISCIPLINE}: a runner-appended segment OUTSIDE `inject()`, so the
@@ -89,6 +119,12 @@ export declare const DEFAULT_HARVEST_DEADLINE_MS = 5000;
89
119
  /** M7 — default per-harvest processed-file budget (deliberately above the file-count cap, so it is
90
120
  * inert unless configured tighter). */
91
121
  export declare const DEFAULT_HARVEST_FILE_BUDGET = 2000;
122
+ /** design/336 §4.2 — the default settlement window: how long a delegation may stay `pending`
123
+ * before reconciliation judges it `expired` (holds disposed as unproven — LOUDLY, never silently
124
+ * dropped — and the session's unprovable window closes exposed). 72h = a comfortable upper bound
125
+ * on background-child lifetimes; the cost of the window is that a held instruction entry is
126
+ * delayed at most this long, never lost. */
127
+ export declare const DEFAULT_HOLD_SETTLE_TIMEOUT_MS: number;
92
128
  /** design/138 §2.4 删除防线 — the mass-deletion fuse threshold (fraction of materialized writable
93
129
  * entries missing at harvest above which the whole harvest is judged an incident and refused). The
94
130
  * fuse guards the BACKEND from having a wipe written back; renames (same id re-appearing elsewhere)
@@ -114,6 +150,39 @@ export interface MemoryEngineOptions {
114
150
  maxFiles?: number;
115
151
  /** Max nesting depth under the writable root (default {@link DEFAULT_MAX_ENTRY_DEPTH}). */
116
152
  maxDepth?: number;
153
+ /**
154
+ * design/336 §13-3 — the memory-provenance master switch (the deployment threads
155
+ * {@link import("../types.js").RunnerDeps.memoryProvenance} here; engine-direct hosts set it
156
+ * directly). Two exact spellings:
157
+ * - `"carry"` (absent ≡ this; the default) — the 336 posture: an externally-exposed session's
158
+ * ORDINARY memory writes commit WITH an engine-minted `origin` marker (tag-admit; the content
159
+ * scan gates still run in full — a marker is not an exemption), instruction-form files
160
+ * (type: feedback / v2 injection hints) are withheld and quarantined (the narrow `polluted`
161
+ * rejection), the derived index's session prose still rolls back to its materialize-time
162
+ * baseline, and exposure carries the SAME file-count cap and harvest budget as a clean
163
+ * session;
164
+ * - `"off"` — the pre-336 behavior: an exposed session's harvest admits nothing (every changed/
165
+ * new file quarantines, host-auditable), no origin marker is ever MINTED, and the read side
166
+ * mounts no origin decorations. One stated deviation from the byte level: origin-form
167
+ * frontmatter written by the model is STILL stripped-with-warning from what commits (the
168
+ * origin seat is engine-authored in both modes — preserving model-authored marker bytes under
169
+ * "off" would hand a forgeable typed field to the next "carry" period), and an EXISTING
170
+ * committed origin still carries forward on edits (the backend's immutability law is
171
+ * structural and mode-independent — "off" stops minting, it never strips standing facts).
172
+ * Any other value refuses loudly at construction (`config.memory_provenance`, #123 — exact
173
+ * spellings, never truthiness).
174
+ */
175
+ provenance?: "off" | "carry";
176
+ /**
177
+ * design/336 §4.2 — the delegation settlement window in ms (default
178
+ * {@link DEFAULT_HOLD_SETTLE_TIMEOUT_MS} = 72h): a `pending` settlement row older than this is
179
+ * judged `expired` at the next harvest reconciliation — the session's unprovable window closes
180
+ * exposed, and its instruction holds dispose (announced explicitly as a TIMEOUT, never a
181
+ * conviction; the `resolveHold` valve can still release them with a `"static"`-cause marker).
182
+ * A bad value (non-finite, zero, negative, non-number) refuses loudly at construction
183
+ * (`config.memory_hold_timeout`, #123 — never folded to the default).
184
+ */
185
+ holdSettleTimeoutMs?: number;
117
186
  /** M7 — harvest deadline in ms (default {@link DEFAULT_HARVEST_DEADLINE_MS}); over-deadline files
118
187
  * are deferred to the next harvest (report.degraded), never dropped. */
119
188
  harvestDeadlineMs?: number;
@@ -264,8 +333,13 @@ export interface EntryProvenanceAccount {
264
333
  * writing memory files, the harvest quarantined every one of them, and nothing said so while a host
265
334
  * could still act on it.
266
335
  *
336
+ * MODE-AWARE MESSAGE (design/336): the wording follows the engine's provenance mode — under
337
+ * `"carry"` (default) it states the tag-admit semantics (ordinary writes commit with an origin
338
+ * marker; instruction-form files are withheld); the `"off"`/absent spelling keeps the pre-336 text
339
+ * byte-identical. The caller passes the mode it constructed the engine with.
340
+ *
267
341
  * SCOPE OF THE CLAIM (adversarial-review round 1, P1 — the first cut PROMISED quarantine on every mark).
268
- * This notice states the VERDICT, not the mechanism's outcome: "no longer eligible", plus what a harvest
342
+ * This notice states the VERDICT, not the mechanism's outcome: "no longer eligible" (its "off" form), plus what a harvest
269
343
  * does WHEN IT COLLECTS. That distinction is load-bearing, because several real paths reach a polluted
270
344
  * harvest that quarantines nothing — a `writeScope`-null layering and a declared-unavailable session
271
345
  * both take `harvestCore`'s zero-admission return (nothing is collected, so nothing is captured), and a
@@ -290,6 +364,7 @@ export interface EntryProvenanceAccount {
290
364
  export declare function memorySessionPollutedNotice(input: {
291
365
  reason: string;
292
366
  sessionId?: string;
367
+ provenance?: "off" | "carry";
293
368
  }): EngineNotice;
294
369
  /**
295
370
  * The polluted harvest's loud half ({@link EngineNotice}): what the containment actually did, minted
@@ -340,7 +415,17 @@ export declare function memoryHarvestQuarantinedNotice(input: {
340
415
  escalated: number;
341
416
  reason?: string;
342
417
  sessionId?: string;
418
+ provenance?: "off" | "carry";
419
+ indexRolledBack?: boolean;
343
420
  }): EngineNotice;
421
+ /**
422
+ * design/336 §6.3 — the hold family's operator notices, derived from ONE harvest report's
423
+ * structured containment signal (`report.containment`), the same runner-minted posture as
424
+ * `memory.session_polluted`. Factual wording only (§13-2 model-psyche guardrail: no threat
425
+ * vocabulary — a hold is a sequencing fact, not an accusation); paths are model-controlled
426
+ * identifiers, neutralized and length-capped before they ride the message or the detail.
427
+ */
428
+ export declare function memoryHoldNotices(report: HarvestReport, sessionId?: string): EngineNotice[];
344
429
  export declare class MemoryEngine {
345
430
  private readonly backend;
346
431
  private readonly memoryDir;
@@ -352,6 +437,10 @@ export declare class MemoryEngine {
352
437
  private readonly maxDepth;
353
438
  private readonly harvestDeadlineMs;
354
439
  private readonly harvestFileBudget;
440
+ /** {@link MemoryEngineOptions.holdSettleTimeoutMs} (screened at construction, #123). */
441
+ private readonly holdSettleTimeoutMs;
442
+ /** {@link MemoryEngineOptions.provenance} — the design/336 master switch (screened at construction). */
443
+ private readonly provenance;
355
444
  /** {@link MemoryEngineOptions.onIncident} — the advisory disclosure seat (partition + announce codes). */
356
445
  private readonly onIncident;
357
446
  /** A backend-pinned directory (FileBackend zero-copy detection). */
@@ -368,6 +457,10 @@ export declare class MemoryEngine {
368
457
  * failure produces no second-order disclosure — the alternative (announcing the announce failure)
369
458
  * would recurse through the very lane that just failed.
370
459
  */
460
+ /** design/336 §3.6 (slice 2) — the session-account incident channel (`memory.session_account_failed`):
461
+ * a degraded residue classification is DISCLOSED, never quiet (the behavioral fail-closed half —
462
+ * harvest refusing on `handle.sessionAccountFailed` — is enforced at the write boundary). */
463
+ private discloseSessionAccountIncident;
371
464
  private discloseAnnounceFailure;
372
465
  /**
373
466
  * Record retrieval hits (entries a memory tool actually RETURNED to the model) into this engine's
@@ -394,7 +487,7 @@ export declare class MemoryEngine {
394
487
  * markers of one session would both read clean and both announce). Callers that do not disclose
395
488
  * ignore it exactly as before.
396
489
  */
397
- markSessionPolluted(sessionId: string, reason: string): SessionPollutionMarkOutcome;
490
+ markSessionPolluted(sessionId: string, reason: string, cause?: import("./types.js").MemoryOriginCause): SessionPollutionMarkOutcome;
398
491
  /** The session's pollution record (in-process mark first, then the durable marker) — undefined =
399
492
  * clean. Reads are side-effect-free. */
400
493
  sessionPollution(sessionId: string): SessionPollutionRecord | undefined;
@@ -584,9 +677,11 @@ export declare class MemoryEngine {
584
677
  private settlePromotions;
585
678
  materialize(scopes: readonly string[], writeScope: string | null, opts?: {
586
679
  adoptionRestricted?: boolean;
680
+ sessionId?: string;
587
681
  }): Promise<MemorySessionHandle>;
588
682
  inject(handle: MemorySessionHandle, opts?: {
589
683
  writeToolMounted?: boolean;
684
+ reminderMark?: string;
590
685
  }): MemoryInjection;
591
686
  /**
592
687
  * design/138 S2-C — gate ONE tool write (Write/Edit/NotebookEdit) against the memory domain.
@@ -617,6 +712,7 @@ export declare class MemoryEngine {
617
712
  harvest(handle: MemorySessionHandle, opts?: {
618
713
  polluted?: {
619
714
  reason: string;
715
+ cause?: import("./types.js").MemoryOriginCause;
620
716
  };
621
717
  sessionId?: string;
622
718
  admitNothing?: {
@@ -624,6 +720,102 @@ export declare class MemoryEngine {
624
720
  };
625
721
  }): Promise<HarvestReport>;
626
722
  private harvestCore;
723
+ /**
724
+ * Settle every DUE hold at harvest opening (the reconciliation leg): a hold whose session's
725
+ * account is all-clean releases (the captured bytes re-walk the FULL gate set — content scan,
726
+ * size cap, origin strip — and commit under the ORIGINAL session's lineage: the true writer is
727
+ * who the retroaction machinery must find); a dirty/unprovable account disposes to quarantine
728
+ * (host-auditable, LOUD — a timeout is announced as a timeout, never as a conviction); the host
729
+ * valve's standing verdicts execute here. A hold whose settlements are still pending stays held.
730
+ * Throws only on a corrupt hold/settlement ledger — the caller's fail-closed reconciliation arm
731
+ * refuses the harvest (integrity unknown must not read as "no holds").
732
+ */
733
+ private settleDueHolds;
734
+ /**
735
+ * The release leg: re-walk the captured bytes through the FULL gate set and commit them under
736
+ * the ORIGINAL writer session's lineage. Returns the released relPath, or undefined when the
737
+ * hold did not release (disposed on a gate refusal / CAS conflict / lost capture, or kept held
738
+ * on a transient backend refusal — retried next harvest, never silently dropped).
739
+ */
740
+ private releaseHold;
741
+ /** §3.3 — the settlement valve: an audited host ruling over one delegation's outcome. `"clean"`
742
+ * releases the post-expiry gates (effective only — the history bit never flips, and a LATER
743
+ * observed `external` overrides the ruling); `"external"` convicts. Advisory trust plane. */
744
+ resolveSettlement(settleId: string, to: "clean" | "external", requestId: string): void;
745
+ /** §4.2③ — the hold valve: `"release"` commits the held entry at the next harvest WITH a
746
+ * `"static"`-cause marker (a valve release is not a cleanliness proof); `"discard"` disposes it
747
+ * to quarantine. Audited (requestId required). */
748
+ resolveHold(holdId: string, action: "release" | "discard", requestId: string): void;
749
+ /** §3.6 — the session-account valve: close a dangling foreign row WITHOUT adjudication (the
750
+ * residue arm keeps firing until the next full-domain harvest closes normally — a valve close
751
+ * must not launder the window it covers). Audited (requestId required). */
752
+ resolveSessionAccount(sessionId: string, requestId: string): void;
753
+ /** The engine's control-plane directory (the sidecar home: pollution markers, lineage/challenge
754
+ * ledgers, and the design/336 settlement/hold/session accounts). Exposed so a host (and the
755
+ * runner's settlement handle) can address the SAME plane the engine writes — a second derivation
756
+ * would be a drift seam. */
757
+ get controlPlaneDir(): string;
758
+ /** Read face: every delegation settlement row with its folded effective status (host audit). */
759
+ readDelegationSettlements(): EffectiveSettlement[];
760
+ /** Read face: every instruction-hold row (host audit; custody bytes are addressable through
761
+ * `captureName`/`disposition.quarantineName` under the control plane). */
762
+ readInstructionHolds(): HoldRow[];
763
+ /** Read face: the dangling foreign session-account rows a given session would classify residue
764
+ * against (host audit for the §3.6 valve). */
765
+ readDanglingSessionAccounts(selfSessionId: string): ReturnType<typeof foreignDanglingSessionAccounts>;
766
+ /** The committed, side-effect-free audit read: the adoption-restricted committed view when the
767
+ * backend offers one (zero-copy File — ledger+shadow, no disk adoption), else the non-adopting
768
+ * retrieval view (copy-out File), else the backend itself (Pg/TiDB shapes — naturally committed
769
+ * and side-effect-free per the getByIds contract clause). */
770
+ private committedAuditFace;
771
+ private static originClearRefusal;
772
+ /**
773
+ * §13-4① — the VIEW face: every marked entry in the given scopes, each with its marker (what /
774
+ * cause / when) and its assembled provenance account (来源委派: the lineage contributors joined
775
+ * with their sessions' pollution records — `provenanceOf`'s answer, one authority, never a
776
+ * second store). Committed state only; a marked entry that is also challenged still lists here
777
+ * (the exclusion rides inside the provenance account) — the host must SEE it to adjudicate it.
778
+ *
779
+ * Enumeration trusts the backend's `MemoryEntryHeader.exposure` clause (§6.2): a third-party
780
+ * backend that violates it UNDER-REPORTS here — the conformance suite is the acceptance
781
+ * contract (its exposure-carriage case reds on exactly that backend), and the B3 upgrade-order
782
+ * duty covers mixed fleets; the engine deliberately does not re-fetch whole scopes to
783
+ * second-guess a header face it published a contract for.
784
+ */
785
+ listExternalOriginEntries(scopes: readonly string[]): Promise<Array<{
786
+ id: string;
787
+ slug: string;
788
+ scope: string;
789
+ origin: MemoryEntryOrigin;
790
+ provenance: EntryProvenanceAccount;
791
+ }>>;
792
+ /** §13-4② read half — the clearance audit trail (pending rows are crash-recovery seats: their
793
+ * custody carries the cleared bytes; a later {@link clearEntryOrigin} call resumes them). */
794
+ listOriginClearances(): OriginClearanceRow[];
795
+ /**
796
+ * §13-4② — the audited UN-MARK valve. There is deliberately NO in-place strip spelling anywhere
797
+ * (the backend immutability law stands untouched); the clear rides the law's own single legal
798
+ * exit (§2.3-2): write-ahead clearance row (custody = the full cleared-entry text) → COMMITTED
799
+ * tombstone (CAS on the judged rev) → later-batch re-record of the SAME id with the marker
800
+ * stripped (the host's explicit vouching starts the entry's unmarked life; same id on purpose —
801
+ * links, usage accounts and the clearance join keep their key). Terminals are appended events
802
+ * (who/when/why stay queryable beside the entry); every failure leaves the custody row standing
803
+ * and a re-call RESUMES it idempotently. Refusals (#123 coded, caller-shape):
804
+ * unattributed/invalid input, unknown/unmarked entry, and a CHALLENGED entry — the clear valve
805
+ * is not a challenge exit (adjudicate the challenge first; clearing a challenged entry would
806
+ * launder the exclusion through the weaker credential).
807
+ */
808
+ clearEntryOrigin(entryId: string, input: {
809
+ requestId: string;
810
+ reason: string;
811
+ }): Promise<{
812
+ entryId: string;
813
+ clearanceId: string;
814
+ origin: MemoryEntryOrigin;
815
+ landedSlug: string;
816
+ }>;
817
+ /** The clear's effect half — replayable from the row alone (the resume arm re-enters here). */
818
+ private completeOriginClearance;
627
819
  /**
628
820
  * @param keepBaseline RB-440 (2026-07-31, hardening probe P3) — relative paths whose baseline must NOT
629
821
  * advance: the files a DEGRADED harvest deferred (`report.degraded.pending`).
@@ -652,6 +844,19 @@ export declare class MemoryEngine {
652
844
  * the deleted disk file WAS the backend's storage). Zero-copy skips getByIds: its read-side scan
653
845
  * cannot see a deleted file, and calling it mid-harvest would sync-adopt in-session edits. */
654
846
  private committedContentFor;
847
+ /**
848
+ * design/336 §2.2 (r4-9) — the COMMITTED frontmatter an origin carry-forward is computed against.
849
+ * Deliberately NOT {@link committedContentFor}'s non-zero-copy leg: that one calls the backend's
850
+ * plain `getByIds`, and the File backend's plain read path ADOPTS out-of-band disk changes (a
851
+ * read-side sync that advances revs and books retrievals) — a carry-forward read must be
852
+ * side-effect-free, or assembling one harvest mutates the store it is reading. Reading order:
853
+ * - zero-copy File: the control-plane shadow IS the committed state (the disk file is the
854
+ * session's own working copy — exactly what must NOT serve as the committed baseline);
855
+ * - copy-out with a `retrievalView` face (File): the lock-free non-adopting view;
856
+ * - twins (Pg/TiDB shapes): plain `getByIds` — naturally committed-state and side-effect-free
857
+ * (the contract clause on {@link MemoryBackend.getByIds}).
858
+ */
859
+ private committedFrontmatterFor;
655
860
  /** L4/C-F9 (S2-0) — capture a gate-rejected file into control-plane quarantine FROM THE SCANNED
656
861
  * CONTENT (never re-reading the path: the disk bytes may have been swapped since the scan —
657
862
  * TOCTOU), then remove the suspect from the model-visible plane (delete, falling back to clearing
@@ -712,6 +917,6 @@ export declare class MemoryEngine {
712
917
  }
713
918
  /** Render drained announcements as ONE engine-owned system-reminder block (the lead/frame is
714
919
  * trusted; item identifiers were neutralized at enqueue — see {@link MemoryAnnouncement.items}). */
715
- export declare function renderAnnouncements(queue: readonly MemoryAnnouncement[], folded: number): string;
920
+ export declare function renderAnnouncements(queue: readonly MemoryAnnouncement[], folded: number, reminderMark?: string): string;
716
921
  /** Truncate the derived index to the CC injection parameters (200 lines / 25KB). */
717
922
  export declare function truncateIndex(text: string): string;