@amalgm/shell 0.1.79 → 0.1.80

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.
@@ -2007,6 +2007,34 @@ function readGroundRowsForRoots(file, table, rootUUIDs) {
2007
2007
  database.close();
2008
2008
  }
2009
2009
  }
2010
+ /** Type and UUID settle locally even when immutable repository capture must
2011
+ * retry. Those rows are identity evidence for the next observation, while
2012
+ * their absence from the notebook still means no verified logical result has
2013
+ * been recorded. Normally this query is empty. */
2014
+ function readMaterializedRowsWithoutNotebook(file, rootUUIDs) {
2015
+ if (!existsSync(file) || rootUUIDs?.size === 0)
2016
+ return [];
2017
+ const database = initializeDatabase(file);
2018
+ try {
2019
+ const roots = rootUUIDs ? [...rootUUIDs] : [];
2020
+ const rootFilter = roots.length > 0
2021
+ ? `AND entities.root_uuid IN (${roots.map(() => "?").join(", ")})`
2022
+ : "";
2023
+ return database.prepare(`
2024
+ SELECT ${GROUND_ROW_PROJECTION}
2025
+ FROM entities
2026
+ WHERE NOT EXISTS (
2027
+ SELECT 1 FROM detection_notebook
2028
+ WHERE detection_notebook.uuid = entities.uuid
2029
+ )
2030
+ ${rootFilter}
2031
+ ORDER BY uuid
2032
+ `).all(...roots);
2033
+ }
2034
+ finally {
2035
+ database.close();
2036
+ }
2037
+ }
2010
2038
  function readGroundRootAtPath(file, table, absolutePath) {
2011
2039
  if (!existsSync(file))
2012
2040
  return null;
@@ -2820,10 +2848,13 @@ async function reconcileGround(input) {
2820
2848
  const notebook = selectedRoots
2821
2849
  ? readGroundRowsForRoots(database, "detection_notebook", selectedRoots)
2822
2850
  : readDetectionNotebook(database);
2823
- const existing = suspicions ? notebook : materialized;
2851
+ const unverifiedIdentity = suspicions
2852
+ ? readMaterializedRowsWithoutNotebook(database, selectedRoots ?? undefined)
2853
+ : [];
2854
+ const existing = suspicions ? [...notebook, ...unverifiedIdentity] : materialized;
2824
2855
  const notebookByUuid = new Map(notebook.map((row) => [row.uuid, row]));
2825
2856
  const materializedBaseline = suspicions
2826
- ? notebook.filter((row) => materializedUUIDs.has(row.uuid))
2857
+ ? existing.filter((row) => materializedUUIDs.has(row.uuid))
2827
2858
  : materialized;
2828
2859
  const materializedByUuid = new Map(materializedBaseline.map((row) => [row.uuid, row]));
2829
2860
  const materializedByRoot = new Map();
@@ -3031,8 +3062,9 @@ async function reconcileRoot(input) {
3031
3062
  evidence && (evidence.gitInspections += 1);
3032
3063
  try {
3033
3064
  // A Git metadata ring can arrive before the corresponding worktree
3034
- // ring. Git already knows every dirty tracked path, so those paths join
3035
- // this observation and Card + Checkpoint cannot carry stale identity.
3065
+ // ring. Git already knows every dirty tracked and untracked path, so
3066
+ // those paths join this observation and Card + Checkpoint cannot carry
3067
+ // stale identity.
3036
3068
  rootRepositoryEvidence = inspectGitRegistration(rootPath);
3037
3069
  }
3038
3070
  catch {
@@ -3059,6 +3091,7 @@ async function reconcileRoot(input) {
3059
3091
  : [...new Set([
3060
3092
  ...normalizedSuspects,
3061
3093
  ...rootRepositoryEvidence.dirtyPaths,
3094
+ ...rootRepositoryEvidence.untrackedPaths,
3062
3095
  ...changedTrackedPaths,
3063
3096
  ])].sort()
3064
3097
  : suspects;
@@ -3181,7 +3214,8 @@ async function reconcileRoot(input) {
3181
3214
  : null;
3182
3215
  const observe = forceObserve || existing === undefined
3183
3216
  || (repositoryPath !== null
3184
- && activeRepository?.evidence?.dirtyPaths.has(repositoryPath) === true)
3217
+ && (activeRepository?.evidence?.dirtyPaths.has(repositoryPath) === true
3218
+ || activeRepository?.evidence?.untrackedPaths.has(repositoryPath) === true))
3185
3219
  || (scanSuspects === null ? !stableDuringCompleteCatchUp : touchesSuspicion(relativePath));
3186
3220
  if (!observe && scanSuspects === null)
3187
3221
  evidence && (evidence.metadataReused += 1);
@@ -3195,7 +3229,10 @@ async function reconcileRoot(input) {
3195
3229
  // provide clean-index evidence, read current worktree bytes; Card +
3196
3230
  // Checkpoint capture below remains the transfer retry boundary.
3197
3231
  activeRepository.evidence = {
3198
- trackedPaths: new Set(), cleanLeaves: new Map(), dirtyPaths: new Set(),
3232
+ trackedPaths: new Set(),
3233
+ cleanLeaves: new Map(),
3234
+ dirtyPaths: new Set(),
3235
+ untrackedPaths: new Set(),
3199
3236
  };
3200
3237
  }
3201
3238
  }
@@ -3484,6 +3521,7 @@ async function reconcileRoot(input) {
3484
3521
  captured = captureRepository(repository.absolutePath, repoIdentity, prior, previousIdentity);
3485
3522
  const after = await refreshRepositoryIdentity();
3486
3523
  if (sameGitIdentity(after, repoIdentity)) {
3524
+ repoIdentity = [...captured.identity];
3487
3525
  coherent = true;
3488
3526
  break;
3489
3527
  }