chore(release): prepare 0.28.0#43
Conversation
Bundles the GitHub org migration (TechMatrix-labs -> Pythoughts-labs) with the 0.28.0 release prep. Org migration: - Repoint all GitHub URLs, install scripts, CI workflow targets (homebrew tap, scoop bucket, pythinker-home dispatch), and the default /feedback repository to github.com/Pythoughts-labs/pythinker-code. - Add the previous owner to the legacy feedback-repo migration set so existing configs auto-update to the new default (with a covering test). Release 0.28.0: - Bump version 0.27.0 -> 0.28.0 (pyproject.toml, uv.lock). - Promote the Unreleased changelog into a dated 0.28.0 block across CHANGELOG.md and docs, mirror the full bullet set, and record the org move; add the 0.28.0 breaking-changes entry (none). - Refresh the README "What's New" section and bump release-asset filenames / download URLs to 0.28.0.
Addresses CodeRabbit: the local build command showed 0.27.0 while its own output listing and the rest of the release docs use 0.28.0.
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds a new built-in ChangesJudge subagent feature
Repository metadata updates
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Suggested labels
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/linux-installer/README.md (1)
47-49:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winUpdate stale tarball example version to 0.28.0.
This section still shows
pythinker-0.27.0-...tar.gz, which conflicts with the 0.28.0 release docs above and can mislead users copying artifact names.Suggested fix
- target-triple naming (e.g. `pythinker-0.27.0-x86_64-unknown-linux-gnu.tar.gz`). + target-triple naming (e.g. `pythinker-0.28.0-x86_64-unknown-linux-gnu.tar.gz`).🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/linux-installer/README.md` around lines 47 - 49, The README example references a stale tarball name "pythinker-0.27.0-x86_64-unknown-linux-gnu.tar.gz"; update that string to "pythinker-0.28.0-x86_64-unknown-linux-gnu.tar.gz" so the example matches the 0.28.0 release docs and the artifact produced by the release-pythinker-cli.yml workflow (and verify scripts/install-native.sh references the same artifact name if present). Locate the example text in packages/linux-installer/README.md and replace the version substring, ensuring the naming pattern remains cargo-dist target-triple style.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@packages/linux-installer/README.md`:
- Around line 47-49: The README example references a stale tarball name
"pythinker-0.27.0-x86_64-unknown-linux-gnu.tar.gz"; update that string to
"pythinker-0.28.0-x86_64-unknown-linux-gnu.tar.gz" so the example matches the
0.28.0 release docs and the artifact produced by the release-pythinker-cli.yml
workflow (and verify scripts/install-native.sh references the same artifact name
if present). Locate the example text in packages/linux-installer/README.md and
replace the version substring, ensuring the naming pattern remains cargo-dist
target-triple style.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 8713513c-27fc-42d6-ba5e-9f67f9565bc4
📒 Files selected for processing (1)
packages/linux-installer/README.md
Add a read-only LLM-as-judge subagent that independently gates high-stakes deliverables before they reach the user, wired into the agent roster, execution profiles, permission profiles, and the subagent runner. Redesign the default prompts for clarity and to cut wasted work: - AGENTS.md guidance now states the root-to-working-dir files are pre-merged and authoritative, and to search only directories below the working dir, which stops redundant AGENTS.md discovery. - The judge gate is scoped to high-stakes or hard-to-reverse deliverables and framed as one cheap evidence-gating pass. - The judge prompt uses a criteria-based rubric that defaults to NEEDS_WORK when a load-bearing claim is unsupported. - Stop discovering .pythinker/AGENTS.md; only AGENTS.md/agents.md from the project root down to the working directory are merged. - Trim off-voice boilerplate from the code-quality defaults. Update inline-snapshot fixtures to match.
|
This release branch now also includes the following, cherry-picked from
The previously-failing |
The read_only/plan/review/verify permission profiles excluded the web tools but still allowed Shell, so curl/wget/ssh/git-fetch could reach the network and bypass a read-only subagent's no-web-tools intent. Classify network CLIs and git-network subcommands as blocked in those profiles. Read-only working-tree git (diff/log/show/status) stays allowed so judge and verifier can inspect changes; script interpreters were already treated as mutating.
An organization handle is not a valid CODEOWNERS owner, so review routing did not fire; use the maintainer account instead. Record the .pythinker/AGENTS.md removal (with migration guidance) and the network-shell hardening under the Unreleased changelog section.
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/CODEOWNERS:
- Line 11: Replace single-person ownership entries in the CODEOWNERS file
(currently assigning `@mohamed-elkholy95` to critical paths and self-owning the
CODEOWNERS file) with a GitHub team to avoid a single point of failure: create
or use an existing org team such as `@Pythoughts-labs/maintainers` or
`@Pythoughts-labs/infra`, add multiple responsible members to that team, and
update the owner lines that reference `@mohamed-elkholy95` (including the entry
that gives ownership of the CODEOWNERS file) to reference the team instead so
critical surfaces (dependency files, telemetry, CI workflows, and the CODEOWNERS
file) require team review rather than a single individual.
- Line 11: The CODEOWNERS entry currently lists an invalid GitHub handle
"`@mohamed-elkholy95`" and concentrates many critical paths under a single
individual; update the .github/CODEOWNERS by replacing the invalid owner with a
valid GitHub team (e.g., a repo or org team like "org-name/team-name") and
distribute ownership of critical patterns (default lines, dependency surfaces,
telemetry, CI, and CODEOWNERS) across the appropriate teams instead of one user;
ensure you remove any self-owning reference to the .github directory and verify
the new team handles resolve on GitHub so review routing works correctly.
In `@docs/en/customization/agents.md`:
- Around line 167-180: Update the Agent tool description to reflect the full set
of built-in subagents (coder, implementer, explore, plan, review, code-reviewer,
security-reviewer, debugger, verifier, judge) and their tool policies; replace
the previous "only three built-ins" wording in the Agent section with a brief
list of these subagents and note which ones allow write tools (coder,
implementer) versus read-only or shell-only variants (explore, plan, review,
code-reviewer, security-reviewer, debugger, verifier, judge) so the Agent
documentation aligns with the table of built-ins above.
In `@src/pythinker_code/soul/permission.py`:
- Around line 361-362: The current check uses the immediate token in subcommand
to detect git network usage (if subcommand in _GIT_NETWORK) but this misses
cases where git flags/options (e.g., -c key=val, --option) appear before the
true subcommand; update the parsing logic where subcommand is evaluated so you
iterate over the git arguments to find the first non-option token (skip tokens
starting with '-' and treat '-c' as consuming its next value, honor '--' to end
options), then test that resolved token against _GIT_NETWORK and return
f"network access via git {resolved_subcommand}" when matched; reference the
existing subcommand variable and _GIT_NETWORK constant in permission.py to
locate and replace the simplistic check.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 0c6bfa32-ee34-4723-ae7c-7b812b72dbdf
📒 Files selected for processing (20)
.github/CODEOWNERSAGENTS.mdCHANGELOG.mddocs/en/customization/agents.mdsrc/pythinker_code/agents/default/agent.yamlsrc/pythinker_code/agents/default/judge.yamlsrc/pythinker_code/agents/default/plan.yamlsrc/pythinker_code/agents/default/system.mdsrc/pythinker_code/execution_profiles.pysrc/pythinker_code/soul/agent.pysrc/pythinker_code/soul/permission.pysrc/pythinker_code/subagents/runner.pysrc/pythinker_code/tools/agent/description.mdtests/core/test_agent_spec.pytests/core/test_default_agent.pytests/core/test_load_agent.pytests/core/test_load_agents_md.pytests/core/test_permission_profiles.pytests/tools/test_tool_descriptions.pytests/utils/test_pyinstaller_utils.py
There was a problem hiding this comment.
♻️ Duplicate comments (1)
.github/CODEOWNERS (1)
11-11:⚠️ Potential issue | 🔴 CriticalPast findings remain unaddressed.
The critical and major issues flagged in previous review comments are still present:
- Critical:
@mohamed-elkholy95does not exist on GitHub (verified 404). CODEOWNERS routing will fail entirely.- Major: Single owner assignment creates operational bottleneck for dependency updates, telemetry changes, CI workflows, and CODEOWNERS itself.
Recommendation remains: Replace with a valid GitHub team handle (e.g.,
@Pythoughts-labs/maintainers) for redundancy and functional review routing.Also applies to: 14-21, 24-25, 29-30
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/CODEOWNERS at line 11, Replace the invalid GitHub user handle `@mohamed-elkholy95` in the CODEOWNERS entries with a valid team handle (for example `@Pythoughts-labs/maintainers`) and add at least one additional owner per path to avoid a single-owner bottleneck; update every CODEOWNERS entry that references `@mohamed-elkholy95` to use the team handle and multiple maintainers, and ensure commit message explains the replacement so review routing and ownership of dependency/CI/telemetry changes works correctly.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Duplicate comments:
In @.github/CODEOWNERS:
- Line 11: Replace the invalid GitHub user handle `@mohamed-elkholy95` in the
CODEOWNERS entries with a valid team handle (for example
`@Pythoughts-labs/maintainers`) and add at least one additional owner per path to
avoid a single-owner bottleneck; update every CODEOWNERS entry that references
`@mohamed-elkholy95` to use the team handle and multiple maintainers, and ensure
commit message explains the replacement so review routing and ownership of
dependency/CI/telemetry changes works correctly.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 51485284-735f-4dcd-9dd9-ee492b3cb4de
📒 Files selected for processing (4)
.github/CODEOWNERSCHANGELOG.mdsrc/pythinker_code/soul/permission.pytests/core/test_permission_profiles.py
…bypass - CODEOWNERS: @mohamed-elkholy95 is a renamed/invalid login (404 on GitHub); use the current maintainer account @elkaix so code-owner review routing works. - permission.py: `git -c key=val <subcmd>` evaded git-network detection because _git_subcommand returned the -c value as the subcommand; consume -c and --config-env values so fetch/clone/ls-remote stay blocked in read-only profiles. - docs: align the Agent tool description's stale 'three built-in subagents' line with the full built-in subagent table.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/CODEOWNERS:
- Around line 11-30: Replace the single-user handle "`@elkaix`" in
.github/CODEOWNERS with a GitHub team that actually has repo access (e.g.,
"`@Pythoughts-labs/reviewers`") so review routing works; update every occurrence
(the top-level "*", dependency entries like "pyproject.toml",
"package.json"/"package-lock.json" and their globs, telemetry path
"src/pythinker_code/telemetry/", docs "docs/en/reference/telemetry.md", CI
workflows ".github/workflows/" and the CODEOWNERS file itself) to reference the
team instead of "`@elkaix`" ensuring the chosen team exists and has the required
permissions.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: bf1f3201-5993-4aa0-bbde-24e56983485d
📒 Files selected for processing (4)
.github/CODEOWNERSdocs/en/customization/agents.mdsrc/pythinker_code/soul/permission.pytests/core/test_permission_profiles.py
Stripping -c/--config-env (previous commit) was insufficient: `git -c core.pager=<cmd> log` runs arbitrary commands via an otherwise read-only subcommand, and stripping the value hid the override behind an allowed subcommand. Instead, treat any -c/--config-env/--exec-path on a git command as unsafe in read-only/review/verify profiles and block it outright (judge/verifier never need config overrides). Plain read-only git (diff/log/show/status, -C <path>) stays allowed. Flagged by automated security review.
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
tests/core/test_permission_profiles.py (1)
77-79:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winKeep this denial test fully offline.
If the guard regresses, this command will make a real outbound request in CI. A no-network invocation of a blocked client, such as
curl --version, still exercises the same permission path without depending on external connectivity.Suggested change
- result = await shell(ShellParams(command="curl -s https://example.com")) + result = await shell(ShellParams(command="curl --version"))🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/core/test_permission_profiles.py` around lines 77 - 79, The test currently invokes Shell with ShellParams(command="curl -s https://example.com") which performs a real outbound request; change the command to a no-network invocation that still exercises the denial path (e.g. ShellParams(command="curl --version") or another local-only curl flag) so the test remains fully offline; update the call in the with tool_call_context("Shell") block where Shell(Approval(yolo=True), environment, runtime) is instantiated and the resulting await shell(...) invocation uses the offline command.src/pythinker_code/soul/permission.py (1)
360-364:⚠️ Potential issue | 🟠 Major | 🏗️ Heavy liftFail-closed
gitsubcommand handling in_segment_mutation_reason(blocks unknowns +git <alias>with!)subcommand = _git_subcommand(args) if subcommand in _GIT_MUTATIONS: return f"git {subcommand}" if subcommand in _GIT_NETWORK: return f"network access via git {subcommand}"In
src/pythinker_code/soul/permission.py(_segment_mutation_reason), ifbase == "git"and_has_unsafe_git_global_option(args)is false, only_GIT_MUTATIONS/_GIT_NETWORKare blocked; any othergit <subcommand>is allowed (fail-open). This is a security boundary hole: Git aliases defined ingitconfiglikealias.foo =! <shell command>are executed as shell commands when invoked asgit foo, even thoughfoois not a built-in. Deny/allowlist unknowngitsubcommands here (fail closed for read-only/review/verify), not just the small set that are known mutating/networking.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/pythinker_code/soul/permission.py` around lines 360 - 364, In _segment_mutation_reason, when base == "git" and _has_unsafe_git_global_option(args) is false, don't allow unknown git subcommands by default; after computing subcommand via _git_subcommand(args), keep the existing checks for _GIT_MUTATIONS and _GIT_NETWORK, and add a fallback that treats any subcommand not in the known safe/read-only allowlist as a mutation (i.e., return f"git {subcommand}" or otherwise mark it denied) so git aliases like `git foo` (which may run shell commands via `alias.foo =! ...`) are blocked—update the logic around _git_subcommand, _GIT_MUTATIONS and _GIT_NETWORK in _segment_mutation_reason to fail-closed for unknown subcommands.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@src/pythinker_code/soul/permission.py`:
- Around line 360-364: In _segment_mutation_reason, when base == "git" and
_has_unsafe_git_global_option(args) is false, don't allow unknown git
subcommands by default; after computing subcommand via _git_subcommand(args),
keep the existing checks for _GIT_MUTATIONS and _GIT_NETWORK, and add a fallback
that treats any subcommand not in the known safe/read-only allowlist as a
mutation (i.e., return f"git {subcommand}" or otherwise mark it denied) so git
aliases like `git foo` (which may run shell commands via `alias.foo =! ...`) are
blocked—update the logic around _git_subcommand, _GIT_MUTATIONS and _GIT_NETWORK
in _segment_mutation_reason to fail-closed for unknown subcommands.
In `@tests/core/test_permission_profiles.py`:
- Around line 77-79: The test currently invokes Shell with
ShellParams(command="curl -s https://example.com") which performs a real
outbound request; change the command to a no-network invocation that still
exercises the denial path (e.g. ShellParams(command="curl --version") or another
local-only curl flag) so the test remains fully offline; update the call in the
with tool_call_context("Shell") block where Shell(Approval(yolo=True),
environment, runtime) is instantiated and the resulting await shell(...)
invocation uses the offline command.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: d5511dab-d0df-49c6-948a-452e07076746
📒 Files selected for processing (2)
src/pythinker_code/soul/permission.pytests/core/test_permission_profiles.py
Related Issue
Resolve #(issue_number)
Description
Checklist
make gen-changelogto update the changelog.make gen-docsto update the user documentation.Summary by CodeRabbit