-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathrelease-notes.json
More file actions
176 lines (176 loc) · 67.2 KB
/
Copy pathrelease-notes.json
File metadata and controls
176 lines (176 loc) · 67.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
{
"channels": {
"alpha": [],
"beta": [
{
"version": "0.203.0",
"date": "2026-10-04",
"items": [
{
"type": "added",
"en": "One persona definition for every repository on a machine. Beside a workspace's own\n`.nxs-personas/`, every workspace now reads the user-level folder `~/.nexusflow/personas/` —\npersonas and a `channels.yaml`, laid out the same way — merged per name: a persona or channel the\nrepository declares itself hides the user-level one of the same name, everything else is added. One\n`pm` written once runs in every repository as that repository's own participant, with its board,\nmemory and working copy. `nxc list` marks each entry that comes from the user-level folder and says\nwhich ones the repository hides, and so does `nxs prime`; a persona from it is told at session start\nwhere its declaration lives, because a path in its instructions relative to \"this repository\" means\nthe repository it runs in. The per-operation freeze holds for it as for the repository's own folder.\nA user-level `external` admits callers only from workspaces the running repository itself trusts\nby name. A development build reads a user-level folder only under a named service instance\n(`~/.nexusflow-<name>/personas/`), never the production one. A machine without the folder behaves\nas before. For embedding apps: `Engine::definitions`,\n`Engine::directory` and `Engine::prime_as` read the same folder (an app cannot choose another);\nnew `user_path`, `from_user` and `shadowed` on `DeclarationSource`, `origin` on `PersonaEntry` and\n`ChannelEntry`, `declared_in` on `PersonaBrief`, `user_declarations_dir`, `merged_channels`, and\n`Definitions::resolve_with_user_dir` / `Definitions::from_source` — a struct literal of those four\ntypes needs the new fields.",
"de": "Eine Persona-Definition für jedes Repository auf einer Maschine. Neben dem eigenen `.nxs-personas/`\nliest jeder Arbeitsbereich jetzt den Ordner auf Benutzerebene `~/.nexusflow/personas/` — Personas\nund eine `channels.yaml`, genauso aufgebaut — und führt beide je Name zusammen: Eine Persona oder ein\nKanal, den das Repository selbst deklariert, verdeckt den gleichnamigen Eintrag auf Benutzerebene,\nalles andere kommt hinzu. Ein einmal geschriebener `pm` läuft in jedem Repository als dessen eigener\nTeilnehmer, mit dessen Board, Gedächtnis und Arbeitskopie. `nxc list` markiert jeden Eintrag aus dem\nOrdner auf Benutzerebene und sagt, welche das Repository verdeckt, `nxs prime` ebenso; eine Persona\nvon dort erfährt beim Sitzungsstart, wo ihre Deklaration liegt, denn ein Pfad in ihren Anweisungen\nrelativ zu „diesem Repository\" meint das Repository, in dem sie läuft. Das Einfrieren je Vorgang gilt\ndort wie für den eigenen Ordner. Ein `external` auf Benutzerebene lässt Aufrufer nur aus Arbeitsbereichen\nzu, denen das laufende Repository selbst beim Namen vertraut. Ein Entwicklungs-Build liest einen\nOrdner auf Benutzerebene nur unter einer benannten Dienst-Instanz (`~/.nexusflow-<name>/personas/`),\nnie den produktiven. Eine Maschine ohne den Ordner verhält sich wie bisher. Für einbettende\nApps: `Engine::definitions`, `Engine::directory` und `Engine::prime_as` lesen denselben Ordner (eine\nApp kann keinen anderen wählen); neu sind `user_path`, `from_user` und `shadowed` an\n`DeclarationSource`, `origin` an `PersonaEntry` und `ChannelEntry`, `declared_in` an `PersonaBrief`,\n`user_declarations_dir`, `merged_channels` sowie `Definitions::resolve_with_user_dir` / `Definitions::from_source` — ein Struct-Literal dieser\nvier Typen braucht die neuen Felder.",
"facade": "breaking"
},
{
"type": "fixed",
"en": "Across a workspace border: when the caller's workspace stops trusting the receiver while a\ncommission is open, the answer no longer sits unread until the two-hour deadline — the commission is\ncanceled at once and the commissioner is woken with \"the answer arrived from <workspace>, a\nworkspace no longer trusted here\". A peer's handover that runs past its 60-second limit is now\nstopped and reaped instead of being left running, so the background service no longer collects\nstuck processes. The guide now says plainly that the depth cap across the border rests on the\ntrusted workspace's word.",
"de": "Über die Grenze eines Arbeitsbereichs: Entzieht der Arbeitsbereich des Aufrufers dem Empfänger das\nVertrauen, während ein Auftrag offen ist, liegt die Antwort nicht mehr ungelesen bis zur\nZwei-Stunden-Frist — der Auftrag wird sofort abgebrochen und der Auftraggeber mit „the answer arrived\nfrom <workspace>, a workspace no longer trusted here\" geweckt. Eine Übergabe beim Nachbarn, die ihre\n60-Sekunden-Grenze überschreitet, wird jetzt gestoppt und eingesammelt, statt weiterzulaufen; der\nHintergrunddienst sammelt so keine hängenden Prozesse mehr an. Der Guide sagt jetzt deutlich, dass\ndie Tiefengrenze über die Grenze auf dem Wort des vertrauten Arbeitsbereichs beruht.",
"facade": "changed"
}
],
"notes": {
"en": "### Added\n- One persona definition for every repository on a machine. Beside a workspace's own\n`.nxs-personas/`, every workspace now reads the user-level folder `~/.nexusflow/personas/` —\npersonas and a `channels.yaml`, laid out the same way — merged per name: a persona or channel the\nrepository declares itself hides the user-level one of the same name, everything else is added. One\n`pm` written once runs in every repository as that repository's own participant, with its board,\nmemory and working copy. `nxc list` marks each entry that comes from the user-level folder and says\nwhich ones the repository hides, and so does `nxs prime`; a persona from it is told at session start\nwhere its declaration lives, because a path in its instructions relative to \"this repository\" means\nthe repository it runs in. The per-operation freeze holds for it as for the repository's own folder.\nA user-level `external` admits callers only from workspaces the running repository itself trusts\nby name. A development build reads a user-level folder only under a named service instance\n(`~/.nexusflow-<name>/personas/`), never the production one. A machine without the folder behaves\nas before. For embedding apps: `Engine::definitions`,\n`Engine::directory` and `Engine::prime_as` read the same folder (an app cannot choose another);\nnew `user_path`, `from_user` and `shadowed` on `DeclarationSource`, `origin` on `PersonaEntry` and\n`ChannelEntry`, `declared_in` on `PersonaBrief`, `user_declarations_dir`, `merged_channels`, and\n`Definitions::resolve_with_user_dir` / `Definitions::from_source` — a struct literal of those four\ntypes needs the new fields.\n\n### Fixed\n- Across a workspace border: when the caller's workspace stops trusting the receiver while a\ncommission is open, the answer no longer sits unread until the two-hour deadline — the commission is\ncanceled at once and the commissioner is woken with \"the answer arrived from <workspace>, a\nworkspace no longer trusted here\". A peer's handover that runs past its 60-second limit is now\nstopped and reaped instead of being left running, so the background service no longer collects\nstuck processes. The guide now says plainly that the depth cap across the border rests on the\ntrusted workspace's word.\n\n### Facade Contract\n- `breaking` · One persona definition for every repository on a machine. Beside a workspace's own\n`.nxs-personas/`, every workspace now reads the user-level folder `~/.nexusflow/personas/` —\npersonas and a `channels.yaml`, laid out the same way — merged per name: a persona or channel the\nrepository declares itself hides the user-level one of the same name, everything else is added. One\n`pm` written once runs in every repository as that repository's own participant, with its board,\nmemory and working copy. `nxc list` marks each entry that comes from the user-level folder and says\nwhich ones the repository hides, and so does `nxs prime`; a persona from it is told at session start\nwhere its declaration lives, because a path in its instructions relative to \"this repository\" means\nthe repository it runs in. The per-operation freeze holds for it as for the repository's own folder.\nA user-level `external` admits callers only from workspaces the running repository itself trusts\nby name. A development build reads a user-level folder only under a named service instance\n(`~/.nexusflow-<name>/personas/`), never the production one. A machine without the folder behaves\nas before. For embedding apps: `Engine::definitions`,\n`Engine::directory` and `Engine::prime_as` read the same folder (an app cannot choose another);\nnew `user_path`, `from_user` and `shadowed` on `DeclarationSource`, `origin` on `PersonaEntry` and\n`ChannelEntry`, `declared_in` on `PersonaBrief`, `user_declarations_dir`, `merged_channels`, and\n`Definitions::resolve_with_user_dir` / `Definitions::from_source` — a struct literal of those four\ntypes needs the new fields.\n- `changed` · Across a workspace border: when the caller's workspace stops trusting the receiver while a\ncommission is open, the answer no longer sits unread until the two-hour deadline — the commission is\ncanceled at once and the commissioner is woken with \"the answer arrived from <workspace>, a\nworkspace no longer trusted here\". A peer's handover that runs past its 60-second limit is now\nstopped and reaped instead of being left running, so the background service no longer collects\nstuck processes. The guide now says plainly that the depth cap across the border rests on the\ntrusted workspace's word.",
"de": "### Neu\n- Eine Persona-Definition für jedes Repository auf einer Maschine. Neben dem eigenen `.nxs-personas/`\nliest jeder Arbeitsbereich jetzt den Ordner auf Benutzerebene `~/.nexusflow/personas/` — Personas\nund eine `channels.yaml`, genauso aufgebaut — und führt beide je Name zusammen: Eine Persona oder ein\nKanal, den das Repository selbst deklariert, verdeckt den gleichnamigen Eintrag auf Benutzerebene,\nalles andere kommt hinzu. Ein einmal geschriebener `pm` läuft in jedem Repository als dessen eigener\nTeilnehmer, mit dessen Board, Gedächtnis und Arbeitskopie. `nxc list` markiert jeden Eintrag aus dem\nOrdner auf Benutzerebene und sagt, welche das Repository verdeckt, `nxs prime` ebenso; eine Persona\nvon dort erfährt beim Sitzungsstart, wo ihre Deklaration liegt, denn ein Pfad in ihren Anweisungen\nrelativ zu „diesem Repository\" meint das Repository, in dem sie läuft. Das Einfrieren je Vorgang gilt\ndort wie für den eigenen Ordner. Ein `external` auf Benutzerebene lässt Aufrufer nur aus Arbeitsbereichen\nzu, denen das laufende Repository selbst beim Namen vertraut. Ein Entwicklungs-Build liest einen\nOrdner auf Benutzerebene nur unter einer benannten Dienst-Instanz (`~/.nexusflow-<name>/personas/`),\nnie den produktiven. Eine Maschine ohne den Ordner verhält sich wie bisher. Für einbettende\nApps: `Engine::definitions`, `Engine::directory` und `Engine::prime_as` lesen denselben Ordner (eine\nApp kann keinen anderen wählen); neu sind `user_path`, `from_user` und `shadowed` an\n`DeclarationSource`, `origin` an `PersonaEntry` und `ChannelEntry`, `declared_in` an `PersonaBrief`,\n`user_declarations_dir`, `merged_channels` sowie `Definitions::resolve_with_user_dir` / `Definitions::from_source` — ein Struct-Literal dieser\nvier Typen braucht die neuen Felder.\n\n### Behoben\n- Über die Grenze eines Arbeitsbereichs: Entzieht der Arbeitsbereich des Aufrufers dem Empfänger das\nVertrauen, während ein Auftrag offen ist, liegt die Antwort nicht mehr ungelesen bis zur\nZwei-Stunden-Frist — der Auftrag wird sofort abgebrochen und der Auftraggeber mit „the answer arrived\nfrom <workspace>, a workspace no longer trusted here\" geweckt. Eine Übergabe beim Nachbarn, die ihre\n60-Sekunden-Grenze überschreitet, wird jetzt gestoppt und eingesammelt, statt weiterzulaufen; der\nHintergrunddienst sammelt so keine hängenden Prozesse mehr an. Der Guide sagt jetzt deutlich, dass\ndie Tiefengrenze über die Grenze auf dem Wort des vertrauten Arbeitsbereichs beruht.\n\n### Facade-Kontrakt\n- `breaking` · Eine Persona-Definition für jedes Repository auf einer Maschine. Neben dem eigenen `.nxs-personas/`\nliest jeder Arbeitsbereich jetzt den Ordner auf Benutzerebene `~/.nexusflow/personas/` — Personas\nund eine `channels.yaml`, genauso aufgebaut — und führt beide je Name zusammen: Eine Persona oder ein\nKanal, den das Repository selbst deklariert, verdeckt den gleichnamigen Eintrag auf Benutzerebene,\nalles andere kommt hinzu. Ein einmal geschriebener `pm` läuft in jedem Repository als dessen eigener\nTeilnehmer, mit dessen Board, Gedächtnis und Arbeitskopie. `nxc list` markiert jeden Eintrag aus dem\nOrdner auf Benutzerebene und sagt, welche das Repository verdeckt, `nxs prime` ebenso; eine Persona\nvon dort erfährt beim Sitzungsstart, wo ihre Deklaration liegt, denn ein Pfad in ihren Anweisungen\nrelativ zu „diesem Repository\" meint das Repository, in dem sie läuft. Das Einfrieren je Vorgang gilt\ndort wie für den eigenen Ordner. Ein `external` auf Benutzerebene lässt Aufrufer nur aus Arbeitsbereichen\nzu, denen das laufende Repository selbst beim Namen vertraut. Ein Entwicklungs-Build liest einen\nOrdner auf Benutzerebene nur unter einer benannten Dienst-Instanz (`~/.nexusflow-<name>/personas/`),\nnie den produktiven. Eine Maschine ohne den Ordner verhält sich wie bisher. Für einbettende\nApps: `Engine::definitions`, `Engine::directory` und `Engine::prime_as` lesen denselben Ordner (eine\nApp kann keinen anderen wählen); neu sind `user_path`, `from_user` und `shadowed` an\n`DeclarationSource`, `origin` an `PersonaEntry` und `ChannelEntry`, `declared_in` an `PersonaBrief`,\n`user_declarations_dir`, `merged_channels` sowie `Definitions::resolve_with_user_dir` / `Definitions::from_source` — ein Struct-Literal dieser\nvier Typen braucht die neuen Felder.\n- `changed` · Über die Grenze eines Arbeitsbereichs: Entzieht der Arbeitsbereich des Aufrufers dem Empfänger das\nVertrauen, während ein Auftrag offen ist, liegt die Antwort nicht mehr ungelesen bis zur\nZwei-Stunden-Frist — der Auftrag wird sofort abgebrochen und der Auftraggeber mit „the answer arrived\nfrom <workspace>, a workspace no longer trusted here\" geweckt. Eine Übergabe beim Nachbarn, die ihre\n60-Sekunden-Grenze überschreitet, wird jetzt gestoppt und eingesammelt, statt weiterzulaufen; der\nHintergrunddienst sammelt so keine hängenden Prozesse mehr an. Der Guide sagt jetzt deutlich, dass\ndie Tiefengrenze über die Grenze auf dem Wort des vertrauten Arbeitsbereichs beruht."
}
},
{
"version": "0.202.0",
"date": "2026-10-04",
"items": [
{
"type": "fixed",
"en": "An answer that reaches a caller while it is still finishing its turn is now delivered. On the\ncommand line the background service was handed the delivery as a channel deadline on a session id\n(\"no such thread\"), so a held answer was never handed over; and the caller's sidecar, seeing its\nsub-round already answered, reminded it and then posted a substitute reply in its name. A sub-round\nwhose answer is held for its commissioner now counts as still in flight (`waiting_on_sub_round` in\n`nxc status --json` and on the facade). Also fixed: a persona that declares no `tools:` and is woken\nwith an answer it still has to pass on is granted its `nxc reply` (the wake carries the obligation it\nstill has), and a session spawned by a development build resolves that build's service home, not the\ninstalled one.",
"de": "Eine Antwort, die einen Aufrufer erreicht, während er seinen Zug noch beendet, wird jetzt\nzugestellt. Auf der Kommandozeile bekam der Hintergrunddienst die Zustellung als Kanal-Frist auf\neine Sitzungs-ID („no such thread“), eine zurückgehaltene Antwort wurde also nie übergeben; und die\nSidecar des Aufrufers sah seine Unterrunde schon beantwortet, erinnerte ihn und postete dann eine\nErsatzantwort in seinem Namen. Eine Unterrunde, deren Antwort für ihren Auftraggeber zurückgehalten\nwird, zählt jetzt weiter als unterwegs (`waiting_on_sub_round` in `nxc status --json` und in der\nFassade). Außerdem behoben: Eine Persona ohne `tools:`, die mit einer Antwort geweckt wird, die sie\nnoch weitergeben muss, darf ihr `nxc reply` ausführen (die Weckung trägt die Pflicht mit, die sie\nnoch hat), und eine Sitzung, die ein Entwicklungs-Build startet, nutzt dessen Dienst-Verzeichnis,\nnicht das installierte.",
"facade": "changed"
},
{
"type": "added",
"en": "A persona can commission a persona of another workspace on the same machine, and the answer comes\nback. `nxc send --to <owner>/<repo>/<persona>` records the commission in the caller's own workspace\nand hands over that one thread; the other workspace checks access, starts its persona in its own\nworking copy, and the answer — or a question, which always goes to whoever commissioned — wakes the\ncaller. Only the border thread crosses. Access is the receiver's: `addressable.external` admits a\nrole from trusted workspaces (`\"*/pm\"`, `nxsflow/manufakt-io/pm`), and without it nothing comes in.\nNew: `nxs name` (a workspace's stored `<owner>/<repo>` name), `nxs sync trust add --workspace\n<owner>/<repo>` (trust a neighbouring workspace by name; needed on both sides), and `nxc status`\nshowing a border thread in both workspaces with the other side and its state (submitted, working,\ninput-required, completed, rejected, canceled). Two hours without a sign of life cancel it;\n`nxc withdraw` takes it back on both sides. An engine older than this release cannot load a persona\nfile that carries `external:` — add it only once every reader of the repository is on this version.\nFor embedding apps: `EngineConfig::peers` and `Ctx::peers` (the host's way to reach other\nworkspaces; `None` keeps everything as before), `Engine::handover`, `Addressable::OnlyWithExternal`,\n`Coordinator::Border`, and new `border` fields on `Refs`, `SendToReceipt`, `ReplyReceipt` and\n`StatusThread` — a struct literal of `EngineConfig`, `Ctx`, `Adapter` or `Refs` without\n`..Default::default()` needs the new field.",
"de": "Eine Persona kann eine Persona eines anderen Arbeitsbereichs auf derselben Maschine beauftragen,\nund die Antwort kommt zurück. `nxc send --to <besitzer>/<repo>/<persona>` legt den Auftrag im\neigenen Arbeitsbereich ab und übergibt genau diesen einen Faden; der andere Arbeitsbereich prüft den\nZugang, startet seine Persona in seiner eigenen Arbeitskopie, und die Antwort — oder eine\nRückfrage, die immer an den Auftraggeber geht — weckt den Aufrufer. Nur der Grenzfaden geht hinüber.\nDen Zugang bestimmt der Empfänger: `addressable.external` lässt eine Rolle aus vertrauten\nArbeitsbereichen zu (`\"*/pm\"`, `nxsflow/manufakt-io/pm`), ohne das Feld kommt nichts herein. Neu:\n`nxs name` (der gespeicherte Name `<besitzer>/<repo>` eines Arbeitsbereichs), `nxs sync trust add\n--workspace <besitzer>/<repo>` (einem benachbarten Arbeitsbereich beim Namen vertrauen; auf beiden\nSeiten nötig) und `nxc status`, das einen Grenzfaden in beiden Arbeitsbereichen mit der Gegenseite\nund seinem Zustand zeigt (submitted, working, input-required, completed, rejected, canceled). Zwei\nStunden ohne Lebenszeichen brechen ihn ab; `nxc withdraw` zieht ihn auf beiden Seiten zurück. Eine\nEngine, die älter ist als dieses Release, kann eine Persona-Datei mit `external:` nicht laden —\nsetzen Sie das Feld erst, wenn alle Leser des Repositorys diesen Stand haben. Für einbettende Apps:\n`EngineConfig::peers` und `Ctx::peers` (der Weg des Hosts zu anderen Arbeitsbereichen; `None` lässt\nalles wie bisher), `Engine::handover`, `Addressable::OnlyWithExternal`, `Coordinator::Border` und neue\nFelder `border` an `Refs`, `SendToReceipt`, `ReplyReceipt` und `StatusThread` — ein Struct-Literal\nvon `EngineConfig`, `Ctx`, `Adapter` oder `Refs` ohne `..Default::default()` braucht das neue Feld.",
"facade": "breaking"
},
{
"type": "fixed",
"en": "Safety fix: a persona declared with `tools: []` can no longer run arbitrary shell commands when it\nowes a reply. Until now the engine granted every such session the bare, auto-approved `Bash` so that\nit could answer, which gave a persona declared to have no tools a full shell (`gh pr merge`,\n`git push --force`, a release). It now grants `Bash(nxc reply:*)`: the reply runs, every other\ncommand needs an approval nobody is there to give and is refused. A persona whose `tools:` is absent,\nor lists `Bash`, behaves as before; one that declares `Bash(nxc reply:*)` itself now stays that\nnarrow. For an embedding app's own worker: `RoleSpec::granted_tools` (`grantedTools` in the sidecar\nspec) can now carry a scoped permission rule rather than a tool name — put the tool it names into the\nSDK's `tools` and the rule itself into `allowedTools`, as the bundled sidecar does.",
"de": "Sicherheitskorrektur: Eine Persona mit `tools: []` kann keine beliebigen Shell-Befehle mehr\nausführen, wenn sie eine Antwort schuldet. Bisher gewährte die Engine jeder solchen Sitzung das\nnackte, automatisch freigegebene `Bash`, damit sie antworten konnte — eine Persona ohne Werkzeuge\nhatte damit eine volle Shell (`gh pr merge`, `git push --force`, ein Release). Jetzt gewährt sie\n`Bash(nxc reply:*)`: Die Antwort läuft, jeder andere Befehl braucht eine Freigabe, die niemand\nerteilen kann, und wird abgewiesen. Eine Persona ohne `tools:` oder mit `Bash` in der Liste verhält\nsich wie bisher; eine, die selbst `Bash(nxc reply:*)` deklariert, bleibt jetzt so eng. Für den\neigenen Worker einer einbettenden App: `RoleSpec::granted_tools` (`grantedTools` in der\nSidecar-Spezifikation) kann jetzt eine eingeschränkte Berechtigungsregel statt eines Werkzeugnamens\ntragen — das genannte Werkzeug gehört in `tools` des SDK, die Regel selbst in `allowedTools`, wie es\ndie mitgelieferte Sidecar tut.",
"facade": "changed"
}
],
"notes": {
"en": "### Added\n- A persona can commission a persona of another workspace on the same machine, and the answer comes\nback. `nxc send --to <owner>/<repo>/<persona>` records the commission in the caller's own workspace\nand hands over that one thread; the other workspace checks access, starts its persona in its own\nworking copy, and the answer — or a question, which always goes to whoever commissioned — wakes the\ncaller. Only the border thread crosses. Access is the receiver's: `addressable.external` admits a\nrole from trusted workspaces (`\"*/pm\"`, `nxsflow/manufakt-io/pm`), and without it nothing comes in.\nNew: `nxs name` (a workspace's stored `<owner>/<repo>` name), `nxs sync trust add --workspace\n<owner>/<repo>` (trust a neighbouring workspace by name; needed on both sides), and `nxc status`\nshowing a border thread in both workspaces with the other side and its state (submitted, working,\ninput-required, completed, rejected, canceled). Two hours without a sign of life cancel it;\n`nxc withdraw` takes it back on both sides. An engine older than this release cannot load a persona\nfile that carries `external:` — add it only once every reader of the repository is on this version.\nFor embedding apps: `EngineConfig::peers` and `Ctx::peers` (the host's way to reach other\nworkspaces; `None` keeps everything as before), `Engine::handover`, `Addressable::OnlyWithExternal`,\n`Coordinator::Border`, and new `border` fields on `Refs`, `SendToReceipt`, `ReplyReceipt` and\n`StatusThread` — a struct literal of `EngineConfig`, `Ctx`, `Adapter` or `Refs` without\n`..Default::default()` needs the new field.\n\n### Fixed\n- An answer that reaches a caller while it is still finishing its turn is now delivered. On the\ncommand line the background service was handed the delivery as a channel deadline on a session id\n(\"no such thread\"), so a held answer was never handed over; and the caller's sidecar, seeing its\nsub-round already answered, reminded it and then posted a substitute reply in its name. A sub-round\nwhose answer is held for its commissioner now counts as still in flight (`waiting_on_sub_round` in\n`nxc status --json` and on the facade). Also fixed: a persona that declares no `tools:` and is woken\nwith an answer it still has to pass on is granted its `nxc reply` (the wake carries the obligation it\nstill has), and a session spawned by a development build resolves that build's service home, not the\ninstalled one.\n- Safety fix: a persona declared with `tools: []` can no longer run arbitrary shell commands when it\nowes a reply. Until now the engine granted every such session the bare, auto-approved `Bash` so that\nit could answer, which gave a persona declared to have no tools a full shell (`gh pr merge`,\n`git push --force`, a release). It now grants `Bash(nxc reply:*)`: the reply runs, every other\ncommand needs an approval nobody is there to give and is refused. A persona whose `tools:` is absent,\nor lists `Bash`, behaves as before; one that declares `Bash(nxc reply:*)` itself now stays that\nnarrow. For an embedding app's own worker: `RoleSpec::granted_tools` (`grantedTools` in the sidecar\nspec) can now carry a scoped permission rule rather than a tool name — put the tool it names into the\nSDK's `tools` and the rule itself into `allowedTools`, as the bundled sidecar does.\n\n### Facade Contract\n- `changed` · An answer that reaches a caller while it is still finishing its turn is now delivered. On the\ncommand line the background service was handed the delivery as a channel deadline on a session id\n(\"no such thread\"), so a held answer was never handed over; and the caller's sidecar, seeing its\nsub-round already answered, reminded it and then posted a substitute reply in its name. A sub-round\nwhose answer is held for its commissioner now counts as still in flight (`waiting_on_sub_round` in\n`nxc status --json` and on the facade). Also fixed: a persona that declares no `tools:` and is woken\nwith an answer it still has to pass on is granted its `nxc reply` (the wake carries the obligation it\nstill has), and a session spawned by a development build resolves that build's service home, not the\ninstalled one.\n- `breaking` · A persona can commission a persona of another workspace on the same machine, and the answer comes\nback. `nxc send --to <owner>/<repo>/<persona>` records the commission in the caller's own workspace\nand hands over that one thread; the other workspace checks access, starts its persona in its own\nworking copy, and the answer — or a question, which always goes to whoever commissioned — wakes the\ncaller. Only the border thread crosses. Access is the receiver's: `addressable.external` admits a\nrole from trusted workspaces (`\"*/pm\"`, `nxsflow/manufakt-io/pm`), and without it nothing comes in.\nNew: `nxs name` (a workspace's stored `<owner>/<repo>` name), `nxs sync trust add --workspace\n<owner>/<repo>` (trust a neighbouring workspace by name; needed on both sides), and `nxc status`\nshowing a border thread in both workspaces with the other side and its state (submitted, working,\ninput-required, completed, rejected, canceled). Two hours without a sign of life cancel it;\n`nxc withdraw` takes it back on both sides. An engine older than this release cannot load a persona\nfile that carries `external:` — add it only once every reader of the repository is on this version.\nFor embedding apps: `EngineConfig::peers` and `Ctx::peers` (the host's way to reach other\nworkspaces; `None` keeps everything as before), `Engine::handover`, `Addressable::OnlyWithExternal`,\n`Coordinator::Border`, and new `border` fields on `Refs`, `SendToReceipt`, `ReplyReceipt` and\n`StatusThread` — a struct literal of `EngineConfig`, `Ctx`, `Adapter` or `Refs` without\n`..Default::default()` needs the new field.\n- `changed` · Safety fix: a persona declared with `tools: []` can no longer run arbitrary shell commands when it\nowes a reply. Until now the engine granted every such session the bare, auto-approved `Bash` so that\nit could answer, which gave a persona declared to have no tools a full shell (`gh pr merge`,\n`git push --force`, a release). It now grants `Bash(nxc reply:*)`: the reply runs, every other\ncommand needs an approval nobody is there to give and is refused. A persona whose `tools:` is absent,\nor lists `Bash`, behaves as before; one that declares `Bash(nxc reply:*)` itself now stays that\nnarrow. For an embedding app's own worker: `RoleSpec::granted_tools` (`grantedTools` in the sidecar\nspec) can now carry a scoped permission rule rather than a tool name — put the tool it names into the\nSDK's `tools` and the rule itself into `allowedTools`, as the bundled sidecar does.",
"de": "### Neu\n- Eine Persona kann eine Persona eines anderen Arbeitsbereichs auf derselben Maschine beauftragen,\nund die Antwort kommt zurück. `nxc send --to <besitzer>/<repo>/<persona>` legt den Auftrag im\neigenen Arbeitsbereich ab und übergibt genau diesen einen Faden; der andere Arbeitsbereich prüft den\nZugang, startet seine Persona in seiner eigenen Arbeitskopie, und die Antwort — oder eine\nRückfrage, die immer an den Auftraggeber geht — weckt den Aufrufer. Nur der Grenzfaden geht hinüber.\nDen Zugang bestimmt der Empfänger: `addressable.external` lässt eine Rolle aus vertrauten\nArbeitsbereichen zu (`\"*/pm\"`, `nxsflow/manufakt-io/pm`), ohne das Feld kommt nichts herein. Neu:\n`nxs name` (der gespeicherte Name `<besitzer>/<repo>` eines Arbeitsbereichs), `nxs sync trust add\n--workspace <besitzer>/<repo>` (einem benachbarten Arbeitsbereich beim Namen vertrauen; auf beiden\nSeiten nötig) und `nxc status`, das einen Grenzfaden in beiden Arbeitsbereichen mit der Gegenseite\nund seinem Zustand zeigt (submitted, working, input-required, completed, rejected, canceled). Zwei\nStunden ohne Lebenszeichen brechen ihn ab; `nxc withdraw` zieht ihn auf beiden Seiten zurück. Eine\nEngine, die älter ist als dieses Release, kann eine Persona-Datei mit `external:` nicht laden —\nsetzen Sie das Feld erst, wenn alle Leser des Repositorys diesen Stand haben. Für einbettende Apps:\n`EngineConfig::peers` und `Ctx::peers` (der Weg des Hosts zu anderen Arbeitsbereichen; `None` lässt\nalles wie bisher), `Engine::handover`, `Addressable::OnlyWithExternal`, `Coordinator::Border` und neue\nFelder `border` an `Refs`, `SendToReceipt`, `ReplyReceipt` und `StatusThread` — ein Struct-Literal\nvon `EngineConfig`, `Ctx`, `Adapter` oder `Refs` ohne `..Default::default()` braucht das neue Feld.\n\n### Behoben\n- Eine Antwort, die einen Aufrufer erreicht, während er seinen Zug noch beendet, wird jetzt\nzugestellt. Auf der Kommandozeile bekam der Hintergrunddienst die Zustellung als Kanal-Frist auf\neine Sitzungs-ID („no such thread“), eine zurückgehaltene Antwort wurde also nie übergeben; und die\nSidecar des Aufrufers sah seine Unterrunde schon beantwortet, erinnerte ihn und postete dann eine\nErsatzantwort in seinem Namen. Eine Unterrunde, deren Antwort für ihren Auftraggeber zurückgehalten\nwird, zählt jetzt weiter als unterwegs (`waiting_on_sub_round` in `nxc status --json` und in der\nFassade). Außerdem behoben: Eine Persona ohne `tools:`, die mit einer Antwort geweckt wird, die sie\nnoch weitergeben muss, darf ihr `nxc reply` ausführen (die Weckung trägt die Pflicht mit, die sie\nnoch hat), und eine Sitzung, die ein Entwicklungs-Build startet, nutzt dessen Dienst-Verzeichnis,\nnicht das installierte.\n- Sicherheitskorrektur: Eine Persona mit `tools: []` kann keine beliebigen Shell-Befehle mehr\nausführen, wenn sie eine Antwort schuldet. Bisher gewährte die Engine jeder solchen Sitzung das\nnackte, automatisch freigegebene `Bash`, damit sie antworten konnte — eine Persona ohne Werkzeuge\nhatte damit eine volle Shell (`gh pr merge`, `git push --force`, ein Release). Jetzt gewährt sie\n`Bash(nxc reply:*)`: Die Antwort läuft, jeder andere Befehl braucht eine Freigabe, die niemand\nerteilen kann, und wird abgewiesen. Eine Persona ohne `tools:` oder mit `Bash` in der Liste verhält\nsich wie bisher; eine, die selbst `Bash(nxc reply:*)` deklariert, bleibt jetzt so eng. Für den\neigenen Worker einer einbettenden App: `RoleSpec::granted_tools` (`grantedTools` in der\nSidecar-Spezifikation) kann jetzt eine eingeschränkte Berechtigungsregel statt eines Werkzeugnamens\ntragen — das genannte Werkzeug gehört in `tools` des SDK, die Regel selbst in `allowedTools`, wie es\ndie mitgelieferte Sidecar tut.\n\n### Facade-Kontrakt\n- `changed` · Eine Antwort, die einen Aufrufer erreicht, während er seinen Zug noch beendet, wird jetzt\nzugestellt. Auf der Kommandozeile bekam der Hintergrunddienst die Zustellung als Kanal-Frist auf\neine Sitzungs-ID („no such thread“), eine zurückgehaltene Antwort wurde also nie übergeben; und die\nSidecar des Aufrufers sah seine Unterrunde schon beantwortet, erinnerte ihn und postete dann eine\nErsatzantwort in seinem Namen. Eine Unterrunde, deren Antwort für ihren Auftraggeber zurückgehalten\nwird, zählt jetzt weiter als unterwegs (`waiting_on_sub_round` in `nxc status --json` und in der\nFassade). Außerdem behoben: Eine Persona ohne `tools:`, die mit einer Antwort geweckt wird, die sie\nnoch weitergeben muss, darf ihr `nxc reply` ausführen (die Weckung trägt die Pflicht mit, die sie\nnoch hat), und eine Sitzung, die ein Entwicklungs-Build startet, nutzt dessen Dienst-Verzeichnis,\nnicht das installierte.\n- `breaking` · Eine Persona kann eine Persona eines anderen Arbeitsbereichs auf derselben Maschine beauftragen,\nund die Antwort kommt zurück. `nxc send --to <besitzer>/<repo>/<persona>` legt den Auftrag im\neigenen Arbeitsbereich ab und übergibt genau diesen einen Faden; der andere Arbeitsbereich prüft den\nZugang, startet seine Persona in seiner eigenen Arbeitskopie, und die Antwort — oder eine\nRückfrage, die immer an den Auftraggeber geht — weckt den Aufrufer. Nur der Grenzfaden geht hinüber.\nDen Zugang bestimmt der Empfänger: `addressable.external` lässt eine Rolle aus vertrauten\nArbeitsbereichen zu (`\"*/pm\"`, `nxsflow/manufakt-io/pm`), ohne das Feld kommt nichts herein. Neu:\n`nxs name` (der gespeicherte Name `<besitzer>/<repo>` eines Arbeitsbereichs), `nxs sync trust add\n--workspace <besitzer>/<repo>` (einem benachbarten Arbeitsbereich beim Namen vertrauen; auf beiden\nSeiten nötig) und `nxc status`, das einen Grenzfaden in beiden Arbeitsbereichen mit der Gegenseite\nund seinem Zustand zeigt (submitted, working, input-required, completed, rejected, canceled). Zwei\nStunden ohne Lebenszeichen brechen ihn ab; `nxc withdraw` zieht ihn auf beiden Seiten zurück. Eine\nEngine, die älter ist als dieses Release, kann eine Persona-Datei mit `external:` nicht laden —\nsetzen Sie das Feld erst, wenn alle Leser des Repositorys diesen Stand haben. Für einbettende Apps:\n`EngineConfig::peers` und `Ctx::peers` (der Weg des Hosts zu anderen Arbeitsbereichen; `None` lässt\nalles wie bisher), `Engine::handover`, `Addressable::OnlyWithExternal`, `Coordinator::Border` und neue\nFelder `border` an `Refs`, `SendToReceipt`, `ReplyReceipt` und `StatusThread` — ein Struct-Literal\nvon `EngineConfig`, `Ctx`, `Adapter` oder `Refs` ohne `..Default::default()` braucht das neue Feld.\n- `changed` · Sicherheitskorrektur: Eine Persona mit `tools: []` kann keine beliebigen Shell-Befehle mehr\nausführen, wenn sie eine Antwort schuldet. Bisher gewährte die Engine jeder solchen Sitzung das\nnackte, automatisch freigegebene `Bash`, damit sie antworten konnte — eine Persona ohne Werkzeuge\nhatte damit eine volle Shell (`gh pr merge`, `git push --force`, ein Release). Jetzt gewährt sie\n`Bash(nxc reply:*)`: Die Antwort läuft, jeder andere Befehl braucht eine Freigabe, die niemand\nerteilen kann, und wird abgewiesen. Eine Persona ohne `tools:` oder mit `Bash` in der Liste verhält\nsich wie bisher; eine, die selbst `Bash(nxc reply:*)` deklariert, bleibt jetzt so eng. Für den\neigenen Worker einer einbettenden App: `RoleSpec::granted_tools` (`grantedTools` in der\nSidecar-Spezifikation) kann jetzt eine eingeschränkte Berechtigungsregel statt eines Werkzeugnamens\ntragen — das genannte Werkzeug gehört in `tools` des SDK, die Regel selbst in `allowedTools`, wie es\ndie mitgelieferte Sidecar tut."
}
},
{
"version": "0.201.0",
"date": "2026-10-03",
"items": [
{
"type": "changed",
"en": "`nxf show` now points at an item's parents in a neutral line — `Parents: <ids> (read for full context)` —\ninstead of \"URGENT RECOMMENDATION: … !!!\". Agents reading the board had flagged the old line as a\npossible prompt injection. The `parents_notice` field in `--json` and on the facade carries the same\nnew text; its name and when it appears are unchanged.",
"de": "`nxf show` verweist auf die Eltern eines Eintrags jetzt in einer neutralen Zeile —\n`Parents: <ids> (read for full context)` — statt mit „URGENT RECOMMENDATION: … !!!“. Agenten, die das\nBoard lesen, hatten die alte Zeile als möglichen Prompt-Injection-Versuch gemeldet. Das Feld\n`parents_notice` in `--json` und in der Fassade trägt denselben neuen Text; Name und Bedingung, wann es\nerscheint, bleiben gleich.",
"facade": "changed"
}
],
"notes": {
"en": "### Changed\n- `nxf show` now points at an item's parents in a neutral line — `Parents: <ids> (read for full context)` —\ninstead of \"URGENT RECOMMENDATION: … !!!\". Agents reading the board had flagged the old line as a\npossible prompt injection. The `parents_notice` field in `--json` and on the facade carries the same\nnew text; its name and when it appears are unchanged.\n\n### Facade Contract\n- `changed` · `nxf show` now points at an item's parents in a neutral line — `Parents: <ids> (read for full context)` —\ninstead of \"URGENT RECOMMENDATION: … !!!\". Agents reading the board had flagged the old line as a\npossible prompt injection. The `parents_notice` field in `--json` and on the facade carries the same\nnew text; its name and when it appears are unchanged.",
"de": "### Geändert\n- `nxf show` verweist auf die Eltern eines Eintrags jetzt in einer neutralen Zeile —\n`Parents: <ids> (read for full context)` — statt mit „URGENT RECOMMENDATION: … !!!“. Agenten, die das\nBoard lesen, hatten die alte Zeile als möglichen Prompt-Injection-Versuch gemeldet. Das Feld\n`parents_notice` in `--json` und in der Fassade trägt denselben neuen Text; Name und Bedingung, wann es\nerscheint, bleiben gleich.\n\n### Facade-Kontrakt\n- `changed` · `nxf show` verweist auf die Eltern eines Eintrags jetzt in einer neutralen Zeile —\n`Parents: <ids> (read for full context)` — statt mit „URGENT RECOMMENDATION: … !!!“. Agenten, die das\nBoard lesen, hatten die alte Zeile als möglichen Prompt-Injection-Versuch gemeldet. Das Feld\n`parents_notice` in `--json` und in der Fassade trägt denselben neuen Text; Name und Bedingung, wann es\nerscheint, bleiben gleich."
}
},
{
"version": "0.200.2",
"date": "2026-10-02",
"items": [],
"notes": {
"en": "",
"de": ""
}
},
{
"version": "0.200.1",
"date": "2026-10-02",
"items": [],
"notes": {
"en": "",
"de": ""
}
},
{
"version": "0.200.0",
"date": "2026-09-23",
"items": [
{
"type": "changed",
"en": "**nexus-flow's source now lives in a public repository, starting from a single commit.** The code is\nthe same as in 0.103.0; what changed is where it is published. The history before this release stays\nin a private archive, so the release list on GitHub begins here. Installing and updating are\nunaffected: `install.sh` and `nxs self-update` keep fetching from `nxsflow.com/nxs`.",
"de": "**Der Quellcode von nexus-flow liegt jetzt in einem öffentlichen Repository, beginnend mit einem\neinzigen Commit.** Der Code ist derselbe wie in 0.103.0; geändert hat sich, wo er veröffentlicht wird.\nDie Historie vor diesem Release bleibt in einem privaten Archiv, deshalb beginnt die Release-Liste auf\nGitHub hier. Installation und Aktualisierung sind nicht betroffen: `install.sh` und\n`nxs self-update` holen weiterhin von `nxsflow.com/nxs`."
}
],
"notes": {
"en": "### Changed\n- **nexus-flow's source now lives in a public repository, starting from a single commit.** The code is\nthe same as in 0.103.0; what changed is where it is published. The history before this release stays\nin a private archive, so the release list on GitHub begins here. Installing and updating are\nunaffected: `install.sh` and `nxs self-update` keep fetching from `nxsflow.com/nxs`.",
"de": "### Geändert\n- **Der Quellcode von nexus-flow liegt jetzt in einem öffentlichen Repository, beginnend mit einem\neinzigen Commit.** Der Code ist derselbe wie in 0.103.0; geändert hat sich, wo er veröffentlicht wird.\nDie Historie vor diesem Release bleibt in einem privaten Archiv, deshalb beginnt die Release-Liste auf\nGitHub hier. Installation und Aktualisierung sind nicht betroffen: `install.sh` und\n`nxs self-update` holen weiterhin von `nxsflow.com/nxs`."
}
}
],
"stable": [
{
"version": "0.202.0",
"date": "2026-10-04",
"items": [
{
"type": "fixed",
"en": "An answer that reaches a caller while it is still finishing its turn is now delivered. On the\ncommand line the background service was handed the delivery as a channel deadline on a session id\n(\"no such thread\"), so a held answer was never handed over; and the caller's sidecar, seeing its\nsub-round already answered, reminded it and then posted a substitute reply in its name. A sub-round\nwhose answer is held for its commissioner now counts as still in flight (`waiting_on_sub_round` in\n`nxc status --json` and on the facade). Also fixed: a persona that declares no `tools:` and is woken\nwith an answer it still has to pass on is granted its `nxc reply` (the wake carries the obligation it\nstill has), and a session spawned by a development build resolves that build's service home, not the\ninstalled one.",
"de": "Eine Antwort, die einen Aufrufer erreicht, während er seinen Zug noch beendet, wird jetzt\nzugestellt. Auf der Kommandozeile bekam der Hintergrunddienst die Zustellung als Kanal-Frist auf\neine Sitzungs-ID („no such thread“), eine zurückgehaltene Antwort wurde also nie übergeben; und die\nSidecar des Aufrufers sah seine Unterrunde schon beantwortet, erinnerte ihn und postete dann eine\nErsatzantwort in seinem Namen. Eine Unterrunde, deren Antwort für ihren Auftraggeber zurückgehalten\nwird, zählt jetzt weiter als unterwegs (`waiting_on_sub_round` in `nxc status --json` und in der\nFassade). Außerdem behoben: Eine Persona ohne `tools:`, die mit einer Antwort geweckt wird, die sie\nnoch weitergeben muss, darf ihr `nxc reply` ausführen (die Weckung trägt die Pflicht mit, die sie\nnoch hat), und eine Sitzung, die ein Entwicklungs-Build startet, nutzt dessen Dienst-Verzeichnis,\nnicht das installierte.",
"facade": "changed"
},
{
"type": "added",
"en": "A persona can commission a persona of another workspace on the same machine, and the answer comes\nback. `nxc send --to <owner>/<repo>/<persona>` records the commission in the caller's own workspace\nand hands over that one thread; the other workspace checks access, starts its persona in its own\nworking copy, and the answer — or a question, which always goes to whoever commissioned — wakes the\ncaller. Only the border thread crosses. Access is the receiver's: `addressable.external` admits a\nrole from trusted workspaces (`\"*/pm\"`, `nxsflow/manufakt-io/pm`), and without it nothing comes in.\nNew: `nxs name` (a workspace's stored `<owner>/<repo>` name), `nxs sync trust add --workspace\n<owner>/<repo>` (trust a neighbouring workspace by name; needed on both sides), and `nxc status`\nshowing a border thread in both workspaces with the other side and its state (submitted, working,\ninput-required, completed, rejected, canceled). Two hours without a sign of life cancel it;\n`nxc withdraw` takes it back on both sides. An engine older than this release cannot load a persona\nfile that carries `external:` — add it only once every reader of the repository is on this version.\nFor embedding apps: `EngineConfig::peers` and `Ctx::peers` (the host's way to reach other\nworkspaces; `None` keeps everything as before), `Engine::handover`, `Addressable::OnlyWithExternal`,\n`Coordinator::Border`, and new `border` fields on `Refs`, `SendToReceipt`, `ReplyReceipt` and\n`StatusThread` — a struct literal of `EngineConfig`, `Ctx`, `Adapter` or `Refs` without\n`..Default::default()` needs the new field.",
"de": "Eine Persona kann eine Persona eines anderen Arbeitsbereichs auf derselben Maschine beauftragen,\nund die Antwort kommt zurück. `nxc send --to <besitzer>/<repo>/<persona>` legt den Auftrag im\neigenen Arbeitsbereich ab und übergibt genau diesen einen Faden; der andere Arbeitsbereich prüft den\nZugang, startet seine Persona in seiner eigenen Arbeitskopie, und die Antwort — oder eine\nRückfrage, die immer an den Auftraggeber geht — weckt den Aufrufer. Nur der Grenzfaden geht hinüber.\nDen Zugang bestimmt der Empfänger: `addressable.external` lässt eine Rolle aus vertrauten\nArbeitsbereichen zu (`\"*/pm\"`, `nxsflow/manufakt-io/pm`), ohne das Feld kommt nichts herein. Neu:\n`nxs name` (der gespeicherte Name `<besitzer>/<repo>` eines Arbeitsbereichs), `nxs sync trust add\n--workspace <besitzer>/<repo>` (einem benachbarten Arbeitsbereich beim Namen vertrauen; auf beiden\nSeiten nötig) und `nxc status`, das einen Grenzfaden in beiden Arbeitsbereichen mit der Gegenseite\nund seinem Zustand zeigt (submitted, working, input-required, completed, rejected, canceled). Zwei\nStunden ohne Lebenszeichen brechen ihn ab; `nxc withdraw` zieht ihn auf beiden Seiten zurück. Eine\nEngine, die älter ist als dieses Release, kann eine Persona-Datei mit `external:` nicht laden —\nsetzen Sie das Feld erst, wenn alle Leser des Repositorys diesen Stand haben. Für einbettende Apps:\n`EngineConfig::peers` und `Ctx::peers` (der Weg des Hosts zu anderen Arbeitsbereichen; `None` lässt\nalles wie bisher), `Engine::handover`, `Addressable::OnlyWithExternal`, `Coordinator::Border` und neue\nFelder `border` an `Refs`, `SendToReceipt`, `ReplyReceipt` und `StatusThread` — ein Struct-Literal\nvon `EngineConfig`, `Ctx`, `Adapter` oder `Refs` ohne `..Default::default()` braucht das neue Feld.",
"facade": "breaking"
},
{
"type": "fixed",
"en": "Safety fix: a persona declared with `tools: []` can no longer run arbitrary shell commands when it\nowes a reply. Until now the engine granted every such session the bare, auto-approved `Bash` so that\nit could answer, which gave a persona declared to have no tools a full shell (`gh pr merge`,\n`git push --force`, a release). It now grants `Bash(nxc reply:*)`: the reply runs, every other\ncommand needs an approval nobody is there to give and is refused. A persona whose `tools:` is absent,\nor lists `Bash`, behaves as before; one that declares `Bash(nxc reply:*)` itself now stays that\nnarrow. For an embedding app's own worker: `RoleSpec::granted_tools` (`grantedTools` in the sidecar\nspec) can now carry a scoped permission rule rather than a tool name — put the tool it names into the\nSDK's `tools` and the rule itself into `allowedTools`, as the bundled sidecar does.",
"de": "Sicherheitskorrektur: Eine Persona mit `tools: []` kann keine beliebigen Shell-Befehle mehr\nausführen, wenn sie eine Antwort schuldet. Bisher gewährte die Engine jeder solchen Sitzung das\nnackte, automatisch freigegebene `Bash`, damit sie antworten konnte — eine Persona ohne Werkzeuge\nhatte damit eine volle Shell (`gh pr merge`, `git push --force`, ein Release). Jetzt gewährt sie\n`Bash(nxc reply:*)`: Die Antwort läuft, jeder andere Befehl braucht eine Freigabe, die niemand\nerteilen kann, und wird abgewiesen. Eine Persona ohne `tools:` oder mit `Bash` in der Liste verhält\nsich wie bisher; eine, die selbst `Bash(nxc reply:*)` deklariert, bleibt jetzt so eng. Für den\neigenen Worker einer einbettenden App: `RoleSpec::granted_tools` (`grantedTools` in der\nSidecar-Spezifikation) kann jetzt eine eingeschränkte Berechtigungsregel statt eines Werkzeugnamens\ntragen — das genannte Werkzeug gehört in `tools` des SDK, die Regel selbst in `allowedTools`, wie es\ndie mitgelieferte Sidecar tut.",
"facade": "changed"
}
],
"notes": {
"en": "### Added\n- A persona can commission a persona of another workspace on the same machine, and the answer comes\nback. `nxc send --to <owner>/<repo>/<persona>` records the commission in the caller's own workspace\nand hands over that one thread; the other workspace checks access, starts its persona in its own\nworking copy, and the answer — or a question, which always goes to whoever commissioned — wakes the\ncaller. Only the border thread crosses. Access is the receiver's: `addressable.external` admits a\nrole from trusted workspaces (`\"*/pm\"`, `nxsflow/manufakt-io/pm`), and without it nothing comes in.\nNew: `nxs name` (a workspace's stored `<owner>/<repo>` name), `nxs sync trust add --workspace\n<owner>/<repo>` (trust a neighbouring workspace by name; needed on both sides), and `nxc status`\nshowing a border thread in both workspaces with the other side and its state (submitted, working,\ninput-required, completed, rejected, canceled). Two hours without a sign of life cancel it;\n`nxc withdraw` takes it back on both sides. An engine older than this release cannot load a persona\nfile that carries `external:` — add it only once every reader of the repository is on this version.\nFor embedding apps: `EngineConfig::peers` and `Ctx::peers` (the host's way to reach other\nworkspaces; `None` keeps everything as before), `Engine::handover`, `Addressable::OnlyWithExternal`,\n`Coordinator::Border`, and new `border` fields on `Refs`, `SendToReceipt`, `ReplyReceipt` and\n`StatusThread` — a struct literal of `EngineConfig`, `Ctx`, `Adapter` or `Refs` without\n`..Default::default()` needs the new field.\n\n### Fixed\n- An answer that reaches a caller while it is still finishing its turn is now delivered. On the\ncommand line the background service was handed the delivery as a channel deadline on a session id\n(\"no such thread\"), so a held answer was never handed over; and the caller's sidecar, seeing its\nsub-round already answered, reminded it and then posted a substitute reply in its name. A sub-round\nwhose answer is held for its commissioner now counts as still in flight (`waiting_on_sub_round` in\n`nxc status --json` and on the facade). Also fixed: a persona that declares no `tools:` and is woken\nwith an answer it still has to pass on is granted its `nxc reply` (the wake carries the obligation it\nstill has), and a session spawned by a development build resolves that build's service home, not the\ninstalled one.\n- Safety fix: a persona declared with `tools: []` can no longer run arbitrary shell commands when it\nowes a reply. Until now the engine granted every such session the bare, auto-approved `Bash` so that\nit could answer, which gave a persona declared to have no tools a full shell (`gh pr merge`,\n`git push --force`, a release). It now grants `Bash(nxc reply:*)`: the reply runs, every other\ncommand needs an approval nobody is there to give and is refused. A persona whose `tools:` is absent,\nor lists `Bash`, behaves as before; one that declares `Bash(nxc reply:*)` itself now stays that\nnarrow. For an embedding app's own worker: `RoleSpec::granted_tools` (`grantedTools` in the sidecar\nspec) can now carry a scoped permission rule rather than a tool name — put the tool it names into the\nSDK's `tools` and the rule itself into `allowedTools`, as the bundled sidecar does.\n\n### Facade Contract\n- `changed` · An answer that reaches a caller while it is still finishing its turn is now delivered. On the\ncommand line the background service was handed the delivery as a channel deadline on a session id\n(\"no such thread\"), so a held answer was never handed over; and the caller's sidecar, seeing its\nsub-round already answered, reminded it and then posted a substitute reply in its name. A sub-round\nwhose answer is held for its commissioner now counts as still in flight (`waiting_on_sub_round` in\n`nxc status --json` and on the facade). Also fixed: a persona that declares no `tools:` and is woken\nwith an answer it still has to pass on is granted its `nxc reply` (the wake carries the obligation it\nstill has), and a session spawned by a development build resolves that build's service home, not the\ninstalled one.\n- `breaking` · A persona can commission a persona of another workspace on the same machine, and the answer comes\nback. `nxc send --to <owner>/<repo>/<persona>` records the commission in the caller's own workspace\nand hands over that one thread; the other workspace checks access, starts its persona in its own\nworking copy, and the answer — or a question, which always goes to whoever commissioned — wakes the\ncaller. Only the border thread crosses. Access is the receiver's: `addressable.external` admits a\nrole from trusted workspaces (`\"*/pm\"`, `nxsflow/manufakt-io/pm`), and without it nothing comes in.\nNew: `nxs name` (a workspace's stored `<owner>/<repo>` name), `nxs sync trust add --workspace\n<owner>/<repo>` (trust a neighbouring workspace by name; needed on both sides), and `nxc status`\nshowing a border thread in both workspaces with the other side and its state (submitted, working,\ninput-required, completed, rejected, canceled). Two hours without a sign of life cancel it;\n`nxc withdraw` takes it back on both sides. An engine older than this release cannot load a persona\nfile that carries `external:` — add it only once every reader of the repository is on this version.\nFor embedding apps: `EngineConfig::peers` and `Ctx::peers` (the host's way to reach other\nworkspaces; `None` keeps everything as before), `Engine::handover`, `Addressable::OnlyWithExternal`,\n`Coordinator::Border`, and new `border` fields on `Refs`, `SendToReceipt`, `ReplyReceipt` and\n`StatusThread` — a struct literal of `EngineConfig`, `Ctx`, `Adapter` or `Refs` without\n`..Default::default()` needs the new field.\n- `changed` · Safety fix: a persona declared with `tools: []` can no longer run arbitrary shell commands when it\nowes a reply. Until now the engine granted every such session the bare, auto-approved `Bash` so that\nit could answer, which gave a persona declared to have no tools a full shell (`gh pr merge`,\n`git push --force`, a release). It now grants `Bash(nxc reply:*)`: the reply runs, every other\ncommand needs an approval nobody is there to give and is refused. A persona whose `tools:` is absent,\nor lists `Bash`, behaves as before; one that declares `Bash(nxc reply:*)` itself now stays that\nnarrow. For an embedding app's own worker: `RoleSpec::granted_tools` (`grantedTools` in the sidecar\nspec) can now carry a scoped permission rule rather than a tool name — put the tool it names into the\nSDK's `tools` and the rule itself into `allowedTools`, as the bundled sidecar does.",
"de": "### Neu\n- Eine Persona kann eine Persona eines anderen Arbeitsbereichs auf derselben Maschine beauftragen,\nund die Antwort kommt zurück. `nxc send --to <besitzer>/<repo>/<persona>` legt den Auftrag im\neigenen Arbeitsbereich ab und übergibt genau diesen einen Faden; der andere Arbeitsbereich prüft den\nZugang, startet seine Persona in seiner eigenen Arbeitskopie, und die Antwort — oder eine\nRückfrage, die immer an den Auftraggeber geht — weckt den Aufrufer. Nur der Grenzfaden geht hinüber.\nDen Zugang bestimmt der Empfänger: `addressable.external` lässt eine Rolle aus vertrauten\nArbeitsbereichen zu (`\"*/pm\"`, `nxsflow/manufakt-io/pm`), ohne das Feld kommt nichts herein. Neu:\n`nxs name` (der gespeicherte Name `<besitzer>/<repo>` eines Arbeitsbereichs), `nxs sync trust add\n--workspace <besitzer>/<repo>` (einem benachbarten Arbeitsbereich beim Namen vertrauen; auf beiden\nSeiten nötig) und `nxc status`, das einen Grenzfaden in beiden Arbeitsbereichen mit der Gegenseite\nund seinem Zustand zeigt (submitted, working, input-required, completed, rejected, canceled). Zwei\nStunden ohne Lebenszeichen brechen ihn ab; `nxc withdraw` zieht ihn auf beiden Seiten zurück. Eine\nEngine, die älter ist als dieses Release, kann eine Persona-Datei mit `external:` nicht laden —\nsetzen Sie das Feld erst, wenn alle Leser des Repositorys diesen Stand haben. Für einbettende Apps:\n`EngineConfig::peers` und `Ctx::peers` (der Weg des Hosts zu anderen Arbeitsbereichen; `None` lässt\nalles wie bisher), `Engine::handover`, `Addressable::OnlyWithExternal`, `Coordinator::Border` und neue\nFelder `border` an `Refs`, `SendToReceipt`, `ReplyReceipt` und `StatusThread` — ein Struct-Literal\nvon `EngineConfig`, `Ctx`, `Adapter` oder `Refs` ohne `..Default::default()` braucht das neue Feld.\n\n### Behoben\n- Eine Antwort, die einen Aufrufer erreicht, während er seinen Zug noch beendet, wird jetzt\nzugestellt. Auf der Kommandozeile bekam der Hintergrunddienst die Zustellung als Kanal-Frist auf\neine Sitzungs-ID („no such thread“), eine zurückgehaltene Antwort wurde also nie übergeben; und die\nSidecar des Aufrufers sah seine Unterrunde schon beantwortet, erinnerte ihn und postete dann eine\nErsatzantwort in seinem Namen. Eine Unterrunde, deren Antwort für ihren Auftraggeber zurückgehalten\nwird, zählt jetzt weiter als unterwegs (`waiting_on_sub_round` in `nxc status --json` und in der\nFassade). Außerdem behoben: Eine Persona ohne `tools:`, die mit einer Antwort geweckt wird, die sie\nnoch weitergeben muss, darf ihr `nxc reply` ausführen (die Weckung trägt die Pflicht mit, die sie\nnoch hat), und eine Sitzung, die ein Entwicklungs-Build startet, nutzt dessen Dienst-Verzeichnis,\nnicht das installierte.\n- Sicherheitskorrektur: Eine Persona mit `tools: []` kann keine beliebigen Shell-Befehle mehr\nausführen, wenn sie eine Antwort schuldet. Bisher gewährte die Engine jeder solchen Sitzung das\nnackte, automatisch freigegebene `Bash`, damit sie antworten konnte — eine Persona ohne Werkzeuge\nhatte damit eine volle Shell (`gh pr merge`, `git push --force`, ein Release). Jetzt gewährt sie\n`Bash(nxc reply:*)`: Die Antwort läuft, jeder andere Befehl braucht eine Freigabe, die niemand\nerteilen kann, und wird abgewiesen. Eine Persona ohne `tools:` oder mit `Bash` in der Liste verhält\nsich wie bisher; eine, die selbst `Bash(nxc reply:*)` deklariert, bleibt jetzt so eng. Für den\neigenen Worker einer einbettenden App: `RoleSpec::granted_tools` (`grantedTools` in der\nSidecar-Spezifikation) kann jetzt eine eingeschränkte Berechtigungsregel statt eines Werkzeugnamens\ntragen — das genannte Werkzeug gehört in `tools` des SDK, die Regel selbst in `allowedTools`, wie es\ndie mitgelieferte Sidecar tut.\n\n### Facade-Kontrakt\n- `changed` · Eine Antwort, die einen Aufrufer erreicht, während er seinen Zug noch beendet, wird jetzt\nzugestellt. Auf der Kommandozeile bekam der Hintergrunddienst die Zustellung als Kanal-Frist auf\neine Sitzungs-ID („no such thread“), eine zurückgehaltene Antwort wurde also nie übergeben; und die\nSidecar des Aufrufers sah seine Unterrunde schon beantwortet, erinnerte ihn und postete dann eine\nErsatzantwort in seinem Namen. Eine Unterrunde, deren Antwort für ihren Auftraggeber zurückgehalten\nwird, zählt jetzt weiter als unterwegs (`waiting_on_sub_round` in `nxc status --json` und in der\nFassade). Außerdem behoben: Eine Persona ohne `tools:`, die mit einer Antwort geweckt wird, die sie\nnoch weitergeben muss, darf ihr `nxc reply` ausführen (die Weckung trägt die Pflicht mit, die sie\nnoch hat), und eine Sitzung, die ein Entwicklungs-Build startet, nutzt dessen Dienst-Verzeichnis,\nnicht das installierte.\n- `breaking` · Eine Persona kann eine Persona eines anderen Arbeitsbereichs auf derselben Maschine beauftragen,\nund die Antwort kommt zurück. `nxc send --to <besitzer>/<repo>/<persona>` legt den Auftrag im\neigenen Arbeitsbereich ab und übergibt genau diesen einen Faden; der andere Arbeitsbereich prüft den\nZugang, startet seine Persona in seiner eigenen Arbeitskopie, und die Antwort — oder eine\nRückfrage, die immer an den Auftraggeber geht — weckt den Aufrufer. Nur der Grenzfaden geht hinüber.\nDen Zugang bestimmt der Empfänger: `addressable.external` lässt eine Rolle aus vertrauten\nArbeitsbereichen zu (`\"*/pm\"`, `nxsflow/manufakt-io/pm`), ohne das Feld kommt nichts herein. Neu:\n`nxs name` (der gespeicherte Name `<besitzer>/<repo>` eines Arbeitsbereichs), `nxs sync trust add\n--workspace <besitzer>/<repo>` (einem benachbarten Arbeitsbereich beim Namen vertrauen; auf beiden\nSeiten nötig) und `nxc status`, das einen Grenzfaden in beiden Arbeitsbereichen mit der Gegenseite\nund seinem Zustand zeigt (submitted, working, input-required, completed, rejected, canceled). Zwei\nStunden ohne Lebenszeichen brechen ihn ab; `nxc withdraw` zieht ihn auf beiden Seiten zurück. Eine\nEngine, die älter ist als dieses Release, kann eine Persona-Datei mit `external:` nicht laden —\nsetzen Sie das Feld erst, wenn alle Leser des Repositorys diesen Stand haben. Für einbettende Apps:\n`EngineConfig::peers` und `Ctx::peers` (der Weg des Hosts zu anderen Arbeitsbereichen; `None` lässt\nalles wie bisher), `Engine::handover`, `Addressable::OnlyWithExternal`, `Coordinator::Border` und neue\nFelder `border` an `Refs`, `SendToReceipt`, `ReplyReceipt` und `StatusThread` — ein Struct-Literal\nvon `EngineConfig`, `Ctx`, `Adapter` oder `Refs` ohne `..Default::default()` braucht das neue Feld.\n- `changed` · Sicherheitskorrektur: Eine Persona mit `tools: []` kann keine beliebigen Shell-Befehle mehr\nausführen, wenn sie eine Antwort schuldet. Bisher gewährte die Engine jeder solchen Sitzung das\nnackte, automatisch freigegebene `Bash`, damit sie antworten konnte — eine Persona ohne Werkzeuge\nhatte damit eine volle Shell (`gh pr merge`, `git push --force`, ein Release). Jetzt gewährt sie\n`Bash(nxc reply:*)`: Die Antwort läuft, jeder andere Befehl braucht eine Freigabe, die niemand\nerteilen kann, und wird abgewiesen. Eine Persona ohne `tools:` oder mit `Bash` in der Liste verhält\nsich wie bisher; eine, die selbst `Bash(nxc reply:*)` deklariert, bleibt jetzt so eng. Für den\neigenen Worker einer einbettenden App: `RoleSpec::granted_tools` (`grantedTools` in der\nSidecar-Spezifikation) kann jetzt eine eingeschränkte Berechtigungsregel statt eines Werkzeugnamens\ntragen — das genannte Werkzeug gehört in `tools` des SDK, die Regel selbst in `allowedTools`, wie es\ndie mitgelieferte Sidecar tut."
}
},
{
"version": "0.201.0",
"date": "2026-10-03",
"items": [
{
"type": "changed",
"en": "`nxf show` now points at an item's parents in a neutral line — `Parents: <ids> (read for full context)` —\ninstead of \"URGENT RECOMMENDATION: … !!!\". Agents reading the board had flagged the old line as a\npossible prompt injection. The `parents_notice` field in `--json` and on the facade carries the same\nnew text; its name and when it appears are unchanged.",
"de": "`nxf show` verweist auf die Eltern eines Eintrags jetzt in einer neutralen Zeile —\n`Parents: <ids> (read for full context)` — statt mit „URGENT RECOMMENDATION: … !!!“. Agenten, die das\nBoard lesen, hatten die alte Zeile als möglichen Prompt-Injection-Versuch gemeldet. Das Feld\n`parents_notice` in `--json` und in der Fassade trägt denselben neuen Text; Name und Bedingung, wann es\nerscheint, bleiben gleich.",
"facade": "changed"
}
],
"notes": {
"en": "### Changed\n- `nxf show` now points at an item's parents in a neutral line — `Parents: <ids> (read for full context)` —\ninstead of \"URGENT RECOMMENDATION: … !!!\". Agents reading the board had flagged the old line as a\npossible prompt injection. The `parents_notice` field in `--json` and on the facade carries the same\nnew text; its name and when it appears are unchanged.\n\n### Facade Contract\n- `changed` · `nxf show` now points at an item's parents in a neutral line — `Parents: <ids> (read for full context)` —\ninstead of \"URGENT RECOMMENDATION: … !!!\". Agents reading the board had flagged the old line as a\npossible prompt injection. The `parents_notice` field in `--json` and on the facade carries the same\nnew text; its name and when it appears are unchanged.",
"de": "### Geändert\n- `nxf show` verweist auf die Eltern eines Eintrags jetzt in einer neutralen Zeile —\n`Parents: <ids> (read for full context)` — statt mit „URGENT RECOMMENDATION: … !!!“. Agenten, die das\nBoard lesen, hatten die alte Zeile als möglichen Prompt-Injection-Versuch gemeldet. Das Feld\n`parents_notice` in `--json` und in der Fassade trägt denselben neuen Text; Name und Bedingung, wann es\nerscheint, bleiben gleich.\n\n### Facade-Kontrakt\n- `changed` · `nxf show` verweist auf die Eltern eines Eintrags jetzt in einer neutralen Zeile —\n`Parents: <ids> (read for full context)` — statt mit „URGENT RECOMMENDATION: … !!!“. Agenten, die das\nBoard lesen, hatten die alte Zeile als möglichen Prompt-Injection-Versuch gemeldet. Das Feld\n`parents_notice` in `--json` und in der Fassade trägt denselben neuen Text; Name und Bedingung, wann es\nerscheint, bleiben gleich."
}
},
{
"version": "0.200.2",
"date": "2026-10-02",
"items": [],
"notes": {
"en": "",
"de": ""
}
},
{
"version": "0.200.0",
"date": "2026-09-23",
"items": [
{
"type": "changed",
"en": "**nexus-flow's source now lives in a public repository, starting from a single commit.** The code is\nthe same as in 0.103.0; what changed is where it is published. The history before this release stays\nin a private archive, so the release list on GitHub begins here. Installing and updating are\nunaffected: `install.sh` and `nxs self-update` keep fetching from `nxsflow.com/nxs`.",
"de": "**Der Quellcode von nexus-flow liegt jetzt in einem öffentlichen Repository, beginnend mit einem\neinzigen Commit.** Der Code ist derselbe wie in 0.103.0; geändert hat sich, wo er veröffentlicht wird.\nDie Historie vor diesem Release bleibt in einem privaten Archiv, deshalb beginnt die Release-Liste auf\nGitHub hier. Installation und Aktualisierung sind nicht betroffen: `install.sh` und\n`nxs self-update` holen weiterhin von `nxsflow.com/nxs`."
}
],
"notes": {
"en": "### Changed\n- **nexus-flow's source now lives in a public repository, starting from a single commit.** The code is\nthe same as in 0.103.0; what changed is where it is published. The history before this release stays\nin a private archive, so the release list on GitHub begins here. Installing and updating are\nunaffected: `install.sh` and `nxs self-update` keep fetching from `nxsflow.com/nxs`.",
"de": "### Geändert\n- **Der Quellcode von nexus-flow liegt jetzt in einem öffentlichen Repository, beginnend mit einem\neinzigen Commit.** Der Code ist derselbe wie in 0.103.0; geändert hat sich, wo er veröffentlicht wird.\nDie Historie vor diesem Release bleibt in einem privaten Archiv, deshalb beginnt die Release-Liste auf\nGitHub hier. Installation und Aktualisierung sind nicht betroffen: `install.sh` und\n`nxs self-update` holen weiterhin von `nxsflow.com/nxs`."
}
}
]
}
}