Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
fef005e
fix: commit thread events atomically and block legacy permanent deletion
claude Oct 27, 2026
6ee9b01
feat: declare module capabilities and serialize module data writes
claude Oct 27, 2026
cedb935
build: pin the command schema validator and include dependency notices
claude Oct 27, 2026
81d617a
feat: finish shared commands, reversible trash and activity graph
claude Oct 27, 2026
ef3168d
fix: bind graph clients to their workspace and preserve clickable ove…
claude Oct 27, 2026
8c99527
test: exercise context handoffs returns and SQLite migration through …
claude Oct 27, 2026
6cc3763
fix: tolerate command reservations when reviewing lifecycle conflicts
claude Oct 27, 2026
f10fb10
fix: stream complete portable backups with inert link metadata
claude Oct 29, 2026
1accfc6
docs: record verified backup v3 development integration
claude Oct 29, 2026
4e31f82
fix: preserve lifecycle and activity evidence through retries and sync
claude Oct 29, 2026
cf8358d
fix(sync): reject lifecycle writes from read-only room peers
claude Oct 29, 2026
5a6142e
fix(sync): bind restored history adoption to native project scope
claude Oct 29, 2026
75cba96
fix(ui): read pinned command result pages in the trash view
claude Oct 29, 2026
e817e46
fix(search): bind index manifest publication to current generation
claude Oct 30, 2026
d72e97e
fix(sync): authorize room changes against retained local scope
claude Oct 30, 2026
0a37dcb
fix(graph): keep neighbor positions stable across node identities
claude Oct 30, 2026
e5711f7
test(rooms): use authorized thread fixtures for a new reader room
claude Oct 30, 2026
02975cf
fix(sync): restore child lifecycle under retained trashed owners
claude Oct 30, 2026
fe7f0a4
fix(graph): restore complete saved filter contexts before acknowledging
claude Oct 30, 2026
81e9f09
ci: budget both expanded browser acceptance runs
claude Oct 30, 2026
61755d1
fix(backup): omit only the current export reservation from snapshots
claude Oct 30, 2026
249924a
ci: budget complete acceptance from measured expanded runs
claude Oct 30, 2026
d1afdb4
fix(graph): preserve exact node filters through view restoration
claude Oct 30, 2026
765b4c8
fix(sync): defer absent room history and import first restores atomic…
claude Oct 30, 2026
b1cf529
ci: include measured exact-filter browser coverage in both runs
claude Oct 30, 2026
91a63d2
fix(sync): enforce local authority grants and serialize binding writers
claude Oct 30, 2026
2f6e4ae
fix(graph): retain structural filter context during live refresh
claude Oct 30, 2026
a57fa20
fix(trash): bind conflict reviews to all affected contributions
claude Oct 30, 2026
f1e5bc1
fix(graph): restore active centers and exact GPU camera state
claude Oct 30, 2026
e029e90
ci: budget both complete runs with measured renderer coverage
claude Oct 30, 2026
b3ed0da
fix(import): recover verified activity after source conflicts
claude Oct 30, 2026
145cbbd
fix(trash): copy file references before sorting inventory
claude Oct 30, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,10 @@ jobs:
test:
name: Complete suite including browser, twice
runs-on: ubuntu-latest
timeout-minutes: 15
# CI 41003824290 measured 1242s for the previous whole acceptance run.
# New cases measured 94.086s UI/observation + 3.890s conflict tests locally.
# Budget both runs, setup and jitter; individual deadlines/gates unchanged.
timeout-minutes: 55
env:
PYTHONPATH: src:tests
PYTEST_PLUGINS: http_navigation_diagnostics
Expand Down Expand Up @@ -86,12 +89,9 @@ jobs:
PY
- name: Check JavaScript
run: |
node --check src/threaddesk/ui/static/map.js
node --check src/threaddesk/ui/static/map-layout.js
node --check src/threaddesk/ui/static/map-viewport.js
node --check src/threaddesk/ui/static/graph-workspace.js
node --check src/threaddesk/ui/static/app.js
node --check src/threaddesk/ui/static/graph-files.js
for script in src/threaddesk/ui/static/*.js; do
node --check "$script"
done
- name: Test results
if: always()
uses: actions/upload-artifact@v4
Expand Down
33 changes: 23 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,16 +177,29 @@ Threads, Notizen, Zwischenstände, Wissenskarte, Whiteboards und lokal gespeiche
Empfangsbestätigungen und gespeicherte Teile angefangener Dateiübertragungen
werden gesichert. Nach Wiederherstellung können diese Übertragungen mit ihrer
bisherigen Kennung fortgesetzt werden. Verlinkte Dateien außerhalb von ThreadDesk bleiben
an ihrem ursprünglichen Ort. Symbolische Links und Verzeichnisverknüpfungen im
ausgewählten Sicherungsbestand werden mit einer Fehlermeldung abgewiesen;
ihre Ziele werden nicht gelesen. Änderungen oder ein Austausch der Quelldateien
während der Sicherung führen ebenfalls zum Abbruch.

Die portable Sicherung ist auf 128 MiB und 20000 Archiveinträge begrenzt;
Manifest und Archiv zählen mit. Eine zu große Bibliothek führt zu einer
Fehlermeldung, nicht zu einer Sicherung mit ausgelassenen Dateien. Neue
Bibliothekssicherungen benötigen eine aktuelle ThreadDesk-Version zum Öffnen;
bestehende ältere Sicherungen bleiben lesbar.
an ihrem ursprünglichen Ort. Der bestehende portable Backupweg verarbeitet große
Dateien blockweise über temporäre Dateien. Er umfasst auch die lokalen Ordner
`Tool-Planung`, `Workflow`, `Zukunftsvisionen`, `Bilder` und gespeicherte
Agenten-Laufzeitdaten; versteckte Daten innerhalb dieser Fachordner bleiben erhalten.

Symbolische Links in Artefakt-, Import- und Planungsordnern werden nur mit ihrer
Zielangabe im Integritätsmanifest gespeichert. Ihre Ziele werden nie verfolgt;
beim Wiederherstellen bleiben sie inerte Metadaten und werden nicht als Links
angelegt. Links an kanonischen Thread-, Datenbank- und Bibliothekspfaden bleiben
gesperrt. Leere Fachverzeichnisse werden ebenfalls wiederhergestellt. Reguläre
Quelldateien werden über gebundene Deskriptoren und erneute Hashvergleiche geprüft;
eine beobachtete Änderung bricht den Export ab. Der parallel fortgeschriebene
Pollerstatus `library-watch.json` wird ausdrücklich als geprüfter Dateistand zu
einem Zeitpunkt aufgenommen, ohne eine globale Transaktion aller Dienste zu behaupten.

Die dateibasierte portable Sicherung ist standardmäßig auf 8 GiB und 200000
Einträge einschließlich Verzeichnis-/Linkmetadaten begrenzt; das Manifest darf
höchstens 32 MiB groß sein. Unkomprimierte Daten, Manifest und Archiv unterliegen
der Bytegrenze. Überschreitungen führen zu einer Fehlermeldung; Dateien werden
nicht zum Einhalten der Grenze ausgelassen. Das portable Format v3 benötigt den
aktuellen Leser; bestehende v1/v2-Sicherungen bleiben lesbar. Der ältere
Bytes-Hilfsaufruf ist weiterhin auf 128 MiB begrenzt, während Oberfläche und
Fachbefehle den dateibasierten Streamingweg verwenden.

Zum Wiederherstellen die Sicherung auswählen, das Öffnen bestätigen und
**Sicherung öffnen** wählen. ThreadDesk prüft die Dateien und öffnet einen eigenen
Expand Down
1 change: 1 addition & 0 deletions docs/MCP.md
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@ overwrite fallback.
| Return inbox / Nutzerentscheidung | `import_return`, `list_returns`, `get_return`, `review_return` | No |
| Existing Gnom binding / callback | `bind_gnom_job`, `receive_gnom_callback`, `list_gnom_jobs` | No |
| Local gate / board | `check_gate`, `dashboard` | No; ThreadDesk LocalGate is not the TollGate product |
| Shared commands / Gemeinsame Befehle | read-only `command_catalog`, read-only `command_query`, explicit `command_invoke` | No implicit agent start; current scope/backend/transport checks and durable operation status. See [command contract](contracts/commands-v1.md). |

## Issued handoff and bound return / Ausgestellte Übergabe und Rückgabe (M2)

Expand Down
48 changes: 48 additions & 0 deletions docs/contracts/commands-v1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Gemeinsamer Befehlsvertrag v1

Dieser Vertrag konkretisiert B03–B05 des bestehenden [Gesamtplans](../plans/THREADDESK-GRAPH-PAPIERKORB-BEDIENUNG-20261026.md). Er führt keine zweite Fachlogik ein. `services/commands` registriert bestehende Domainservices; UI, CLI und MCP delegieren dorthin. Neu geplante Workshop-Arbeiten sind auf Nutzeranweisung vollständig gestrichen. Historische Nutzerdaten werden dadurch nicht gelöscht.

## Entdecken und aufrufen

`td command --catalog --limit 10 --offset 0` beziehungsweise der paketierte Server mit `--command-catalog` liefert `threaddesk.command-catalog.v1`. `next_offset` bis `null` verfolgen. Der Katalog enthält pro Command das Eingabeschema, Wirkung, Scope, Backends, tatsächliche Transportbeschränkungen, erforderliche Revision und aktuelle Verfügbarkeit. Die Registryrevision bindet auch aktuelle Modulrechte und Schemas; Aktivierung, Widerruf und Deinstallation wirken ohne Neustart. Ein eingetragener Command ist noch kein End-to-End-Nachweis.

Ein Aufruf verwendet `td command --request-file request.json` beziehungsweise `ThreadDeskServer --command-file request.json`:

```json
{
"version": 1,
"workspace_id": "ws-WERT_AUS_DEM_AKTUELLEN_KATALOG",
"command": "graph.query",
"arguments": {"mode": "work", "limit": 100}
}
```

`workspace_id` ist eine opake Bindung an das ausgewählte lokale Profil. Nach Profilwechsel den Katalog neu lesen. Optionale `catalog_revision` verhindert Aufrufe gegen einen inzwischen geänderten Katalog. Unbekannte Envelopefelder, ungültige JSON-Werte, externe Schemaabfragen und übergroße Eingaben werden vor dem Handler abgewiesen. Maximal 1 MiB Request, 24 Verschachtelungsstufen; Domainlimits können enger sein.

Mutation: eine eindeutige `operation_id` und die laut Katalog erforderliche `expected_revision` mitsenden. Erstellung nutzt Revision 0. Native Domainverträge erhalten exakt dieselbe Operation und Revision, keine verdeckte zweite Kennung. Bei Libraryimport bleibt die ursprüngliche Manifestoperation unverändert; `library.resume` erhält eine neue Commandoperation und referenziert `import_operation_id`.

## Antworten, Konflikte und Wiederaufnahme

Erfolg: `threaddesk.command-result.v1` mit Workspace, Katalogrevision, Command, SHA256-Ergebnisdigest und `result`. CLI ergänzt `ok`; Exitcode 0 bedeutet Erfolg, Exitcode 2 einen strukturierten Fehler. HTTP `/api/commands` verwendet dieselben Eingaben, Konflikte ergeben 409. MCP bietet `command_catalog`, `command_query` (ausschließlich Reads) und `command_invoke`; alte Toolnamen bleiben erhalten.

CLI-/MCP-Resultate werden auf 24.000 Bytes begrenzt. Große Ergebnisse erscheinen als JSON-Textseiten: `result_page`, `encoding=json-text-codepoint-pages`, `offset`, `next_offset`, `total`. Beim Weiterlesen ursprünglichen Request plus `result_digest` und `result_offset` verwenden; alle Seiten in Reihenfolge verbinden und erst danach als JSON parsen. Bei zeitabhängigen Reads außerdem das zurückgegebene `snapshot_at` weitergeben. Ein geändertes Ergebnis führt zu `result_changed`; nie Seiten verschiedener Versionen vermischen. Große Exporte/Backups sind SHA256-gebundene Artefakte mit geschütztem Download, kein unbeschränkter Terminaltext.

Gleiche Operation und identischer kanonischer Request liefern den dauerhaften Ergebnisbeleg, ohne Wirkung oder Erfolgsevent zu wiederholen. Andere Nutzlast unter derselben Operation ergibt `operation_conflict`. Veraltete Objektversion ergibt `revision_conflict`; den Entwurf behalten, aktuellen Stand lesen und bewusst entscheiden.

`command.operation` zeigt `pending`, `failed` oder `complete`. Vor Dateisystem-, Netzwerk- und OS-Effekten wird eine Reservation gespeichert. Unbestätigte Wirkung wird niemals blind wiederholt. `command.reconcile` übernimmt ausschließlich nachweisbare, exakt gebundene Ownerreceipts und führt die ursprüngliche Mutation nicht erneut aus. Unterstützte Owner: Threadmanagement, Knowledge, Libraryvorgänge einschließlich bestätigtem Öffnen, gespeicherte Graphansichten, Trash und Handoffausgabe. Fehlt ein prüfbarer Ownerbeleg, bleibt `owner_receipt_unverifiable` eine konkrete Grenze; ein äußerer Fehler beweist keine ausgebliebene Wirkung.

Eine ausdrücklich bestätigte endgültige Löschung darf im v2-Purgevertrag aufgeführte historische Resultatkopien in Tombstones reduzieren. Requesthash, Operationsidentität und Ausführungsstatus bleiben erhalten. Replay ist dann ausdrücklich `content_purged`, statt gelöschten Inhalt erneut auszugeben. Fremde offene Commandreservationen und mehrdeutige Inhaltskopien blockieren Purge. Details: [Papierkorbvertrag](trash-v1.md).

## Oberfläche und sichere Transportgrenzen

Öffentliche HTTP-Aufrufe bleiben an die bestehenden Localhost-/Origin-/CSRF-Regeln gebunden. Fähigkeiten des Graphclients sind kurzlebige, workspacegebundene Zustellungsrechte; sie sind kein Ersatz für Fachberechtigungen. `graph_view.apply` gilt erst nach tatsächlicher Anwendung und geprüftem UI-ACK als angewendet. `queued` und `waiting_for_client` sind keine Erfolgsmeldung für die sichtbare Ansicht. Der [Graphvertrag](graph-activity-v1.md) beschreibt Kontrolle und Änderungsstatus genauer.

Die optionale Ownerkontextsuche `search.*` ist ausschließlich `local`/`cli` zugänglich. HTTP/MCP/Rooms erhalten dafür keine versteckte Freigabe. Dateisuche im autorisierten Bibliotheksvertrag bleibt davon getrennt. Module verwenden den bestehenden [deklarativen Modulvertrag](module-commands-v1.md), keine Ausführung hochgeladenen Codes.

KiraBridge wird nicht verändert. Native KiraBridge-Verträge und der autorisierte sichtbare CLI-Weg sind verschiedene, offen benannte Zugänge. Für neue Writes ist der sichtbare Terminalweg verwendbar, wenn die aktuelle Bridge ihn tatsächlich autorisiert und ein freies sichtbares Terminal bestätigt. Tatsächlicher Principal, Taskreceipt, Abschluss und unabhängiger Readback gehören zum Nachweis. Ein lokaler Test oder MCP-Katalog beweist keine Bedienbarkeit aus ChatGPT. Unklare abgeschickte Aktionen zuerst anhand ihrer dauerhaften Operation abgleichen; nicht erneut absenden.

## Grenzen der Abnahme

Die skriptbaren privaten Fixtures `scripts/check_workspace_commands.py`, `scripts/check_workspace_operations.py` und `scripts/check_library_workflow.py` prüfen Originalerhalt und frische CLI-Prozesse; optional unterstützen sie den finalen Paketserver. Sie behaupten selbst keine Bridgeidentität. Netzwerkprüfungen verwenden echte originale Loopback-HTTP-Server, keine Modellanbieter. Produktionsdaten, fremde Originale und Code von KiraBridge werden nicht als Testfixture verwendet.

Der releasebezogene Beleg muss getrennt ausweisen: Quellimplementierung, gezielte Tests, tatsächliche Bridgeaufrufe, Pflicht-CI, integrierter Quellpin und installierter Paketpin. Kein Katalogeintrag und kein Teiltest setzt diese übrigen Spalten automatisch auf erfolgreich.
Loading
Loading