Before submitting
Problem
A profile created with c starts empty by design ("Create a new, empty profile"), and /gentle:models never writes into it. Its u action targets the current profile, resolved by resolveCurrentProfileTarget as the repository pin, else the globally active profile. So the natural operator flow — create a profile, configure the models, then select that profile — cannot populate the new profile: every configuration write lands in the previously active profile. The final enter (apply) on the still-empty profile then writes {} to ~/.pi/gentle-ai/models.json and replaces the materialized routing of every discoverable agent with clear entries, so all agents return to inherit. The whole model configuration is destroyed with no confirmation, no warning, and no recovery.
The panel already computes the exact signal for this state and renders it in the detail pane's "Profile routing" section ("No routing entries — every agent inherits its default model"), but enter acts on that state destructively instead of guarding it.
Because writing {} is a successful write, the compensation path already present in runProfilesPanelAction (revertClaim, which restores the previous active marker and the previously active profile's routing) never fires.
Steps to reproduce
/gentle:profiles → press c → name the profile (for example hybrid). The store now holds "hybrid": {}.
/gentle:models → assign model and effort to the agents → save with ctrl+s, or with u.
/gentle:profiles → select hybrid → press enter to apply.
Observed after step 3: ~/.pi/gentle-ai/models.json is {}, ~/.pi/agent/subagents.json holds clear entries for every agent, and no confirmation was shown.
Step 2 is the decisive detail. Whichever save key is used, the just-created profile stays {}; u writes to the pinned profile or the globally active one, never to the new profile. An operator who expects "configure the models into the profile I just created" gets no error and no hint, because the global save succeeds and the panel reports success.
Expected and actual behavior
Expected: applying a profile that has zero routing entries either refuses with an actionable message, or asks for explicit confirmation that names the destructive effect (global routing replaced with {}, every omitted agent returned to inherit). The previous routing and active marker should remain recoverable.
Actual: enter silently replaces the global routing with {} and clears every agent's materialized route. Nothing is restored, reported, or reversible from the UI.
A second, independent behavior amplifies it: c creates the profile without any seed from the current routing, so the empty state is the default first touch of a new profile rather than an exceptional one. Seeding the new profile from the effective routing (the same snapshot s takes) would make the documented create-then-configure flow work.
Two independent occurrences on the same machine left the same artifact signature:
# profiles store backup: an empty profile became active
active: "<profile>", "<profile>": {}
# models.json backup: global routing wiped
{}
# subagents.json backup: materialized routing wiped
{}
This is not fixed as of 3.5.1. The case "apply" and case "create" blocks in extensions/gentle-ai.ts and lib/agent-profiles.ts are byte-identical between the installed 3.3.0 and the 3.5.1 tarball, so upgrading does not change the behavior.
Relevant code paths: runProfilesPanelAction (cases apply and create), resolveCurrentProfileTarget, updateCurrentProfileFromSavedRouting, withOmittedAgentsClearedAsync, writeModelConfigAsync, applyModelConfigAsync; createProfile, setActiveProfile, normalizeProfilesFile in lib/agent-profiles.ts.
Documented keys that feed the trap, from docs/readme-reference.md (Agent-model profiles): enter applies live and "replaces the routing of every agent"; c creates "a new, empty profile"; s snapshots the current routing into the selected profile. The safe sequence exists, but nothing in the UI steers a new profile toward s before enter is ever pressed.
gentle-pi version
3.3.0 (installed from npm; 3.5.1 verified to be identical in the affected code paths)
Pi version
0.86.1
Operating system
macOS
Relevant logs or error output (optional)
# after step 1 — the new profile is empty, active is still the previous profile
~/.pi/gentle-ai/profiles.json
openai: 23 roles | hybrid: {} | active: "openai"
# after step 3 — the global routing is gone
~/.pi/gentle-ai/models.json
{} # held 23 routing entries immediately before `enter`
# same signature from an earlier occurrence in the same store
profiles.json.bak-<epoch> -> active: "nan", "nan": {}
models.json.bak-<epoch> -> {}
subagents.json.bak-<epoch> -> {}
Before submitting
Problem
A profile created with
cstarts empty by design ("Create a new, empty profile"), and/gentle:modelsnever writes into it. Itsuaction targets the current profile, resolved byresolveCurrentProfileTargetas the repository pin, else the globally active profile. So the natural operator flow — create a profile, configure the models, then select that profile — cannot populate the new profile: every configuration write lands in the previously active profile. The finalenter(apply) on the still-empty profile then writes{}to~/.pi/gentle-ai/models.jsonand replaces the materialized routing of every discoverable agent with clear entries, so all agents return to inherit. The whole model configuration is destroyed with no confirmation, no warning, and no recovery.The panel already computes the exact signal for this state and renders it in the detail pane's "Profile routing" section ("No routing entries — every agent inherits its default model"), but
enteracts on that state destructively instead of guarding it.Because writing
{}is a successful write, the compensation path already present inrunProfilesPanelAction(revertClaim, which restores the previous active marker and the previously active profile's routing) never fires.Steps to reproduce
/gentle:profiles→ pressc→ name the profile (for examplehybrid). The store now holds"hybrid": {}./gentle:models→ assign model and effort to the agents → save withctrl+s, or withu./gentle:profiles→ selecthybrid→ pressenterto apply.Observed after step 3:
~/.pi/gentle-ai/models.jsonis{},~/.pi/agent/subagents.jsonholds clear entries for every agent, and no confirmation was shown.Step 2 is the decisive detail. Whichever save key is used, the just-created profile stays
{};uwrites to the pinned profile or the globally active one, never to the new profile. An operator who expects "configure the models into the profile I just created" gets no error and no hint, because the global save succeeds and the panel reports success.Expected and actual behavior
Expected: applying a profile that has zero routing entries either refuses with an actionable message, or asks for explicit confirmation that names the destructive effect (global routing replaced with
{}, every omitted agent returned to inherit). The previous routing and active marker should remain recoverable.Actual:
entersilently replaces the global routing with{}and clears every agent's materialized route. Nothing is restored, reported, or reversible from the UI.A second, independent behavior amplifies it:
ccreates the profile without any seed from the current routing, so the empty state is the default first touch of a new profile rather than an exceptional one. Seeding the new profile from the effective routing (the same snapshotstakes) would make the documented create-then-configure flow work.Two independent occurrences on the same machine left the same artifact signature:
This is not fixed as of 3.5.1. The
case "apply"andcase "create"blocks inextensions/gentle-ai.tsandlib/agent-profiles.tsare byte-identical between the installed 3.3.0 and the 3.5.1 tarball, so upgrading does not change the behavior.Relevant code paths:
runProfilesPanelAction(casesapplyandcreate),resolveCurrentProfileTarget,updateCurrentProfileFromSavedRouting,withOmittedAgentsClearedAsync,writeModelConfigAsync,applyModelConfigAsync;createProfile,setActiveProfile,normalizeProfilesFileinlib/agent-profiles.ts.Documented keys that feed the trap, from
docs/readme-reference.md(Agent-model profiles):enterapplies live and "replaces the routing of every agent";ccreates "a new, empty profile";ssnapshots the current routing into the selected profile. The safe sequence exists, but nothing in the UI steers a new profile towardsbeforeenteris ever pressed.gentle-pi version
3.3.0 (installed from npm; 3.5.1 verified to be identical in the affected code paths)
Pi version
0.86.1
Operating system
macOS
Relevant logs or error output (optional)