mirror of
https://github.com/Kaelio/ktx.git
synced 2026-07-04 10:52:13 +02:00
fix(ingest): honor storage.git.auto_commit and memory.auto_commit
Both documented flags were read only for status display; every ingest path squash-committed to main unconditionally, so setting either to false was a silent no-op (the reported symptom: 'Memory ingest (external_ingest): ...' commits despite memory.auto_commit: false). Gate the commit at the squash-merge onto main — the one point where ingest work becomes a permanent commit (intermediate session-worktree commits must still happen for the squash to collapse). When auto-commit is off, apply the squash to main's working tree and leave it staged instead of committing, so the run is never silently discarded: - GitService.stageSquashMergeIntoMain: shares the merge core with squashMergeIntoMain but stops before committing and returns the staged tree SHA (a valid diff/read ref). - memory.auto_commit gates MemoryAgentService (its DB writes are eager, so the staged files stay consistent); the commit-message job is skipped. - storage.git.auto_commit gates IngestBundleRunner; the wiki index is reconciled from the staged tree via the existing syncFromCommit (git diff/show accept a write-tree ref), and SL reindex already reads from files. Config descriptions now state precisely what each flag gates and the staged semantics when false.
This commit is contained in:
parent
1a6da14f62
commit
a02fcab487
15 changed files with 303 additions and 43 deletions
|
|
@ -2677,29 +2677,51 @@ export class IngestBundleRunner {
|
|||
throw error;
|
||||
}
|
||||
const commitMessage = this.buildCommitMessage(job, syncId, diffSummary, failedWorkUnits);
|
||||
// With auto-commit disabled, apply the run onto main's working tree and leave it staged
|
||||
// rather than committing. The wiki index is reconciled from the staged tree (a valid
|
||||
// diff/read ref), so search stays consistent with the staged files; only the git commit
|
||||
// and its message-enhancement job are skipped.
|
||||
const autoCommit = this.deps.storage.autoCommit;
|
||||
const squashResult = await this.deps.lockingService.withLock('config:repo', async () => {
|
||||
const preSquashSha = await this.deps.gitService.revParseHead();
|
||||
const merge = await this.deps.gitService.squashMergeIntoMain(
|
||||
sessionWorktree.branch,
|
||||
this.deps.storage.systemGitAuthor.name,
|
||||
this.deps.storage.systemGitAuthor.email,
|
||||
commitMessage,
|
||||
);
|
||||
return { preSquashSha, merge };
|
||||
if (autoCommit) {
|
||||
const merge = await this.deps.gitService.squashMergeIntoMain(
|
||||
sessionWorktree.branch,
|
||||
this.deps.storage.systemGitAuthor.name,
|
||||
this.deps.storage.systemGitAuthor.email,
|
||||
commitMessage,
|
||||
);
|
||||
return { preSquashSha, committed: true as const, merge };
|
||||
}
|
||||
const merge = await this.deps.gitService.stageSquashMergeIntoMain(sessionWorktree.branch);
|
||||
return { preSquashSha, committed: false as const, merge };
|
||||
});
|
||||
const mergeResult = squashResult.merge;
|
||||
if (!mergeResult.ok) {
|
||||
if (!squashResult.merge.ok) {
|
||||
await this.deps.runs.markFailed(runRow.id);
|
||||
throw new Error(`squash merge conflict: ${mergeResult.conflictPaths.join(', ')}`);
|
||||
throw new Error(`squash merge conflict: ${squashResult.merge.conflictPaths.join(', ')}`);
|
||||
}
|
||||
const touchedPaths = squashResult.merge.touchedPaths;
|
||||
const hasChanges = touchedPaths.length > 0;
|
||||
// `syncRef` is the tree-ish to diff/read when reconciling the wiki index: the new commit
|
||||
// SHA when committed, the staged tree SHA when staging. `commitSha` is only set when an
|
||||
// actual commit was created (it surfaces in the report and progress UI).
|
||||
let commitSha: string | null = null;
|
||||
let syncRef: string | null = null;
|
||||
if (hasChanges) {
|
||||
if (squashResult.committed) {
|
||||
commitSha = squashResult.merge.squashSha;
|
||||
syncRef = commitSha;
|
||||
} else {
|
||||
syncRef = squashResult.merge.stagedTree;
|
||||
}
|
||||
}
|
||||
const commitSha = mergeResult.touchedPaths.length === 0 ? null : mergeResult.squashSha;
|
||||
await runTrace.event(
|
||||
'debug',
|
||||
'squash',
|
||||
'squash_finished',
|
||||
{
|
||||
commitSha,
|
||||
touchedPaths: mergeResult.touchedPaths,
|
||||
touchedPaths,
|
||||
},
|
||||
undefined,
|
||||
Date.now() - squashStartedAt,
|
||||
|
|
@ -2714,18 +2736,28 @@ export class IngestBundleRunner {
|
|||
wikiCount: countMemoryFlowActions(memoryFlowSavedActions, 'wiki'),
|
||||
slCount: countMemoryFlowActions(memoryFlowSavedActions, 'sl'),
|
||||
});
|
||||
await stage6?.updateProgress(1.0, commitSha ? `Saved changes (${commitSha.slice(0, 8)})` : 'No changes to save');
|
||||
await stage6?.updateProgress(
|
||||
1.0,
|
||||
commitSha
|
||||
? `Saved changes (${commitSha.slice(0, 8)})`
|
||||
: hasChanges
|
||||
? 'Staged changes (auto-commit disabled)'
|
||||
: 'No changes to save',
|
||||
);
|
||||
|
||||
// Sync the shared `knowledge` index from the squashed diff in a single
|
||||
// transaction. If this throws, the run fails and no partial index state
|
||||
// survives (thanks to the transactional upsert in applyDiffTransactional).
|
||||
if (commitSha) {
|
||||
// `syncRef` is the new commit when committed, or the staged tree when staging.
|
||||
if (syncRef) {
|
||||
const indexSyncStartedAt = Date.now();
|
||||
// Multi-file squash → omit path so the handler diffs the whole commit
|
||||
// (a comma-joined pathspec would match nothing and the job would no-op).
|
||||
const pathFilter = mergeResult.touchedPaths.length === 1 ? mergeResult.touchedPaths[0] : '';
|
||||
await this.deps.commitMessages.enqueueForExternalCommit({ commitHash: commitSha }, commitMessage, pathFilter);
|
||||
await this.deps.wikiService.syncFromCommit(squashResult.preSquashSha, commitSha, runRow.id);
|
||||
const pathFilter = touchedPaths.length === 1 ? touchedPaths[0] : '';
|
||||
if (squashResult.committed) {
|
||||
await this.deps.commitMessages.enqueueForExternalCommit({ commitHash: syncRef }, commitMessage, pathFilter);
|
||||
}
|
||||
await this.deps.wikiService.syncFromCommit(squashResult.preSquashSha, syncRef, runRow.id);
|
||||
await this.syncKnowledgeSlRefsFromActions(job.connectionId, memoryFlowSavedActions);
|
||||
const touchedConnections = [
|
||||
...new Set(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue