@sema-agent/core 5.35.0 → 5.37.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.
- package/CHANGELOG.md +115 -0
- package/dist/agents/subagent.d.ts +10 -0
- package/dist/agents/subagent.js +29 -2
- package/dist/core/auto-compaction.d.ts +23 -0
- package/dist/core/auto-compaction.js +8 -0
- package/dist/core/checkpoint-store.d.ts +16 -0
- package/dist/core/context-guard.d.ts +41 -0
- package/dist/core/context-guard.js +76 -0
- package/dist/core/governance-codes.js +4 -0
- package/dist/core/memory-engine/engine.d.ts +142 -0
- package/dist/core/memory-engine/engine.js +265 -3
- package/dist/core/memory-engine/file-backend.d.ts +490 -16
- package/dist/core/memory-engine/file-backend.js +1099 -36
- package/dist/core/memory-engine/index.d.ts +2 -2
- package/dist/core/memory-engine/index.js +1 -1
- package/dist/core/memory-engine/layout.d.ts +42 -2
- package/dist/core/memory-engine/layout.js +76 -12
- package/dist/core/memory-engine/memory-backend-contract.d.ts +13 -0
- package/dist/core/memory-engine/memory-backend-contract.js +89 -0
- package/dist/core/park-selfcheck.d.ts +5 -0
- package/dist/core/protocol-table.d.ts +4 -4
- package/dist/core/runner/assemble-result.d.ts +8 -0
- package/dist/core/runner/assemble-result.js +4 -1
- package/dist/core/runner/git-status-frame.d.ts +219 -0
- package/dist/core/runner/git-status-frame.js +212 -0
- package/dist/core/runner/prepare-memory.d.ts +11 -1
- package/dist/core/runner/prepare-memory.js +48 -2
- package/dist/core/runner/prepare-task.d.ts +21 -0
- package/dist/core/runner/prepare-task.js +28 -35
- package/dist/core/runner/runtask.js +270 -5
- package/dist/core/task-registry-agent.d.ts +15 -0
- package/dist/core/task-registry-agent.js +9 -0
- package/dist/core/task-registry.d.ts +3 -0
- package/dist/core/task-registry.js +4 -1
- package/dist/core/types.d.ts +122 -7
- package/dist/engine/harness/types.d.ts +65 -1
- package/dist/engine/harness/types.js +20 -0
- package/dist/engine/session/import-validate.js +10 -1
- package/dist/engine/session/session.d.ts +37 -1
- package/dist/engine/session/session.js +56 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/internal/harness-types.d.ts +1 -0
- package/dist/internal/harness.d.ts +2 -0
- package/dist/internal/harness.js +2 -0
- package/dist/prompt-assembly/epoch.js +1 -1
- package/dist/prompt-assembly/event-registry.js +1 -0
- package/dist/prompts/default.d.ts +20 -7
- package/dist/prompts/default.js +2 -7
- package/package.json +1 -1
- package/test/export-surface.snapshot.json +13 -1
package/dist/core/types.d.ts
CHANGED
|
@@ -2713,6 +2713,79 @@ export interface RemoteEnvFailureNote {
|
|
|
2713
2713
|
message: string;
|
|
2714
2714
|
}
|
|
2715
2715
|
/** Result returned when a task finishes or gets stuck. Designed to be machine-readable for an external AI. */
|
|
2716
|
+
/**
|
|
2717
|
+
* design/178 v2 §2.3 (件①) — the value of {@link TaskResult.effectiveMemoryScopes}: the memory
|
|
2718
|
+
* visibility face a leg ACTUALLY ran under, as a DISCRIMINATED three-state union (deliberately no
|
|
2719
|
+
* `"partial"` state — the engine session is built only after every plane materialized, so a
|
|
2720
|
+
* half-mounted scene is a fail-open `memoryless` with residue, never a served half-face):
|
|
2721
|
+
*
|
|
2722
|
+
* - `"mounted"` — the memory engine session mounted. `scopes` is the EFFECTIVE VISIBILITY set in
|
|
2723
|
+
* the effective serving order, both exactly as the engine mounted them: per plane, the
|
|
2724
|
+
* admission-projected read layering PLUS a distinct write-only scope where one exists (the
|
|
2725
|
+
* engine registers the write scope's dir and its entries ride the injected index — a write-only
|
|
2726
|
+
* scope IS visible; the common writeScope∈scopes form dedups to the plain layering), project
|
|
2727
|
+
* plane first on a dual root. Each row carries its admission ORIGIN (`"deployment"` = the
|
|
2728
|
+
* operator's own declared set; `"request"` = the caller's spec — the two trust planes of the
|
|
2729
|
+
* org admission door). `writeScope` is the effective write face as granted (an org writeScope
|
|
2730
|
+
* not explicitly granted reads `null` here, exactly as it ran). `contract` names the
|
|
2731
|
+
* scope-identity contract in force (`"v2"` typed keys / `"legacy"` opaque strings).
|
|
2732
|
+
* SCOPE OF THE CLAIM (stated precisely): the rows are the MEMORY-ENGINE scope set this leg
|
|
2733
|
+
* mounted — the dirs the engine registered and indexed. They deliberately do NOT cover the
|
|
2734
|
+
* separate memory-adjacent faces (the shared-memory store pair, the project-context memory
|
|
2735
|
+
* layer — each its own surface with its own disclosure), and two REGISTERED engine-plane
|
|
2736
|
+
* channels can carry another scope's bytes without a row here: a root-owning scope's non-empty
|
|
2737
|
+
* on-disk index is served verbatim to a later mount of that root ("live file wins"),
|
|
2738
|
+
* and control-plane announcements carry no producing scope and drain plane-wide. Both are
|
|
2739
|
+
* engine mount semantics under their own tickets, disclosed here so this face is never read as
|
|
2740
|
+
* a complete cross-face visibility proof.
|
|
2741
|
+
* - `"memoryless"` — memory was configured but did not mount. `reason: "mount-failed"` = the
|
|
2742
|
+
* fail-open mount arm caught a fault anywhere in the mount phase (directory resolution through
|
|
2743
|
+
* materialize — named for the whole captured span, not one step); `reason: "no-backend"` = the
|
|
2744
|
+
* spec enables memory but no `RunnerDeps.memoryBackend` is configured. `materializedResidue`
|
|
2745
|
+
* (mount-failed only) lists plane scopes whose PHYSICAL materialize had already completed when
|
|
2746
|
+
* the fault hit — a LOWER bound (a plane that threw mid-materialize is not listed; on-disk
|
|
2747
|
+
* residue is ≥ this list), and explicitly NOT a visibility face: an auditor must never read
|
|
2748
|
+
* residue as mounted scopes, which is why it is a separate seat from the always-empty `scopes`.
|
|
2749
|
+
* - `"none"` — memory was not in play at all: `"no-spec"` = the task carries no usable memory
|
|
2750
|
+
* spec; `"disabled"` = a spec is present with `enabled: false`.
|
|
2751
|
+
*
|
|
2752
|
+
* Deliberate-refusal configurations (`config.memory_*` codes) fail the whole prepare and produce
|
|
2753
|
+
* NO observation — this union never dresses a refusal as a state. Honesty note (design r7): the
|
|
2754
|
+
* `?: never` members forbid non-`undefined` values at the type level; the repo does not compile
|
|
2755
|
+
* with `exactOptionalPropertyTypes`, so explicit-`undefined` presence is a wire-validator concern,
|
|
2756
|
+
* not a type-level one.
|
|
2757
|
+
*/
|
|
2758
|
+
export type EffectiveMemoryScopes = {
|
|
2759
|
+
state: "mounted";
|
|
2760
|
+
reason?: never;
|
|
2761
|
+
contract: "v2" | "legacy";
|
|
2762
|
+
scopes: Array<{
|
|
2763
|
+
scope: string;
|
|
2764
|
+
origin: "deployment" | "request";
|
|
2765
|
+
}>;
|
|
2766
|
+
writeScope: string | null;
|
|
2767
|
+
materializedResidue?: never;
|
|
2768
|
+
} | {
|
|
2769
|
+
state: "memoryless";
|
|
2770
|
+
reason: "mount-failed";
|
|
2771
|
+
contract?: "v2" | "legacy";
|
|
2772
|
+
scopes: [];
|
|
2773
|
+
writeScope: null;
|
|
2774
|
+
materializedResidue?: string[];
|
|
2775
|
+
} | {
|
|
2776
|
+
state: "memoryless";
|
|
2777
|
+
reason: "no-backend";
|
|
2778
|
+
contract?: "v2" | "legacy";
|
|
2779
|
+
scopes: [];
|
|
2780
|
+
writeScope: null;
|
|
2781
|
+
} | {
|
|
2782
|
+
state: "none";
|
|
2783
|
+
reason: "no-spec" | "disabled";
|
|
2784
|
+
contract?: never;
|
|
2785
|
+
scopes: [];
|
|
2786
|
+
writeScope: null;
|
|
2787
|
+
materializedResidue?: never;
|
|
2788
|
+
};
|
|
2716
2789
|
export interface TaskResult {
|
|
2717
2790
|
taskId: string;
|
|
2718
2791
|
/** Use this to continue the same conversation on the next call. */
|
|
@@ -2972,6 +3045,28 @@ export interface TaskResult {
|
|
|
2972
3045
|
* governing the WORK, never the contents of any checkpoint row.
|
|
2973
3046
|
*/
|
|
2974
3047
|
effectiveReadDenyPatterns?: readonly import("../tools/fs/read-deny.js").NormalizedReadDenyEntry[];
|
|
3048
|
+
/**
|
|
3049
|
+
* design/178 v2 §2.3 (件①) — the memory VISIBILITY face this leg actually ran under, as an
|
|
3050
|
+
* engine-filled OBSERVATION (never a knob: writing it on a spec does nothing). This is the
|
|
3051
|
+
* EFFECTIVE face, not the requested one: a refused request never reaches a terminal at all (the
|
|
3052
|
+
* whole prepare fails with its governance code), so what this seat answers is "what was actually
|
|
3053
|
+
* given" — the delta against the request is directly readable (an org writeScope not explicitly
|
|
3054
|
+
* granted collapses to `null` here as it did in the run; a fail-open mount failure reads
|
|
3055
|
+
* `memoryless`, never a dressed-up mount).
|
|
3056
|
+
*
|
|
3057
|
+
* **In-presence condition** (same law as {@link effectiveReadFace}): present on every terminal of
|
|
3058
|
+
* a leg that COMPLETED prepare — the memory-less states are answered as their own values
|
|
3059
|
+
* (`none` / `memoryless`), so consumers must never read ABSENCE as "no memory"; absence means
|
|
3060
|
+
* only "prepare never completed". Delegated children mint their own on their own legs (their
|
|
3061
|
+
* request plane can only narrow the parent's frozen org verdict); a resume leg's value is the
|
|
3062
|
+
* re-adjudication at resume time (admission runs in every prepare — the current-policy reading,
|
|
3063
|
+
* same axis as the read-face seats).
|
|
3064
|
+
*
|
|
3065
|
+
* Minted AFTER the materialize outcome, not after the admission verdict — the fail-open mount
|
|
3066
|
+
* arm sits between the two, and stamping earlier would report a mount that never happened.
|
|
3067
|
+
* See {@link EffectiveMemoryScopes} for the per-state field law.
|
|
3068
|
+
*/
|
|
3069
|
+
effectiveMemoryScopes?: EffectiveMemoryScopes;
|
|
2975
3070
|
/**
|
|
2976
3071
|
* `turns`/`tokens`/`costMicroUsd` are this task's OWN model usage. `nested` is the summed usage of any
|
|
2977
3072
|
* delegated sub-runs (sub-agents) it spawned — present only when it delegated. The true total
|
|
@@ -3647,9 +3742,15 @@ export type TaskEvent = ({
|
|
|
3647
3742
|
* (one event per attachment; a multi-attachment boundary still coalesces into ONE steer message
|
|
3648
3743
|
* on the model lane). [c209-C]: the listing family's FIRST-FRAME deliveries (initial roster /
|
|
3649
3744
|
* `<skills>` block riding the first user message, not a steer) emit the same echo frames.
|
|
3745
|
+
*
|
|
3746
|
+
* `git_status` (env-tail migration, additive member): the git-status frame — the turn-dynamic
|
|
3747
|
+
* git facts' carrier since they left the system prompt. Emitted at the frame's append RECEIPT
|
|
3748
|
+
* (first-frame / resume-continuation / compaction re-assert deliveries alike). Its `preview`
|
|
3749
|
+
* is a CONSTANT wording on purpose (never frame bytes): branch names and status text are
|
|
3750
|
+
* repo-controlled and must not enter the event telemetry plane through this echo.
|
|
3650
3751
|
*/
|
|
3651
3752
|
type: "steering_injected";
|
|
3652
|
-
source: "limit_approach" | "todo_reminder" | "task_reminder" | "tool_search_usage_reminder" | "changed_files" | "plan_mode" | "date_change" | "instructions_change" | "workflow_size_guideline_change" | "budget_usd" | "background_tasks" | "tools_delta" | "agent_listing" | "skills_listing" | "mcp_instructions" | "mcp_dropped_tools" | "final_verification";
|
|
3753
|
+
source: "limit_approach" | "todo_reminder" | "task_reminder" | "tool_search_usage_reminder" | "changed_files" | "plan_mode" | "date_change" | "instructions_change" | "workflow_size_guideline_change" | "budget_usd" | "background_tasks" | "tools_delta" | "agent_listing" | "skills_listing" | "mcp_instructions" | "mcp_dropped_tools" | "final_verification" | "git_status";
|
|
3653
3754
|
preview: string;
|
|
3654
3755
|
} & TaskEventIdentity) | ({
|
|
3655
3756
|
/**
|
|
@@ -3790,6 +3891,18 @@ export type TaskEvent = ({
|
|
|
3790
3891
|
* read absence as "not an agent".
|
|
3791
3892
|
*/
|
|
3792
3893
|
taskType?: DelegationTaskType;
|
|
3894
|
+
/**
|
|
3895
|
+
* #258 — the registry row's STOP-CYCLE generation this tick reports from (fresh
|
|
3896
|
+
* spawn = 1, every launched revival bumps it), the same counter `TaskNotificationPayload.seq`
|
|
3897
|
+
* and `BackgroundChildEvent.seq` already speak — one axis, not a third spelling. It answers
|
|
3898
|
+
* the one question a fleet consumer cannot otherwise decide when a frame arrives late: "late
|
|
3899
|
+
* first frame of the cycle I know (same value), or a revived run I have not folded yet
|
|
3900
|
+
* (higher value)?" Advisory observation, stamped at spawn/revive from the registry's own
|
|
3901
|
+
* counter; the settle-time ledger stays the authority. ABSENT is a fact, not a gap: a run
|
|
3902
|
+
* with no `a*` registry row (a SYNCHRONOUS delegated child, a workflow `wa*` agent, a
|
|
3903
|
+
* top-level run) has no generation concept, and absence must never be read as "cycle 1".
|
|
3904
|
+
*/
|
|
3905
|
+
seq?: number;
|
|
3793
3906
|
/** [1611] workflow-lane self-identification (server field-proof: the SSE-forwarded tick of a
|
|
3794
3907
|
* WORKFLOW child previously carried a bare uuid with no workflow identity — indistinguishable
|
|
3795
3908
|
* from an unknown nested subagent; the fleet lane had `wa*`+workflowRunId but this lane had
|
|
@@ -4294,12 +4407,14 @@ export interface BackgroundChildEvent {
|
|
|
4294
4407
|
resumable?: boolean;
|
|
4295
4408
|
/** terminal: the settled status. */
|
|
4296
4409
|
status?: "completed" | "killed" | "failed";
|
|
4297
|
-
/** terminal (
|
|
4298
|
-
* task_notification's `TaskNotificationPayload.seq` (same settle, same X3
|
|
4299
|
-
*
|
|
4300
|
-
*
|
|
4301
|
-
*
|
|
4302
|
-
*
|
|
4410
|
+
/** terminal + spawn/tick (#258 widened the carriers): the stop-cycle number — on a TERMINAL frame
|
|
4411
|
+
* a MIRROR of the sibling task_notification's `TaskNotificationPayload.seq` (same settle, same X3
|
|
4412
|
+
* snapshot); on SPAWN and TICK frames the registry row's generation at emit (fresh spawn = 1, a
|
|
4413
|
+
* revived cycle's bumped counter), so a fleet consumer can tell a LATE first frame from a revived
|
|
4414
|
+
* cycle's frame without waiting for the terminal. One axis with `task_progress`'s `seq` — the tick
|
|
4415
|
+
* mirrors the frame's own stamp. Same honest downgrade as ever: present whenever a cycle number is
|
|
4416
|
+
* knowable (the registry handle / retain ledger's `cycleSeq`, the durable row's `seq` on a tier-3
|
|
4417
|
+
* revival / parked resume), absent when no carrier exists (forging a period would lie). */
|
|
4303
4418
|
seq?: number;
|
|
4304
4419
|
/** terminal, P1-3(黑板 [1920]/[1921]/[1924]/[1925]): the cross-channel completion correlation id —
|
|
4305
4420
|
* MIRROR of the sibling task_notification's `TaskNotificationPayload.completionId` (same settle,
|
|
@@ -498,6 +498,53 @@ export interface WorkspaceState {
|
|
|
498
498
|
export interface WorkspaceStateEntry extends SessionTreeEntryBase, WorkspaceState {
|
|
499
499
|
type: "workspace_state";
|
|
500
500
|
}
|
|
501
|
+
/** The closed kind set of a git-status announcement (the availability half of the `(kind, hash)`
|
|
502
|
+
* comparison tuple): `full` = five-segment snapshot frame; `degraded` = branch+dirty two-line frame
|
|
503
|
+
* (the snapshot round-trip failed while the basic probe succeeded); `unavailable` / `non-repo` =
|
|
504
|
+
* tombstone frames announcing that earlier git frames no longer describe the tree. */
|
|
505
|
+
export type GitAnnouncementKind = "full" | "degraded" | "unavailable" | "non-repo";
|
|
506
|
+
/**
|
|
507
|
+
* The git-status frame ANNOUNCED STATE — which rendered git view the model has last been shown on
|
|
508
|
+
* this branch, as a `(kind, hash)` tuple (hash = content hash of the rendered frame body with the
|
|
509
|
+
* frame format version and the canonical repo root bound into the digest domain). Two-phase receipt
|
|
510
|
+
* protocol: `pending: true` = a re-announcement is OWED but its frame append has not produced a
|
|
511
|
+
* receipt (a compaction restates the tuple as pending in the same CAS that lands the summary; the
|
|
512
|
+
* announced form is written only once the frame's own append returned an entry id) — any reader
|
|
513
|
+
* that finds pending nearest MUST conservatively re-announce. `entryId` = the session entry of the
|
|
514
|
+
* message CARRYING the announced frame; an announced state whose entryId is not on the active
|
|
515
|
+
* branch (rewind cut it) is treated as pending by the read walk (branch-authority read ladder).
|
|
516
|
+
*/
|
|
517
|
+
export interface GitAnnouncementState {
|
|
518
|
+
kind: GitAnnouncementKind;
|
|
519
|
+
hash: string;
|
|
520
|
+
/** Session entry id of the message carrying the announced frame (absent on a pending restatement). */
|
|
521
|
+
entryId?: string;
|
|
522
|
+
/** Two-phase receipt: the tuple is owed but its frame append has no receipt yet. */
|
|
523
|
+
pending?: true;
|
|
524
|
+
}
|
|
525
|
+
/**
|
|
526
|
+
* The git-status announced state as a FIRST-CLASS typed entry (same snapshot doctrine as
|
|
527
|
+
* {@link AnnouncedListingEntry}): the nearest carrier on the branch IS the announced state.
|
|
528
|
+
* Written at every frame COMMIT point (first-frame receipt / resume-continuation receipt /
|
|
529
|
+
* compaction re-assertion receipt); a compaction additionally restates the tuple as `pending`
|
|
530
|
+
* inside its own `details.gitAnnouncement` (same-CAS with the new baseline) until the re-asserted
|
|
531
|
+
* frame's append receipt lands. The checkpoint mirror (`CheckpointState.gitAnnouncement`) is the
|
|
532
|
+
* lower seed rung, consulted only when the branch carries no mirror at all.
|
|
533
|
+
*/
|
|
534
|
+
export interface GitAnnouncementEntry extends SessionTreeEntryBase, GitAnnouncementState {
|
|
535
|
+
type: "git_announcement";
|
|
536
|
+
}
|
|
537
|
+
/** Bounded cap for {@link normalizeGitAnnouncement} entry ids (self-generated ids are short; an
|
|
538
|
+
* oversize value is a forgery signal, same posture as the sibling caps). */
|
|
539
|
+
export declare const GIT_ANNOUNCEMENT_MAX_ENTRY_ID_CHARS = 256;
|
|
540
|
+
/**
|
|
541
|
+
* Strict shape gate for the git announced state — the SINGLE normalization the read walk, the
|
|
542
|
+
* public append, and the import-validate door all use (the {@link normalizeAnnouncedListing}
|
|
543
|
+
* posture). Returns a shaped copy carrying ONLY the known keys, or undefined when the value is not
|
|
544
|
+
* structurally valid: closed kind set, full `sha256:<hex64>` hash grammar (a prefix-only check
|
|
545
|
+
* would accept junk), bounded entryId, `pending` only as literal `true`.
|
|
546
|
+
*/
|
|
547
|
+
export declare function normalizeGitAnnouncement(v: unknown): GitAnnouncementState | undefined;
|
|
501
548
|
/** Bounded cap for {@link normalizeWorkspaceState} paths (a sha is capped by its hex shape check). */
|
|
502
549
|
export declare const WORKSPACE_STATE_MAX_PATH_CHARS = 4096;
|
|
503
550
|
/**
|
|
@@ -544,7 +591,7 @@ export declare function normalizeAnnouncedListing(v: unknown): {
|
|
|
544
591
|
models?: string[];
|
|
545
592
|
} | undefined;
|
|
546
593
|
/** All persisted session tree entry variants. */
|
|
547
|
-
export type SessionTreeEntry = MessageEntry | ThinkingLevelChangeEntry | ModelChangeEntry | CompactionEntry | CustomEntry | CustomMessageEntry | LabelEntry | SessionInfoEntry | LeafEntry | PromptEpochEntry | AnnouncedListingEntry | WorkspaceStateEntry;
|
|
594
|
+
export type SessionTreeEntry = MessageEntry | ThinkingLevelChangeEntry | ModelChangeEntry | CompactionEntry | CustomEntry | CustomMessageEntry | LabelEntry | SessionInfoEntry | LeafEntry | PromptEpochEntry | AnnouncedListingEntry | GitAnnouncementEntry | WorkspaceStateEntry;
|
|
548
595
|
export interface SessionContext {
|
|
549
596
|
messages: AgentMessage[];
|
|
550
597
|
thinkingLevel: string;
|
|
@@ -684,6 +731,23 @@ export interface Session<TMetadata extends SessionMetadata = SessionMetadata> {
|
|
|
684
731
|
* epoch restatement) calls it with `?.()` — an implementer without it degrades to the pre-epoch
|
|
685
732
|
* path (no restatement), never a crash. */
|
|
686
733
|
getPromptEpoch?(): Promise<import("../../prompt-assembly/epoch.js").PromptEpochDescriptor | undefined>;
|
|
734
|
+
/** Persist the git-status announced state as a first-class {@link GitAnnouncementEntry}
|
|
735
|
+
* (snapshot semantics; see `Session.appendGitAnnouncement`). OPTIONAL on the interface — same
|
|
736
|
+
* external-implementer posture as `getPromptEpoch`; consumers call it with `?.()` and an
|
|
737
|
+
* implementer without it degrades to conservative re-announcement every leg (duplicate-tolerant
|
|
738
|
+
* by design), never a crash. */
|
|
739
|
+
appendGitAnnouncement?(state: GitAnnouncementState): Promise<string>;
|
|
740
|
+
/** Branch-authority read of the git announced state (see `Session.getGitAnnouncement`): nearest
|
|
741
|
+
* carrier on the active branch, with a pending restatement — or an announced state whose frame
|
|
742
|
+
* entryId is NOT on the active branch — surfaced as `status:"pending"` (the reader must
|
|
743
|
+
* conservatively re-announce). Undefined ⇒ no carrier visible on this branch. OPTIONAL, same
|
|
744
|
+
* posture as `appendGitAnnouncement`. */
|
|
745
|
+
getGitAnnouncement?(): Promise<{
|
|
746
|
+
kind: GitAnnouncementKind;
|
|
747
|
+
hash: string;
|
|
748
|
+
status: "announced" | "pending";
|
|
749
|
+
entryId?: string;
|
|
750
|
+
} | undefined>;
|
|
687
751
|
}
|
|
688
752
|
export interface SessionCreateOptions {
|
|
689
753
|
id?: string;
|
|
@@ -66,6 +66,26 @@ export class AgentHarnessError extends Error {
|
|
|
66
66
|
this.code = code;
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
|
+
export const GIT_ANNOUNCEMENT_MAX_ENTRY_ID_CHARS = 256;
|
|
70
|
+
export function normalizeGitAnnouncement(v) {
|
|
71
|
+
if (typeof v !== "object" || v === null)
|
|
72
|
+
return undefined;
|
|
73
|
+
const src = v;
|
|
74
|
+
if (src.kind !== "full" && src.kind !== "degraded" && src.kind !== "unavailable" && src.kind !== "non-repo")
|
|
75
|
+
return undefined;
|
|
76
|
+
if (typeof src.hash !== "string" || !/^sha256:[0-9a-f]{64}$/.test(src.hash))
|
|
77
|
+
return undefined;
|
|
78
|
+
if (src.entryId !== undefined && (typeof src.entryId !== "string" || src.entryId.length === 0 || src.entryId.length > GIT_ANNOUNCEMENT_MAX_ENTRY_ID_CHARS))
|
|
79
|
+
return undefined;
|
|
80
|
+
if (src.pending !== undefined && src.pending !== true)
|
|
81
|
+
return undefined;
|
|
82
|
+
return {
|
|
83
|
+
kind: src.kind,
|
|
84
|
+
hash: src.hash,
|
|
85
|
+
...(src.entryId !== undefined ? { entryId: src.entryId } : {}),
|
|
86
|
+
...(src.pending === true ? { pending: true } : {}),
|
|
87
|
+
};
|
|
88
|
+
}
|
|
69
89
|
export const WORKSPACE_STATE_MAX_PATH_CHARS = 4096;
|
|
70
90
|
export function normalizeWorkspaceState(value) {
|
|
71
91
|
if (value === null || typeof value !== "object")
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SessionError, normalizeAnnouncedListing, normalizeWorkspaceState, normalizeCompactionStateCarrier, isValidThinkingLevelChange, isValidModelChange, isOptionalDisplayString, } from "../harness/types.js";
|
|
1
|
+
import { SessionError, normalizeAnnouncedListing, normalizeGitAnnouncement, normalizeWorkspaceState, normalizeCompactionStateCarrier, isValidThinkingLevelChange, isValidModelChange, isOptionalDisplayString, } from "../harness/types.js";
|
|
2
2
|
import { leafIdAfterEntry } from "./storage-base.js";
|
|
3
3
|
import { parseSessionTimestampMs } from "./timestamps.js";
|
|
4
4
|
import { flattenableUserText, normalizeEngineSegments } from "../../core/untrusted-text.js";
|
|
@@ -87,6 +87,11 @@ export class StreamingImportValidator {
|
|
|
87
87
|
throw new SessionError("invalid_session", `workspace_state entry "${e.id}" is structurally invalid`);
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
|
+
else if (e.type === "git_announcement") {
|
|
91
|
+
if (!normalizeGitAnnouncement(e)) {
|
|
92
|
+
throw new SessionError("invalid_session", `git_announcement entry "${e.id}" is structurally invalid`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
90
95
|
if (e.type === "thinking_level_change" && !isValidThinkingLevelChange(e)) {
|
|
91
96
|
throw new SessionError("invalid_session", `thinking_level_change entry "${e.id}" carries an invalid thinkingLevel`);
|
|
92
97
|
}
|
|
@@ -119,6 +124,10 @@ export class StreamingImportValidator {
|
|
|
119
124
|
if (restatedListings !== undefined && !normalizeAnnouncedListing(restatedListings)) {
|
|
120
125
|
throw new SessionError("invalid_session", `compaction "${e.id}" carries a structurally invalid announcedListings restatement`);
|
|
121
126
|
}
|
|
127
|
+
const restatedGit = e.details?.gitAnnouncement;
|
|
128
|
+
if (restatedGit !== undefined && !normalizeGitAnnouncement(restatedGit)) {
|
|
129
|
+
throw new SessionError("invalid_session", `compaction "${e.id}" carries a structurally invalid gitAnnouncement restatement`);
|
|
130
|
+
}
|
|
122
131
|
const carrier = e.details;
|
|
123
132
|
const shaped = normalizeCompactionStateCarrier(e.details);
|
|
124
133
|
if (carrier?.thinkingLevel !== undefined && shaped.thinkingLevel === undefined) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ImageContent, TextContent } from "../llm/index.js";
|
|
2
2
|
import type { AgentMessage } from "../loop/types.js";
|
|
3
|
-
import type { Session, SessionContext, SessionMetadata, SessionStorage, SessionTreeEntry, WorkspaceState } from "../harness/types.js";
|
|
3
|
+
import type { GitAnnouncementState, Session, SessionContext, SessionMetadata, SessionStorage, SessionTreeEntry, WorkspaceState } from "../harness/types.js";
|
|
4
4
|
import type { BuildContextOptions } from "../harness/types.js";
|
|
5
5
|
import type { PromptEpochDescriptor } from "../../prompt-assembly/epoch.js";
|
|
6
6
|
/** Build model context from the active session branch and its latest state markers.
|
|
@@ -45,6 +45,31 @@ export declare class StoredSession<TMetadata extends SessionMetadata = SessionMe
|
|
|
45
45
|
skills?: readonly string[];
|
|
46
46
|
models?: readonly string[];
|
|
47
47
|
}): Promise<string>;
|
|
48
|
+
/**
|
|
49
|
+
* Git-status frame announced state (branch-authority mirror): persist the `(kind, hash)` tuple —
|
|
50
|
+
* announced form carries the frame's own entry id; a compaction restates the tuple as `pending`
|
|
51
|
+
* inside its `details.gitAnnouncement` instead (same-CAS with the new baseline). Called
|
|
52
|
+
* best-effort at every frame COMMIT point (append receipt in hand) — an append failure degrades
|
|
53
|
+
* to a conservative re-announcement on the next leg (duplicate-tolerant), never fails the run.
|
|
54
|
+
*/
|
|
55
|
+
appendGitAnnouncement(state: GitAnnouncementState): Promise<string>;
|
|
56
|
+
/**
|
|
57
|
+
* Branch-authority read of the git announced state: the nearest carrier walking back from the
|
|
58
|
+
* leaf (a `git_announcement` entry or a compaction's `details.gitAnnouncement` restatement;
|
|
59
|
+
* SNAPSHOT semantics — first hit wins). The pending gate is a MANDATORY one: a nearest carrier
|
|
60
|
+
* that is pending, or an announced carrier whose frame entryId is NOT on the active branch (a
|
|
61
|
+
* rewind cut the frame while a descendant mirror survived), reads as `status:"pending"` — the
|
|
62
|
+
* caller must conservatively re-announce rather than trust a mirror whose frame the model cannot
|
|
63
|
+
* see. Malformed carriers are skipped (defense in depth behind the import door). Undefined ⇒ no
|
|
64
|
+
* carrier visible on this branch (pre-migration session / bounded-tail floor cut every carrier) —
|
|
65
|
+
* callers fall back to the checkpoint mirror rung, then to conservative re-announcement.
|
|
66
|
+
*/
|
|
67
|
+
getGitAnnouncement(): Promise<{
|
|
68
|
+
kind: GitAnnouncementState["kind"];
|
|
69
|
+
hash: string;
|
|
70
|
+
status: "announced" | "pending";
|
|
71
|
+
entryId?: string;
|
|
72
|
+
} | undefined>;
|
|
48
73
|
/**
|
|
49
74
|
* design/155 (cli [1580]): persist the settle-time workspace state (tracked cwd + active
|
|
50
75
|
* EnterWorktree session) as a first-class typed entry. Called best-effort at task settle when the
|
|
@@ -115,3 +140,14 @@ export declare class StoredSession<TMetadata extends SessionMetadata = SessionMe
|
|
|
115
140
|
appendLabel(targetId: string, label: string | undefined): Promise<string>;
|
|
116
141
|
appendSessionName(name: string): Promise<string>;
|
|
117
142
|
}
|
|
143
|
+
/**
|
|
144
|
+
* Falsification round 1 (F3) — is `entryId` not merely ON the active branch but inside the region
|
|
145
|
+
* a context rebuild can actually contain? A branch walk sees the whole tree; `buildSessionContext`
|
|
146
|
+
* replays only [latest compaction's firstKeptEntryId .. leaf] (plus the summary). A git frame that
|
|
147
|
+
* sits BEFORE the latest compaction's kept tail is therefore gone from every future request even
|
|
148
|
+
* though its id is a legitimate branch member — an announced mirror pointing at it must read as
|
|
149
|
+
* PENDING (re-announce), or the announced hash would suppress re-sends of bytes the model can no
|
|
150
|
+
* longer see. Shared by the session mirror walk and the run loop's checkpoint seeding rung (one
|
|
151
|
+
* rule, both readers). Conservative on damage: an unresolvable firstKeptEntryId reads as invisible.
|
|
152
|
+
*/
|
|
153
|
+
export declare function gitFrameContextVisible(branch: SessionTreeEntry[], entryId: string): boolean;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { asAgentMessage, createCompactionSummaryMessage, createCustomMessage, } from "../harness/messages.js";
|
|
2
|
-
import { SessionError, isValidModelChange, normalizeAnnouncedListing, normalizeCompactionStateCarrier, normalizeWorkspaceState } from "../harness/types.js";
|
|
2
|
+
import { SessionError, isValidModelChange, normalizeAnnouncedListing, normalizeCompactionStateCarrier, normalizeGitAnnouncement, normalizeWorkspaceState } from "../harness/types.js";
|
|
3
3
|
import { normalizePromptEpoch } from "../../prompt-assembly/epoch.js";
|
|
4
4
|
import { budgetInvokedSkillsRetention, readElidedMessages, readRetainedInvokedSkills, renderInvokedSkillsRetention, } from "../compaction/utils.js";
|
|
5
5
|
const RETENTION_CLAMP_DEFAULT_CHARS_PER_TOKEN = 4;
|
|
@@ -181,6 +181,39 @@ export class StoredSession {
|
|
|
181
181
|
...shaped,
|
|
182
182
|
});
|
|
183
183
|
}
|
|
184
|
+
async appendGitAnnouncement(state) {
|
|
185
|
+
const shaped = normalizeGitAnnouncement(state);
|
|
186
|
+
if (!shaped) {
|
|
187
|
+
throw new SessionError("invalid_entry", "appendGitAnnouncement: state is not a structurally valid git announcement (closed kind, sha256 hash, bounded entryId)");
|
|
188
|
+
}
|
|
189
|
+
return this.appendTypedEntry({
|
|
190
|
+
type: "git_announcement",
|
|
191
|
+
id: await this.storage.createEntryId(),
|
|
192
|
+
parentId: await this.storage.getLeafId(),
|
|
193
|
+
timestamp: new Date().toISOString(),
|
|
194
|
+
...shaped,
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
async getGitAnnouncement() {
|
|
198
|
+
const branch = await this.getBranch();
|
|
199
|
+
for (let i = branch.length - 1; i >= 0; i--) {
|
|
200
|
+
const entry = branch[i];
|
|
201
|
+
let carried;
|
|
202
|
+
if (entry.type === "git_announcement") {
|
|
203
|
+
carried = normalizeGitAnnouncement(entry);
|
|
204
|
+
}
|
|
205
|
+
else if (entry.type === "compaction") {
|
|
206
|
+
carried = normalizeGitAnnouncement(entry.details?.gitAnnouncement);
|
|
207
|
+
}
|
|
208
|
+
if (carried === undefined)
|
|
209
|
+
continue;
|
|
210
|
+
const announced = carried.pending !== true && carried.entryId !== undefined && gitFrameContextVisible(branch, carried.entryId);
|
|
211
|
+
return announced
|
|
212
|
+
? { kind: carried.kind, hash: carried.hash, status: "announced", entryId: carried.entryId }
|
|
213
|
+
: { kind: carried.kind, hash: carried.hash, status: "pending" };
|
|
214
|
+
}
|
|
215
|
+
return undefined;
|
|
216
|
+
}
|
|
184
217
|
async appendWorkspaceState(state) {
|
|
185
218
|
const shaped = normalizeWorkspaceState(state);
|
|
186
219
|
if (!shaped) {
|
|
@@ -314,3 +347,25 @@ export class StoredSession {
|
|
|
314
347
|
});
|
|
315
348
|
}
|
|
316
349
|
}
|
|
350
|
+
export function gitFrameContextVisible(branch, entryId) {
|
|
351
|
+
let frameIdx = -1;
|
|
352
|
+
let compactionIdx = -1;
|
|
353
|
+
let firstKeptId;
|
|
354
|
+
for (let i = 0; i < branch.length; i++) {
|
|
355
|
+
const e = branch[i];
|
|
356
|
+
if (e.id === entryId)
|
|
357
|
+
frameIdx = i;
|
|
358
|
+
if (e.type === "compaction") {
|
|
359
|
+
compactionIdx = i;
|
|
360
|
+
firstKeptId = e.firstKeptEntryId;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
if (frameIdx === -1)
|
|
364
|
+
return false;
|
|
365
|
+
if (compactionIdx === -1 || frameIdx > compactionIdx)
|
|
366
|
+
return true;
|
|
367
|
+
if (firstKeptId === undefined)
|
|
368
|
+
return false;
|
|
369
|
+
const keptIdx = branch.findIndex((e) => e.id === firstKeptId);
|
|
370
|
+
return keptIdx !== -1 && frameIdx >= keptIdx;
|
|
371
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -164,7 +164,7 @@ export { AdoptionError, assertAdoptionBootGate, readRootAdoptionFile, writeRootA
|
|
|
164
164
|
export { adoptLocalDataRoot, ackAdoptionConfig, witnessAdoptionConfig, listAdoptionQuarantine, readAdoptionStatus, type AdoptionStatus, type AdoptLocalDataRootOptions, type AdoptLocalDataRootResult, type AdoptionCarriageLeg, type AdoptionCarriageLegContext, type AdoptionConfigWitnessReceipt, } from "./stores/file/adoption/adopt.js";
|
|
165
165
|
export { formatHookFeedback, runToolGate, createHookEnvCapabilities, createPreToolUseConstraintPolicy, type PersistedRuleHit, type PersistedRuleUnreadable, type PersistedRuleAnswer, normalizePersistedRuleHit, type Hooks, type HookToolContext, type HookEnvCapabilities, type HookToolOutput, type PreToolUseResult, type PostToolUseResult, type UserPromptSubmitResult, type HookToolFailure, type PostToolUseFailureResult, type PostToolBatchCall, type PostToolBatchResult, type PreCompactContext, type PreCompactResult, type PostCompactContext, type StopFailureContext, type PermissionDeniedPayload, type PermissionDeniedSource, } from "./core/hooks.js";
|
|
166
166
|
export { InMemoryMemoryStore, composeMemoryBlock, composeLayeredMemoryBlock, normalizeMemorySpec, type NormalizedMemorySpec, type MemorySpecInput, supportsConsolidation, supportsPeriodicConsolidation, firstSentence, expandLexicalTerms, lexicalSearchMatch, type Embedder, classifyPromotable, enforcePromotableWriteGate, guardedMemoryStore, MemoryGateError, detectSecret, enforceSecretWriteGate, enforceStructuredNoteSecretGate, type UtilityGate, type MemoryStore, type MemoryVectorMode, type ScoredMemory, type MemoryNoteHeader, type MemoryNoteRecord, type MemoryNoteType, type StructuredNoteInput, } from "./core/memory.js";
|
|
167
|
-
export { MemoryEngine, FileMemoryEngineBackend, memoryBackendContract, assertMemoryBackendSearchEquivalence, type MemoryBackendContractHooks, buildMemoryInstruction, truncateIndex, scanEntryFiles, deriveRepoKey, deriveRepoMemoryDir, deriveControlPlaneDir, deriveRepoControlPlaneDir, resolveMemoryEngineRoot, scopeDirName, ControlPlaneCorruptError, parseEntryFile, serializeEntryFile, computeEntryRev, entryFromFile, MEMORY_INSTRUCTION_TEMPLATE, MEMORY_RECALL_DISCIPLINE, MEMORY_PREFERENCE_DISCIPLINE, MEMORY_READONLY_NOTICE, readV2HeaderHints, type V2HeaderHints, LINEAGE_FILE, CHALLENGES_FILE, CHALLENGED_HISTORY_FILE, CHALLENGE_LEDGER_MAX_EVENTS, rebuildStrictControlPlaneLedger, type ControlPlaneRebuildReceipt, type StrictControlPlaneLedger, type ChallengeAssignment, type ChallengeEvent, type ChallengedHistoryRow, type LineagePendingTxn, type LineagePromotion, MEMORY_INDEX_FILENAME, MEMORY_INDEX_MAX_LINES, MEMORY_INDEX_MAX_BYTES, MEMORY_SEARCH_TOOL_NAME, MEMORY_GET_TOOL_NAME, MEMORY_ENGINE_TOOL_NAMES, type MemorySearchDetails, type MemorySearchHit, type MemoryGetDetails, STUB_ARCHIVED_LINE, DEFAULT_MAX_MEMORY_FILES, DEFAULT_MAX_ENTRY_DEPTH, DEFAULT_HARVEST_DEADLINE_MS, DEFAULT_HARVEST_FILE_BUDGET, MASS_DELETION_FUSE_RATIO, scanMemoryWrite, scanMemoryFileName, scanRemediation, MEMORY_FILENAME_SEGMENT_RE, renderAnnouncements, enqueueMemoryAnnouncement, drainMemoryAnnouncements, peekMemoryAnnouncements, bumpScanFuse, scanFuseCount, clearScanFuse, ANNOUNCEMENTS_FILE, MEMORY_ANNOUNCEMENTS_MAX, SCAN_FUSE_FILE, SCAN_FUSE_THRESHOLD, type MemoryAnnouncement, type ScanFinding, type MemoryEngineOptions, type MemoryInjection, type MemoryBackend, type MemoryEntry, type MemoryEntryFrontmatter, type MemoryEntryHeader, type ScoredMemoryEntry, type NotePatch, type PatchReport, type MaterializedFile, type MemorySessionHandle, type HarvestReport, type HarvestRejection, type HarvestRejectionCode, type ParsedEntryFile, type ScannedEntryFile, SCOPE_SEGMENT_MAX_ENCODED, PROJECT_MARKER_PATH, encodeScopeSegment, decodeScopeSegment, parseScopeKey, formatUserScope, formatOrgScope, formatProjScope, formatUserProjScope, isPersonalScope, assertScopeContractPlacement, formatProjectMarker, parseProjectMarker, resolveProjectId, PROJECT_ID_REGEX, type ParsedScopeKey, migrateScope, type MigrateScopeReport, materializeEntriesToFiles, harvestFilesToPatches, projectionsToWriteBack, screenInboundEntries, REMOTE_HARVEST_PER_FILE_BYTES, REMOTE_MASS_DELETION_FUSE_RATIO, type RemoteMemoryFile, type RemoteMemoryBaseline, type RemoteMaterialization, type RemoteHarvestResult, type InboundEntryFinding, deriveProjectMemoryDir, deriveProjectControlDir, recordProjectIdHint, lookupProjectIdHint, PROJECT_ID_HINTS_FILE, reconcileMemoryEntries, nextSyncBaseline, mergeRecallHits, type MemorySyncCursor, type MemorySyncConflict, type MemorySyncPlan, type RecallSource, syncMemoryScope, type MemorySyncTransport, type MemorySyncRequestBody, type MemorySyncResponseBody, type MemorySyncClientConflict, type SyncMemoryScopeOptions, type MemorySyncClientResult, } from "./core/memory-engine/index.js";
|
|
167
|
+
export { MemoryEngine, FileMemoryEngineBackend, memoryBackendContract, assertMemoryBackendSearchEquivalence, type MemoryBackendContractHooks, buildMemoryInstruction, truncateIndex, scanEntryFiles, deriveRepoKey, deriveRepoMemoryDir, deriveControlPlaneDir, deriveRepoControlPlaneDir, resolveMemoryEngineRoot, scopeDirName, ControlPlaneCorruptError, parseEntryFile, serializeEntryFile, computeEntryRev, entryFromFile, MEMORY_INSTRUCTION_TEMPLATE, MEMORY_RECALL_DISCIPLINE, MEMORY_PREFERENCE_DISCIPLINE, MEMORY_READONLY_NOTICE, readV2HeaderHints, type V2HeaderHints, LINEAGE_FILE, CHALLENGES_FILE, CHALLENGED_HISTORY_FILE, CHALLENGE_LEDGER_MAX_EVENTS, rebuildStrictControlPlaneLedger, type ControlPlaneRebuildReceipt, type StrictControlPlaneLedger, type ChallengeAssignment, type ChallengeEvent, type ChallengedHistoryRow, type LineagePendingTxn, type LineagePromotion, MEMORY_INDEX_FILENAME, MEMORY_INDEX_MAX_LINES, MEMORY_INDEX_MAX_BYTES, MEMORY_SEARCH_TOOL_NAME, MEMORY_GET_TOOL_NAME, MEMORY_ENGINE_TOOL_NAMES, type MemorySearchDetails, type MemorySearchHit, type MemoryGetDetails, STUB_ARCHIVED_LINE, DEFAULT_MAX_MEMORY_FILES, DEFAULT_MAX_ENTRY_DEPTH, DEFAULT_HARVEST_DEADLINE_MS, DEFAULT_HARVEST_FILE_BUDGET, MASS_DELETION_FUSE_RATIO, scanMemoryWrite, scanMemoryFileName, scanRemediation, MEMORY_FILENAME_SEGMENT_RE, renderAnnouncements, enqueueMemoryAnnouncement, drainMemoryAnnouncements, peekMemoryAnnouncements, bumpScanFuse, scanFuseCount, clearScanFuse, ANNOUNCEMENTS_FILE, MEMORY_ANNOUNCEMENTS_MAX, SCAN_FUSE_FILE, SCAN_FUSE_THRESHOLD, type MemoryAnnouncement, type ScanFinding, type MemoryEngineOptions, type MemoryInjection, type EntryProvenanceAccount, type TransferEvidence, type CommittedBinding, type CommittedEntrySnapshot, type CommittedScopeSnapshots, type EntryCustodyReport, erasureSelectHash, type EraseMemoryEntriesInput, type ErasureSelect, type ErasedBinding, type MemoryErasureAttestation, type MemoryBackend, type MemoryEntry, type MemoryEntryFrontmatter, type MemoryEntryHeader, type ScoredMemoryEntry, type NotePatch, type PatchReport, type MaterializedFile, type MemorySessionHandle, type HarvestReport, type HarvestRejection, type HarvestRejectionCode, type ParsedEntryFile, type ScannedEntryFile, SCOPE_SEGMENT_MAX_ENCODED, PROJECT_MARKER_PATH, encodeScopeSegment, decodeScopeSegment, parseScopeKey, formatUserScope, formatOrgScope, formatProjScope, formatUserProjScope, isPersonalScope, assertScopeContractPlacement, formatProjectMarker, parseProjectMarker, resolveProjectId, PROJECT_ID_REGEX, type ParsedScopeKey, migrateScope, type MigrateScopeReport, materializeEntriesToFiles, harvestFilesToPatches, projectionsToWriteBack, screenInboundEntries, REMOTE_HARVEST_PER_FILE_BYTES, REMOTE_MASS_DELETION_FUSE_RATIO, type RemoteMemoryFile, type RemoteMemoryBaseline, type RemoteMaterialization, type RemoteHarvestResult, type InboundEntryFinding, deriveProjectMemoryDir, deriveProjectControlDir, recordProjectIdHint, lookupProjectIdHint, PROJECT_ID_HINTS_FILE, reconcileMemoryEntries, nextSyncBaseline, mergeRecallHits, type MemorySyncCursor, type MemorySyncConflict, type MemorySyncPlan, type RecallSource, syncMemoryScope, type MemorySyncTransport, type MemorySyncRequestBody, type MemorySyncResponseBody, type MemorySyncClientConflict, type SyncMemoryScopeOptions, type MemorySyncClientResult, } from "./core/memory-engine/index.js";
|
|
168
168
|
export { SHARED_MEMORY_READ_CAP_BYTES, SHARED_MEMORY_LIST_PAGE_SIZE, SharedMemoryStoreError, type SharedMemoryStoreProvider, type SharedMemoryStoreReader, type SharedMemoryPagedList, type SharedMemoryStoreInfo, type SharedMemoryDocumentEntry, type SharedMemorySnapshot, type SharedMemoryRequestContext, type MemoryListDetails, type MemoryReadDetails, } from "./core/shared-memory/types.js";
|
|
169
169
|
export { sharedMemoryStoreContract, type SharedMemoryFixture, type SharedMemoryStoreContractHooks, } from "./core/shared-memory/contract.js";
|
|
170
170
|
export { termSet, jaccardDistance, cosineDistance } from "./core/memory-vector.js";
|
|
@@ -254,7 +254,7 @@ export { retryBackoffMs, parseRetryAfter } from "./brain/retry.js";
|
|
|
254
254
|
export { type BrainTimeoutConfig } from "./brain/timeout.js";
|
|
255
255
|
export { createAssistantMessageEventStream } from "./internal/llm.js";
|
|
256
256
|
export type { AssistantMessage, AssistantMessageEvent, CompleteSimpleFn, Context, DocumentContent, ImageContent, Message, StopReason, StreamFn, TextContent, ThinkingContent, ToolCall, ToolResultMessage, Usage, UserMessage, } from "./internal/llm.js";
|
|
257
|
-
export type { AgentDefinition, BeforeWriteHook, BeforeWriteRequest, BeforeWriteResult, HandsBandOptions, Brain, BrainStatus, BrainStatusPhase, BrainRetryErrClass, ImageInput, McpElicitRequest, McpElicitResponse, McpServerSpec, A2aServerSpec, OnElicit, Model, ModelRef, ProjectMemoryLoad, RunnerDeps, EngineNotice, RuntimeCaps, BackgroundChildEvent, SkillManifest, SkillSpec, TaskEvent, TaskEventIdentity, ToolActivity, TaskLimits, StaleToolResultOffloadOptions, TaskResult, RemoteEnvFailureNote, TaskSpec, TaskStatus, TaskStream, CompactOutcome, ThinkingLevel, ToolExecuteContext, ToolReturn, ToolSpec, ReversibilityVerdict, ToolEffect, ToolContentOrigin, WorkflowGovernanceBaseline, DelegationTaskType, } from "./core/types.js";
|
|
257
|
+
export type { AgentDefinition, BeforeWriteHook, BeforeWriteRequest, BeforeWriteResult, HandsBandOptions, Brain, BrainStatus, BrainStatusPhase, BrainRetryErrClass, ImageInput, McpElicitRequest, McpElicitResponse, McpServerSpec, A2aServerSpec, OnElicit, Model, ModelRef, ProjectMemoryLoad, RunnerDeps, EngineNotice, RuntimeCaps, BackgroundChildEvent, SkillManifest, SkillSpec, TaskEvent, TaskEventIdentity, ToolActivity, TaskLimits, StaleToolResultOffloadOptions, TaskResult, EffectiveMemoryScopes, RemoteEnvFailureNote, TaskSpec, TaskStatus, TaskStream, CompactOutcome, ThinkingLevel, ToolExecuteContext, ToolReturn, ToolSpec, ReversibilityVerdict, ToolEffect, ToolContentOrigin, WorkflowGovernanceBaseline, DelegationTaskType, } from "./core/types.js";
|
|
258
258
|
export { Type } from "typebox";
|
|
259
259
|
export type { TSchema, Static } from "typebox";
|
|
260
260
|
export { explainPromptAssembly, describeDefaultPack, type DefaultPackDescription, type ExplainInput } from "./prompt-assembly/explain.js";
|
package/dist/index.js
CHANGED
|
@@ -126,7 +126,7 @@ export { AdoptionError, assertAdoptionBootGate, readRootAdoptionFile, writeRootA
|
|
|
126
126
|
export { adoptLocalDataRoot, ackAdoptionConfig, witnessAdoptionConfig, listAdoptionQuarantine, readAdoptionStatus, } from "./stores/file/adoption/adopt.js";
|
|
127
127
|
export { formatHookFeedback, runToolGate, createHookEnvCapabilities, createPreToolUseConstraintPolicy, normalizePersistedRuleHit, } from "./core/hooks.js";
|
|
128
128
|
export { InMemoryMemoryStore, composeMemoryBlock, composeLayeredMemoryBlock, normalizeMemorySpec, supportsConsolidation, supportsPeriodicConsolidation, firstSentence, expandLexicalTerms, lexicalSearchMatch, classifyPromotable, enforcePromotableWriteGate, guardedMemoryStore, MemoryGateError, detectSecret, enforceSecretWriteGate, enforceStructuredNoteSecretGate, } from "./core/memory.js";
|
|
129
|
-
export { MemoryEngine, FileMemoryEngineBackend, memoryBackendContract, assertMemoryBackendSearchEquivalence, buildMemoryInstruction, truncateIndex, scanEntryFiles, deriveRepoKey, deriveRepoMemoryDir, deriveControlPlaneDir, deriveRepoControlPlaneDir, resolveMemoryEngineRoot, scopeDirName, ControlPlaneCorruptError, parseEntryFile, serializeEntryFile, computeEntryRev, entryFromFile, MEMORY_INSTRUCTION_TEMPLATE, MEMORY_RECALL_DISCIPLINE, MEMORY_PREFERENCE_DISCIPLINE, MEMORY_READONLY_NOTICE, readV2HeaderHints, LINEAGE_FILE, CHALLENGES_FILE, CHALLENGED_HISTORY_FILE, CHALLENGE_LEDGER_MAX_EVENTS, rebuildStrictControlPlaneLedger, MEMORY_INDEX_FILENAME, MEMORY_INDEX_MAX_LINES, MEMORY_INDEX_MAX_BYTES, MEMORY_SEARCH_TOOL_NAME, MEMORY_GET_TOOL_NAME, MEMORY_ENGINE_TOOL_NAMES, STUB_ARCHIVED_LINE, DEFAULT_MAX_MEMORY_FILES, DEFAULT_MAX_ENTRY_DEPTH, DEFAULT_HARVEST_DEADLINE_MS, DEFAULT_HARVEST_FILE_BUDGET, MASS_DELETION_FUSE_RATIO, scanMemoryWrite, scanMemoryFileName, scanRemediation, MEMORY_FILENAME_SEGMENT_RE, renderAnnouncements, enqueueMemoryAnnouncement, drainMemoryAnnouncements, peekMemoryAnnouncements, bumpScanFuse, scanFuseCount, clearScanFuse, ANNOUNCEMENTS_FILE, MEMORY_ANNOUNCEMENTS_MAX, SCAN_FUSE_FILE, SCAN_FUSE_THRESHOLD, SCOPE_SEGMENT_MAX_ENCODED, PROJECT_MARKER_PATH, encodeScopeSegment, decodeScopeSegment, parseScopeKey, formatUserScope, formatOrgScope, formatProjScope, formatUserProjScope, isPersonalScope, assertScopeContractPlacement, formatProjectMarker, parseProjectMarker, resolveProjectId, PROJECT_ID_REGEX, migrateScope, materializeEntriesToFiles, harvestFilesToPatches, projectionsToWriteBack, screenInboundEntries, REMOTE_HARVEST_PER_FILE_BYTES, REMOTE_MASS_DELETION_FUSE_RATIO, deriveProjectMemoryDir, deriveProjectControlDir, recordProjectIdHint, lookupProjectIdHint, PROJECT_ID_HINTS_FILE, reconcileMemoryEntries, nextSyncBaseline, mergeRecallHits, syncMemoryScope, } from "./core/memory-engine/index.js";
|
|
129
|
+
export { MemoryEngine, FileMemoryEngineBackend, memoryBackendContract, assertMemoryBackendSearchEquivalence, buildMemoryInstruction, truncateIndex, scanEntryFiles, deriveRepoKey, deriveRepoMemoryDir, deriveControlPlaneDir, deriveRepoControlPlaneDir, resolveMemoryEngineRoot, scopeDirName, ControlPlaneCorruptError, parseEntryFile, serializeEntryFile, computeEntryRev, entryFromFile, MEMORY_INSTRUCTION_TEMPLATE, MEMORY_RECALL_DISCIPLINE, MEMORY_PREFERENCE_DISCIPLINE, MEMORY_READONLY_NOTICE, readV2HeaderHints, LINEAGE_FILE, CHALLENGES_FILE, CHALLENGED_HISTORY_FILE, CHALLENGE_LEDGER_MAX_EVENTS, rebuildStrictControlPlaneLedger, MEMORY_INDEX_FILENAME, MEMORY_INDEX_MAX_LINES, MEMORY_INDEX_MAX_BYTES, MEMORY_SEARCH_TOOL_NAME, MEMORY_GET_TOOL_NAME, MEMORY_ENGINE_TOOL_NAMES, STUB_ARCHIVED_LINE, DEFAULT_MAX_MEMORY_FILES, DEFAULT_MAX_ENTRY_DEPTH, DEFAULT_HARVEST_DEADLINE_MS, DEFAULT_HARVEST_FILE_BUDGET, MASS_DELETION_FUSE_RATIO, scanMemoryWrite, scanMemoryFileName, scanRemediation, MEMORY_FILENAME_SEGMENT_RE, renderAnnouncements, enqueueMemoryAnnouncement, drainMemoryAnnouncements, peekMemoryAnnouncements, bumpScanFuse, scanFuseCount, clearScanFuse, ANNOUNCEMENTS_FILE, MEMORY_ANNOUNCEMENTS_MAX, SCAN_FUSE_FILE, SCAN_FUSE_THRESHOLD, erasureSelectHash, SCOPE_SEGMENT_MAX_ENCODED, PROJECT_MARKER_PATH, encodeScopeSegment, decodeScopeSegment, parseScopeKey, formatUserScope, formatOrgScope, formatProjScope, formatUserProjScope, isPersonalScope, assertScopeContractPlacement, formatProjectMarker, parseProjectMarker, resolveProjectId, PROJECT_ID_REGEX, migrateScope, materializeEntriesToFiles, harvestFilesToPatches, projectionsToWriteBack, screenInboundEntries, REMOTE_HARVEST_PER_FILE_BYTES, REMOTE_MASS_DELETION_FUSE_RATIO, deriveProjectMemoryDir, deriveProjectControlDir, recordProjectIdHint, lookupProjectIdHint, PROJECT_ID_HINTS_FILE, reconcileMemoryEntries, nextSyncBaseline, mergeRecallHits, syncMemoryScope, } from "./core/memory-engine/index.js";
|
|
130
130
|
export { SHARED_MEMORY_READ_CAP_BYTES, SHARED_MEMORY_LIST_PAGE_SIZE, SharedMemoryStoreError, } from "./core/shared-memory/types.js";
|
|
131
131
|
export { sharedMemoryStoreContract, } from "./core/shared-memory/contract.js";
|
|
132
132
|
export { termSet, jaccardDistance, cosineDistance } from "./core/memory-vector.js";
|
|
@@ -12,4 +12,5 @@ export type { AgentHarnessEvent, CompactionSettings, ExecutionEnv, ExecutionErro
|
|
|
12
12
|
export type { ExecutionEnvExecOptions, ExecResult } from "../engine/harness/types.js";
|
|
13
13
|
export type { SessionWriteOptions, CompactionEntry } from "../engine/harness/types.js";
|
|
14
14
|
export type { ActiveWorktreeSession, WorkspaceState } from "../engine/harness/types.js";
|
|
15
|
+
export type { GitAnnouncementKind, GitAnnouncementState } from "../engine/harness/types.js";
|
|
15
16
|
export type { SessionForkOptions } from "../engine/harness/types.js";
|
|
@@ -23,3 +23,5 @@ export { InMemorySessionStorage } from "../engine/session/memory-storage.js";
|
|
|
23
23
|
export { InMemorySessionRepo } from "../engine/session/memory-repo.js";
|
|
24
24
|
export { uuidv7 } from "../engine/session/uuid.js";
|
|
25
25
|
export { SessionError } from "../engine/harness/types.js";
|
|
26
|
+
export { normalizeGitAnnouncement } from "../engine/harness/types.js";
|
|
27
|
+
export { gitFrameContextVisible } from "../engine/session/session.js";
|
package/dist/internal/harness.js
CHANGED
|
@@ -12,3 +12,5 @@ export { InMemorySessionStorage } from "../engine/session/memory-storage.js";
|
|
|
12
12
|
export { InMemorySessionRepo } from "../engine/session/memory-repo.js";
|
|
13
13
|
export { uuidv7 } from "../engine/session/uuid.js";
|
|
14
14
|
export { SessionError } from "../engine/harness/types.js";
|
|
15
|
+
export { normalizeGitAnnouncement } from "../engine/harness/types.js";
|
|
16
|
+
export { gitFrameContextVisible } from "../engine/session/session.js";
|
|
@@ -50,7 +50,7 @@ const PROBE_INPUTS_BASE = {
|
|
|
50
50
|
roleBase: "\u0000probe-role\u0000",
|
|
51
51
|
roleAppend: "\u0000probe-append\u0000",
|
|
52
52
|
mcpInstructionsBlock: "\u0000probe-mcp\u0000",
|
|
53
|
-
environmentBlock: "\u0000probe-env\u0000",
|
|
53
|
+
environmentBlock: "\u0000probe-env@2\u0000",
|
|
54
54
|
memoryBlock: "\u0000probe-memory\u0000",
|
|
55
55
|
modelGuidance: "\u0000probe-guidance\u0000",
|
|
56
56
|
};
|
|
@@ -13,6 +13,7 @@ export const EVENT_PROMPT_REGISTRY = new Map([
|
|
|
13
13
|
{ kind: "skills_listing", carrier: "message.user-prefix", trust: "operator", dedupe: "replace-by-key", defaultPolicy: "on", rendererRef: "turn-attachments.ts#renderSkillsListingDelta" },
|
|
14
14
|
{ kind: "mcp_instructions", carrier: "message.user-prefix", trust: "external", dedupe: "replace-by-key", defaultPolicy: "off", rendererRef: "turn-attachments.ts#renderMcpInstructionsDelta" },
|
|
15
15
|
{ kind: "mcp_dropped_tools", carrier: "message.user-prefix", trust: "external", dedupe: "replace-by-key", defaultPolicy: "off", rendererRef: "turn-attachments.ts#renderMcpDroppedTools" },
|
|
16
|
+
{ kind: "git_status", carrier: "message.user-prefix", trust: "external", dedupe: "replace-by-key", defaultPolicy: "always", rendererRef: "git-status-frame.ts#renderGitStatusFrameBody" },
|
|
16
17
|
{ kind: "limit_approach_converge", carrier: "message.user-prefix", trust: "operator", dedupe: "once-per-run", defaultPolicy: "always", rendererRef: "runtask.ts#limitApproachFrames" },
|
|
17
18
|
{ kind: "limit_approach_deliver", carrier: "message.user-prefix", trust: "operator", dedupe: "once-per-run", defaultPolicy: "always", rendererRef: "runtask.ts#limitApproachFrames" },
|
|
18
19
|
{ kind: "final_verification", carrier: "message.user-prefix", trust: "operator", dedupe: "once-per-run", defaultPolicy: "always", rendererRef: "runtask.ts#final-verification" },
|
|
@@ -271,9 +271,13 @@ export interface EnvironmentFacts {
|
|
|
271
271
|
cwd?: string;
|
|
272
272
|
isGitRepo?: boolean;
|
|
273
273
|
/** design/99 §E14 — the current git branch (remote = the container's repo). `"HEAD (detached)"` when on a
|
|
274
|
-
* detached HEAD. Absent when not a git repo / no git. A prepare-time snapshot, like cwd (may go stale mid-run).
|
|
274
|
+
* detached HEAD. Absent when not a git repo / no git. A prepare-time snapshot, like cwd (may go stale mid-run).
|
|
275
|
+
* env-tail migration (#254 shape): NO LONGER RENDERED by {@link buildEnvironmentContext} — the
|
|
276
|
+
* branch is a turn-dynamic fact and rides the `git_status` frame instead; the field remains as a
|
|
277
|
+
* structured data carrier for callers that assembled it. */
|
|
275
278
|
gitBranch?: string;
|
|
276
|
-
/** design/99 §E14 — whether the working tree has uncommitted changes (`git status --porcelain` non-empty).
|
|
279
|
+
/** design/99 §E14 — whether the working tree has uncommitted changes (`git status --porcelain` non-empty).
|
|
280
|
+
* env-tail migration: NO LONGER RENDERED here (turn-dynamic; rides the `git_status` frame). */
|
|
277
281
|
gitDirty?: boolean;
|
|
278
282
|
/** design/99 §E14 — the working tree's toplevel (`git rev-parse --show-toplevel`). Lets the agent/shell know
|
|
279
283
|
* it may be in a linked worktree rather than the main checkout. */
|
|
@@ -319,10 +323,10 @@ export interface EnvironmentFacts {
|
|
|
319
323
|
/** A1 — outbound-network posture; `none` renders an explicit downloads-will-fail caveat (TB
|
|
320
324
|
* autopsy 2026-07-05: agents burned budget retrying downloads in a no-egress sandbox). */
|
|
321
325
|
sandboxEgress?: "none" | "allowlist" | "full";
|
|
322
|
-
/** H4 (CC 2.1.198 git snapshot) — the pre-rendered {@link buildGitSnapshot} block
|
|
323
|
-
*
|
|
324
|
-
*
|
|
325
|
-
*
|
|
326
|
+
/** H4 (CC 2.1.198 git snapshot) — the pre-rendered {@link buildGitSnapshot} block. env-tail
|
|
327
|
+
* migration (#254 shape): NO LONGER RENDERED by {@link buildEnvironmentContext} — the snapshot is
|
|
328
|
+
* the turn-dynamic git view and rides the `git_status` frame (re-sent only when the rendered view
|
|
329
|
+
* changes); the field remains as a structured data carrier for callers that assembled it. */
|
|
326
330
|
gitSnapshot?: string;
|
|
327
331
|
/** [1451] B-half — per-lane resume-continuity facts (deployment-supplied via `TaskSpec.envFacts.resumeFacts`,
|
|
328
332
|
* copied by prepare ONLY on a durable-resume leg). Each present field renders one honest sentence; absent
|
|
@@ -353,11 +357,20 @@ export interface EnvironmentFacts {
|
|
|
353
357
|
export declare function buildScratchpadSection(scratchpadDir: string): string;
|
|
354
358
|
/** CC 2.1.198 `Juo` — the git status truncation bound (chars) for {@link buildGitSnapshot}. */
|
|
355
359
|
export declare const GIT_STATUS_MAX_CHARS = 2000;
|
|
360
|
+
/** The CC-verbatim first paragraph of the git snapshot (CC 2.1.198 `Quo` head sentence). Kept as a
|
|
361
|
+
* named constant so the git-status FRAME renderer (the snapshot's carrier since the env-tail
|
|
362
|
+
* migration) can swap exactly this paragraph for its own update-semantics preamble — under the
|
|
363
|
+
* frame protocol the snapshot IS re-sent when the visible view changes, so the "will not update"
|
|
364
|
+
* claim would be false there. {@link buildGitSnapshot} itself still renders it byte-exact. */
|
|
365
|
+
export declare const GIT_SNAPSHOT_CC_PREAMBLE = "This is the git status at the start of the conversation. Note that this status is a snapshot in time, and will not update during the conversation.";
|
|
356
366
|
/**
|
|
357
367
|
* H4 — the CC 2.1.198 ENV git snapshot block (B1/B2; template + truncation copy verified against
|
|
358
368
|
* observed Claude Code v2.1.198 behavior). Pure renderer — the Runner gathers the raw values through the
|
|
359
369
|
* ExecutionEnv seam (remote = the container's repo) and calls this once per prepareTask (a durable
|
|
360
|
-
* resume re-prepares → re-snapshots, CC new-session 同型).
|
|
370
|
+
* resume re-prepares → re-snapshots, CC new-session 同型). env-tail migration (#254 shape): the
|
|
371
|
+
* rendered block now feeds the `git_status` TURN FRAME (src/core/runner/git-status-frame.ts, which
|
|
372
|
+
* swaps the {@link GIT_SNAPSHOT_CC_PREAMBLE} for an update-semantics preamble) instead of the
|
|
373
|
+
* `# Environment` system-prompt section — the template body itself stays CC-verbatim.
|
|
361
374
|
*
|
|
362
375
|
* Sanitization (deliberate CC deviation — CC injects raw): status/log/branch/user are REPO-controlled
|
|
363
376
|
* text (filenames, commit subjects, a hostile clone's config) landing in the TRUSTED prompt region →
|