@sema-agent/core 7.15.0 → 7.16.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 (119) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/dist/core/governance-codes.js +2 -0
  3. package/dist/core/memory-engine/delegation-settlement.d.ts +37 -12
  4. package/dist/core/memory-engine/delegation-settlement.js +128 -39
  5. package/dist/core/memory-engine/engine.d.ts +9 -8
  6. package/dist/core/memory-engine/engine.js +115 -120
  7. package/dist/core/memory-engine/file-backend.d.ts +17 -5
  8. package/dist/core/memory-engine/file-backend.js +78 -34
  9. package/dist/core/memory-engine/index.d.ts +2 -2
  10. package/dist/core/memory-engine/index.js +2 -2
  11. package/dist/core/memory-engine/layout.d.ts +152 -54
  12. package/dist/core/memory-engine/layout.js +441 -104
  13. package/dist/core/memory-engine/types.d.ts +8 -3
  14. package/dist/core/memory-engine/types.js +5 -0
  15. package/dist/core/runner/abort-race.d.ts +3 -3
  16. package/dist/core/runner/active-skill-scope.d.ts +2 -2
  17. package/dist/core/runner/assemble-result.d.ts +29 -29
  18. package/dist/core/runner/checkpoint-scope.d.ts +4 -4
  19. package/dist/core/runner/clock-and-limits.d.ts +3 -3
  20. package/dist/core/runner/compaction-call-options.d.ts +11 -11
  21. package/dist/core/runner/compaction-knobs.d.ts +4 -4
  22. package/dist/core/runner/compaction-seams.d.ts +5 -5
  23. package/dist/core/runner/contracts.d.ts +222 -224
  24. package/dist/core/runner/decide-continuation.d.ts +6 -6
  25. package/dist/core/runner/denial-limit-arms.d.ts +8 -8
  26. package/dist/core/runner/derived-route-fallback.d.ts +2 -2
  27. package/dist/core/runner/gate-exit.d.ts +6 -6
  28. package/dist/core/runner/git-status-frame.d.ts +7 -7
  29. package/dist/core/runner/inherited-ask-grants.d.ts +6 -6
  30. package/dist/core/runner/memory-capture-optout.d.ts +1 -1
  31. package/dist/core/runner/memory-consolidation-driver.d.ts +4 -4
  32. package/dist/core/runner/memory-consolidation.d.ts +6 -6
  33. package/dist/core/runner/park-commit.d.ts +6 -6
  34. package/dist/core/runner/permission-rule-lanes.d.ts +19 -19
  35. package/dist/core/runner/prepare-acquire-reconcile.d.ts +4 -4
  36. package/dist/core/runner/prepare-ask-lane.d.ts +3 -3
  37. package/dist/core/runner/prepare-boundary-parks.d.ts +3 -3
  38. package/dist/core/runner/prepare-caps-and-workflow.d.ts +5 -5
  39. package/dist/core/runner/prepare-config-doors.d.ts +21 -21
  40. package/dist/core/runner/prepare-context-lane.d.ts +6 -6
  41. package/dist/core/runner/prepare-defer-classify.d.ts +2 -2
  42. package/dist/core/runner/prepare-delegation-surface.d.ts +1 -1
  43. package/dist/core/runner/prepare-file-history.d.ts +2 -2
  44. package/dist/core/runner/prepare-gate-stations.d.ts +5 -5
  45. package/dist/core/runner/prepare-hands-readface.d.ts +33 -33
  46. package/dist/core/runner/prepare-inherited-gate.d.ts +4 -4
  47. package/dist/core/runner/prepare-listings.d.ts +3 -3
  48. package/dist/core/runner/prepare-lsp.d.ts +3 -3
  49. package/dist/core/runner/prepare-memory-engine-session.d.ts +5 -5
  50. package/dist/core/runner/prepare-memory.js +6 -7
  51. package/dist/core/runner/prepare-offload-wrappers.d.ts +2 -2
  52. package/dist/core/runner/prepare-park-ask.d.ts +6 -6
  53. package/dist/core/runner/prepare-policy-chain.d.ts +4 -4
  54. package/dist/core/runner/prepare-prompt-inputs.d.ts +5 -5
  55. package/dist/core/runner/prepare-protocol-tools.d.ts +1 -1
  56. package/dist/core/runner/prepare-question-face.d.ts +4 -4
  57. package/dist/core/runner/prepare-run-refs.d.ts +11 -11
  58. package/dist/core/runner/prepare-safety-scan.d.ts +1 -1
  59. package/dist/core/runner/prepare-suspend-saga.d.ts +4 -4
  60. package/dist/core/runner/prepare-task.d.ts +12 -12
  61. package/dist/core/runner/prepare-tool-disclosure-mount.d.ts +2 -3
  62. package/dist/core/runner/prepare-wiring-manifest.d.ts +4 -4
  63. package/dist/core/runner/prepare-workspace-restore.d.ts +1 -1
  64. package/dist/core/runner/remote-env-retry.d.ts +3 -3
  65. package/dist/core/runner/resume-admission.d.ts +1 -1
  66. package/dist/core/runner/resume-claim.d.ts +1 -1
  67. package/dist/core/runner/resume-internals-and-config.d.ts +1 -1
  68. package/dist/core/runner/resume-policy-outcome.d.ts +1 -1
  69. package/dist/core/runner/resume-preflight.d.ts +1 -1
  70. package/dist/core/runner/resume-review-outcome.d.ts +1 -1
  71. package/dist/core/runner/run-brain-sinks.d.ts +1 -1
  72. package/dist/core/runner/run-clock-and-content.d.ts +4 -4
  73. package/dist/core/runner/run-compaction-machinery.d.ts +3 -3
  74. package/dist/core/runner/run-git-lane.d.ts +1 -1
  75. package/dist/core/runner/run-harness-handlers.d.ts +2 -2
  76. package/dist/core/runner/run-identity-wiring.d.ts +4 -4
  77. package/dist/core/runner/run-leg.d.ts +3 -3
  78. package/dist/core/runner/run-notification-lane.d.ts +2 -2
  79. package/dist/core/runner/run-reasoning-seat.d.ts +2 -2
  80. package/dist/core/runner/run-settle-and-teardown.d.ts +4 -4
  81. package/dist/core/runner/run-telemetry-and-budget-seats.d.ts +2 -2
  82. package/dist/core/runner/run-terminal-adoption.d.ts +5 -5
  83. package/dist/core/runner/runtask.d.ts +14 -14
  84. package/dist/core/runner/session-file-state-replay.d.ts +3 -3
  85. package/dist/core/runner/session-rule-policy.d.ts +2 -2
  86. package/dist/core/runner/steer-admission.d.ts +2 -2
  87. package/dist/core/runner/stream-halt-verbs.d.ts +1 -1
  88. package/dist/core/runner/stream-reap.d.ts +1 -1
  89. package/dist/core/runner/synthetic-tools.d.ts +8 -8
  90. package/dist/core/runner/teardown-bounded.d.ts +2 -2
  91. package/dist/core/runner/tool-defer-gate.d.ts +1 -1
  92. package/dist/core/runner/tool-disclosure.d.ts +33 -33
  93. package/dist/core/runner/tool-end-body.d.ts +3 -3
  94. package/dist/core/runner/tool-face-overlay.d.ts +2 -2
  95. package/dist/core/runner/tool-output-projection.d.ts +2 -2
  96. package/dist/core/runner/turn-attachments.d.ts +53 -53
  97. package/dist/core/runner/usage-accounting.d.ts +4 -4
  98. package/dist/core/runner/workspace-path.d.ts +1 -1
  99. package/dist/engine/llm/types.d.ts +1 -1
  100. package/dist/index.d.ts +2 -2
  101. package/dist/index.js +2 -2
  102. package/dist/tools/fs/bash-readonly-classifier.d.ts +40 -40
  103. package/dist/tools/fs/encoding.d.ts +31 -40
  104. package/dist/tools/fs/fs-bash.d.ts +35 -35
  105. package/dist/tools/fs/fs-pdf.d.ts +8 -8
  106. package/dist/tools/fs/fs-search-tools.d.ts +4 -4
  107. package/dist/tools/fs/fs-shared.d.ts +144 -158
  108. package/dist/tools/fs/fs-write.d.ts +8 -8
  109. package/dist/tools/fs/gh-rate-limit.d.ts +13 -14
  110. package/dist/tools/fs/index.d.ts +74 -78
  111. package/dist/tools/fs/notebook.d.ts +24 -25
  112. package/dist/tools/fs/pdf.d.ts +3 -3
  113. package/dist/tools/fs/read-deny.d.ts +22 -22
  114. package/dist/tools/fs/read-face.d.ts +21 -24
  115. package/dist/tools/fs/repo-map.d.ts +8 -8
  116. package/dist/tools/fs/safety.d.ts +116 -129
  117. package/dist/tools/fs/search.d.ts +63 -71
  118. package/package.json +5 -2
  119. package/test/export-surface.snapshot.json +5 -1
@@ -1,16 +1,13 @@
1
1
  import type { ExecutionEnv } from "../../internal/harness-types.js";
2
- /** backlog #310 — the JS scanner's own output ceiling, in bytes of emitted content rows. Pinned to the
2
+ /** The JS scanner's own output ceiling, in bytes of emitted content rows. Pinned to the
3
3
  * ripgrep leg's figure ({@link MAX_EXEC_OUTPUT_BYTES}, the exec pipe's rolling-tail bound) so the two
4
4
  * legs cannot disagree about how much one search may return; see the collection site in {@link jsGrep}
5
5
  * for why this leg bounds the HEAD where the pipe bounds the tail. */
6
6
  export declare const JS_GREP_OUTPUT_MAX_BYTES: number;
7
- /** Directories never worth crawling (design/64 §10.3) — dependency/build/cache trees, PLUS the VCS
8
- * metadata directories CC names explicitly (RB-200 F1, 220 @368402: `Ok_ = [".git",".svn",".hg",
9
- * ".bzr",".jj",".sl"]` git/svn/mercurial/bazaar/jujutsu/sapling). `.bzr`/`.jj`/`.sl` are additive here
10
- * (the other three VCS dirs already lived in this list for the build/cache reason above; they're
11
- * identical either way). See {@link buildIgnore}'s own comment for why this list is now the ENTIRE
12
- * directory-skip story — the blanket "any dot-prefixed name is invisible" rule this list used to sit
13
- * beside is gone. */
7
+ /** Directories never worth crawling — dependency/build/cache trees, PLUS the six VCS metadata
8
+ * directories CC names explicitly (git/svn/mercurial/bazaar/jujutsu/sapling). See {@link buildIgnore}'s
9
+ * own comment for why this list is the ENTIRE directory-skip story: there is deliberately no blanket
10
+ * "any dot-prefixed name is invisible" rule beside it. */
14
11
  export declare const DEFAULT_IGNORE_DIRS: ReadonlySet<string>;
15
12
  export interface GrepParams {
16
13
  /** Regular expression (ripgrep semantics) — CC 2.1.209 parity: the pattern is ALWAYS a regex; the
@@ -19,12 +16,12 @@ export interface GrepParams {
19
16
  pattern: string;
20
17
  /** Restrict the search to this sub-path (relative to root, or absolute within root). */
21
18
  path?: string;
22
- /** Only search files matching this glob (e.g. `*.ts`, `*.{ts,tsx}`). 批④ #6 (CC parity): a
19
+ /** Only search files matching this glob (e.g. `*.ts`, `*.{ts,tsx}`). CC parity: a
23
20
  * comma/whitespace-separated list (`"*.ts,*.tsx"`) is split into multiple globs (brace globs kept whole). */
24
21
  glob?: string;
25
- /** 批④ #5 (CC 2.1.201 `-o`): print only the matched (non-empty) parts of each matching line, one match
26
- * per output line (rg -o / --only-matching). content mode only; ignored otherwise (CC parity).
27
- * 1.253: with `multiline` the JS fallback emits the matched SEGMENT's lines (rg -U -o shape). */
22
+ /** CC `-o`: print only the matched (non-empty) parts of each matching line, one match per output
23
+ * line (rg -o / --only-matching). content mode only; ignored otherwise (CC parity). With
24
+ * `multiline` the JS fallback emits the matched SEGMENT's lines (rg -U -o shape). */
28
25
  only_matching?: boolean;
29
26
  /** content: `path:line:text`. files_with_matches (default, CC 2.1.209): `path`. count: `path:count`. */
30
27
  output_mode?: "content" | "files_with_matches" | "count";
@@ -46,7 +43,7 @@ export interface GrepParams {
46
43
  /** Skip the first N output lines — CC's `offset` (pagination partner of head_limit). */
47
44
  offset?: number;
48
45
  }
49
- /** 批④ #6 (CC 2.1.198 Grep call, bundle :333383-333390): split the `glob` param into individual glob
46
+ /** CC 2.1.198 Grep parity: split the `glob` param into individual glob
50
47
  * tokens — whitespace-separated first; a token WITHOUT braces is further split on commas
51
48
  * (`"*.ts,*.tsx"` → two globs), while a brace token (`*.{ts,tsx}`) is kept whole (its commas are
52
49
  * alternation syntax, not separators). CC-verbatim splitting rules. */
@@ -54,28 +51,26 @@ export declare function splitGlobParam(glob: string): string[];
54
51
  /**
55
52
  * POSIX-safe single-quote so an arbitrary model-supplied string can't break out of the shell command that
56
53
  * runs ripgrep. Wraps in single quotes (inside which the shell expands nothing — no `$()`, backtick, `;`, or
57
- * glob) and escapes any embedded single quote via the `'\''` idiom (close, escaped-quote, reopen). Exported
58
- * for direct injection testing (council [R145]). Renamed from `shq` for legibility.
54
+ * glob) and escapes any embedded single quote via the `'\''` idiom (close, escaped-quote, reopen).
55
+ * Exported for direct injection testing.
59
56
  */
60
57
  export declare function shellQuote(s: string): string;
61
58
  /**
62
- * RB-284 (成批, CC 220 `xGg`/`MCu` @240961-240967 亲核) the tokens of a `glob` argument that this
63
- * engine CANNOT compile as glob syntax, i.e. the ones whose metacharacter would silently degrade to a
64
- * literal match.
59
+ * The tokens of a `glob` argument that this engine CANNOT compile as glob syntax, i.e. the ones whose
60
+ * metacharacter would silently degrade to a literal match.
65
61
  *
66
62
  * The harm this closes is specific and asymmetric. An unknown `type` degrades to searching EVERY file —
67
63
  * a SUPERSET of what was asked, wrong but self-evidently over-broad, and sema already discloses it with
68
64
  * a `[note: unknown type …]` line. An unparseable `glob` degrades the other way: `src/[ab.ts` stops
69
65
  * being a character class and becomes a request for a file literally NAMED `src/[ab.ts`, so the filter
70
- * silently narrows to (almost always) nothing and the search answers a clean "No matches." — a
71
- * false negative wearing the exact shape of a successful exhaustive search. That is the RB-264 G2
72
- * failure class, and this repo's standing verdict on it is: no real data ⇒ isError, never a degraded
73
- * answer.
66
+ * silently narrows to (almost always) nothing and the search answers a clean "No matches." — a false
67
+ * negative wearing the exact shape of a successful exhaustive search. This repo's standing verdict on
68
+ * that class is: no real data ⇒ isError, never a degraded answer.
74
69
  *
75
70
  * CC hard-errors on the same input class rather than searching at all — its ripgrep stderr matcher
76
- * `xGg` covers `error parsing glob` (alongside regex-parse / unrecognized-file-type / flag-parse
77
- * errors) and raises `Search failed — ripgrep rejected the pattern, glob, or file type without
78
- * searching`. sema rejects at the INPUT level instead of waiting for a stderr string, because sema has
71
+ * covers `error parsing glob` (alongside regex-parse / unrecognized-file-type / flag-parse errors) and
72
+ * raises `Search failed — ripgrep rejected the pattern, glob, or file type without searching`. sema
73
+ * rejects at the INPUT level instead of waiting for a stderr string, because sema has
79
74
  * two search engines (rg + the JS fallback) and only the rg one would ever produce that stderr: a
80
75
  * rejection that fires only when ripgrep happens to be installed is not a contract. The `type` leg
81
76
  * deliberately does NOT get this treatment (see the `typeNote` site) — over-broad-with-a-note is an
@@ -85,20 +80,18 @@ export declare function invalidGlobTokens(glob: string): string[];
85
80
  /** Lightweight `.gitignore` matcher (handles comments, negation, dir-only `/`, anchoring, `*`/`?`). */
86
81
  export declare function gitignoreMatcher(content: string): (rel: string, isDir: boolean) => boolean;
87
82
  /** Build the combined ignore predicate (ignore-set ∪ .gitignore) for a JS-fallback walk.
88
- * Exported so repo-map (design/72 §1) walks with the SAME ignore semantics as grep/glob.
83
+ * Exported so repo-map walks with the SAME ignore semantics as grep/glob.
89
84
  *
90
- * RB-200 F1 (CC 220 corpus-confirmed, @368590-368592 Grep `T=["--hidden"]; for(N of Ok_) T.push("--glob",
91
- * "!"+N)`, @367957/367959-367965 Glob `CLAUDE_CODE_GLOB_HIDDEN` defaults to true and also passes `--hidden`): CC's own
92
- * "keep it quiet" posture is NOT "every dot-prefixed name is invisible" — it's `--hidden` (show
85
+ * CC's "keep it quiet" posture is NOT "every dot-prefixed name is invisible" it is `--hidden` (show
93
86
  * everything dot-prefixed) plus an explicit VCS-directory exclusion list ({@link DEFAULT_IGNORE_DIRS}).
94
- * The blanket rule this function used to apply here (`base.startsWith(".")`) instead made EVERY hidden
95
- * file/dir invisible with no caveat — `.github/`, `.claude/`, `.env.example` never existed as far as
96
- * Grep/Glob/repo-map were concerned, not even as an honest "search skipped this" note (A-8 posture: an
97
- * unflagged gap reads as exhaustive). Removed; {@link DEFAULT_IGNORE_DIRS} (dependency/build/cache trees
98
- * + the 6 VCS metadata dirs) and `.gitignore` are now the entire directory-skip story, matching CC. */
87
+ * A blanket `base.startsWith(".")` rule here would make EVERY hidden file/dir invisible with no caveat
88
+ * — `.github/`, `.claude/`, `.env.example` would not exist as far as Grep/Glob/repo-map are concerned,
89
+ * not even as an honest "search skipped this" note, and an unflagged gap reads as exhaustive. So
90
+ * {@link DEFAULT_IGNORE_DIRS} (dependency/build/cache trees + the 6 VCS metadata dirs) and `.gitignore`
91
+ * are the entire directory-skip story, matching CC. */
99
92
  export declare function buildIgnore(env: ExecutionEnv, root: string, signal?: AbortSignal): Promise<(rel: string, isDir: boolean) => boolean>;
100
- /** What a bounded walk actually saw — so consumers can be HONEST about incompleteness (A-4 class sweep:
101
- * silently bounded results must never read as exhaustive). */
93
+ /** What a bounded walk actually saw — so consumers can be HONEST about incompleteness: silently
94
+ * bounded results must never read as exhaustive. */
102
95
  export interface WalkResult {
103
96
  /** Greppable text files (binary-extension and oversize files excluded). */
104
97
  files: string[];
@@ -113,35 +106,34 @@ export interface WalkResult {
113
106
  /** Non-binary files skipped by content search for being over {@link FILE_MAX_BYTES} (also in
114
107
  * `nameOnly`). Surfaced by grep so "No matches." can't silently mean "didn't look". */
115
108
  skippedLarge: number;
116
- /** fidelity-sweep F2: directories whose listing FAILED (EACCES, transient I/O) — whole subtrees the
117
- * walk never saw. */
109
+ /** Directories whose listing FAILED (EACCES, transient I/O) — whole subtrees the walk never saw. */
118
110
  skippedUnreadable: number;
119
- /** F2: the walk was cut short by an abort — the result is a prefix, not a survey. */
111
+ /** The walk was cut short by an abort — the result is a prefix, not a survey. */
120
112
  aborted: boolean;
121
- /** CC 2.1.209 Glob parity (batch A2): modification time (ms epoch) per walked path (files AND
113
+ /** CC 2.1.209 Glob parity: modification time (ms epoch) per walked path (files AND
122
114
  * name-only entries), captured from the listing that discovered them — so glob can sort by mtime
123
115
  * without a second stat pass. An env whose listings carry no numeric `mtimeMs` simply leaves
124
116
  * entries out of this map (consumers fall back to name order). */
125
117
  mtimes: Map<string, number>;
126
- /** design/199 件B — entries withheld by the sensitive-path read deny list: PRUNE-ROOT count only
118
+ /** Entries withheld by the sensitive-path read deny list: PRUNE-ROOT count only
127
119
  * (a denied directory's descendants are not enumerated, so they cannot be counted — the note says
128
120
  * so). 0 when no deny judge was supplied or nothing matched. */
129
121
  denyPruned: number;
130
122
  /** The deny patterns that pruned something, first-seen order (for the disclosure note). */
131
123
  denyPatterns: string[];
132
124
  }
133
- /** F2: any-cause incompleteness — a result built on this walk must not present itself as exhaustive. */
125
+ /** Any-cause incompleteness — a result built on this walk must not present itself as exhaustive. */
134
126
  export declare function walkIsPartial(w: WalkResult): boolean;
135
127
  /** Bounded, ignore-aware recursive walk. Returns absolute file paths under `start`. Exported for
136
- * repo-map (design/72 §1) — same bounded/ignore-aware traversal as grep/glob, one source of truth. */
128
+ * repo-map — same bounded/ignore-aware traversal as grep/glob, one source of truth. */
137
129
  export declare function walk(env: ExecutionEnv, root: string, start: string, ignore: (rel: string, isDir: boolean) => boolean, signal?: AbortSignal, deny?: {
138
130
  matchPath(path: string): {
139
131
  pattern: string;
140
132
  } | null;
141
133
  }): Promise<WalkResult>;
142
- /** design/199 件B — the JS-leg withholding disclosure (§3.1: an empty result must stay
143
- * distinguishable from searched-and-empty, so this note rides EVERY output shape when something was
144
- * pruned). Distinct from {@link walkCaveat}: pruning is deliberate withholding, not incompleteness.
134
+ /** The JS-leg withholding disclosure: an empty result must stay distinguishable from
135
+ * searched-and-empty, so this note rides EVERY output shape when something was pruned. Distinct from
136
+ * {@link walkCaveat}: pruning is deliberate withholding, not incompleteness.
145
137
  * The `[note:` prefix keeps it out of the tool layer's structured row extraction. */
146
138
  export declare function denyWithheldNote(w: Pick<WalkResult, "denyPruned" | "denyPatterns">): string;
147
139
  /** Injectable execution boundaries for the JS-fallback scan (tests shrink them; callers use defaults). */
@@ -150,13 +142,13 @@ export interface JsGrepGuards {
150
142
  budgetMs?: number;
151
143
  /** Longest line/content (chars) a gray-zone pattern may be matched against. */
152
144
  longLineLimit?: number;
153
- /** backlog #310 — bytes of content rows this scan may accumulate before it stops collecting and
145
+ /** Bytes of content rows this scan may accumulate before it stops collecting and
154
146
  * says so (default {@link JS_GREP_OUTPUT_MAX_BYTES}). A seam for the same reason the two above
155
147
  * are: the boundary is pinnable at a testable size instead of only at an 8MB harness. */
156
148
  outputMaxBytes?: number;
157
149
  }
158
- /** design/199 件B — what a traversal withheld under the sensitive-path read deny list, structured
159
- * (the prose note is the model-facing twin). Three shapes (§3.1): `pruned_count` = the JS walker
150
+ /** What a traversal withheld under the sensitive-path read deny list, structured (the prose note is
151
+ * the model-facing twin). Three shapes: `pruned_count` = the JS walker
160
152
  * counted its prune roots; `existence` = the rg leg's bounded probe CONFIRMED matching entries exist
161
153
  * under the scope (rg's own exclusions are silent, so the count is unknowable); `probe_failed` =
162
154
  * the probe itself failed — entries MAY have been withheld. */
@@ -180,11 +172,11 @@ export interface ReadDenyJudge {
180
172
  }>;
181
173
  }
182
174
  /** JS-fallback grep: ignore-aware walk + per-line scan, honoring output_mode / context / head_limit.
183
- * design/199 件B: `deny` prunes the walk (note appended to every output shape); `denyOut` is the
175
+ * `deny` prunes the walk (note appended to every output shape); `denyOut` is the
184
176
  * structured twin — a sink because this function's dozen error returns predate the facts (the sink
185
177
  * is written the moment the walk lands, whatever the scan then returns).
186
178
  *
187
- * backlog #313 — the SERVED rows ride back next to the text. This scanner knows every result's
179
+ * The SERVED rows ride back next to the text. This scanner knows every result's
188
180
  * identity natively (the walk hands it whole paths), so a row's `path` is that walked identity,
189
181
  * never a cut of the rendered line — the mis-split family the text re-parse carries cannot exist
190
182
  * here. The rows ARE the window `text` shows: post offset, post row cap, post byte ceiling, in the
@@ -222,7 +214,7 @@ export type GrepDegradation = {
222
214
  };
223
215
  /** Structured grep result: the model-facing text plus the degradation facts, so the tool layer can
224
216
  * ship them on the structured frame instead of leaving them prose-only. */
225
- /** #313 — one SERVED result RECORD with its path taken from the engine's own knowledge, exactly the
217
+ /** One SERVED result RECORD with its path taken from the engine's own knowledge, exactly the
226
218
  * window `text` shows (post cap/offset): ripgrep's `--null` path field ({@link parseRgRecords}) on
227
219
  * the rg legs, the walked file identity ({@link jsGrepDetailed}) on the JS-scanner legs. A record is
228
220
  * one rendered line except where a path carries a newline (see {@link formatRgRecords}), which is
@@ -247,50 +239,50 @@ export interface GrepRow {
247
239
  }
248
240
  export interface GrepRunResult {
249
241
  text: string;
250
- /** Served rows (#313): present on BOTH engine legs — ripgrep's and the JS scanner's, including the
251
- * rescan legs. Absent only when the JS scanner refused the search outright (a typed
242
+ /** Served rows: present on BOTH engine legs — ripgrep's and the JS scanner's, including the
243
+ * re-scan legs. Absent only when the JS scanner refused the search outright (a typed
252
244
  * `Error (grep): …` text): a refusal has no row set, truthfully, rather than an empty one. */
253
245
  rows?: readonly GrepRow[];
254
246
  degraded?: GrepDegradation;
255
- /** design/199 件B — deny-list withholding facts (see {@link ReadDenyWithheld}); absent = nothing
247
+ /** Deny-list withholding facts (see {@link ReadDenyWithheld}); absent = nothing
256
248
  * withheld / no deny judge in play. */
257
249
  withheld?: ReadDenyWithheld;
258
250
  }
259
251
  /** The output modes the rg leg and {@link jsGrep} share. */
260
252
  type GrepOutputMode = "content" | "files_with_matches" | "count";
261
253
  /**
262
- * backlog #303 (rescan-hardened form) — the rg leg's deny TRIPWIRE. rg's exclusion globs are spelled
254
+ * The rg leg's deny TRIPWIRE. rg's exclusion globs are spelled
263
255
  * from the pattern text and cannot express the win32 component-alias family (`.aws.` / `.aws ` —
264
256
  * trailing dots/spaces the win32 namespace strips), so a directory planted under an alias spelling
265
257
  * slips past the globs while the shared `matchPath` (two-view, read-deny.ts) correctly names it —
266
258
  * the JS leg pruned it, the rg leg returned its contents, and the same tree answered differently
267
259
  * depending on whether ripgrep was installed.
268
260
  *
269
- * The first fix FILTERED rg's text output line-by-line. The rescan killed that shape twice over:
270
- * ripgrep prints filenames verbatim, so a path component containing a NEWLINE splits one record
271
- * across physical lines whose fragments carry no `:line:` boundary — the filter kept them and the
272
- * deny-listed content passed (a protection hole, not a precision residual); and pruning every line
273
- * of a partial run fabricated a `No matches.` row inside the structured card. So this function no
274
- * longer edits anything: it JUDGES. Any deny hit — or any record the format cannot account for —
261
+ * FILTERING rg's text output line-by-line is not an option, on two counts: ripgrep prints filenames
262
+ * verbatim, so a path component containing a NEWLINE splits one record across physical lines whose
263
+ * fragments carry no `:line:` boundary — the filter keeps them and the deny-listed content passes (a
264
+ * protection hole, not a precision residual); and pruning every line of a partial run fabricates a
265
+ * `No matches.` row inside the structured card. So this function edits nothing: it JUDGES. Any deny
266
+ * hit — or any record the format cannot account for —
275
267
  * trips, and the caller abandons the rg run for the JS scanner, whose walk prunes with the
276
268
  * authoritative judge and needs no path parsing at all. rg stays the fast path for the common case
277
269
  * (no guarded entries in the result); the moment a guarded spelling is involved, the engine that
278
270
  * cannot mis-parse it owns the answer.
279
271
  *
280
- * backlog #306 — what it judges is now ripgrep's OWN path field ({@link parseRgRecords}, `--null`),
272
+ * What it judges is ripgrep's OWN path field ({@link parseRgRecords}, `--null`),
281
273
  * not a prefix cut at a guessed separator. Trip conditions, all three modes alike: a record whose
282
274
  * path the deny judge names trips as `deny-hit`; a record with no path field at all (rg's binary-file
283
275
  * notice, a no-filename row, an unterminated tail, output from an env that ignored `--null`) is
284
276
  * unaccountable and trips as `ambiguous-record` — same abandonment, same reason code as before.
285
277
  * `dropIncompleteTail` mirrors {@link parseRgRecords}: on the partial legs the cut tail is dropped
286
278
  * BEFORE judging, because judging a record the caller will never receive can only cost an
287
- * unnecessary rescan — every record that does reach the output is still judged, which is what the
279
+ * unnecessary re-scan — every record that does reach the output is still judged, which is what the
288
280
  * rule is for. (A killed stream ending mid-record is an EXPECTED shape with a rule of its own; the
289
281
  * unaccountable arm is for records that survive that rule.)
290
282
  * `--` group separators and empty lines carry no path by construction and pass. The `:digits:` /
291
- * `-digits-` boundary family this used to reason about is gone with the guessing: both of #303's
292
- * declared residuals (over-tripping on a cluster inside match TEXT, and the dedup key folding two
293
- * denied files whose own names carry a cluster) were artifacts of that decision, not of the judge.
283
+ * `-digits-` boundary family a guessing parser would have to reason about is gone: both of its
284
+ * residuals (over-tripping on a cluster inside match TEXT, and the dedup key folding two denied files
285
+ * whose own names carry a cluster) were artifacts of that decision, not of the judge.
294
286
  */
295
287
  export declare function rgOutputDenyTripwire(stdout: string, mode: GrepOutputMode, judge: Pick<ReadDenyJudge, "matchPath">, opts?: {
296
288
  dropIncompleteTail?: boolean;
@@ -303,21 +295,21 @@ export declare function rgOutputDenyTripwire(stdout: string, mode: GrepOutputMod
303
295
  };
304
296
  /** ripgrep grep: build flags from params, run, normalize to the same output as {@link jsGrep}.
305
297
  * Result-fidelity contract: output ripgrep DID produce is never silently replaced by a fallback
306
- * rescan — partial results ship with a caveat; only a zero-output failure degrades to
298
+ * re-scan — partial results ship with a caveat; only a zero-output failure degrades to
307
299
  * {@link jsGrep}, and that degradation is declared in both text and structure. An external abort
308
300
  * propagates as the interruption it is (no fallback rerun). */
309
301
  export declare function rgGrepDetailed(env: ExecutionEnv, root: string, p: GrepParams, signal?: AbortSignal, deny?: ReadDenyJudge): Promise<GrepRunResult>;
310
- /** grep dispatch: ripgrep when the env has it, else the hardened JS fallback (design/64 §10.3).
302
+ /** grep dispatch: ripgrep when the env has it, else the hardened JS fallback.
311
303
  * Returns the degradation facts alongside the text so the tool layer can surface them structurally. */
312
304
  export declare function runGrepDetailed(env: ExecutionEnv, root: string, p: GrepParams, signal?: AbortSignal, deny?: ReadDenyJudge): Promise<GrepRunResult>;
313
305
  /** Text-only wrapper of {@link runGrepDetailed}. */
314
306
  export declare function runGrep(env: ExecutionEnv, root: string, p: GrepParams, signal?: AbortSignal): Promise<string>;
315
- /** glob: find files by name pattern, with optional sub-path scoping; returns RELATIVE paths (design/64 §10.4). */
307
+ /** glob: find files by name pattern, with optional sub-path scoping; returns RELATIVE paths. */
316
308
  export declare function runGlob(env: ExecutionEnv, root: string, pattern: string, opts?: {
317
309
  path?: string;
318
310
  max?: number;
319
311
  }, signal?: AbortSignal): Promise<string>;
320
- /** Structured sibling of {@link runGlob} (design/116 W3): same walk/match, plus the CC-shaped facts a
312
+ /** Structured sibling of {@link runGlob}: same walk/match, plus the CC-shaped facts a
321
313
  * shell renders (`filenames`/`numFiles`/`truncated`/`durationMs`/`totalMatches`/`countIsComplete`)
322
314
  * without re-parsing the text.
323
315
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sema-agent/core",
3
- "version": "7.15.0",
3
+ "version": "7.16.0",
4
4
  "description": "Stateless, task-oriented AI agent core",
5
5
  "type": "module",
6
6
  "license": "BUSL-1.1",
@@ -83,7 +83,10 @@
83
83
  "gate:tool-names": "node scripts/verify-tool-name-tables.mjs",
84
84
  "gate:tool-docs": "node scripts/gen-tool-spec-fields.mjs --check",
85
85
  "gate:backlog-ledger": "node scripts/verify-backlog-ledger.mjs",
86
- "gate:all": "node scripts/gate-all.mjs"
86
+ "gate:docs-tool-names": "node scripts/verify-docs-tool-names.mjs",
87
+ "gate:comment-ratio": "vitest run test/comment-ratio-ratchet.test.ts",
88
+ "gate:all": "node scripts/gate-all.mjs",
89
+ "car:gate": "node scripts/car-gate.mjs"
87
90
  },
88
91
  "dependencies": {
89
92
  "@modelcontextprotocol/sdk": "1.30.0",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "_comment": "design/87 L3 — frozen public export surface of src/index.ts (name -> kind). DO NOT edit by hand to silence a red test. A removed/changed entry = a SemVer-BREAKING change; bump MAJOR and update this fixture in the SAME commit (design/87 §4.2 / §5.2). Regenerate via REGEN in test/export-surface.test.ts.",
3
3
  "_tierComment": "#435 v1 — machine-readable layering of the public surface: stable = demonstrated by README.md / src/examples; internal = an `Internal`-marked name or a runner/engine deep-subtree declaration (the model seam src/engine/llm is excluded — it is the BYOM contract, not an engine internal); advanced = a supported export the front door does not walk you through. THIS IS AN INITIAL HEURISTIC, derived mechanically and expected to be refined ticket by ticket: no human reviewed these 1700+ entries one by one, and nothing here claims otherwise. Known bias: a short or English-word export name (ok, err, Result, Usage) can match ordinary prose in README.md and land `stable` on a coincidence. Every export MUST carry a tier — a new export with no row fails the gate in export-surface.test.ts.",
4
- "count": 2293,
4
+ "count": 2295,
5
5
  "exports": {
6
6
  "A2ATaskState": "type",
7
7
  "A2ATaskStateReversal": "type",
@@ -1885,6 +1885,7 @@
1885
1885
  "isInstructionEntry": "function",
1886
1886
  "isIsolated": "function",
1887
1887
  "isModelGatedForClass": "function",
1888
+ "isModelPriced": "function",
1888
1889
  "isNamespacedCoveringRuleName": "function",
1889
1890
  "isPeerDeliveryReceiptState": "function",
1890
1891
  "isPeerIdleNoticeKind": "function",
@@ -2293,6 +2294,7 @@
2293
2294
  "workflowWhenToUseText": "function",
2294
2295
  "workflowsCapability": "function",
2295
2296
  "worldStillMatchesMint": "function",
2297
+ "writableRootOf": "function",
2296
2298
  "writeRootAdoptionFile": "function",
2297
2299
  "writeThenLink": "function",
2298
2300
  "writerOf": "function"
@@ -4180,6 +4182,7 @@
4180
4182
  "isInstructionEntry": "advanced",
4181
4183
  "isIsolated": "advanced",
4182
4184
  "isModelGatedForClass": "advanced",
4185
+ "isModelPriced": "advanced",
4183
4186
  "isNamespacedCoveringRuleName": "advanced",
4184
4187
  "isPeerDeliveryReceiptState": "advanced",
4185
4188
  "isPeerIdleNoticeKind": "advanced",
@@ -4588,6 +4591,7 @@
4588
4591
  "workflowWhenToUseText": "advanced",
4589
4592
  "workflowsCapability": "advanced",
4590
4593
  "worldStillMatchesMint": "advanced",
4594
+ "writableRootOf": "advanced",
4591
4595
  "writeRootAdoptionFile": "advanced",
4592
4596
  "writeThenLink": "advanced",
4593
4597
  "writerOf": "advanced"