Skip to content

agent: #13 [Agent] Kapitel teilen, zusammenführen und archivieren - #23

Merged
leonatwork merged 1 commit into
mainfrom
agent/bearbeite-github-issue-13-vollst-ndig-un-1020-1327
Oct 21, 2026
Merged

leonatwork merged 1 commit into
mainfrom
agent/bearbeite-github-issue-13-vollst-ndig-un-1020-1327

Conversation

@leonatwork

@leonatwork leonatwork commented Oct 20, 2026 •

Copy link
Copy Markdown
Owner

Zusammenfassung

Autonome Umsetzung von #13: [Agent] Kapitel teilen, zusammenführen und archivieren

Verifikation

  • Coder-/Reviewer-Loop: APPROVE nach 1 Runde(n)

  • Tests und Qualitätsprüfungen: siehe Commit und CI-Checks

  • Kein automatischer Merge oder Produktionsdeploy

  • Modell: azure/gpt-6.1-sol; Decision-1 (active): route gpt-5.3-codex, Risiko high; QS: npm run build && npm test bestanden

  • Art der Änderung (Triage): code; Zweitprüfung: azure/gpt-5.3-codex

  • Kosten (Listenpreis): 7,6 Mio Tokens · 2,13 €

Hinweise der Qualitätsprüfung

  • Review-Hinweis (minor: src/state/store.ts:972: neueId gilt für alle Arten von Einträgen, nicht nur für Kapitel. Es nimmt jetzt immer reservierteKapitelIds und die Archiv-IDs als belegt dazu, auch wenn eine Figur, ein Ort, eine Idee, eine Notiz oder ein Rechercheeintrag angelegt wird. Folge: Eine neue Figur „Flut“ bekommt flut-2, obwohl die ID für Figuren frei ist. Vorschlag: Reservierte IDs nur an den Kapitel-Aufrufstellen dazunehmen (planung.ts:447/548, schreiben.ts:136, importexport.ts:101) oder in einer eigenen neueKapitelId bündeln.)
  • Review-Hinweis (minor: core/projekt/archiv.ts:76: roh.map(h => h.zitate?.some(...)) setzt voraus, dass jeder Eintrag ein Objekt ist und zitate ein Array. Ein von Hand bearbeiteter Eintrag in hinweise.json (null oder zitate als String) wirft einen TypeError. Das Journal setzt dann zwar sauber zurück, aber das Archivieren ist blockiert und die Meldung ist nicht übersetzt. Ähnlich bei Zeile 72: Ist eine Analyse-Datei kaputt, wirft JSON.parse einen rohen SyntaxError. Vorschlag: Mit istObjekt und Array.isArray absichern. Bei kaputter Analyse entweder ungueltig() werfen oder die Datei unverändert lasse)
  • Review-Hinweis (minor: src/state/store.ts:303-342: Das Sperr-Flag umbaut blockiert nur speichereKapitel, speicherePlan, speichereProjekt und entferneKapitel. speichereKiHinweise und speichereAnalysen laufen weiter, zum Beispiel wenn eine KI-Prüfung gleichzeitig fertig wird. Dann kann hinweise.json zwischen dem Lesen und dem Schreiben in archiv.ts geändert werden, und eine Änderung geht verloren oder wird beim Zurücksetzen überschrieben. Vorschlag: Archivieren sperren, solange kiLauf läuft, oder auch diese beiden Speicherwege in umbaut prüfen.)
  • Review-Hinweis (minor: src/features/schreiben/KapitelListe.tsx:101 und src/features/akte/KapitelInspektor.tsx:202,350: Beide zeigen jeden speichern.fehler als role="alert" an, auch Speicherfehler ohne Bezug zum Archiv. Dieselbe Meldung kann so doppelt neben der globalen Anzeige erscheinen. Vorschlag: Nur den Fehler aus der Archivaktion anzeigen (eigenes Feld oder Abgleich mit letzterArchivFehler).)
  • Review-Hinweis (minor: src/features/schreiben/KapitelListe.tsx:88-100: Der Archivbereich ist ein natives <details>/<summary>, und alle Buttons nutzen die Klasse pw-s-kapitel__neu. In docs/design/screens gibt es dafür keine Vorlage. Für die manuelle Abnahme auf dem Mac sollte Leon das Aussehen bestätigen (kein Blocker, die Funktion ist erfüllt).)
  • Review-Hinweis (minor: core/projekt/archiv.ts:76 und core/index/index.ts:163: Hinweise, die mehrere Kapitel betreffen und ein archiviertes Kapitel zitieren, werden als veraltet markiert. Sie bleiben auch nach dem Wiederherstellen dauerhaft ausgeblendet, bis eine neue KI-Prüfung sie wieder erzeugt. Das ist in docs/architektur.md dokumentiert und mit AC-6 vereinbar. Für Autorinnen ist es aber überraschend, dass Hinweise zu nicht archivierten Kapiteln verschwinden. Leon sollte das im PR ausdrücklich bestätigen.)
  • Review-Hinweis (minor: docs/issue-13-handover.md: Der Handover sagt selbst, dass der Live-Thread des Issues und die offenen PRs nicht geprüft wurden, weil gh verweigert wurde. Das muss vor dem PR nachgeholt werden. Die Datei sollte außerdem eher in die PR-Beschreibung als ins Repo.)
  • Review-Hinweis (minor: core/projekt/archiv.ts:79 — h.zitate?.some(...) greift auf h ohne Objekt-Guard zu; bei null-Einträgen in .plotwerk/hinweise.json kann die Archiv-Aktion mit TypeError abbrechen. Konkreter Fix: vor dem Zugriff istObjekt(h) prüfen (oder h?.zitate) und nur dann veraltet setzen.)

Closes #13


Note

Medium Risk
Mehrdatei-Persistenz mit Rollback und neuem Projektformat; Fehler- und Nebenläufer-Pfade (z. B. parallele KI-Speicherung, globale ID-Reservierung) können Randfälle betreffen, sind aber durch Core-, UI- und Abnahmetests abgedeckt.

Overview
Issue #13 (nur Archivieren/Wiederherstellen) führt ein Kapitelarchiv ein: Aktive Manuskript- und Plandateien wandern nach archiv/, werden aus projekt.md entfernt und als ProjektDaten.archiv geladen, ohne Export, KI-Kontext oder aktive Kapitelliste.

Vor jeder Aktion legt core/projekt/archiv.ts neue Schnappschüsse an, verschiebt Dateien bytegenau, aktualisiert archiv/index.json (IDs und Reihenfolge) und setzt bei Fehlern per Änderungsjournal zurück. Betroffene KI-Analysen und Hinweise bleiben erhalten, erhalten veraltet: true und fließen nicht mehr in Index, Hinweisliste oder Analyse-Cache ein.

Der Store exponiert kapitelArchivieren / kapitelWiederherstellen (mit Sperre während des Umbaus); die Schreib-UI und der Akte-Inspektor bieten Archivbefehle, eine Archivliste und einen read-only Archiv-Inspektor; Verweise auf archivierte Kapitel öffnen dort und zeigen „archiviert“. neueId reserviert Archiv-IDs global; Archiv-Umbaut zählen nicht als Schreibstatistik.

Reviewed by Cursor Bugbot for commit c6ff194. Bugbot is set up for automated code reviews on this repo. Configure here.

…bare Lösung.

Lies zuerst den vollständigen Issue-Thread inklusive aller Kommentare, CLAUDE.md und die relevanten Repository-Regeln. Prüfe vorhandene PRs und aktuellen Code, bevor du Änderungen machst. Leite die verbindlichen Akzeptanzkriterien aus dem Issue ab und dokumentiere nicht erfüllbare oder widersprüchliche Kriterien klar.

Arbeite testgetrieben: Erzeuge Regressionstests, verifiziere ihr korrektes Fehlschlagen vor dem Fix und führe danach die relevanten Tests sowie die vorgeschriebenen Qualitätsprüfungen aus. Ändere nur, was für das Issue erforderlich ist. Arbeite ausschließlich auf dem ausgecheckten Stand von origin/main: checke keine Branches fremder offener PRs aus, cherry-picke nichts daraus und baue nicht auf ihnen auf. Hängt die Lösung von einem noch offenen PR ab, liefere nur deinen eigenen Anteil und dokumentiere die Abhängigkeit im Handover. Keine Produktionsdeployments, keine Änderungen an Produktionsdaten oder Produktions-Supabase und kein --prod. Merge den PR nicht.

Issue: #13
Titel: [Agent] Kapitel teilen, zusammenführen und archivieren

Beschreibung:
<!-- hermes-agent-form-v1:start -->
## Ziel und Nutzen
Autorinnen sollen Kapitel mit Text archivieren und wiederherstellen können, ohne Text, Plan oder Notizen zu verlieren. Das ist Paket 1 des Umbau-Issues.

## Ist-Zustand / Problem
Entfernen geht nur für geplante Kapitel ohne Text (geplantesKapitelEntfernen, planung.ts:475). entferneKapitel (store.ts:755) löscht Dateien ohne Schnappschuss und ohne Archiv. Ein archiv/-Ordner existiert nicht.

## Umfang (In Scope)
- Archivieren und Wiederherstellen von Kapiteln mit Text, Plan und Notizen über archiv/
- Schnappschuss vor jeder Aktion (E8), Abbruch ohne Änderung bei Fehler
- Archivierte Kapitel aus Kapitelliste, Export und KI-Kontext ausschließen
- Befehle in Kapitelliste und Kapitel-Inspektor, i18n DE/EN
- Reine Funktionen in core/ mit Vitest gegen MemoryFs mit Demo-Projekt, Akzeptanztest
- Ergänzung von archiv/ im Projektformat in docs/architektur.md

## Nicht Teil dieses Issues (Out of Scope)
- Endgültiges Löschen von Kapiteln mit Text
- Zusammenführen (Paket 2) und Teilen (Paket 3), eigene PRs danach
- Teilen und Zusammenführen von Akten
- KI-Analysen neu berechnen
- Änderungen am Datenmodell außer additiven Feldern

## Fachliche und UX-Entscheidungen
- Aufteilung in 3 PRs: Archiv, Zusammenführen, Teilen (Leon: 1A)
- Archivort ist der Projektordner archiv/, nicht der macOS-Papierkorb (Leon: 2A)
- KI-Analysen und Hinweise bleiben erhalten und werden als veraltet markiert (Leon: 3A)
- E1: IDs bleiben stabil und werden nie doppelt vergeben
- Annahme: Verlinkte archivierte Kapitel bleiben auflösbar oder erscheinen als 'archiviert'
- Offen: Umsetzung der Veraltet-Markierung für Hinweise (.plotwerk/hinweise.json) legt der Agent im Code fest, ohne Datenmodell-Brüche

## Prüfbare Akzeptanzkriterien
- AC-1: Archivieren eines Kapitels mit Text verschiebt Manuskript- und Plandatei nach archiv/ und entfernt es aus projekt.md → kapitel. Text, Plan und Notizen bleiben unverändert erhalten.
- AC-2: Vor dem Archivieren und vor dem Wiederherstellen liegt ein neuer Schnappschuss des betroffenen Kapitels in .versionen/.
- AC-3: Ein archiviertes Kapitel taucht nicht mehr in Kapitelliste, Export und KI-Kontext auf.
- AC-4: Wiederherstellen setzt das Kapitel mit Text, Plan und Notizen an seine alte Position in der Reihenfolge zurück. Die ID bleibt gleich und wird nie doppelt vergeben.
- AC-5: Schlägt der Schnappschuss fehl, bleiben alle Dateien unverändert, und eine Meldung erscheint in DE und EN.
- AC-6: KI-Analysen und Hinweise zu einem archivierten Kapitel bleiben erhalten und werden als veraltet behandelt.
- AC-7: Kapitelliste und Kapitel-Inspektor bieten Archivieren und Wiederherstellen an (Texte in src/i18n/de und src/i18n/en), und archiv/ ist in docs/architektur.md ergänzt.
- AC-8: npm test, npm run typecheck und npm run build sind grün. Die Funktionen werden mit Vitest in core/ gegen MemoryFs mit dem Demo-Projekt getestet, und ein Akzeptanztest in abnahme/akzeptanz.test.tsx deckt AC-1 bis AC-6 ab.

## QS und Nachweis
- Vitest in core/ für Archivieren, Wiederherstellen, Schnappschüsse, ID-Stabilität und Fehlerpfad
- UI-Tests für die Befehle in Kapitelliste und Inspektor
- Akzeptanztest in abnahme/akzeptanz.test.tsx
- npm test, npm run typecheck, npm run build und npm run sperrliste grün
- Manuell auf dem Mac: Archivieren und Wiederherstellen im Demo-Projekt, Dateien in Obsidian prüfen

## Offene Fragen
–

_Automatisch nach dem Formular „Agent-Auftrag“ strukturiert (Hermes-Triage). Die ursprüngliche Beschreibung steht unten unverändert._
<!-- hermes-agent-form-v1:end -->

<details><summary>Ursprüngliche Beschreibung</summary>

<!-- hermes-original:start -->
### Ziel und Nutzen

Als Autorin möchte ich ein Kapitel an einer Stelle teilen, zwei Kapitel zusammenführen und ein Kapitel mit Text archivieren, damit ich die Struktur des Buchs umbauen kann, ohne Text von Hand zu kopieren und ohne Notizen oder Planung zu verlieren.

### Ist-Zustand / Problem

- Entfernen geht nur für geplante Kapitel ohne Text. `geplantesKapitelEntfernen` wirft bei Text einen Fehler (`src/state/slices/planung.ts:475-481`, Meldung „Kapitel mit Text werden hier nicht gelöscht.“ in `src/i18n/de/state.ts:17`).
- `entferneKapitel` löscht Manuskript- und Plandatei ohne Schnappschuss und ohne Archiv (`src/state/store.ts:755-769`).
- Teilen und Zusammenführen gibt es nicht. Nur Figuren lassen sich zusammenführen (`src/state/store.ts:805`).
- Szenen hängen über `Szene.index` an den Abschnitten zwischen `* * *` (`core/model/types.ts:714-730`). Teilen oder Zusammenführen verschiebt diese Indizes.
- Notizen und andere Stellen hängen per `TextAnker` mit Kapitel-ID am Text (`core/model/types.ts:306-313`, Anmerkung `:323-334`). Finden und Erzeugen: `ankerFinden` und `ankerErzeugen` (`core/text/index.ts:410,491`).

### Umfang (In Scope)

- **Teilen** an der Cursorposition (bevorzugt an einem Absatz- oder Szenenwechsel): Der Text davor bleibt im Kapitel, der Rest wird ein neues Kapitel direkt dahinter. Titel vorgeschlagen, änderbar.
- **Zusammenführen** zweier benachbarter Kapitel: Der Text des zweiten wird an das erste angehängt, getrennt durch einen Szenentrenner `* * *` (E3). Das zweite Kapitel wird archiviert.
- **Archivieren**: Ein Kapitel mit Text wird mit Manuskript- und Plandatei nach `archiv/` verschoben und aus `projekt.md → kapitel` entfernt. Es lässt sich wiederherstellen und landet dann wieder in der Reihenfolge.
- Vor jeder dieser Aktionen einen Schnappschuss aller betroffenen Kapitel anlegen (E8).
- Notizen und Anker wandern mit: Anker, deren Stelle nach dem Teilen im neuen Kapitel liegt, bekommen die neue Kapitel-ID. Gilt für Anmerkungen und alle anderen Daten mit `TextAnker`.
- Szenen des Kapitelplans werden nach den neuen Abschnitten neu zugeordnet (`index`, `kapitel`), Szenen-IDs bleiben.
- Befehle in der Kapitelliste und im Kapitel-Inspektor, Texte in `src/i18n/{de,en}`.
- Die Umbau-Logik als reine Funktionen in `core/` mit Tests.

### Nicht Teil dieses Issues (Out of Scope)

- Endgültiges Löschen von Kapiteln mit Text.
- Mehr als zwei Kapitel in einem Schritt zusammenführen.
- Teilen und Zusammenführen von Akten.
- KI-Analysen neu berechnen (sie bleiben, siehe Offen).
- Änderungen am Datenmodell außer additiven Feldern (`core/model/types.ts` nur additiv).

### Fachliche und UX-Entscheidungen

- Geklärt (Code): E1: IDs bleiben stabil. Beim Teilen behält der erste Teil die alte ID, der zweite bekommt eine neue ID über das bestehende Verfahren (`neueId`, wie beim Import in `src/state/slices/importexport.ts:101`). Beim Zusammenführen behält das erste Kapitel seine ID. Das zweite wird archiviert, seine ID wird nicht wiederverwendet.
- Geklärt (Code): E4: Ein Anker, der sich nach dem Umbau nicht mehr eindeutig finden lässt, wird „verwaist“, nie still falsch.
- Geklärt (Code): E7: Teilen und Zusammenführen ändern keinen Text außer dem eingefügten Trenner `* * *`.
- Annahme: Der Kapitelplan des ersten Kapitels bleibt beim ersten Teil. Der zweite Teil bekommt einen Standardplan (`standardPlan`) mit den Szenen, die zu ihm gewandert sind.
- Annahme: Akt-Zuordnung (`KapitelPlan.akt`) übernimmt der neue Teil vom Original.
- Annahme: Teilen und Zusammenführen zählen nicht als geschriebene Wörter (Zählregel `docs/architektur.md:85-90`).
- Annahme: Ein Kapitel, das in einem anderen Datensatz noch verlinkt ist (Verweise, Fäden, Zeitleiste), bleibt nach dem Archivieren auflösbar oder wird als „archiviert“ angezeigt, nicht als fehlend.
- Fehlerfall: Schlägt ein Schnappschuss fehl, bricht die Aktion ab, ohne etwas zu ändern.
- Offen (Leon): Ein eigener Ordner `archiv/` im Projekt oder der Papierkorb von macOS?
- Offen (Leon): Was passiert mit KI-Analysen und Hinweisen zur alten ID (`.plotwerk/analysen/<id>.json`, `.plotwerk/hinweise.json`)? Behalten und als veraltet markieren, mitarchivieren oder verwerfen?

### Prüfbare Akzeptanzkriterien

AC-1: Wenn ich ein Kapitel am Cursor teile, dann enthält es danach nur den Text davor, und direkt dahinter steht ein neues Kapitel mit dem Rest. Beide Texte zusammen ergeben den alten Text.
AC-2: Eine Notiz, deren Stelle im zweiten Teil liegt, hängt danach am neuen Kapitel und markiert dieselbe Stelle.
AC-3: Szenen des geteilten Kapitels stehen danach im richtigen Kapitel mit passendem `index`. Ihre IDs sind unverändert.
AC-4: Wenn ich zwei Kapitel zusammenführe, dann steht der Text des zweiten nach einem `* * *` am Ende des ersten, und das zweite Kapitel ist archiviert.
AC-5: Vor jedem Teilen, Zusammenführen und Archivieren liegt ein neuer Schnappschuss jedes betroffenen Kapitels in `.versionen/`.
AC-6: Ein archiviertes Kapitel taucht nicht mehr in Kapitelliste, Export und KI-Kontext auf. Nach dem Wiederherstellen ist es mit Text, Plan und Notizen wieder da.
AC-7: Die alte ID des ersten Kapitels bleibt in allen Fällen erhalten. Keine ID wird doppelt vergeben.
AC-8: Fehlerfall: Schlägt der Schnappschuss fehl, bleiben alle Dateien unverändert, und eine Meldung erscheint in DE und EN.

### QS und Nachweis

- Agent: Vitest in `core/` für Teilen, Zusammenführen und Archivieren gegen `MemoryFs` mit dem Demo-Projekt: Textsumme, Anker-Umzug, Szenen-Index, ID-Stabilität, Schnappschüsse, Fehlerpfad. UI-Tests für die Befehle in Kapitelliste und Inspektor. `npm test`, `npm run typecheck` und `npm run build` grün. Der Agent-Server ist Linux und kann die Mac-App nicht bauen.
- Manuell auf dem Mac: Kapitel mit Notizen und Szenen im Demo-Projekt teilen, wieder zusammenführen, archivieren und wiederherstellen. Danach in Obsidian prüfen, dass die Dateien lesbar sind.

### Technischer Kontext und Referenzen

- Relevante Dateien: `src/state/slices/planung.ts`, `src/state/store.ts`, `core/model/types.ts` (`Szene`, `TextAnker`, `Anmerkung`, `KapitelPlan`), `core/text/index.ts` (Anker), `core/projekt/lesen.ts` und `core/projekt/schreiben.ts`, `src/features/schreiben/KapitelListe.tsx`, `src/features/akte/KapitelInspektor.tsx`.
- Architektur: E1, E3, E4, E7, E8 in `docs/architektur.md`. Das Projektformat in `docs/architektur.md` wird um `archiv/` ergänzt, falls Leon den Ordner wählt.
- Verwandt: Issue zu „Suchen und Ersetzen im ganzen Projekt“ (gleiche Schnappschuss-Logik).

### Sicherheits- und Liefergrenzen

- [X] Das Issue enthält keine Secrets, Tokens, Zugangsdaten oder vertraulichen Manuskript- und Kundendaten.
- [X] Der Agent darf Code und Tests ändern sowie einen Draft-PR öffnen, aber nicht selbst mergen, releasen oder deployen.
- [X] Änderungen an produktiver Infrastruktur oder veröffentlichten Releases sind nicht Teil dieses Auftrags.

_Angelegt von Claude Code im Auftrag von @leonatwork auf Basis einer Code-Analyse (Stand 2026-10-20)._
<!-- hermes-original:end -->

</details>

Zusätzliche Repo-Regeln:
Commits tragen ein DCO-Sign-off (das macht dev-loop automatisch). Auf diesem Server gibt es kein Rust/Tauri: nur TypeScript-Teil (core/, src/) mit npm run build und npm test prüfen, src-tauri nicht bauen. Keine Inhalte aus privaten Manuskripten; Beispiele nur aus fixtures/. Farben nur über Tokens in src/theme/tokens.css, UI nach docs/design/screens, core/ bleibt reines TypeScript, core/ki nutzt nur ProjektLeser.

Reviewer verdict: APPROVE after 1 round(s). Generated by dev-loop (not pushed).

Signed-off-by: leonatwork <leon.11@live.de>
@leonatwork
leonatwork marked this pull request as ready for review October 21, 2026 09:21

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 5 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit c6ff194. Configure here.

if ((v.typ === 'kapitel' || v.typ === 'plan') && store.daten?.archiv?.[v.id]) {
store.oeffne('akte', { plan: v.id });
return;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Archived chapter links open editor

Medium Severity

verweisOeffnen only routes archived chapters to the archive inspector when store.daten is present, but the live click handler passes { oeffne } alone. Clicks on archived kapitel or plan links therefore open the write view, which then falls back to another active chapter.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit c6ff194. Configure here.

Comment thread src/state/store.ts
},

neueId: (titel, vorhandene) => erzeugeId(titel, vorhandene),
neueId: (titel, vorhandene) => erzeugeId(titel, [...vorhandene, ...(get().daten?.reservierteKapitelIds ?? []), ...Object.keys(get().daten?.archiv ?? {})]),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Archive IDs leak across types

Medium Severity

neueId now always treats reservierteKapitelIds and archive keys as taken. Those lists are chapter IDs — and reservierteKapitelIds is the full reihenfolge, including still-active chapters — so a new figure, place, idea, motif, or note that shares a chapter name gets a suffix such as flut-2.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit c6ff194. Configure here.

Comment thread src/state/store.ts
set((s) => ({ speichern: { ...s.speichern, fehler: fehlertext(e) } }));
throw e;
} finally { archivAktion = false; umbaut = false; }
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

KI save races with archive

High Severity

umbaut blocks only chapter, plan, project, and delete writes. speichereKiHinweise and speichereAnalysen still run, and archive read-modify-writes those same files outside inReihe. A check that finishes during archive can overwrite veraltet flags or lose the new paid result when ladeProjekt reloads the other snapshot.

Additional Locations (2)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit c6ff194. Configure here.

Comment thread core/projekt/archiv.ts
const roh: unknown = JSON.parse(hinweise);
if (!Array.isArray(roh)) throw ungueltig();
const neu = roh.map(h => h.zitate?.some((z: { kapitel: Id }) => z.kapitel === id) || h.plan?.kapitel === id ? { ...h, veraltet: true } : h);
await aendere(PFADE.hinweise, JSON.stringify(neu, null, 2) + '\n');

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Malformed hints abort archive

Medium Severity

Archive parses analysis and hints as raw JSON and then reads h.zitate without an object check. A null array entry or a non-array zitate value throws TypeError; invalid analysis JSON throws SyntaxError. The journal rolls back, but the action stays blocked and the message is not the translated ungueltig text.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit c6ff194. Configure here.

Comment thread src/state/store.ts
const neu = await aktion(fs, id, new Date(), sprache());
if (get().fs !== fs) return;
for (const p of [persistenz.kapitelPfad(id), persistenz.planPfad(id), persistenz.PFADE.projekt, persistenz.PFADE.archiv,
persistenz.analysePfad(id), persistenz.PFADE.hinweise, `archiv/${persistenz.kapitelPfad(id)}`, `archiv/${persistenz.planPfad(id)}`]) eigene.set(p, Date.now());

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Watcher can see partial archive

Medium Severity

eigene is marked only after the whole archive/restore finishes, and those writes do not go through inReihe. A 500 ms gap between file moves lets externeAenderung reload a mid-move tree and merge it over the later successful store update, which can resurrect an active chapter that is already archived on disk.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit c6ff194. Configure here.

@leonatwork
leonatwork merged commit 8831554 into main Oct 21, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Agent] Kapitel teilen, zusammenführen und archivieren

1 participant