feat: add guarded php-bin policy consumer - #8
Conversation
📝 WalkthroughWalkthroughAdds a guarded PHP maintenance system with policy capture, evidence-bound agent contracts, deterministic patch sealing, validation and repair orchestration, readiness records, exact stable-version checks, repository governance documentation, and supporting tests. ChangesGuarded maintenance automation
Exact stable PHP support
Estimated code review effort: 5 (Critical) | ~120 minutes Sequence Diagram(s)sequenceDiagram
participant Schedule
participant MaintenanceConsumerWorkflow
participant Consumer
participant Admission
participant Codex
participant PluginChecks
participant GitHub
Schedule->>MaintenanceConsumerWorkflow: trigger scheduled or manual run
MaintenanceConsumerWorkflow->>Consumer: fetch and compare pinned policy
Consumer-->>MaintenanceConsumerWorkflow: trigger and action key
MaintenanceConsumerWorkflow->>Codex: generate evidence-bound investigation plan
Codex-->>MaintenanceConsumerWorkflow: maintenance plan
MaintenanceConsumerWorkflow->>Admission: admit plan against contract and digests
Admission-->>MaintenanceConsumerWorkflow: admitted plan
MaintenanceConsumerWorkflow->>Codex: implement or repair admitted change
Codex-->>MaintenanceConsumerWorkflow: implementation result
MaintenanceConsumerWorkflow->>Admission: seal deterministic patch
Admission-->>MaintenanceConsumerWorkflow: sealed patch and manifest
MaintenanceConsumerWorkflow->>PluginChecks: apply patch and run authoritative checks
PluginChecks-->>MaintenanceConsumerWorkflow: validation result
MaintenanceConsumerWorkflow->>GitHub: merge validated patch and readiness record
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
5d927d4 to
2d17829
Compare
There was a problem hiding this comment.
Actionable comments posted: 10
🧹 Nitpick comments (4)
maintenance/admission.py (1)
309-323: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winParse git path output with
-zto avoid quoted-path mismatches.
--name-onlyandls-filesquote non-ASCII/special paths ("\303\251.txt") unless-zis used, so those entries won't match the real filesystem path and sealing fails with a misleading "unsupported diff entry". Fail-closed, but confusing.♻️ Proposed refactor
- changed = subprocess.run( - ["git", "diff", "--name-only", "--diff-filter=ACDMRTUXB", base, "--"], + changed = subprocess.run( + ["git", "-c", "core.quotePath=false", "diff", "-z", "--name-only", "--diff-filter=ACDMRTUXB", base, "--"], cwd=repo, check=True, text=True, stdout=subprocess.PIPE, - ).stdout.splitlines() - untracked = subprocess.run( - ["git", "ls-files", "--others", "--exclude-standard"], + ).stdout.split("\0") + untracked = subprocess.run( + ["git", "ls-files", "-z", "--others", "--exclude-standard"], cwd=repo, check=True, text=True, stdout=subprocess.PIPE, - ).stdout.splitlines() - paths = sorted(set(changed + untracked)) + ).stdout.split("\0") + paths = sorted({item for item in changed + untracked if item})🤖 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 `@maintenance/admission.py` around lines 309 - 323, Update the git path collection in the changed and untracked subprocess calls to use NUL-delimited output via the appropriate -z options, then parse stdout by NUL separators instead of splitlines(). Preserve the existing filtering, path combination, and sorting behavior so non-ASCII and special filenames match their real filesystem paths..github/workflows/maintenance-consumer.yml (1)
63-70: 🔒 Security & Privacy | 🔵 Trivial | 💤 Low valueMove
${{ }}expansions intoenv:for therunblocks.zizmor flags the inline expansions; these values are validated upstream so this isn't exploitable today, but binding them via
env:removes the whole class and keeps the interpolation out of the shell parse. Same pattern applies to the other inline expansions inrunsteps in this file.♻️ Proposed refactor
- name: Prepare exact investigation contract if: steps.compare.outputs.trigger != 'quiet' && steps.operator.outputs.state == 'enabled' + env: + OPERATOR_COMMIT: ${{ steps.operator.outputs.commit }} + OPERATOR_STATE: ${{ steps.operator.outputs.state }} run: | jq -n \ ... - --arg phpBinOperatorCommit "${{ steps.operator.outputs.commit }}" \ - --arg operatorState "${{ steps.operator.outputs.state }}" \ + --arg phpBinOperatorCommit "$OPERATOR_COMMIT" \ + --arg operatorState "$OPERATOR_STATE" \🤖 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/workflows/maintenance-consumer.yml around lines 63 - 70, Move all GitHub Actions `${{ }}` expressions used inside `run` steps in the maintenance workflow into step-level `env:` entries, including the values currently passed to jq arguments such as operator commit and state. Update the shell commands to reference the corresponding environment variables, preserving existing names and behavior while removing inline expression interpolation from shell parsing.Source: Linters/SAST tools
test/test_maintenance.py (2)
64-69: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
protected()test only covers 4 of 11 protected globs.
PROTECTEDinmaintenance/admission.pyguards 11 path patterns (.codex/*,schemas/*,.github/CODEOWNERS, the three named admission scripts, etc.), but this test only exercises.github/workflows/*,maintenance/*,maintenance-events/*, andreadiness/*. Given the PR's fail-closed guarantee for these control-plane paths, a regression silently dropping an entry fromPROTECTED(e.g. the admission script names) wouldn't be caught here.♻️ Suggested additional coverage
def test_protected_controls_are_not_admissible(self): self.assertTrue(protected(".github/workflows/maintenance.yml")) self.assertTrue(protected("maintenance/admission.py")) self.assertTrue(protected("maintenance-events/new-patch.json")) self.assertTrue(protected("readiness/new-branch.json")) + self.assertTrue(protected(".codex/implementation.config.toml")) + self.assertTrue(protected("schemas/maintenance-plan.schema.json")) + self.assertTrue(protected(".github/codex/maintenance/shared.md")) + self.assertTrue(protected(".github/CODEOWNERS")) + self.assertTrue(protected("scripts/admit-maintenance-plan")) + self.assertTrue(protected("scripts/seal-maintenance-patch")) + self.assertTrue(protected("scripts/verify-merge-admission")) self.assertFalse(protected("lib/releases.lua"))🤖 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 `@test/test_maintenance.py` around lines 64 - 69, Expand test_protected_controls_are_not_admissible to cover every path pattern defined by PROTECTED in the protected() implementation, including .codex/*, schemas/*, .github/CODEOWNERS, and each explicitly named admission script, while retaining the existing positive and negative assertions.
51-62: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAssert the expected consumer failure type.
readiness(... "main" ...)andpinned_policy_urls("main")raiseConsumerError, but these assertions currently catch bareException. CatchConsumerErrorinstead so unrelated regressions don’t satisfy the expected failure path. Also importConsumerErrorfrommaintenance.consumer.🤖 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 `@test/test_maintenance.py` around lines 51 - 62, Update test_readiness_requires_exact_commits_and_digests to import ConsumerError from maintenance.consumer and assert that the invalid readiness call raises ConsumerError instead of the broad Exception type, preserving the existing failure scenario.Source: Linters/SAST tools
🤖 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 9: Add an explicit CODEOWNERS entry for scripts/consume-php-policy,
assigning the same maintenance policy owners as the related control-path wrapper
so changes require the appropriate review.
In @.github/workflows/maintenance-consumer.yml:
- Around line 458-459: Update the gh pr create invocation in the maintenance
workflow so the --body value contains actual newline characters rather than
literal \n text. Preserve the existing title and body content, using the shell’s
supported multiline or escape-expansion mechanism.
- Around line 424-425: Update the job condition associated with the push/merge
step to use !cancelled() instead of always(), while preserving the existing
validation success requirements involving needs.validate.outputs.passed and
needs['validate-repair'].result.
- Around line 508-515: Replace the hardcoded success written to
maintenance-run/checks.json in the maintenance workflow with the real PR
check-results data already used by the jq -e enforcement step. Ensure the
generated JSON preserves each check’s actual status so verify-merge-admission
can reject non-success results, while keeping the existing verifier invocation
unchanged.
In `@lib/releases.lua`:
- Around line 55-58: Update M.is_exact_stable_version so each version component
rejects leading-zero forms while still accepting 0 and non-zero-leading
integers, including the optional hyphenated suffix. Add regression tests
covering padded components such as 08.01.001 and valid canonical stable
versions.
In `@maintenance/admission.py`:
- Around line 344-345: Update the secret-detection regex in the admission check
around the `re.search` call to use a regex word-boundary escape for the `sk-`
token pattern, rather than matching a literal backslash and `b`. Preserve the
existing private-key and `github_pat_` detection alternatives.
- Around line 211-218: Update the evidence validation around evidence_refs so
completeness requires every captured policy to be cited exactly once, not merely
matching the count. Reject duplicate captureId values and ensure the resulting
unique references cover all keys in captures_by_id while preserving the existing
digest validation.
- Around line 140-146: Update the admission logic for the action validation
block and downstream edit-bound checks so a valid “no_change” plan terminates
quietly before requiring editsRequired or support-snapshot.json in allowedPaths.
Preserve rejection of blocked and needs_human plans, and keep all other accepted
actions subject to the existing admission requirements.
In `@maintenance/consumer.py`:
- Around line 190-218: Update the policy validation around maintainedBranches,
sourceEvidenceDigests, actionKey, and acceptedAt to require string values before
passing them to re.fullmatch; ensure malformed JSON types, including numeric
list entries or non-string scalar fields, raise the existing ConsumerError
instead of TypeError. Preserve the current format, ordering, and policy-action
validations after type checks.
In `@schemas/agent-completion-assessment.schema.json`:
- Around line 4-12: Harden the control-plane schemas: in
schemas/agent-completion-assessment.schema.json (lines 4-12), validate
instruction digest fields and enforce that goNoGo "go" requires phaseStatus
"complete" with no unresolved items; in schemas/agent-task-contract.schema.json
(lines 4-14), require non-empty, correctly typed authority, criteria, non-goal,
and stop-condition values; in schemas/maintenance-plan.schema.json (lines
10-29), require exactly one non-empty evidence record for each of the four
distinct evidence types.
---
Nitpick comments:
In @.github/workflows/maintenance-consumer.yml:
- Around line 63-70: Move all GitHub Actions `${{ }}` expressions used inside
`run` steps in the maintenance workflow into step-level `env:` entries,
including the values currently passed to jq arguments such as operator commit
and state. Update the shell commands to reference the corresponding environment
variables, preserving existing names and behavior while removing inline
expression interpolation from shell parsing.
In `@maintenance/admission.py`:
- Around line 309-323: Update the git path collection in the changed and
untracked subprocess calls to use NUL-delimited output via the appropriate -z
options, then parse stdout by NUL separators instead of splitlines(). Preserve
the existing filtering, path combination, and sorting behavior so non-ASCII and
special filenames match their real filesystem paths.
In `@test/test_maintenance.py`:
- Around line 64-69: Expand test_protected_controls_are_not_admissible to cover
every path pattern defined by PROTECTED in the protected() implementation,
including .codex/*, schemas/*, .github/CODEOWNERS, and each explicitly named
admission script, while retaining the existing positive and negative assertions.
- Around line 51-62: Update test_readiness_requires_exact_commits_and_digests to
import ConsumerError from maintenance.consumer and assert that the invalid
readiness call raises ConsumerError instead of the broad Exception type,
preserving the existing failure scenario.
🪄 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: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 60bc9323-49ca-435a-bcb5-e6afd297c285
📒 Files selected for processing (33)
.codex/implementation.config.toml.codex/investigation.config.toml.codex/repair.config.toml.github/CODEOWNERS.github/codex/maintenance/implementation.md.github/codex/maintenance/investigation.md.github/codex/maintenance/repair.md.github/codex/maintenance/shared.md.github/workflows/ci.yml.github/workflows/e2e.yml.github/workflows/maintenance-consumer.yml.gitignoreREADME.mddocs/admin-state/mise-php-before.jsondocs/repository-settings.mdhooks/pre_install.lualib/releases.luamaintenance-events/.gitkeepmaintenance/__init__.pymaintenance/admission.pymaintenance/consumer.pyreadiness/.gitkeepschemas/agent-completion-assessment.schema.jsonschemas/agent-task-contract.schema.jsonschemas/maintenance-plan.schema.jsonscripts/admit-maintenance-planscripts/consume-php-policyscripts/seal-maintenance-patchscripts/test.shscripts/verify-merge-admissionsupport-snapshot.jsontest/mock_server.pytest/test_maintenance.py
| /schemas/ @loadinglucian | ||
| /scripts/admit-maintenance-plan @loadinglucian | ||
| /scripts/seal-maintenance-patch @loadinglucian | ||
| /scripts/verify-merge-admission @loadinglucian |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
Protect the policy-consumer entrypoint.
scripts/consume-php-policy is currently unmatched, so it can be altered without the CODEOWNER review applied to maintenance/. Add an explicit ownership rule for this control-path wrapper.
Proposed fix
/scripts/verify-merge-admission `@loadinglucian`
+/scripts/consume-php-policy `@loadinglucian`📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| /scripts/verify-merge-admission @loadinglucian | |
| /scripts/verify-merge-admission `@loadinglucian` | |
| /scripts/consume-php-policy `@loadinglucian` |
🤖 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 9, Add an explicit CODEOWNERS entry for
scripts/consume-php-policy, assigning the same maintenance policy owners as the
related control-path wrapper so changes require the appropriate review.
| needs: [investigate, validate, validate-repair] | ||
| if: always() && (needs.validate.outputs.passed == 'true' || needs['validate-repair'].result == 'success') |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
Use !cancelled() rather than always() on a job that pushes and merges.
always() keeps this job running when the workflow run is cancelled, so a cancelled run can still push a branch and merge a PR.
🐛 Proposed fix
- if: always() && (needs.validate.outputs.passed == 'true' || needs['validate-repair'].result == 'success')
+ if: ${{ !cancelled() && needs.investigate.result == 'success' && (needs.validate.outputs.passed == 'true' || needs['validate-repair'].result == 'success') }}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| needs: [investigate, validate, validate-repair] | |
| if: always() && (needs.validate.outputs.passed == 'true' || needs['validate-repair'].result == 'success') | |
| needs: [investigate, validate, validate-repair] | |
| if: ${{ !cancelled() && needs.investigate.result == 'success' && (needs.validate.outputs.passed == 'true' || needs['validate-repair'].result == 'success') }} |
🤖 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/workflows/maintenance-consumer.yml around lines 424 - 425, Update
the job condition associated with the push/merge step to use !cancelled()
instead of always(), while preserving the existing validation success
requirements involving needs.validate.outputs.passed and
needs['validate-repair'].result.
| url="$(gh pr create --base main --head "$branch" --title "chore: $action_key" \ | ||
| --body "Deterministically sealed mise-php maintenance patch.\n\nValidated commit: \`$validated\`.")" |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
\n is not interpreted inside double quotes; the PR body renders literal \n.
🐛 Proposed fix
- url="$(gh pr create --base main --head "$branch" --title "chore: $action_key" \
- --body "Deterministically sealed mise-php maintenance patch.\n\nValidated commit: \`$validated\`.")"
+ url="$(gh pr create --base main --head "$branch" --title "chore: $action_key" \
+ --body "$(printf 'Deterministically sealed mise-php maintenance patch.\n\nValidated commit: `%s`.' "$validated")")"📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| url="$(gh pr create --base main --head "$branch" --title "chore: $action_key" \ | |
| --body "Deterministically sealed mise-php maintenance patch.\n\nValidated commit: \`$validated\`.")" | |
| url="$(gh pr create --base main --head "$branch" --title "chore: $action_key" \ | |
| --body "$(printf 'Deterministically sealed mise-php maintenance patch.\n\nValidated commit: `%s`.' "$validated")")" |
🤖 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/workflows/maintenance-consumer.yml around lines 458 - 459, Update
the gh pr create invocation in the maintenance workflow so the --body value
contains actual newline characters rather than literal \n text. Preserve the
existing title and body content, using the shell’s supported multiline or
escape-expansion mechanism.
| jq -n '{"Plugin contract":"success"}' > maintenance-run/checks.json | ||
| ./scripts/verify-merge-admission \ | ||
| --repo . \ | ||
| --head "$expected" \ | ||
| --manifest maintenance-run/sealed/patch-manifest.json \ | ||
| --checks maintenance-run/checks.json \ | ||
| --preconditions maintenance-run/preconditions.json \ | ||
| --current maintenance-run/current.json |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win
Derive checks.json from the real PR check results instead of hardcoding success.
verify_merge rejects when any check value is not "success" (maintenance/admission.py line 427), but the input is synthesized as a constant here, so that gate can never fire. The actual enforcement only lives in the jq -e on line 470; feed the same data to the verifier.
♻️ Proposed fix
- jq -n '{"Plugin contract":"success"}' > maintenance-run/checks.json
+ jq '[.[] | {key: .name, value: (if .bucket == "pass" then "success" else .bucket end)}] | from_entries' \
+ maintenance-run/pr-checks.json > maintenance-run/checks.json📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| jq -n '{"Plugin contract":"success"}' > maintenance-run/checks.json | |
| ./scripts/verify-merge-admission \ | |
| --repo . \ | |
| --head "$expected" \ | |
| --manifest maintenance-run/sealed/patch-manifest.json \ | |
| --checks maintenance-run/checks.json \ | |
| --preconditions maintenance-run/preconditions.json \ | |
| --current maintenance-run/current.json | |
| jq '[.[] | {key: .name, value: (if .bucket == "pass" then "success" else .bucket end)}] | from_entries' \ | |
| maintenance-run/pr-checks.json > maintenance-run/checks.json | |
| ./scripts/verify-merge-admission \ | |
| --repo . \ | |
| --head "$expected" \ | |
| --manifest maintenance-run/sealed/patch-manifest.json \ | |
| --checks maintenance-run/checks.json \ | |
| --preconditions maintenance-run/preconditions.json \ | |
| --current maintenance-run/current.json |
🤖 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/workflows/maintenance-consumer.yml around lines 508 - 515, Replace
the hardcoded success written to maintenance-run/checks.json in the maintenance
workflow with the real PR check-results data already used by the jq -e
enforcement step. Ensure the generated JSON preserves each check’s actual status
so verify-merge-admission can reject non-success results, while keeping the
existing verifier invocation unchanged.
| function M.is_exact_stable_version(version) | ||
| return version:match("^%d+%.%d+%.%d+$") ~= nil | ||
| or version:match("^%d+%.%d+%.%d+%-[1-9]%d*$") ~= nil | ||
| end |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== locate releases.lua =="
fd -a 'releases\.lua$' . | sed 's#^\./##'
echo "== git diff stat =="
git diff --stat || true
echo "== inspect file outline and relevant lines =="
if [ -f lib/releases.lua ]; then
wc -l lib/releases.lua
ast-grep outline lib/releases.lua || true
echo "== lines 1-140 =="
sed -n '1,140p' lib/releases.lua | nl -ba
fi
echo "== search is_exact_stable_version usages =="
rg -n "is_exact_stable_version|find|release|stable_version|match\\^%d+\\.%" . || trueRepository: Bigpixelrocket/mise-php
Length of output: 399
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== Locate version parsing in relevant files =="
rg -n "is_exact_stable_version|find.*version|release_lookup|GetLatest|GetRelease|match\\^%d|VERSION" . \
-g '!*.png' -g '!*.jpg' -g '!*.gif' || true
echo "== Focus Lua parser/version behavior from config files =="
fd -i '.*\\.(toml|json|lua|sh|m4|ac)$' . | head -200 | sed -n '1,160p'Repository: Bigpixelrocket/mise-php
Length of output: 1203
🌐 Web query:
mise-php Bigpixelrocket releases.lua is_exact_stable_version version patterns
💡 Result:
The terms mentioned, such as "Bigpixelrocket," "releases.lua," "is_exact_stable_version," and specific "version patterns," do not appear to be standard components of the official core mise project (formerly asdf-rust) [1][2] or the common verzly/mise-php plugin [3][4]. Based on the available evidence: 1. Bigpixelrocket: This name appears in license files for specific community projects (e.g., laravel-omakase and laravel-mise) [5][6], but it is not a recognized maintainer or component of the primary mise CLI or its standard PHP plugins [4]. 2. Releases.lua, is_exact_stable_version, and version patterns: These do not exist as public-facing configurations or internal APIs in the official mise codebase [1][2] or the verzly/mise-php repository [3][4]. Version resolution in mise is generally handled through its core backend logic [2], which supports automatic detection of tags (optionally handling "v" prefixes) [2] rather than user-defined Lua scripts or specific "is_exact_stable_version" flags [1]. If you are encountering these terms, they are likely part of a specific, private, or experimental wrapper or plugin unrelated to the standard ecosystem. You may wish to check the specific repository where you encountered these files for custom documentation or README.md files, as they are not standard to mise itself.
Citations:
- 1: https://github.com/Homebrew/homebrew-core/blob/2a176ef86ce1e74f17358a631e4c685b5fcfb6e4/Formula/m/mise.rb
- 2: feat: improve asset auto-detection and version prefix handling jdx/mise#5625
- 3: https://github.com/verzly/mise-php/releases
- 4: https://github.com/verzly/mise-php
- 5: https://github.com/loadinglucian/laravel-mise/blob/HEAD/LICENSE
- 6: https://github.com/bigpixelrocket/laravel-omakase/blob/main/LICENSE
🌐 Web query:
Bigpixelrocket Bigpixelrocket/mise-php releases.lua is_exact_stable_version
💡 Result:
There is no official or commonly referenced code, file, or function named is_exact_stable_version associated with a repository named Bigpixelrocket/mise-php. The primary plugin for managing PHP versions within the mise tool is verzly/mise-php [1]. Research indicates that Bigpixelrocket is a separate entity/handle associated with other projects, such as laravel-omakase, but is not the maintainer of the standard PHP plugin for mise [2][3]. Furthermore, the term is_exact_stable_version does not appear in the public source code or documentation for the mise tool or its common PHP plugins [4][1][5][6]. It is possible that the query refers to internal logic within a specific, non-standard, or private repository, or perhaps a misunderstanding of mise's internal mechanisms, which prioritize version resolution based on tags or definitions provided in the plugin's metadata [1]. If you are encountering this term in a specific script or configuration, it may be a custom-defined variable or function within that local environment rather than part of the mise-php ecosystem.
Citations:
- 1: https://github.com/verzly/mise-php
- 2: https://github.com/loadinglucian/laravel-mise/blob/HEAD/LICENSE
- 3: https://github.com/bigpixelrocket/laravel-omakase/blob/main/LICENSE
- 4: https://github.com/verzly/mise-php/releases
- 5: https://github.com/jdx/mise/releases
- 6: https://github.com/jdx/mise/blob/main/CHANGELOG.md
🌐 Web query:
"Bigpixelrocket" "lib/releases.lua" "is_exact_stable_version" "8.1.99"
💡 Result:
Based on the available information, there is no widely recognized or authoritative technical library or project known as "Bigpixelrocket" that contains a lib/releases.lua file with a function named is_exact_stable_version. The term "Bigpixelrocket" appears to be associated with a small graphic design agency [1] and has been identified as a vendor namespace in certain PHP/Laravel-related projects [2][3], but it is not a known source for Lua-based versioning utilities. Publicly available Lua versioning tools, such as kikito/semver.lua [4] or Akionka/lua-semver [5], use standard Semantic Versioning (SemVer) practices but do not feature a function specifically named is_exact_stable_version in a lib/releases.lua file. Similarly, general scripts named releases.lua exist in various open-source projects (e.g., pixie-io/pixie [6] or ColumPaget/releases.lua [7]), but they do not appear to match the specific query parameters provided. It is possible that this function exists within a private or highly specific internal codebase not indexed by public search engines.
Citations:
- 1: https://linkedin.com/company/bigpixelrocket
- 2: https://libraries.io/packagist/loadinglucian%2Flaravel-mise
- 3: wip loadinglucian/deployer-php#8
- 4: https://github.com/kikito/semver.lua
- 5: https://github.com/Akionka/lua-semver
- 6: https://github.com/pixie-io/pixie/blob/ce714e6e/scripts/regclient/releases.lua
- 7: https://github.com/ColumPaget/releases.lua
🌐 Web query:
"8.4.99" "php-bin" "bigpixelrocket" release tags
💡 Result:
There is no known software release, package, or technical identifier corresponding to "8.4.99 php-bin bigpixelrocket". Research indicates that "Bigpixelrocket" is a small graphic design agency [1], and while it is associated with developers (such as those managing projects like "deployer-php" or "laravel-mise" on GitHub [2][3][4]), there is no evidence linking the entity to a product named "php-bin" or a version "8.4.99". "php-bin" is a common name for repositories providing pre-compiled PHP binaries (often used by projects like NativePHP [5], phpacker [6][7], or Cecil [8]), but these projects are distinct from Bigpixelrocket. Furthermore, PHP 8.4 versions are currently in the 8.4.x series (e.g., 8.4.12, 8.4.20) [9][8], and "8.4.99" is not a standard release tag for any PHP-related binary project. It is likely that this query conflates unrelated terms.
Citations:
- 1: https://linkedin.com/company/bigpixelrocket
- 2: wip loadinglucian/deployer-php#8
- 3: Test review testing rules workflow loadinglucian/deployer-php#11
- 4: https://libraries.io/packagist/loadinglucian%2Flaravel-mise
- 5: https://github.com/NativePHP/php-bin
- 6: https://packagist.org/packages/phpacker/php-bin
- 7: https://github.com/Tinywan/php-bin
- 8: Update PHP 8.4 build for linux x64 Cecilapp/php-bin#46
- 9: Update PHP 8.4 build for linux x64 NativePHP/php-bin#266
🌐 Web query:
"lib/releases.lua" "55-58" "is_exact_stable_version" "version:match"
💡 Result:
The phrase "is_exact_stable_version" paired with "version:match" does not appear to be part of a single, widely recognized standard library or public Lua project. Based on a search of common Lua repositories, these terms are likely specific to a private or project-specific implementation of version management. In the context of Lua version handling: 1. Version Matching Logic: Projects like kong/version.lua [1][2] and kikito/semver.lua [3] use match methods as part of their object-oriented APIs to determine if a version satisfies a range or condition. The version:match pattern is common in these libraries, where a version object (or range object) is evaluated against another string or object. 2. Implementation Examples: Other tools, such as toolchainlib (using Luau), utilize version:match with variant-like patterns to branch logic based on whether a version is provided (Some/None) [4]. 3. Semantic Versioning: If you are looking for code responsible for parsing and matching versions, you should verify if your project relies on one of the common Lua semantic versioning libraries mentioned above, which handle version string parsing via string.match internally [5][3]. If lib/releases.lua is a file in a specific repository you are working with, it is highly probable that is_exact_stable_version is a helper function defined within that file to restrict matching to stable releases (e.g., excluding pre-releases like -alpha or -beta tags) by using version:match to validate the version's format or to compare it against a strict pattern [5][6]. You may find the exact implementation by examining that specific file's source code.
Citations:
- 1: https://kong.github.io/version.lua/
- 2: https://github.com/Kong/version.lua/blob/master/src/version.lua
- 3: https://github.com/kikito/semver.lua
- 4: https://github.com/pesde-pkg/tooling/blob/e17fd8c40948ab553e984fd9d154ba5394d0a532/toolchainlib/src/init.luau
- 5: https://github.com/mason-org/mason.nvim/blob/b03fb0f2/lua/mason-vendor/semver.lua
- 6: https://github.com/keplerproject/luarocks/blob/7a7c124/src/luarocks/deps.lua
🌐 Web query:
GitHub "Bigpixelrocket" "mise-php" "test/mock_server.py"
💡 Result:
There is no public GitHub repository or project named Bigpixelrocket/mise-php, and no file path matching test/mock_server.py exists within any known context for such a project [1][2][3]. It is possible that the query refers to a private repository, a misremembered name, or a conflation of several different projects: 1. PHP plugins for mise: The most prominent mise plugins for PHP are verzly/mise-php [1][2] and tobiashochguertel/mise-php-plugin [3]. 2. Mock servers in testing: Files named mock_server.py are common in many open-source projects for testing purposes [4][5][6], but none are associated with a "Bigpixelrocket" project. 3. Laravel-related packages: There is a separate package associated with the handle "bigpixelrocket" called laravel-omakase [7], but it is unrelated to mise or a mock server of that name. If you are looking for a specific testing script for mise-related development, you may be thinking of the official mise repository, which includes a tool_stub_test_server.py file used for end-to-end testing [4].
Citations:
- 1: https://github.com/verzly/mise-php
- 2: https://github.com/verzly/mise-php/tree/v0.7.0
- 3: https://github.com/tobiashochguertel/mise-php-plugin
- 4: https://github.com/jdx/mise/blob/14f2830c/e2e/helpers/scripts/tool_stub_test_server.py
- 5: https://github.com/gca-americas/way-back-home/blob/main/solutions/level_3/mock/mock_server.py
- 6: https://github.com/slavaZim/episodiq/blob/main/benchmarks/demo_eval/mock_server.py
- 7: https://libraries.io/packagist/loadinglucian%2Flaravel-mise
🌐 Web query:
"lib/releases.lua" "\"08.01.001\" \"%d+%.%d+%.%d+\""
💡 Result:
The string "08.01.001" and the Lua pattern "%d+%.%d+%.%d+" are frequently used in Lua programming for version parsing and validation [1][2]. In Lua, the pattern "%d+%.%d+%.%d+" is a common way to match semantic version strings [2][3]. The components work as follows: - %d+: Matches one or more digits [2]. - %.: Matches a literal dot character (the % escapes the special meaning of the dot in Lua patterns) [2][3]. While there is no single authoritative library named "lib/releases.lua" that defines these globally, many projects use files named releases.lua to handle versioning, release metadata, or registry synchronization [4][5][6][7][8]. In such contexts, code typically utilizes string.match or string.find with this pattern to validate or extract version numbers from strings like "08.01.001" [2][9][3]. For example, a typical implementation might look like this: local version = "08.01.001" local match = string.match(version, "%d+%.%d+%.%d+") if match then print("Valid version format: ".. match) end This approach is standard for parsing version identifiers in Lua, leveraging the language's built-in pattern-matching library [2][9].
Citations:
- 1: https://tst2005.github.io/lua-users.org/wiki/PatternsTutorial.html
- 2: https://www.lua.org/pil/20.2.html
- 3: https://tst2005.github.io/lua-users.org/wiki/StringLibraryTutorial.html
- 4: https://github.com/pixie-io/pixie/blob/ce714e6e/scripts/regclient/releases.lua
- 5: https://github.com/alpinelinux/docker-alpine/blob/master/fetch-latest-releases.lua
- 6: https://github.com/ColumPaget/releases.lua
- 7: pixie-io/pixie@4c79b64
- 8: taigrr/neocrush.nvim@0eee05d
- 9: https://www.lua.org/pil/20.1.html
Enforce canonical version components.
%d+ accepts zero-padded versions such as 08.01.001, so malformed stable versions can pass the “exact stable” gate before release lookup. Validate each component as 0 or a non-zero-leading integer, and add regression tests.
🤖 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 `@lib/releases.lua` around lines 55 - 58, Update M.is_exact_stable_version so
each version component rejects leading-zero forms while still accepting 0 and
non-zero-leading integers, including the optional hyphenated suffix. Add
regression tests covering padded components such as 08.01.001 and valid
canonical stable versions.
| if plan.get("action") not in { | ||
| "no_change", "new_patch", "new_branch", "branch_eol", "repair", | ||
| "reconcile_partial", "blocked", "needs_human", | ||
| }: | ||
| raise AdmissionError("invalid maintenance action") | ||
| if plan.get("action") in {"blocked", "needs_human"}: | ||
| raise AdmissionError("no-go plan cannot advance") |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
no_change is an accepted action but can never be admitted.
Line 241 requires editsRequired is True and line 263 requires support-snapshot.json in allowedPaths, so any no_change plan is rejected with a hard error rather than terminating quietly. The workflow's edits_required output is only consulted after admission, so a legitimate no-change conclusion fails the scheduled run. Either drop no_change from the accepted set or short-circuit it before the edit-bound checks.
♻️ Sketch
- if plan.get("action") in {"blocked", "needs_human"}:
+ if plan.get("action") in {"blocked", "needs_human"}:
raise AdmissionError("no-go plan cannot advance")
+ if plan.get("action") == "no_change":
+ return {
+ "admitted": True,
+ "actionKey": plan.get("actionKey", ""),
+ "planDigest": digest_bytes(canonical(plan)),
+ "instructionDigests": {},
+ }📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if plan.get("action") not in { | |
| "no_change", "new_patch", "new_branch", "branch_eol", "repair", | |
| "reconcile_partial", "blocked", "needs_human", | |
| }: | |
| raise AdmissionError("invalid maintenance action") | |
| if plan.get("action") in {"blocked", "needs_human"}: | |
| raise AdmissionError("no-go plan cannot advance") | |
| if plan.get("action") not in { | |
| "no_change", "new_patch", "new_branch", "branch_eol", "repair", | |
| "reconcile_partial", "blocked", "needs_human", | |
| }: | |
| raise AdmissionError("invalid maintenance action") | |
| if plan.get("action") in {"blocked", "needs_human"}: | |
| raise AdmissionError("no-go plan cannot advance") | |
| if plan.get("action") == "no_change": | |
| return { | |
| "admitted": True, | |
| "actionKey": plan.get("actionKey", ""), | |
| "planDigest": digest_bytes(canonical(plan)), | |
| "instructionDigests": {}, | |
| } |
🤖 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 `@maintenance/admission.py` around lines 140 - 146, Update the admission logic
for the action validation block and downstream edit-bound checks so a valid
“no_change” plan terminates quietly before requiring editsRequired or
support-snapshot.json in allowedPaths. Preserve rejection of blocked and
needs_human plans, and keep all other accepted actions subject to the existing
admission requirements.
| evidence = plan.get("evidence", []) | ||
| if not isinstance(evidence, list) or len(evidence) != len(captures_by_id): | ||
| raise AdmissionError("plan does not cite the complete captured policy set") | ||
| evidence_refs = set() | ||
| for index, item in enumerate(evidence): | ||
| capture = captures_by_id.get(item.get("captureId")) if isinstance(item, dict) else None | ||
| if capture is None or item.get("digest") != capture.get("digest"): | ||
| raise AdmissionError("plan evidence does not match the captured policy") |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
Evidence completeness check can be satisfied by duplicate citations.
len(evidence) != len(captures_by_id) only enforces a count. Four entries all citing support_policy pass, so the plan need not cite all four captures despite the error message claiming completeness.
🔒 Proposed fix
evidence = plan.get("evidence", [])
if not isinstance(evidence, list) or len(evidence) != len(captures_by_id):
raise AdmissionError("plan does not cite the complete captured policy set")
+ cited = {item.get("captureId") for item in evidence if isinstance(item, dict)}
+ if cited != set(captures_by_id):
+ raise AdmissionError("plan does not cite each captured policy exactly once")📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| evidence = plan.get("evidence", []) | |
| if not isinstance(evidence, list) or len(evidence) != len(captures_by_id): | |
| raise AdmissionError("plan does not cite the complete captured policy set") | |
| evidence_refs = set() | |
| for index, item in enumerate(evidence): | |
| capture = captures_by_id.get(item.get("captureId")) if isinstance(item, dict) else None | |
| if capture is None or item.get("digest") != capture.get("digest"): | |
| raise AdmissionError("plan evidence does not match the captured policy") | |
| evidence = plan.get("evidence", []) | |
| if not isinstance(evidence, list) or len(evidence) != len(captures_by_id): | |
| raise AdmissionError("plan does not cite the complete captured policy set") | |
| cited = {item.get("captureId") for item in evidence if isinstance(item, dict)} | |
| if cited != set(captures_by_id): | |
| raise AdmissionError("plan does not cite each captured policy exactly once") | |
| evidence_refs = set() | |
| for index, item in enumerate(evidence): | |
| capture = captures_by_id.get(item.get("captureId")) if isinstance(item, dict) else None | |
| if capture is None or item.get("digest") != capture.get("digest"): | |
| raise AdmissionError("plan evidence does not match the captured policy") |
🤖 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 `@maintenance/admission.py` around lines 211 - 218, Update the evidence
validation around evidence_refs so completeness requires every captured policy
to be cited exactly once, not merely matching the count. Reject duplicate
captureId values and ensure the resulting unique references cover all keys in
captures_by_id while preserving the existing digest validation.
| if re.search(r"-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----|github_pat_|\\bsk-[A-Za-z0-9_-]{20,}", text): | ||
| raise AdmissionError(f"secret-like material in diff: {path}") |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
\\b in the raw-string regex is a literal backslash, disabling the sk- token check.
In a raw string \\b matches a backslash followed by b, not a word boundary, so sk-… keys are only detected when literally preceded by \. Use \b.
🔒 Proposed fix
- if re.search(r"-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----|github_pat_|\\bsk-[A-Za-z0-9_-]{20,}", text):
+ if re.search(r"-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----|github_pat_|\bsk-[A-Za-z0-9_-]{20,}", text):
raise AdmissionError(f"secret-like material in diff: {path}")📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if re.search(r"-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----|github_pat_|\\bsk-[A-Za-z0-9_-]{20,}", text): | |
| raise AdmissionError(f"secret-like material in diff: {path}") | |
| if re.search(r"-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----|github_pat_|\bsk-[A-Za-z0-9_-]{20,}", text): | |
| raise AdmissionError(f"secret-like material in diff: {path}") |
🤖 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 `@maintenance/admission.py` around lines 344 - 345, Update the secret-detection
regex in the admission check around the `re.search` call to use a regex
word-boundary escape for the `sk-` token pattern, rather than matching a literal
backslash and `b`. Preserve the existing private-key and `github_pat_` detection
alternatives.
| branches = policy_document.get("maintainedBranches") | ||
| if not ( | ||
| isinstance(branches, list) | ||
| and all(re.fullmatch(r"\d+\.\d+", value) for value in branches) | ||
| and branches == sorted(set(branches), key=lambda value: tuple(map(int, value.split(".")))) | ||
| ): | ||
| raise ConsumerError("captured php-bin branches are invalid or non-canonical") | ||
| evidence = policy_document.get("sourceEvidenceDigests") | ||
| if not ( | ||
| isinstance(evidence, list) | ||
| and all(re.fullmatch(r"sha256:[0-9a-f]{64}", value) for value in evidence) | ||
| and evidence == sorted(set(evidence)) | ||
| ): | ||
| raise ConsumerError("captured php-bin support evidence is invalid or non-canonical") | ||
| policy_action = policy_document.get("actionKey") | ||
| if not ( | ||
| policy_action == "bootstrap" | ||
| or re.fullmatch( | ||
| r"(?:new_branch:\d+\.\d+|branch_eol:\d+\.\d+:\d{4}-\d{2}-\d{2})", | ||
| policy_action or "", | ||
| ) | ||
| ): | ||
| raise ConsumerError("captured php-bin support action key is invalid") | ||
| if policy_action != "bootstrap" and not evidence: | ||
| raise ConsumerError("captured php-bin support policy lacks accepted evidence") | ||
| if not re.fullmatch( | ||
| r"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z", policy_document.get("acceptedAt", "") | ||
| ): | ||
| raise ConsumerError("captured php-bin support acceptance time is invalid") |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
Validate JSON value types before regex matching.
A malformed value such as maintainedBranches: [1] raises TypeError in re.fullmatch() and escapes the controlled rejection path. Require strings for branch, evidence, action-key, and timestamp fields before matching.
Proposed fix
- and all(re.fullmatch(r"\d+\.\d+", value) for value in branches)
+ and all(isinstance(value, str) and re.fullmatch(r"\d+\.\d+", value) for value in branches)
...
- and all(re.fullmatch(r"sha256:[0-9a-f]{64}", value) for value in evidence)
+ and all(isinstance(value, str) and re.fullmatch(r"sha256:[0-9a-f]{64}", value) for value in evidence)
...
- if not re.fullmatch(
- r"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z", policy_document.get("acceptedAt", "")
- ):
+ accepted_at = policy_document.get("acceptedAt")
+ if not isinstance(accepted_at, str) or not re.fullmatch(
+ r"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z", accepted_at
+ ):🤖 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 `@maintenance/consumer.py` around lines 190 - 218, Update the policy validation
around maintainedBranches, sourceEvidenceDigests, actionKey, and acceptedAt to
require string values before passing them to re.fullmatch; ensure malformed JSON
types, including numeric list entries or non-string scalar fields, raise the
existing ConsumerError instead of TypeError. Preserve the current format,
ordering, and policy-action validations after type checks.
| "required": ["contractVersion", "instructionDigests", "phaseStatus", "criteria", "goNoGo", "unresolved", "summary"], | ||
| "properties": { | ||
| "contractVersion": {"const": 1}, | ||
| "instructionDigests": {"type": "object"}, | ||
| "phaseStatus": {"enum": ["complete", "blocked", "needs_human"]}, | ||
| "criteria": {"type": "array"}, | ||
| "goNoGo": {"enum": ["go", "no_go"]}, | ||
| "unresolved": {"type": "array"}, | ||
| "summary": {"type": "string"} |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift
Harden the control-plane schemas before relying on them as admission gates.
The schemas enforce field presence more than semantic validity, allowing contradictory completion states, vacuous agent contracts, and incomplete evidence sets.
schemas/agent-completion-assessment.schema.json#L4-L12: validate digest fields and require GO to imply a complete phase with no unresolved work.schemas/agent-task-contract.schema.json#L4-L14: require non-empty, typed authority, criteria, non-goal, and stop-condition values.schemas/maintenance-plan.schema.json#L10-L29: require all four distinct evidence records exactly once.
📍 Affects 3 files
schemas/agent-completion-assessment.schema.json#L4-L12(this comment)schemas/agent-task-contract.schema.json#L4-L14schemas/maintenance-plan.schema.json#L10-L29
🤖 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 `@schemas/agent-completion-assessment.schema.json` around lines 4 - 12, Harden
the control-plane schemas: in schemas/agent-completion-assessment.schema.json
(lines 4-12), validate instruction digest fields and enforce that goNoGo "go"
requires phaseStatus "complete" with no unresolved items; in
schemas/agent-task-contract.schema.json (lines 4-14), require non-empty,
correctly typed authority, criteria, non-goal, and stop-condition values; in
schemas/maintenance-plan.schema.json (lines 10-29), require exactly one
non-empty evidence record for each of the four distinct evidence types.
Summary
Implements the mise-php side of
PLAN-HYBRID-AI.md: commit-pinned php-bin policy capture, evidence-bound planning, offline implementation and repair, deterministic sealing and exact-SHA merge admission, coordinated readiness records, and historical exact-version support.The review follow-up adds fail-closed evidence path containment, strict plan budgets and types, exact Git argument validation, and broader protected schema ownership.
Verification
scripts/test.shSecurity
Summary by CodeRabbit
New Features
Bug Fixes
Documentation
Security