Skip to content

feat(pi): version gentle-pi model profiles and sync them on install - #106

Merged
barbatdev merged 2 commits into
mainfrom
feat/pi-model-profiles
Oct 31, 2026
Merged

barbatdev merged 2 commits into
mainfrom
feat/pi-model-profiles

Conversation

@barbatdev

Copy link
Copy Markdown
Owner

Why

Model routing lived only in each machine's gentle-pi profile store, so machines drifted. Fresh gentle-shell homes even started the orchestrator on the removed openai/gpt-5.5, which fails with: "The 'gpt-5.5' model is not supported when using Codex with a ChatGPT account". The openai profile also needed GPT-6.1 Terra so the ChatGPT subscription goes further.

What

  • pi/gentle-ai/profiles.json: the versioned gentle-pi profile store, without the machine-local current snapshot. In the openai profile, GPT-6.1 Terra routes gentle-ai-verify, review-reliability, review-resilience, jd-judge-a, cortex-requirements-analyst and cortex-adversarial-tester. GPT-6 Astra stays only on review-risk. nan-qa-reliability-sol keeps Sol.
  • scripts/sync-pi-model-profiles.py: merges the repo profiles into ~/.pi and ~/.gentle-shell. Same-name profiles are replaced; local-only profiles and current are kept. It then materializes the active profile into settings.json (orchestrator), subagents.json and the agent frontmatter. A home without a store starts on the empty current profile, so its routing is untouched. Changed files are backed up; a second run changes nothing.
  • install.sh runs it; --dry-run is supported.
  • tests/sync_pi_model_profiles_test.py: 6 tests covering merge, materialization, idempotence, dry run, a home without a store, and a home without an agent dir. CI runs them.
  • README section describing the flow.

Verification

  • python3 tests/sync_pi_model_profiles_test.py: 6 passed.
  • bash -n install.sh and scripts/check-install-symlinks.sh pass.
  • Applied on the Mac, agent-dev and agent-gentle. A second run reports 0 changes, and the orchestrator follows the active profile.
  • The tests were written alongside the script, so no RED run was observed first.

🤖 Generated with Claude Code

https://claude.ai/code/session_01A9D7phtHFYfszv6WKeXbiU

Track the gentle-pi model profile store in pi/gentle-ai/profiles.json and
merge it into ~/.pi and ~/.gentle-shell, materializing the active profile.
The openai profile routes verify/review/judge roles to GPT-6.1 Terra and
keeps GPT-6 Astra only for review-risk. Homes without a store keep their
current routing.
@barbatdev
barbatdev merged commit 83d7791 into main Oct 31, 2026
1 check passed
@barbatdev
barbatdev deleted the feat/pi-model-profiles branch October 31, 2026 13:38
@barbatdev

Copy link
Copy Markdown
Owner Author

Post-merge QA (glm)

Lens: requirements + adversarial. Versions the gentle-pi model profile store in pi/gentle-ai/profiles.json and adds scripts/sync-pi-model-profiles.py to merge it into ~/.pi and ~/.gentle-shell and materialize the active profile. The merge logic is sound adversarially: local-only profiles and 'current' survive, the local 'active' pointer is kept when it still exists, a home without a store starts on an empty 'current' profile so materialization is skipped and routing is untouched, and homes without an agent/ dir are skipped. write_if_changed makes runs idempotent with backups, and set_frontmatter only rewrites the body-surrounding frontmatter, leaving content intact. Six tests cover merge, materialization, idempotence, dry-run, and both empty-home edge cases; CI runs them and install.sh wires the script with a non-fatal failure message.

Question (1)

  • set_frontmatter silently does nothing when the key is absent (scripts/sync-pi-model-profiles.py:88): set_frontmatter substitutes 'model:'/'thinking:' only if the line already exists in the frontmatter ('head = line.sub(...) if line.search(head) else head'); it never inserts a missing key. An agent .md whose frontmatter lacks 'model:' or 'thinking:' keeps its old routing after sync while subagents.json and settings.json are updated, so frontmatter and subagents.json can disagree about the same agent. The PR does not state which source gentle-pi prefers, so the practical impact depends on that precedence.

Verdict: clean

@barbatdev

Copy link
Copy Markdown
Owner Author

Post-merge QA (deepseek)

Lens: evidence + test design. The six tests cover the merge, the materialization, idempotence, the dry run, a home without a store and a home without an agent dir, and the script writes atomically with per-file backups before replacing. The merge rules hold by inspection: repo profiles replace same-name local ones, local-only profiles and current survive, and an empty store starts on current, so its routing is untouched. Three points are thinner than the PR body suggests: the subagent side of the materialization is asserted only against the script's own output, and two branches (removed local active profile, agent markdown without a model: line) have no test at all.

Suggestion (2)

  • Fallback for an active profile that no longer exists is untested (scripts/sync-pi-model-profiles.py:75): elif active not in profiles: active = repo["active"] is the branch that keeps a machine working when someone deletes the profile it was pinned to, and the docstring states the rule ('the local active profile is kept when it still exists'). No test covers it: every fixture starts with an active that survives the merge. Condition worth covering: a store whose active names a profile absent from both the store and the repo, expected to resolve to the repo's active profile and materialize it, with the previous settings.json backed up.
  • Agent markdown without a model: line is skipped silently while subagents.json is updated (scripts/sync-pi-model-profiles.py:87): set_frontmatter returns the text unchanged when the key is absent, and materialize writes the file only if it changed. So an agent whose frontmatter has no model: line (it inherits the default) keeps whatever it had, while the same agent is rewritten in subagents.json. The two sources then disagree and nothing reports it. Either add the key when missing or note in the README that frontmatter is only rewritten where the line already exists.

Question (1)

  • subagents.json writes effort but the real gentle-pi schema is not evidenced anywhere in the repo (scripts/sync-pi-model-profiles.py:107): For every non-orchestrator agent the script sets model_profiles.<agent>.model and .effort from the profile's thinking. The only fixture that shows that shape is the one written inside this PR's own test, so the test proves the script is self-consistent, not that gentle-pi reads effort there. The PR's live verification reports that 'the orchestrator follows the active profile', which covers settings.json only. A repo fixture copied from a real subagents.json, or one check of a subagent's effective model after the sync, would turn this into evidence. If the key were wrong, subagents would keep their previous routing while the file looks updated.

Verdict: clean

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.

1 participant