@rpamis/comet 0.4.0-beta.7 → 0.4.0-beta.9

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 (161) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +3 -3
  3. package/assets/manifest.json +1 -1
  4. package/assets/skills/comet/reference/comet-yaml-fields.md +2 -2
  5. package/assets/skills/comet/scripts/comet-entry-runtime.mjs +118 -6
  6. package/assets/skills/comet/scripts/comet-hook-router.mjs +244 -26
  7. package/assets/skills/comet/scripts/comet-runtime.mjs +221 -104
  8. package/assets/skills/comet-archive/SKILL.md +29 -20
  9. package/assets/skills/comet-native/SKILL.md +23 -15
  10. package/assets/skills/comet-native/reference/artifacts.md +19 -4
  11. package/assets/skills/comet-native/reference/commands.md +8 -2
  12. package/assets/skills/comet-native/reference/recovery.md +1 -1
  13. package/assets/skills/comet-native/scripts/comet-native-runtime.mjs +1136 -471
  14. package/assets/skills-zh/comet/reference/comet-yaml-fields.md +2 -2
  15. package/assets/skills-zh/comet-archive/SKILL.md +29 -20
  16. package/assets/skills-zh/comet-native/SKILL.md +23 -15
  17. package/assets/skills-zh/comet-native/reference/artifacts.md +20 -5
  18. package/assets/skills-zh/comet-native/reference/commands.md +8 -2
  19. package/assets/skills-zh/comet-native/reference/recovery.md +1 -1
  20. package/dist/app/commands/init.d.ts.map +1 -1
  21. package/dist/app/commands/init.js +3 -6
  22. package/dist/app/commands/init.js.map +1 -1
  23. package/dist/domains/bundle/bundle-platform.d.ts.map +1 -1
  24. package/dist/domains/bundle/bundle-platform.js +1 -1
  25. package/dist/domains/bundle/bundle-platform.js.map +1 -1
  26. package/dist/domains/comet-classic/classic-guard.d.ts.map +1 -1
  27. package/dist/domains/comet-classic/classic-guard.js +3 -2
  28. package/dist/domains/comet-classic/classic-guard.js.map +1 -1
  29. package/dist/domains/comet-entry/current-selection.d.ts.map +1 -1
  30. package/dist/domains/comet-entry/current-selection.js +6 -8
  31. package/dist/domains/comet-entry/current-selection.js.map +1 -1
  32. package/dist/domains/comet-entry/project-status.d.ts.map +1 -1
  33. package/dist/domains/comet-entry/project-status.js +5 -1
  34. package/dist/domains/comet-entry/project-status.js.map +1 -1
  35. package/dist/domains/comet-native/native-archive-transaction.d.ts.map +1 -1
  36. package/dist/domains/comet-native/native-archive-transaction.js +5 -6
  37. package/dist/domains/comet-native/native-archive-transaction.js.map +1 -1
  38. package/dist/domains/comet-native/native-atomic-file.d.ts.map +1 -1
  39. package/dist/domains/comet-native/native-atomic-file.js +11 -7
  40. package/dist/domains/comet-native/native-atomic-file.js.map +1 -1
  41. package/dist/domains/comet-native/native-bounded-file.d.ts.map +1 -1
  42. package/dist/domains/comet-native/native-bounded-file.js +11 -7
  43. package/dist/domains/comet-native/native-bounded-file.js.map +1 -1
  44. package/dist/domains/comet-native/native-build-evidence.js +2 -2
  45. package/dist/domains/comet-native/native-build-evidence.js.map +1 -1
  46. package/dist/domains/comet-native/native-change.d.ts +4 -2
  47. package/dist/domains/comet-native/native-change.d.ts.map +1 -1
  48. package/dist/domains/comet-native/native-change.js +18 -4
  49. package/dist/domains/comet-native/native-change.js.map +1 -1
  50. package/dist/domains/comet-native/native-check-receipt-storage.d.ts.map +1 -1
  51. package/dist/domains/comet-native/native-check-receipt-storage.js +11 -7
  52. package/dist/domains/comet-native/native-check-receipt-storage.js.map +1 -1
  53. package/dist/domains/comet-native/native-check-receipt.d.ts.map +1 -1
  54. package/dist/domains/comet-native/native-check-receipt.js +16 -11
  55. package/dist/domains/comet-native/native-check-receipt.js.map +1 -1
  56. package/dist/domains/comet-native/native-cli.d.ts.map +1 -1
  57. package/dist/domains/comet-native/native-cli.js +120 -16
  58. package/dist/domains/comet-native/native-cli.js.map +1 -1
  59. package/dist/domains/comet-native/native-config.d.ts +5 -1
  60. package/dist/domains/comet-native/native-config.d.ts.map +1 -1
  61. package/dist/domains/comet-native/native-config.js +78 -0
  62. package/dist/domains/comet-native/native-config.js.map +1 -1
  63. package/dist/domains/comet-native/native-continuation.d.ts +2 -1
  64. package/dist/domains/comet-native/native-continuation.d.ts.map +1 -1
  65. package/dist/domains/comet-native/native-continuation.js +13 -5
  66. package/dist/domains/comet-native/native-continuation.js.map +1 -1
  67. package/dist/domains/comet-native/native-diagnostics.d.ts +7 -3
  68. package/dist/domains/comet-native/native-diagnostics.d.ts.map +1 -1
  69. package/dist/domains/comet-native/native-diagnostics.js +19 -9
  70. package/dist/domains/comet-native/native-diagnostics.js.map +1 -1
  71. package/dist/domains/comet-native/native-evidence-retention.d.ts.map +1 -1
  72. package/dist/domains/comet-native/native-evidence-retention.js +5 -3
  73. package/dist/domains/comet-native/native-evidence-retention.js.map +1 -1
  74. package/dist/domains/comet-native/native-evidence-storage.d.ts.map +1 -1
  75. package/dist/domains/comet-native/native-evidence-storage.js +11 -7
  76. package/dist/domains/comet-native/native-evidence-storage.js.map +1 -1
  77. package/dist/domains/comet-native/native-file-identity.d.ts +3 -0
  78. package/dist/domains/comet-native/native-file-identity.d.ts.map +1 -0
  79. package/dist/domains/comet-native/native-file-identity.js +2 -0
  80. package/dist/domains/comet-native/native-file-identity.js.map +1 -0
  81. package/dist/domains/comet-native/native-findings.d.ts.map +1 -1
  82. package/dist/domains/comet-native/native-findings.js +19 -1
  83. package/dist/domains/comet-native/native-findings.js.map +1 -1
  84. package/dist/domains/comet-native/native-guards.d.ts +2 -1
  85. package/dist/domains/comet-native/native-guards.d.ts.map +1 -1
  86. package/dist/domains/comet-native/native-guards.js +14 -0
  87. package/dist/domains/comet-native/native-guards.js.map +1 -1
  88. package/dist/domains/comet-native/native-lock.d.ts.map +1 -1
  89. package/dist/domains/comet-native/native-lock.js +30 -35
  90. package/dist/domains/comet-native/native-lock.js.map +1 -1
  91. package/dist/domains/comet-native/native-protected-file.d.ts.map +1 -1
  92. package/dist/domains/comet-native/native-protected-file.js +9 -8
  93. package/dist/domains/comet-native/native-protected-file.js.map +1 -1
  94. package/dist/domains/comet-native/native-root-move.d.ts.map +1 -1
  95. package/dist/domains/comet-native/native-root-move.js +2 -0
  96. package/dist/domains/comet-native/native-root-move.js.map +1 -1
  97. package/dist/domains/comet-native/native-run-store.d.ts.map +1 -1
  98. package/dist/domains/comet-native/native-run-store.js +9 -8
  99. package/dist/domains/comet-native/native-run-store.js.map +1 -1
  100. package/dist/domains/comet-native/native-snapshot.d.ts +5 -1
  101. package/dist/domains/comet-native/native-snapshot.d.ts.map +1 -1
  102. package/dist/domains/comet-native/native-snapshot.js +225 -5
  103. package/dist/domains/comet-native/native-snapshot.js.map +1 -1
  104. package/dist/domains/comet-native/native-transitions.d.ts +2 -1
  105. package/dist/domains/comet-native/native-transitions.d.ts.map +1 -1
  106. package/dist/domains/comet-native/native-transitions.js +34 -11
  107. package/dist/domains/comet-native/native-transitions.js.map +1 -1
  108. package/dist/domains/comet-native/native-types.d.ts +16 -0
  109. package/dist/domains/comet-native/native-types.d.ts.map +1 -1
  110. package/dist/domains/comet-native/native-verification-runtime.d.ts.map +1 -1
  111. package/dist/domains/comet-native/native-verification-runtime.js +5 -3
  112. package/dist/domains/comet-native/native-verification-runtime.js.map +1 -1
  113. package/dist/domains/comet-native/native-verification-scope.d.ts +2 -1
  114. package/dist/domains/comet-native/native-verification-scope.d.ts.map +1 -1
  115. package/dist/domains/comet-native/native-verification-scope.js +6 -1
  116. package/dist/domains/comet-native/native-verification-scope.js.map +1 -1
  117. package/dist/domains/dashboard/native-collector.d.ts.map +1 -1
  118. package/dist/domains/dashboard/native-collector.js +4 -1
  119. package/dist/domains/dashboard/native-collector.js.map +1 -1
  120. package/dist/domains/dashboard/web/index.html +14 -14
  121. package/dist/domains/skill/platform-install.d.ts.map +1 -1
  122. package/dist/domains/skill/platform-install.js +9 -0
  123. package/dist/domains/skill/platform-install.js.map +1 -1
  124. package/dist/domains/skill/project-instructions.d.ts.map +1 -1
  125. package/dist/domains/skill/project-instructions.js +4 -2
  126. package/dist/domains/skill/project-instructions.js.map +1 -1
  127. package/dist/domains/workflow-contract/project-config.d.ts +1 -1
  128. package/dist/domains/workflow-contract/project-config.d.ts.map +1 -1
  129. package/dist/domains/workflow-contract/project-config.js +24 -2
  130. package/dist/domains/workflow-contract/project-config.js.map +1 -1
  131. package/dist/platform/fs/file-identity.d.ts +9 -0
  132. package/dist/platform/fs/file-identity.d.ts.map +1 -0
  133. package/dist/platform/fs/file-identity.js +21 -0
  134. package/dist/platform/fs/file-identity.js.map +1 -0
  135. package/dist/platform/fs/file-system.d.ts.map +1 -1
  136. package/dist/platform/fs/file-system.js +13 -9
  137. package/dist/platform/fs/file-system.js.map +1 -1
  138. package/dist/platform/fs/race-safe-read.d.ts +47 -0
  139. package/dist/platform/fs/race-safe-read.d.ts.map +1 -0
  140. package/dist/platform/fs/race-safe-read.js +132 -0
  141. package/dist/platform/fs/race-safe-read.js.map +1 -0
  142. package/eval/README.md +1 -1
  143. package/eval/local/tasks/comet-native-clarification-depth/environment/Dockerfile +27 -0
  144. package/eval/local/tasks/comet-native-clarification-depth/environment/test_wordcount.py +25 -0
  145. package/eval/local/tasks/comet-native-clarification-depth/environment/wordcount.py +36 -0
  146. package/eval/local/tasks/comet-native-clarification-depth/instruction.md +17 -0
  147. package/eval/local/tasks/comet-native-clarification-depth/task.toml +47 -0
  148. package/eval/local/tasks/comet-native-clarification-depth/validation/test_native_clarification_depth.py +618 -0
  149. package/eval/local/tasks/comet-native-clarification-modes/validation/test_native_clarification_modes.py +1 -1
  150. package/eval/local/tasks/index.yaml +6 -0
  151. package/eval/local/tests/conftest.py +146 -2
  152. package/eval/local/tests/scaffold/test_conftest_helpers.py +188 -1
  153. package/eval/local/tests/scaffold/test_tasks.py +440 -8
  154. package/eval/local/tests/scaffold/test_utils.py +114 -1
  155. package/eval/local/tests/tasks/test_tasks.py +2 -0
  156. package/eval/pyproject.toml +4 -4
  157. package/eval/scaffold/python/aligned_comparison.py +1 -0
  158. package/eval/scaffold/python/tasks.py +2 -0
  159. package/eval/scaffold/shell/docker.sh +1 -1
  160. package/eval/scaffold/shell/run-claude-loop.sh +25 -2
  161. package/package.json +8 -1
@@ -3,7 +3,9 @@ import { spawn } from 'node:child_process';
3
3
  import { promises as fs } from 'fs';
4
4
  import path from 'path';
5
5
  import { atomicWriteJson } from './native-atomic-file.js';
6
+ import { DEFAULT_NATIVE_SNAPSHOT_CONFIG, normalizeNativeSnapshotPattern, readProjectConfig, } from './native-config.js';
6
7
  import { sha256Text } from './native-hash.js';
8
+ import { hasComparableNativeFileObject, sameNativeFileObject } from './native-file-identity.js';
7
9
  import { isInsidePath, resolveContainedNativePath } from './native-paths.js';
8
10
  import { readNativeProtectedTextFile } from './native-protected-file.js';
9
11
  import { nativeSensitiveRelativePathReason } from './native-sensitive-paths.js';
@@ -27,8 +29,16 @@ const MANIFEST_KEYS = new Set([
27
29
  'omitted',
28
30
  'omittedCount',
29
31
  'omissionOverflow',
32
+ 'policy',
30
33
  ]);
31
- const LIMIT_KEYS = new Set(['maxFiles', 'maxFileBytes', 'maxTotalBytes', 'maxManifestBytes']);
34
+ const LIMIT_KEYS = new Set([
35
+ 'maxFiles',
36
+ 'maxFileBytes',
37
+ 'maxTotalBytes',
38
+ 'maxManifestBytes',
39
+ 'maxDurationMs',
40
+ ]);
41
+ const POLICY_KEYS = new Set(['schema', 'include', 'exclude', 'hash']);
32
42
  const CAPTURE_KEYS = new Set(['provider', 'gitSelection', 'physicalSelection', 'projection']);
33
43
  const GIT_PROJECTION_KEYS = new Set(['provider', 'selection']);
34
44
  const GIT_SELECTION_KEYS = new Set([
@@ -1026,6 +1036,157 @@ function isChangedDuringReadError(error) {
1026
1036
  function serializedManifestBytes(manifest) {
1027
1037
  return Buffer.byteLength(JSON.stringify(manifest, null, 2) + '\n');
1028
1038
  }
1039
+ function snapshotPolicyHash(include, exclude) {
1040
+ return sha256Text(`comet.native.snapshot-policy.v1\n${JSON.stringify({ include, exclude, hash: 'sha256' })}`);
1041
+ }
1042
+ function epsilonClosure(tokens, positions, checkpoint) {
1043
+ const closure = new Set(positions);
1044
+ const pending = [...positions];
1045
+ while (pending.length > 0) {
1046
+ if (checkpoint && !checkpoint())
1047
+ return null;
1048
+ const position = pending.pop();
1049
+ const token = tokens[position];
1050
+ if (token &&
1051
+ (token.kind === 'star' || token.kind === 'globstar' || token.kind === 'globstar-slash') &&
1052
+ !closure.has(position + 1)) {
1053
+ closure.add(position + 1);
1054
+ pending.push(position + 1);
1055
+ }
1056
+ }
1057
+ return closure;
1058
+ }
1059
+ function cooperativePatternCheckpoint(hasBudget) {
1060
+ let operationsUntilCheck = 0;
1061
+ return () => {
1062
+ if (operationsUntilCheck > 0) {
1063
+ operationsUntilCheck -= 1;
1064
+ return true;
1065
+ }
1066
+ if (!hasBudget())
1067
+ return false;
1068
+ operationsUntilCheck = 63;
1069
+ return true;
1070
+ };
1071
+ }
1072
+ export function compileNativeSnapshotPattern(pattern) {
1073
+ const normalized = normalizeNativeSnapshotPattern(pattern, 'Native snapshot pattern');
1074
+ const tokens = [];
1075
+ for (let index = 0; index < normalized.length; index += 1) {
1076
+ const character = normalized[index];
1077
+ if (character === '*' && normalized[index + 1] === '*') {
1078
+ index += 1;
1079
+ if (normalized[index + 1] === '/') {
1080
+ index += 1;
1081
+ tokens.push({ kind: 'globstar-slash' });
1082
+ }
1083
+ else {
1084
+ tokens.push({ kind: 'globstar' });
1085
+ }
1086
+ }
1087
+ else if (character === '*') {
1088
+ tokens.push({ kind: 'star' });
1089
+ }
1090
+ else if (character === '?') {
1091
+ tokens.push({ kind: 'question' });
1092
+ }
1093
+ else {
1094
+ tokens.push({ kind: 'literal', value: character });
1095
+ }
1096
+ }
1097
+ return (relative, hasBudget) => {
1098
+ const checkpoint = hasBudget ? cooperativePatternCheckpoint(hasBudget) : undefined;
1099
+ if (checkpoint && !checkpoint())
1100
+ return false;
1101
+ let positions = epsilonClosure(tokens, new Set([0]), checkpoint);
1102
+ if (positions === null)
1103
+ return false;
1104
+ for (const character of relative) {
1105
+ if (checkpoint && !checkpoint())
1106
+ return false;
1107
+ const next = new Set();
1108
+ for (const position of positions) {
1109
+ if (checkpoint && !checkpoint())
1110
+ return false;
1111
+ const token = tokens[position];
1112
+ if (!token)
1113
+ continue;
1114
+ if (token.kind === 'literal' && token.value === character) {
1115
+ next.add(position + 1);
1116
+ }
1117
+ else if (token.kind === 'question' && character !== '/') {
1118
+ next.add(position + 1);
1119
+ }
1120
+ else if (token.kind === 'star' && character !== '/') {
1121
+ next.add(position);
1122
+ }
1123
+ else if (token.kind === 'globstar') {
1124
+ next.add(position);
1125
+ }
1126
+ else if (token.kind === 'globstar-slash') {
1127
+ next.add(position);
1128
+ if (character === '/')
1129
+ next.add(position + 1);
1130
+ }
1131
+ }
1132
+ positions = epsilonClosure(tokens, next, checkpoint);
1133
+ if (positions === null)
1134
+ return false;
1135
+ if (positions.size === 0)
1136
+ return false;
1137
+ }
1138
+ return epsilonClosure(tokens, positions, checkpoint)?.has(tokens.length) ?? false;
1139
+ };
1140
+ }
1141
+ function resolveSnapshotPolicy(value) {
1142
+ if (value === undefined)
1143
+ return undefined;
1144
+ const include = [
1145
+ ...new Set(value.include.map((item) => normalizeNativeSnapshotPattern(item, 'include'))),
1146
+ ].sort((left, right) => left.localeCompare(right, 'en'));
1147
+ const exclude = [
1148
+ ...new Set(value.exclude.map((item) => normalizeNativeSnapshotPattern(item, 'exclude'))),
1149
+ ].sort((left, right) => left.localeCompare(right, 'en'));
1150
+ if (include.length === 0)
1151
+ throw new Error('Native snapshot policy include must not be empty');
1152
+ const hash = snapshotPolicyHash(include, exclude);
1153
+ if ('hash' in value && value.hash !== hash) {
1154
+ throw new Error('Native snapshot policy hash is invalid');
1155
+ }
1156
+ return {
1157
+ manifest: {
1158
+ schema: 'comet.native.snapshot-policy.v1',
1159
+ include,
1160
+ exclude,
1161
+ hash,
1162
+ },
1163
+ includeMatchers: include.map(compileNativeSnapshotPattern),
1164
+ excludeMatchers: exclude.map(compileNativeSnapshotPattern),
1165
+ };
1166
+ }
1167
+ function snapshotPolicyIncludes(policy, relative, execution) {
1168
+ if (!policy)
1169
+ return true;
1170
+ const hasBudget = () => nativeSnapshotExecutionHasBudget(execution);
1171
+ let included = false;
1172
+ for (const matcher of policy.includeMatchers) {
1173
+ if (!hasBudget())
1174
+ return false;
1175
+ if (matcher(relative, hasBudget)) {
1176
+ included = true;
1177
+ break;
1178
+ }
1179
+ }
1180
+ if (!included)
1181
+ return false;
1182
+ for (const matcher of policy.excludeMatchers) {
1183
+ if (!hasBudget())
1184
+ return false;
1185
+ if (matcher(relative, hasBudget))
1186
+ return false;
1187
+ }
1188
+ return true;
1189
+ }
1029
1190
  function foldSnapshotOverflowHash(previous, kind, value) {
1030
1191
  const payload = JSON.stringify(value);
1031
1192
  return sha256Text(`${previous}\n${Buffer.byteLength(kind)}:${kind}\n${Buffer.byteLength(payload)}:${payload}`);
@@ -1047,10 +1208,13 @@ function takeLastCompactableOmission(omissions) {
1047
1208
  return null;
1048
1209
  }
1049
1210
  function sameFileIdentity(left, right) {
1050
- if (left.dev !== 0 || left.ino !== 0 || right.dev !== 0 || right.ino !== 0) {
1051
- return left.dev === right.dev && left.ino === right.ino;
1211
+ const leftObject = { ...left, birthtime: left.birthtimeMs };
1212
+ const rightObject = { ...right, birthtime: right.birthtimeMs };
1213
+ if (hasComparableNativeFileObject(leftObject, rightObject)) {
1214
+ return sameNativeFileObject(leftObject, rightObject);
1052
1215
  }
1053
- return (left.birthtimeMs === right.birthtimeMs &&
1216
+ return (sameNativeFileObject(leftObject, rightObject) &&
1217
+ left.birthtimeMs === right.birthtimeMs &&
1054
1218
  left.ctimeMs === right.ctimeMs &&
1055
1219
  left.size === right.size);
1056
1220
  }
@@ -1399,7 +1563,29 @@ export function parseNativeContentSnapshotManifest(value) {
1399
1563
  maxFileBytes: positiveInteger(limitValue.maxFileBytes, 'Native snapshot maxFileBytes'),
1400
1564
  maxTotalBytes: positiveInteger(limitValue.maxTotalBytes, 'Native snapshot maxTotalBytes'),
1401
1565
  maxManifestBytes: positiveInteger(limitValue.maxManifestBytes, 'Native snapshot maxManifestBytes'),
1566
+ ...(limitValue.maxDurationMs === undefined
1567
+ ? {}
1568
+ : {
1569
+ maxDurationMs: positiveInteger(limitValue.maxDurationMs, 'Native snapshot maxDurationMs'),
1570
+ }),
1402
1571
  };
1572
+ let policy;
1573
+ if (manifest.policy !== undefined) {
1574
+ const policyValue = record(manifest.policy, 'Native snapshot policy');
1575
+ rejectUnknown(policyValue, POLICY_KEYS, 'Native snapshot policy');
1576
+ if (policyValue.schema !== 'comet.native.snapshot-policy.v1') {
1577
+ throw new Error('Native snapshot policy schema is invalid');
1578
+ }
1579
+ if (!Array.isArray(policyValue.include) || !Array.isArray(policyValue.exclude)) {
1580
+ throw new Error('Native snapshot policy patterns must be arrays');
1581
+ }
1582
+ policy = resolveSnapshotPolicy({
1583
+ include: policyValue.include,
1584
+ exclude: policyValue.exclude,
1585
+ hash: policyValue.hash,
1586
+ schema: 'comet.native.snapshot-policy.v1',
1587
+ }).manifest;
1588
+ }
1403
1589
  if (!Array.isArray(manifest.entries) || !Array.isArray(manifest.omitted)) {
1404
1590
  throw new Error('Native content snapshot entries and omissions must be arrays');
1405
1591
  }
@@ -1476,6 +1662,7 @@ export function parseNativeContentSnapshotManifest(value) {
1476
1662
  createdAt: manifest.createdAt,
1477
1663
  complete: manifest.complete,
1478
1664
  limits,
1665
+ ...(policy ? { policy } : {}),
1479
1666
  entries,
1480
1667
  omitted,
1481
1668
  omittedCount,
@@ -1615,13 +1802,20 @@ export function nativeBaselineManifestFile(paths, name) {
1615
1802
  return path.join(changeDir, 'runtime', 'baseline-manifest.json');
1616
1803
  }
1617
1804
  export async function createNativeContentSnapshot(paths, options = {}) {
1618
- const execution = createNativeSnapshotExecution(options);
1619
1805
  const limits = {
1620
1806
  maxFiles: options.limits?.maxFiles ?? DEFAULT_NATIVE_SNAPSHOT_LIMITS.maxFiles,
1621
1807
  maxFileBytes: options.limits?.maxFileBytes ?? DEFAULT_NATIVE_SNAPSHOT_LIMITS.maxFileBytes,
1622
1808
  maxTotalBytes: options.limits?.maxTotalBytes ?? DEFAULT_NATIVE_SNAPSHOT_LIMITS.maxTotalBytes,
1623
1809
  maxManifestBytes: options.limits?.maxManifestBytes ?? DEFAULT_NATIVE_SNAPSHOT_LIMITS.maxManifestBytes,
1810
+ ...(options.limits?.maxDurationMs === undefined
1811
+ ? {}
1812
+ : { maxDurationMs: options.limits.maxDurationMs }),
1624
1813
  };
1814
+ const policy = resolveSnapshotPolicy(options.policy);
1815
+ const execution = createNativeSnapshotExecution({
1816
+ ...options,
1817
+ deadlineMs: options.deadlineMs ?? limits.maxDurationMs,
1818
+ });
1625
1819
  const gitSelectionLimits = resolveNativeGitSelectionLimits(options.gitSelectionLimits);
1626
1820
  const physicalSelectionLimits = resolveNativePhysicalSelectionLimits(options.physicalSelectionLimits);
1627
1821
  if (limits.maxFiles < 1 ||
@@ -2049,6 +2243,10 @@ export async function createNativeContentSnapshot(paths, options = {}) {
2049
2243
  continue;
2050
2244
  if (remainingNativeSnapshotTime(execution) < 1)
2051
2245
  break;
2246
+ if (!snapshotPolicyIncludes(policy, record.path, execution))
2247
+ continue;
2248
+ if (remainingNativeSnapshotTime(execution) < 1)
2249
+ break;
2052
2250
  const target = path.resolve(projectRoot, ...record.path.split('/'));
2053
2251
  let stat;
2054
2252
  try {
@@ -2112,6 +2310,12 @@ export async function createNativeContentSnapshot(paths, options = {}) {
2112
2310
  for (const relative of selectionPaths(gitSelection)) {
2113
2311
  if (!isSnapshotProjectRef(paths, relative))
2114
2312
  continue;
2313
+ if (remainingNativeSnapshotTime(execution) < 1)
2314
+ break;
2315
+ if (!snapshotPolicyIncludes(policy, relative, execution))
2316
+ continue;
2317
+ if (remainingNativeSnapshotTime(execution) < 1)
2318
+ break;
2115
2319
  const target = path.resolve(projectRoot, ...relative.split('/'));
2116
2320
  if (target === configFile ||
2117
2321
  target === selectionFile ||
@@ -2243,6 +2447,7 @@ export async function createNativeContentSnapshot(paths, options = {}) {
2243
2447
  createdAt: (options.now ?? new Date()).toISOString(),
2244
2448
  complete: omittedCount === 0,
2245
2449
  limits,
2450
+ ...(policy ? { policy: policy.manifest } : {}),
2246
2451
  entries,
2247
2452
  omitted,
2248
2453
  omittedCount,
@@ -2282,6 +2487,21 @@ export async function createNativeContentSnapshot(paths, options = {}) {
2282
2487
  }
2283
2488
  return manifest;
2284
2489
  }
2490
+ export async function createNativeCurrentContentSnapshot(paths, baseline, options = {}) {
2491
+ const config = await readProjectConfig(paths.projectRoot);
2492
+ const settings = config?.native.snapshot ?? DEFAULT_NATIVE_SNAPSHOT_CONFIG;
2493
+ return createNativeContentSnapshot(paths, {
2494
+ ...options,
2495
+ policy: baseline.policy,
2496
+ limits: {
2497
+ maxFiles: settings.max_files,
2498
+ maxFileBytes: settings.max_total_bytes,
2499
+ maxTotalBytes: settings.max_total_bytes,
2500
+ maxDurationMs: settings.max_duration_ms,
2501
+ },
2502
+ deadlineMs: settings.max_duration_ms,
2503
+ });
2504
+ }
2285
2505
  export async function writeNativeBaselineManifest(paths, name, manifest) {
2286
2506
  const file = nativeBaselineManifestFile(paths, name);
2287
2507
  await resolveContainedNativePath(paths.nativeRoot, file);