Verlorene Updates erkennen statt warten: optimistische Pruefung beim Ersetzen, Konflikte im Audit und im Lagebild (#720)
FileLedger merkt je Agent die gelesene Fassung einer Datei in gemeinsamen Bereichen. write, copy und Downloads (FTP, RocketChat) ersetzen eine Datei nur, wenn sie seit dem Lesen unveraendert ist; eine fremde Datei nicht ungelesen. append bleibt ungeprueft, macht aeltere Lesestaende aber ungueltig. Abgelehnte Schreibvorgaenge: eigener Audit-Status Conflict, Tabelle FileConflicts, Hotspots (>= 3 in 7 Tagen) in der Teamuebersicht. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
8a7212c240
commit
79a3a7854f
@@ -317,10 +317,20 @@ public sealed class FTPTool : IAgentTool
|
||||
{
|
||||
var (localFull, wsLabel) = ResolveLocalPath(localRel, context, write: true);
|
||||
|
||||
// #720: a download over a shared file replaces it — not over a change this agent has not seen.
|
||||
var guarded = wsLabel != WorkspaceLayout.Personal && context.Files is not null;
|
||||
if (guarded && context.Files!.CheckReplace(context.AgentId, context.RunId, localFull, wsLabel, Core.Files.FileLedger.HashOf(localFull)) is { } conflict)
|
||||
{
|
||||
await context.Files.RecordAsync(conflict, ct);
|
||||
return ToolResult.Conflict(conflict.Message(localRel));
|
||||
}
|
||||
|
||||
var localDir = Path.GetDirectoryName(localFull);
|
||||
if (localDir != null && !Directory.Exists(localDir)) Directory.CreateDirectory(localDir);
|
||||
|
||||
var status = await client.DownloadFile(localFull, remote, FtpLocalExists.Overwrite, FtpVerify.None, null, ct);
|
||||
if (guarded && status == FtpStatus.Success)
|
||||
context.Files!.NoteReplace(context.AgentId, context.RunId, localFull, Core.Files.FileLedger.HashOf(localFull));
|
||||
return status == FtpStatus.Success
|
||||
? ToolResult.Ok($"[{wsLabel} Workspace] File successfully downloaded: {remote} → {localRel}")
|
||||
: ToolResult.Fail($"Download failed: {status}");
|
||||
|
||||
Reference in New Issue
Block a user