maintenance/workflows audit#687
Conversation
Introduce a comprehensive audit of GitHub Actions workflows across the `phlex` monorepo and sibling `action/*` repositories. The report analyzes: - Structural consistency and naming of `workflow_call` inputs. - Trigger correctness and `if:` gating logic. - Fork-PR compatibility, highlighting failures in `*-fix` workflows. - Permission minimality and `WORKFLOW_PAT` usage. - CI parity between the primary repo and action repositories. It concludes with prioritized recommendations to improve security (least-privilege tokens), reliability (split-workflow pattern for forks), and maintainability (centralized CI sync script).
Create a new developer guide explaining the workflow for producing and running structured execution plans using the Kilo agent system. The documentation covers: - Using the `plan` sub-agent to generate JSON-based execution plans. - The structure of a plan, including idempotency, step definitions, and model selection. - Executing plans via the `orchestrate` agent. - Model selection policies and verification using `prek`.
Switch `devcontainer.json` to use `docker-compose.yml` for service definition, volume mounts, and environment variables to improve configurability and consistency. Key changes include: - Update `Dockerfile` to use a pinned base image (`2026-06-24`), install additional utilities (`jq`, `tree`, `yq`), and upgrade Node.js to 26.x. - Replace `kiro-cli` with `@kilocode/cli` installed via npm. - Refactor `KILO_CONFIG_CONTENT` handling: `ensure-repos.sh` now generates a `.phlex-kilo.env` file on the host which is loaded by Docker Compose. This ensures the VS Code plugin receives the correct configuration (including the `host.docker.internal` relay) at startup, replacing the previous `.bashrc` modification in `post-create.sh`. - Remove Copilot-related extensions and settings from the workspace and devcontainer configuration.
Update the guide to reflect recent changes in the Kilo CLI and agent behavior: * Update `kilo run` usage to use positional arguments for prompts instead of `--prompt` and `--description` flags. * Rename the `orchestrate` agent to `execute`. * Document in-flight re-planning, including the `on_error: replan` mechanism and the `mode: all` configuration for the `plan` agent. * Clarify that only `fnal-litellm` provider models are permitted and update model examples and defaults.
Rename the `plan` agent to `genplan` to avoid conflicts with the Kilo CLI's reserved native "Plan mode". Expand the guide with detailed sections on: * Model selection policy: Justification for using `gpt-oss-120b` for planning and `claude-sonnet-4-6` for orchestration. * Resuming interrupted executions: Guidance on using `--continue`, `--session`, and `--fork` based on plan idempotency. * Invocation modes: Comparison between non-interactive (headless) and interactive (`-i`) modes.
- Create docs/dev/WORKFLOW_CALLS.md documenting reusable workflow interfaces, inputs, and trigger models. - Add scripts/check-gating-block.sh and a corresponding CI job in actionlint-check.yaml to enforce consistency of if-gating blocks. - Standardize boolean inputs in cmake-build.yaml to snake_case (perfetto_heap_profile, perfetto_cpu_profile). - Reduce WORKFLOW_PAT usage in codeql-comment.yaml by switching to github.token for PR commenting. - Update workflow-audit-report.md with corrected analysis on fork handling and token requirements, and add workflow-audit-implementation-plan.json. - Apply pre-commit style fixes to form/ and test/python/.
…ocks Add _render_section() function to wrap alert sections exceeding _FOLD_THRESHOLD (10 items) in collapsible <details> blocks, improving readability of PR comments with many alerts. Short lists remain unwrapped. Replace all _format_section() calls with _render_section() in build_comment() and _build_multi_section_comment(), passing appropriate summary labels for each section (new alerts, resolved alerts, etc.). Add comprehensive test coverage for _render_section() including: - Short lists not folded - Long lists wrapped with proper <details>/<summary> structure - Blank line separation for GFM Markdown rendering inside <details> - All bullets preserved when folded Add integration tests verifying folding behavior in build_comment() and _build_multi_section_comment() workflows.
|
Note Currently processing new changes in this PR. This may take a few minutes, please wait... ⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (20)
✨ 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 |
There was a problem hiding this comment.
Pull request overview
This PR consolidates a “workflow audit” effort by documenting current GitHub Actions patterns (and recommended policies), adding CI guardrails for workflow gating blocks, improving CodeQL PR-comment readability by folding long alert lists, and updating the devcontainer implementation to a Docker Compose-based setup with refreshed tooling.
Changes:
- Add workflow audit documentation (report, implementation plan JSON, and
WORKFLOW_CALLS.md) plus a Kilo plan generation/execution guide. - Add a gating-block verification script and wire it into
actionlint-checkas an additional CI job. - Improve operational UX: fold long CodeQL alert sections behind
<details>, standardize Perfetto workflow_dispatch input names, and migrate devcontainer to Docker Compose with updated toolchain.
Reviewed changes
Copilot reviewed 20 out of 20 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
test/python/jited.py |
Minor numeric-literal and formatting normalization for tests. |
test/python/adder.py |
Formatting/indent consistency in an error-path test. |
scripts/test/test_check_codeql_alerts.py |
Adds unit coverage for the new _render_section folding behavior. |
scripts/check-gating-block.sh |
New script to assert required gating phrases exist in workflow files. |
scripts/check_codeql_alerts.py |
Implements folding of long CodeQL alert sections via <details> blocks. |
plugins/python/python/phlex/_typing.py |
Formatting-only adjustments. |
form/root_storage/root_rfield_read_container.cpp |
Minor C++ style tweak (east-const style in catch). |
docs/dev/workflow-audit-report.md |
Adds an audit report capturing workflow semantics and recommendations. |
docs/dev/workflow-audit-implementation-plan.json |
Adds a machine-readable implementation plan for audit recommendations. |
docs/dev/WORKFLOW_CALLS.md |
Adds a reusable-workflow input/usage reference document. |
docs/dev/generating-executing-kilo-plans.md |
Adds a guide for generating/executing Kilo plans (genplan/execute). |
.github/workflows/codeql-comment.yaml |
Uses github.token for comment write actions (PAT retained for artifact download). |
.github/workflows/cmake-build.yaml |
Renames perfetto workflow_dispatch inputs to snake_case and updates references. |
.github/workflows/actionlint-check.yaml |
Adds gating_check job to run the gating-block verification script. |
.devcontainer/post-create.sh |
Removes KILO_CONFIG_CONTENT shell wiring and kiro-cli install. |
.devcontainer/ensure-repos.sh |
Generates .phlex-kilo.env for Docker Compose/devcontainer Kilo config injection. |
.devcontainer/Dockerfile |
Pins base image tag and installs additional dev utilities + Node/Kilo CLI. |
.devcontainer/docker-compose.yml |
New Compose definition for the devcontainer service and mounts. |
.devcontainer/devcontainer.json |
Switches from Dockerfile-only to Docker Compose-based devcontainer config. |
.devcontainer/codespace.code-workspace |
Removes Copilot Chat recommendation from the workspace file. |
| # Verify that the shared if-gating blocks are present and consistent across | ||
| # GitHub Actions workflows. Exits 1 if any required phrase is missing. |
|
21 fixed, 0 new since branch point (cf6781a) ✅ 21 CodeQL alerts resolved since the previous PR commit21 resolved alerts
✅ 21 CodeQL alerts resolved since the branch point21 resolved alerts
Review the full CodeQL report for details. |
Codecov Report✅ All modified and coverable lines are covered by tests. @@ Coverage Diff @@
## main #687 +/- ##
==========================================
+ Coverage 83.43% 83.63% +0.20%
==========================================
Files 174 174
Lines 6820 6913 +93
Branches 837 848 +11
==========================================
+ Hits 5690 5782 +92
+ Misses 853 851 -2
- Partials 277 280 +3
Flags with carried forward coverage won't be shown. Click here to find out more.
... and 4 files with indirect coverage changes Continue to review full report in Codecov by Harness.
🚀 New features to boost your workflow:
|
Clang-Tidy Check ResultsFound 5762 issue(s); none are newly introduced by this patch. All issues by check:
See inline comments for details. Comment |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Clang-Tidy Check ResultsFound 5790 issue(s); none are newly introduced by this patch. All issues by check:
See inline comments for details. Comment |
Clang-Tidy Check ResultsFound 5790 issue(s); none are newly introduced by this patch. All issues by check:
See inline comments for details. Comment |
Clang-Tidy Check ResultsFound 5790 issue(s); none are newly introduced by this patch. All issues by check:
See inline comments for details. Comment |
|
@coderabbitai full review |
✅ Action performedFull review finished. |
|
Caution Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted. Error details |
There was a problem hiding this comment.
Actionable comments posted: 8
🤖 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 @.devcontainer/docker-compose.yml:
- Line 1: Remove the obsolete top-level version key from the docker-compose
definition since Compose v2 ignores it and warns on every up. Update the
.devcontainer/docker-compose.yml content to rely on the Compose spec without a
version field, keeping the rest of the service configuration unchanged.
In @.devcontainer/Dockerfile:
- Around line 96-98: The Dockerfile heredoc currently mixes `apt` and `sudo`
unnecessarily; update the `RUN` sequence to use only non-interactive `apt-get`
commands. In the install block around the `jq`, `podman`, `ssh`, `socat`,
`tree`, and `yq` step, add `curl` to that same `apt-get install -y
--no-install-recommends` invocation, and change the `apt purge` / `apt
autoremove` calls to `apt-get purge -y ... && apt-get autoremove -y` so the
script remains root-friendly and Docker-safe.
In @.devcontainer/ensure-repos.sh:
- Line 201: The KILO_CONFIG_CONTENT write in ensure-repos.sh needs to preserve
apostrophes because a raw single-quoted value will break if the content contains
an embedded '. Update the logic around the ENV_FILE write to either escape
apostrophes in KILO_CONFIG_CONTENT for Compose env_file parsing or change the
generated file format to a raw env-file style, keeping the existing behavior for
literal $ intact.
In `@docs/dev/WORKFLOW_CALLS.md`:
- Around line 7-9: The workflow list in the `WORKFLOW_CALLS` documentation
includes `clang-tidy-fix` under `workflow_call`, but the later `clang-tidy-fix`
section only supports `issue_comment` and `workflow_dispatch`, so the trigger
summary is inconsistent. Update the trigger list in the introductory `*-fix`
workflows section to remove `clang-tidy-fix` from `workflow_call`, and keep the
rest of the workflow names and trigger references aligned with the
`clang-tidy-fix` documentation.
In `@docs/dev/workflow-audit-report.md`:
- Around line 82-91: The `workflow_call` table incorrectly includes
`clang-tidy-fix.yaml` even though that workflow does not expose `workflow_call`;
remove that row from the reusable-workflow list and keep `tidy-checks`
documented only under the `workflow_dispatch`/fix-workflow section. Update the
`workflow_call` summary in this doc so it only lists workflows that actually
share the reusable trigger, using the existing `clang-tidy-fix.yaml`,
`python-fix.yaml`, and `cmake-build.yaml` references to relocate the entry
correctly.
In `@scripts/check-gating-block.sh`:
- Around line 26-58: The gating check in check-gating-block.sh is missing two
workflow families that still use setup-job gating logic: coverage.yaml and
clang-tidy-fix.yaml. Add dedicated entries/small phrase lists for these
workflows in the script’s existing workflow groupings (alongside
CHECK_WORKFLOWS, TIDY_CHECK_WORKFLOWS, FIX_WORKFLOWS, and BUILD_WORKFLOWS) so
their setup-job event gates and bot-command conditions are audited too.
In `@scripts/test/test_check_codeql_alerts.py`:
- Around line 714-737: The folding coverage in build_comment only tests
new_alerts, so add a parallel folded-case test for fixed_alerts using the same
_FOLD_THRESHOLD boundary. Reuse the existing test pattern in
test_long_new_alert_list_is_folded and target the build_comment path with
fixed_alerts populated and new_alerts empty to verify the details/summary
wrapping is applied there too.
- Around line 1220-1233: The `_build_multi_section_comment` folding coverage is
incomplete because only `new_vs_base` has explicit threshold tests. Add a single
parametrized test in `test_check_codeql_alerts.py` that exercises all comparison
sections and fallback paths using the shared `_render_section` flow, including
`new_vs_prev`, `fixed_vs_prev`, `fixed_vs_base`, and the non-comparison
branches, so each path is verified to fold or not fold consistently with
`_FOLD_THRESHOLD`.
🪄 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: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 479a648e-d8f7-471f-938a-ceda729e513f
📒 Files selected for processing (20)
.devcontainer/Dockerfile.devcontainer/codespace.code-workspace.devcontainer/devcontainer.json.devcontainer/docker-compose.yml.devcontainer/ensure-repos.sh.devcontainer/post-create.sh.github/workflows/actionlint-check.yaml.github/workflows/cmake-build.yaml.github/workflows/codeql-comment.yamldocs/dev/WORKFLOW_CALLS.mddocs/dev/generating-executing-kilo-plans.mddocs/dev/workflow-audit-implementation-plan.jsondocs/dev/workflow-audit-report.mdform/root_storage/root_rfield_read_container.cppplugins/python/python/phlex/_typing.pyscripts/check-gating-block.shscripts/check_codeql_alerts.pyscripts/test/test_check_codeql_alerts.pytest/python/adder.pytest/python/jited.py
💤 Files with no reviewable changes (2)
- .devcontainer/codespace.code-workspace
- .devcontainer/post-create.sh
📜 Review details
⚠️ CI failures not shown inline (8)
GitHub Actions: greenc-FNAL checking C++ code format / 0_clang-format-check.txt: greenc-FNAL checking C++ code format
Conclusion: failure
##[group]Run REPO_NAME="${REPO##*/}"
�[36;1mREPO_NAME="${REPO##*/}"�[0m
�[36;1mif [ "success" = 'success' ]; then�[0m
�[36;1m echo "✅ clang-format check passed."�[0m
�[36;1melse�[0m
�[36;1m echo "::error::clang-format check failed. Please review the output above for details."�[0m
GitHub Actions: greenc-FNAL checking YAML files / 0_yaml-check.txt: greenc-FNAL checking YAML files
Conclusion: failure
##[group]Run REPO_NAME="${REPO##*/}"
�[36;1mREPO_NAME="${REPO##*/}"�[0m
�[36;1mif [ "success" = "success" ]; then�[0m
�[36;1m echo "✅ YAML check passed."�[0m
�[36;1melse�[0m
�[36;1m echo "::error::YAML check failed."�[0m
GitHub Actions: greenc-FNAL checking Markdown format / 0_markdown-check.txt: greenc-FNAL checking Markdown format
Conclusion: failure
##[group]Run REPO_NAME="${REPO##*/}"
�[36;1mREPO_NAME="${REPO##*/}"�[0m
�[36;1mif [ "success" = "success" ]; then�[0m
�[36;1m echo "✅ Markdown formatting check passed."�[0m
�[36;1melse�[0m
�[36;1m echo "::error::Markdown formatting check failed."�[0m
GitHub Actions: greenc-FNAL checking Python code / 1_python-check.txt: greenc-FNAL checking Python code
Conclusion: failure
##[group]Run REPO_NAME="${REPO##*/}"
�[36;1mREPO_NAME="${REPO##*/}"�[0m
�[36;1mif [ "success" = 'success' ] && [ "success" = 'success' ]; then�[0m
�[36;1m echo "✅ Python checks passed."�[0m
�[36;1melse�[0m
�[36;1m echo "::error::Python checks failed. Comment '@${REPO_NAME}bot python-fix' on the PR to attempt auto-fix."�[0m
GitHub Actions: greenc-FNAL checking Python code / 0_scripts-test.txt: greenc-FNAL checking Python code
Conclusion: failure
fMode::test_no_alerts_returns_zero_no_comment PASSED [ 25%]
scripts/test/test_check_codeql_alerts.py::TestMainSarifMode::test_below_threshold_alert_not_reported PASSED [ 25%]
scripts/test/test_check_codeql_alerts.py::TestMainSarifMode::test_missing_sarif_exits_nonzero PASSED [ 25%]
scripts/test/test_check_codeql_alerts.py::TestMainSarifMode::test_github_output_written PASSED [ 26%]
scripts/test/test_check_codeql_alerts.py::TestMainSarifMode::test_github_output_false_when_no_alerts PASSED [ 26%]
scripts/test/test_check_codeql_alerts.py::TestMainSarifMode::test_directory_of_sarif_files PASSED [ 26%]
scripts/test/test_check_codeql_alerts.py::TestMainSarifMode::test_sarif_mode_pr_ref_produces_filtered_url PASSED [ 26%]
scripts/test/test_check_codeql_alerts.py::TestMainSarifMode::test_non_integer_pr_ref_no_filtered_url PASSED [ 26%]
scripts/test/test_check_codeql_alerts.py::TestMainApiMode::test_api_mode_new_alert PASSED [ 27%]
scripts/test/test_check_codeql_alerts.py::TestMainApiMode::test_api_mode_min_level_filtering PASSED [ 27%]
scripts/test/test_check_codeql_alerts.py::TestMainApiMode::test_api_mode_github_api_error_exits_2 PASSED [ 27%]
scripts/test/test_check_codeql_alerts.py::TestMainApiMode::test_api_mode_missing_github_repository_exits_2 PASSED [ 27%]
scripts/test/test_check_codeql_alerts.py::TestMainApiMode::test_api_mode_skipped_when_sarif_has_baseline PASSED [ 27%]
scripts/test/test_check_codeql_alerts.py::TestMainApiModeWithPrRef::test_api_mode_pr_ref_produces_filtered_url PASSED [ 28%]
scripts/test/test_check_codeql_alerts.py::TestMainEntrypoint::test_entrypoint_no_alerts_exits_zero PASSED [ 28%]
scripts/test/test_clang_tidy_check_summary.py::TestLoadDiagnostics::test_reads_from_file PASSED [ 28%]
scripts/test/test_clang_tidy_check_summary.py::TestLoadDiagnostics::test_reads_from_stdin PASSED [ 28%]
scripts/test/test_clang_tidy_check_summary.py::TestLoadDiagnostics::test_invalid_yaml_returns_empty PASSED [ 28%]
scripts/test/test_clang_...
GitHub Actions: greenc-FNAL building and testing Framework-R-D/phlex / 1_build (gcc, none).txt: greenc-FNAL building and testing Framework-R-D/phlex
Conclusion: failure
�[36;1mecho "::group::Running ctest"�[0m
�[36;1mif ctest --progress --output-on-failure -j "$(nproc)"; then�[0m
�[36;1m echo "::endgroup::"�[0m
�[36;1m echo "✅ All tests passed."�[0m
�[36;1melse�[0m
�[36;1m echo "::endgroup::"�[0m
�[36;1m echo "::error:: Some tests failed."�[0m
GitHub Actions: greenc-FNAL checking C++ code with clang-tidy / 1_clang-tidy-check.txt: greenc-FNAL checking C++ code with clang-tidy
Conclusion: failure
##[group]Run . /entrypoint.sh
�[36;1m. /entrypoint.sh�[0m
�[36;1mREPO_NAME="${REPO##*/}"�[0m
�[36;1mSOURCE_DIR="$GITHUB_WORKSPACE/$SOURCE_PATH"�[0m
�[36;1mBUILD_DIR="$GITHUB_WORKSPACE/$BUILD_PATH"�[0m
�[36;1m�[0m
�[36;1m# run-clang-tidy runs clang-tidy on every translation unit in�[0m
�[36;1m# compile_commands.json in parallel and merges the per-TU fix YAML files�[0m
�[36;1m# into a single comprehensive clang-tidy-fixes.yaml. The alternative�[0m
�[36;1m# (setting CMAKE_CXX_CLANG_TIDY=clang-tidy;--export-fixes=... and�[0m
�[36;1m# building with -j) suffers from a race condition: every parallel�[0m
�[36;1m# clang-tidy invocation independently overwrites the same output file, so�[0m
�[36;1m# only the fixes from whichever translation unit finishes last are�[0m
�[36;1m# retained.�[0m
�[36;1m#�[0m
�[36;1m# Path arguments are substring-matched against file paths in�[0m
�[36;1m# compile_commands.json; restricting to the source directory automatically�[0m
�[36;1m# excludes generated files (e.g. version.cpp, ROOT dictionaries) that live�[0m
�[36;1m# in the build directory and lack access to the .clang-tidy config.�[0m
�[36;1m#�[0m
�[36;1m# run-clang-tidy validates the check list by calling clang-tidy from its�[0m
�[36;1m# working directory; run from the source root so that clang-tidy discovers�[0m
�[36;1m# the .clang-tidy config file there, preventing a spurious "No checks�[0m
�[36;1m# enabled." error.�[0m
�[36;1mif ! command -v run-clang-tidy >/dev/null 2>&1; then�[0m
�[36;1m echo "::error::run-clang-tidy not found in PATH; cannot run clang-tidy checks"�[0m
GitHub Actions: CodeQL Analysis / 4_determine-languages.txt: maintenance/workflows audit
Conclusion: failure
##[group]Run # If detection was skipped, use all languages or the provided language-matrix
�[36;1m# If detection was skipped, use all languages or the provided language-matrix�[0m
�[36;1mif [ "${SKIP_DETECTION}" = "true" ]; then�[0m
�[36;1m if [ "${GITHUB_EVENT_NAME}" = "workflow_call" ] && [ -n "${LANGUAGE_MATRIX}" ]; then�[0m
�[36;1m # Validate that language-matrix is valid JSON�[0m
�[36;1m if ! echo "${LANGUAGE_MATRIX}" | python3 -c "import sys, json; json.load(sys.stdin)" 2>/dev/null; then�[0m
�[36;1m echo "::error::Invalid language-matrix input: must be valid JSON array"�[0m
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{cpp,cc,cxx,h,hpp}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.{cpp,cc,cxx,h,hpp}: Use clang-format tool for all C++ code formatting (VS Code auto-formats on save); configuration defined in.clang-formatwith 100-character line limit and 2-space indentation
Follow clang-tidy recommendations defined in.clang-tidy
Files:
form/root_storage/root_rfield_read_container.cpp
**/*.{hpp,cpp}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{hpp,cpp}: Use.hppfor header files,.cppfor implementation, and*_test.cppfor test files in C++
Enforce 100-character line limit and 2-space indentation in C++ code via.clang-format
UseQualifierAlignment: Right(east-const) style:int const xnotconst int xin C++
UsePointerAlignment: Leftin C++ (pointer*attached to type, not variable name)
All C++ identifiers must uselower_casenaming: namespaces, classes, structs, enums, functions, variables, parameters, members, and constants
Exception to C++ naming: template parameters useCamelCase
Exception to C++ naming: macros useUPPER_CASE
Private, protected, and constant members in C++ must have a trailing underscore (_), no trailing underscore on anything else
Useenum classpreferred over plainenumin C++
Usestd::shared_ptrfor shared ownership,std::unique_ptrfor exclusive ownership, raw pointers for non-owning references only in C++
Use functors with agent-noun pattern:ModelEvaluator evaluate_model(...)in C++
Apply.clang-tidychecks for bugprone, cert, clang-analyzer, concurrency, cppcoreguidelines, misc, modernize, performance, portability, and readability as defined in the.clang-tidyconfiguration file
Usephlex::namespace for core code,phlex::experimental::for experimental features in C++
Files:
form/root_storage/root_rfield_read_container.cpp
**/*.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.py: Use ruff for Python formatting and linting (configured inpyproject.toml); follow Google-style docstring conventions; use line length of 99 characters; use double quotes for strings
Usefrom __future__ import annotationsto enable deferred evaluation of type annotations (avoids forward-reference issues; Python >=3.12)
Type hints are recommended; mypy is configured inpyproject.toml
Avoid naming Python test scriptstypes.pyor other names that shadow standard library modules, as this causes obscure import errors
Python test scripts should follow the test structure pattern: C++ driver provides data streams, Jsonnet config wires the graph, and Python script implements algorithms
**/*.py: Enforce 99-character line limit and double quotes in Python via ruff configured inpyproject.toml
Use Google-style docstrings in Python code
Use type hints in Python code and configure mypy for type checking
Usefrom __future__ import annotationsin Python to enable deferred evaluation of type annotations
Use PEP 8 naming in Python:CapWordsfor classes,snake_casefor everything else
When using thereadtool for Python files, always use integer values foroffsetandlimitparameters, never float/double values
Files:
test/python/adder.pytest/python/jited.pyplugins/python/python/phlex/_typing.pyscripts/check_codeql_alerts.pyscripts/test/test_check_codeql_alerts.py
test/**/*.py
📄 CodeRabbit inference engine (AGENTS.md)
Name Python test files as
test_*.py, do NOT name files after stdlib modules (e.g.,types.py)
Files:
test/python/adder.pytest/python/jited.py
**/*.md
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.md: All Markdown files must follow markdownlint rule MD012: no multiple consecutive blank lines (never more than one blank line in a row)
All Markdown files must follow markdownlint rule MD022: headings must be surrounded by exactly one blank line before and after
All Markdown files must follow markdownlint rule MD031: fenced code blocks must be surrounded by exactly one blank line before and after
All Markdown files must follow markdownlint rule MD032: lists must be surrounded by exactly one blank line before and after (including after headings and code blocks)
All Markdown files must follow markdownlint rule MD034: no bare URLs (use markdown link syntax like[text](destination)instead of plain URLs)
All Markdown files must follow markdownlint rule MD036: use # headings for titles, not Bold:
All Markdown files must follow markdownlint rule MD040: always specify code block language (for example, use 'bash', 'python', '```text', etc.)
**/*.md: Do not use multiple consecutive blank lines in Markdown (MD012)
Surround Markdown headings with exactly one blank line (MD022)
Surround Markdown fenced code blocks with exactly one blank line (MD031)
Surround Markdown lists with exactly one blank line (MD032)
Do not use bare URLs in Markdown; use[text](url)syntax instead (MD034)
Use#headings in Markdown, not**Bold**for section titles (MD036)
Always specify language on fenced code blocks in Markdown (MD040)
Files:
docs/dev/workflow-audit-report.mddocs/dev/WORKFLOW_CALLS.mddocs/dev/generating-executing-kilo-plans.md
🧠 Learnings (1)
📚 Learning: 2026-06-18T23:48:04.336Z
Learnt from: wlav
Repo: Framework-R-D/phlex PR: 626
File: test/python/jited.py:25-25
Timestamp: 2026-06-18T23:48:04.336Z
Learning: In Phlex Python test/module files under `test/python/` (e.g., `test/python/jited.py`), treat `PHLEX_REGISTER_ALGORITHMS` as an intentional macro-based interface that mirrors the equivalent C++ macro. Do not add or change type hints for `PHLEX_REGISTER_ALGORITHMS`; it should remain untyped because it’s part of Phlex’s macro contract and Phlex internal types are not exposed to Python by design.
Applied to files:
test/python/adder.pytest/python/jited.py
🪛 Checkov (3.3.2)
.devcontainer/Dockerfile
[low] 1-118: Ensure that HEALTHCHECK instructions have been added to container images
(CKV_DOCKER_2)
[low] 1-118: Ensure that a user for the container has been created
(CKV_DOCKER_3)
🪛 Hadolint (2.14.0)
.devcontainer/Dockerfile
[info] 93-93: Multiple consecutive RUN instructions. Consider consolidation.
(DL3059)
[info] 105-105: Multiple consecutive RUN instructions. Consider consolidation.
(DL3059)
🪛 LanguageTool
docs/dev/workflow-audit-report.md
[uncategorized] ~24-~24: The official name of this software platform is spelled with a capital “H”.
Context: ...x workflows** | All 27 YAML files under phlex/.github/workflows/ | grep, read, bash to...
(GITHUB)
[uncategorized] ~25-~25: The official name of this software platform is spelled with a capital “H”.
Context: ...ion//action.yaml+ CI workflows underaction//.github/workflows/` | Same tooling | | **Cross-...
(GITHUB)
[uncategorized] ~92-~92: The official name of this software platform is spelled with a capital “H”.
Context: ...orkflow's inputs in a shared reference (.github/WORKFLOW_CALLS.md). > **Note on de-du...
(GITHUB)
[uncategorized] ~154-~154: The official name of this software platform is spelled with a capital “H”.
Context: ...-tidy-report.yaml, which comments with github.token`, no PAT. | | **Push the fix comm...
(GITHUB)
[uncategorized] ~309-~309: The official name of this software platform is spelled with a capital “H”.
Context: ...ble workflow (e.g., action-ci.yaml in Framework-R-D/.github or a dedicated repo) that each acti...
(GITHUB)
[uncategorized] ~390-~390: The official name of this software platform is spelled with a capital “H”.
Context: ...re workflow_run-triggered and gate on `github.event.workflow_run.event == 'pull_reque...
(GITHUB)
docs/dev/generating-executing-kilo-plans.md
[grammar] ~35-~35: Ensure spelling is correct
Context: ... * description * model – any builtin agent shortcut (reason, ask, chat...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~118-~118: Ensure spelling is correct
Context: ... ## 4. Model‑selection policy * Prefer builtin agent shortcuts for simplicity. * For p...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~161-~161: Ensure spelling is correct
Context: ...-6` completed all steps — delegating the test‑ and doc‑authoring, applying the one‑lin...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
🪛 Trivy (0.69.3)
.devcontainer/Dockerfile
[error] 1-1: Image user should not be 'root'
Specify at least 1 USER command in Dockerfile with non-root user as argument
Rule: DS-0002
(IaC/Dockerfile)
[info] 1-1: No HEALTHCHECK defined
Add HEALTHCHECK instruction in your Dockerfile
Rule: DS-0026
(IaC/Dockerfile)
🪛 zizmor (1.26.1)
.github/workflows/actionlint-check.yaml
[info] 119-119: workflow or action definition without a name (anonymous-definition): this job
(anonymous-definition)
🔇 Additional comments (24)
form/root_storage/root_rfield_read_container.cpp (1)
87-87: LGTM!Also applies to: 114-114
plugins/python/python/phlex/_typing.py (1)
19-19: LGTM!Also applies to: 52-68, 189-189
test/python/adder.py (1)
60-65: LGTM!test/python/jited.py (1)
18-19: LGTM!Also applies to: 43-67
scripts/check_codeql_alerts.py (4)
713-740: Clean implementation of the folding helper.The
_render_sectionhelper correctly delegates bullet generation to_format_sectionand conditionally wraps in a<details>block when the alert count exceeds the threshold. The blank lines surrounding the bullet list inside<details>are essential for GFM to render the Markdown content — good attention to detail. The threshold check onlen(alerts)(notlen(lines)) is the right choice since_format_sectionmay truncate viamax_results.
781-801: Folding wired correctly intobuild_comment.Both the new-alerts and fixed-alerts sections now use
_render_sectionwith dynamically pluralized labels. The heading remains outside the<details>block, keeping the alert count visible at a glance — good UX.
1117-1170: Folding wired correctly into all_build_multi_section_commentpaths.All four comparison sections (new_vs_prev, fixed_vs_prev, new_vs_base, fixed_vs_base) consistently use
_render_sectionwith proper label pluralization.
1190-1210: Fallback paths correctly use_render_section.The fallback new/fixed-vs-main sections also use the folding helper, ensuring consistent behavior across all comment paths.
scripts/test/test_check_codeql_alerts.py (1)
534-577: Solid unit tests for_render_sectionwith correct boundary conditions.The three tests correctly cover the fold/no-fold boundary (exactly
_FOLD_THRESHOLDvs_FOLD_THRESHOLD + 1), validate the GFM-critical blank-line structure inside<details>, and confirm folding doesn't drop bullets. Well done..devcontainer/Dockerfile (3)
105-110: LGTM!
1-1: LGTM!
99-100: 🩺 Stability & AvailabilityNo issue:
setup_26.xis a valid NodeSource bootstrap URL. The concern about a 404 doesn’t apply here.> Likely an incorrect or invalid review comment..devcontainer/devcontainer.json (1)
3-9: LGTM!.devcontainer/docker-compose.yml (1)
8-34: LGTM!.devcontainer/ensure-repos.sh (1)
200-200: 🎯 Functional CorrectnessDrop this comment.
HEADROOM_RELAY_PORTis assigned earlier (HEADROOM_RELAY_PORT=$(( HEADROOM_PORT + 10000 ))), andHEADROOM_PORTdefaults to9797, so this rewrite won’t see an empty or unset port here.> Likely an incorrect or invalid review comment.scripts/check-gating-block.sh (1)
1-170: LGTM otherwise.Solid, defensive bash:
set -euo pipefail, per-file existence guard, clear pass/fail accounting, non-zero exit on failure. Nice callback to the audit report's P4 recommendation..github/workflows/actionlint-check.yaml (1)
119-143: LGTM — mirrors the already-hardened checkout pattern.New
gating_checkjob reuses the sameneeds.setup-scoped,persist-credentials: falsecheckout as the existingactionlint-checkjob, and wires the new gating script correctly. This is the same pattern that resolved the prior CodeQLuntrusted-checkoutfinding on this file, so no new exposure here.zizmor flags Line 119 for an anonymous job definition, but
actionlint-check(Line 73) has the same shape without aname:— this is pre-existing convention in this file, not a regression..github/workflows/cmake-build.yaml (1)
29-34: LGTM — snake_case rename matches audit P2 recommendation and env wiring is consistent.
perfetto_heap_profile/perfetto_cpu_profileinputs and theirPERFETTO_HEAP_PROFILE/PERFETTO_CPU_PROFILEenv mappings are updated together, so there's no split-brain reference to the old hyphenated names in this hunk.Also applies to: 231-234
docs/dev/WORKFLOW_CALLS.md (1)
1-607: Otherwise thorough and well-organized reference doc.Nice per-workflow input tables and example invocations; markdown formatting (headings, fences, lists) looks compliant with the repo's markdownlint rules throughout.
docs/dev/workflow-audit-report.md (1)
1-395: Otherwise a solid, well-sourced audit doc.Appreciate the explicit "corrected accordingly" callout for the earlier draft's mistakes on trigger semantics — that kind of self-correction transparency is rare and genuinely useful for future readers. The LanguageTool "GitHub casing" hints on Lines 24, 25, 92, 154, 309, 390 are all false positives (they're flagging
.github/directory paths and Actions-expression syntax likegithub.token, not prose).docs/dev/workflow-audit-implementation-plan.json (1)
1-97: LGTM — schema matches the genplan format documented elsewhere in this PR.Fields (
id,model,gate,retry,on_error,self_check, etc.) line up with the schema described indocs/dev/generating-executing-kilo-plans.md, andidempotent: falsecorrectly reflects that Step 2's renames aren't safely re-runnable.docs/dev/generating-executing-kilo-plans.md (2)
181-185: 📐 Maintainability & Code Quality | ⚡ Quick winLeftover mid-document footer before Sections 6 & 7.
The
---+*Generated by the Kilo planner and orchestrator.*footer at Line 182-183 reads as the end of the document, but Sections 6 and 7 follow it, and the real closing footer is duplicated again at the true end of the file (Line 290-291). Looks like this footer was the original file's closing boilerplate and got left in place when new sections were appended after it. Worth deleting the mid-document copy so the doc doesn't read as if it ends prematurely.🧹 Suggested fix
`prek` checks for trailing whitespace, multiple final newlines, and basic markdown linting. This file follows those rules out‑of‑the‑box. ---- -*Generated by the Kilo planner and orchestrator.* - ## 6. Resuming an interrupted execution
1-292: Rest of the doc is clear and useful.The
genplan-vs-planreserved-name explanation and the resume/re-planning walkthroughs are genuinely helpful onboarding material. Minor LanguageTool "spelling" hints onbuiltin(Lines 35, 118) are stylistic/false-positive noise (it's a common compound in CLI docs), not worth chasing..github/workflows/codeql-comment.yaml (1)
35-40: 🩺 Stability & AvailabilityNo issue:
github.tokenalready has comment permissionsThe workflow grants
pull-requests: writeat the top level, so this step can usegithub.tokenforcreateComment/updateCommentwithout theWORKFLOW_PAT.> Likely an incorrect or invalid review comment.
| @@ -0,0 +1,34 @@ | |||
| version: "3.8" | |||
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
version is a no-op in Compose v2.
The top-level version key has been obsolete since Compose v2 and just emits a "the attribute version is obsolete" warning on every up. Safe to drop it entirely.
🧹 Proposed change
-version: "3.8"
-
services:📝 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.
| version: "3.8" |
🤖 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 @.devcontainer/docker-compose.yml at line 1, Remove the obsolete top-level
version key from the docker-compose definition since Compose v2 ignores it and
warns on every up. Update the .devcontainer/docker-compose.yml content to rely
on the Compose spec without a version field, keeping the rest of the service
configuration unchanged.
| apt-get install -y --no-install-recommends jq podman ssh socat tree yq | ||
| apt purge nodejs npm -y && apt autoremove -y || true | ||
| sudo apt-get install -y curl |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Look for any other reliance on `sudo` in the devcontainer setup.
rg -nP '\bsudo\b' .devcontainer/Repository: Framework-R-D/phlex
Length of output: 214
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect the relevant Dockerfile section with line numbers.
sed -n '1,140p' .devcontainer/Dockerfile | cat -n
printf '\n---\n'
# Check for any other apt/apt-get usage in the devcontainer Dockerfile.
rg -n '\bapt(-get)?\b|sudo\b|set -euo pipefail' .devcontainer/DockerfileRepository: Framework-R-D/phlex
Length of output: 6227
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Show the base image and early setup in case sudo availability depends on it.
sed -n '1,120p' .devcontainer/Dockerfile | cat -nRepository: Framework-R-D/phlex
Length of output: 5597
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Focus on the package-install block around the comment.
sed -n '88,104p' .devcontainer/Dockerfile | cat -nRepository: Framework-R-D/phlex
Length of output: 744
🏁 Script executed:
#!/bin/bash
set -euo pipefail
sed -n '88,104p' .devcontainer/Dockerfile | cat -n
rg -n '\bapt(-get)?\b|sudo\b|set -euo pipefail' .devcontainer/DockerfileRepository: Framework-R-D/phlex
Length of output: 1369
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Read the full relevant span to understand whether curl belongs in the same install block.
nl -ba .devcontainer/Dockerfile | sed -n '88,104p'Repository: Framework-R-D/phlex
Length of output: 197
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect the exact Dockerfile block around the review comment.
nl -ba .devcontainer/Dockerfile | sed -n '88,104p'
printf '\n---\n'
# Check whether this Dockerfile sets a shell mode that would make the command chain brittle.
rg -n 'set -euo pipefail|SHELL \[' .devcontainer/Dockerfile
printf '\n---\n'
# Confirm whether sudo is used anywhere else in the devcontainer setup.
rg -nP '\bsudo\b' .devcontainer/Repository: Framework-R-D/phlex
Length of output: 197
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Check the devcontainer config for how this Dockerfile is built and whether USER changes later.
rg -n 'phlex-dev:2026-06-24|Dockerfile|USER\b|sudo\b|apt purge|apt-get install -y curl|setup_26\.x' .devcontainer .github README.mdRepository: Framework-R-D/phlex
Length of output: 520
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Read the devcontainer config to see whether the Dockerfile runs as root and how the image is referenced.
if [ -f .devcontainer/devcontainer.json ]; then
cat -n .devcontainer/devcontainer.json
fiRepository: Framework-R-D/phlex
Length of output: 5092
🌐 Web query:
Debian apt command line interface unstable use apt-get in scripts official documentation
💡 Result:
According to official Debian documentation, the apt command-line interface is designed primarily for interactive end-user use and is not guaranteed to have a stable interface for automated scripts [1][2]. Because the apt command may change its behavior or output format between versions to better suit interactive needs, Debian explicitly recommends using apt-get and apt-cache for scripting purposes [3][1][2]. Key points regarding this distinction include: - Stable Interface: The apt-get and apt-cache commands have a well-defined, stable public interface that provides guaranteed backward compatibility, making them the appropriate choice for shell scripts and automated tasks [4][1][5]. - Interactive Focus: The apt command acts as a high-level wrapper and, while it improves the user experience with features like colorized output or progress bars, it prioritizes interactive usability over script stability [1][2]. - Warning Messages: When used in non-interactive environments (such as pipes or scripts), the apt command may issue a warning stating: "WARNING: apt does not have a stable CLI interface. Use with caution in scripts" [5][6][7]. - Functionality: All core features available in apt are also provided by apt-get and apt-cache [1][2]. Therefore, for consistent and predictable behavior in scripts, developers should rely on the latter tools [3][4].
Citations:
- 1: https://manpages.debian.org/bookworm/apt/apt.8.en.html
- 2: https://manpages.debian.org/trixie/apt/apt.8.en.html
- 3: https://www.debian.org/doc/manuals/debian-reference/ch02.en.html
- 4: https://www.debian.org/doc/manuals/debian-handbook/sect.apt-get.en.html
- 5: https://askubuntu.com/questions/829864/is-apt-get-deprecated
- 6: https://serverfault.com/questions/958003/how-to-disable-warning-apt-does-not-have-a-stable-cli-interface
- 7: https://askubuntu.com/questions/990823/apt-gives-unstable-cli-interface-warning
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Confirm there is no USER override before the dev-utils block.
rg -n '^\s*USER\b' .devcontainer/DockerfileRepository: Framework-R-D/phlex
Length of output: 157
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect the devcontainer compose file for any build-time user settings.
cat -n .devcontainer/docker-compose.ymlRepository: Framework-R-D/phlex
Length of output: 1449
Drop sudo and use apt-get in this heredoc
RUNalready executes as root, sosudois redundant here; addcurlto the existing install list instead of a separate step.apt purge/apt autoremoveuse the interactiveaptCLI; switch those toapt-get purge -y ... && apt-get autoremove -yfor Dockerfile scripting.
🤖 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 @.devcontainer/Dockerfile around lines 96 - 98, The Dockerfile heredoc
currently mixes `apt` and `sudo` unnecessarily; update the `RUN` sequence to use
only non-interactive `apt-get` commands. In the install block around the `jq`,
`podman`, `ssh`, `socat`, `tree`, and `yq` step, add `curl` to that same
`apt-get install -y --no-install-recommends` invocation, and change the `apt
purge` / `apt autoremove` calls to `apt-get purge -y ... && apt-get autoremove
-y` so the script remains root-friendly and Docker-safe.
| # We avoid stripping comments with sed to prevent corrupting URLs (https://), | ||
| # as the Kilo plugin's JSONC parser handles comments correctly. | ||
| KILO_CONFIG_CONTENT="$(perl -0777 -pe 's|("fnal-litellm".*?)"baseURL":\s*"[^"]*"|$1"baseURL": "http://host.docker.internal:'${HEADROOM_RELAY_PORT}'"|s; s/"[^"]*"(*SKIP)(*F)|\/\/.*//g; s/^\s+//gm; s/\n//g' "${HOME}/.config/kilo/kilo.jsonc")" | ||
| echo "KILO_CONFIG_CONTENT='${KILO_CONFIG_CONTENT}'" > "${ENV_FILE}" |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Map the script around the relevant area.
ast-grep outline .devcontainer/ensure-repos.sh --view expanded || true
# Show the nearby lines with numbers.
sed -n '160,230p' .devcontainer/ensure-repos.sh | cat -n
# Locate any other writes/reads of KILO_CONFIG_CONTENT and ENV_FILE.
rg -n "KILO_CONFIG_CONTENT|ENV_FILE|env_file|compose" .devcontainer/ensure-repos.sh .Repository: Framework-R-D/phlex
Length of output: 4021
🌐 Web query:
Docker Compose env_file quote interpolation single quotes dollar sign literal
💡 Result:
In Docker Compose, the behavior of interpolation and quoting within files referenced by the env_file attribute is governed by the Compose Specification [1]. Key rules for env_file syntax: 1. Default Interpolation: By default, Docker Compose performs variable interpolation (e.g., expanding ${VAR} or $VAR) for unquoted and double-quoted (") values [1]. 2. Single Quotes for Literals: Single quotes (') are used to prevent interpolation [2][1]. If you need to include a literal dollar sign ($) or other special characters that should not be expanded by Compose, enclose the value in single quotes (e.g., VAR='my$literal') [2][1]. 3. Raw Format Option: As of the modern Compose Specification, you can specify format: raw for an env_file entry in your compose.yaml [3][1]. When using the raw format, Docker Compose does not attempt any parsing or interpolation of the values, allowing you to pass values, including quotes and dollar signs, exactly as they appear in the file [1]. Example using format: raw: services: app: env_file: - path:./my.env format: raw Example of single-quote usage: # In your.env file PASSWORD='my$literal_password' Note that interpolation in env_file is a feature of the Docker Compose CLI and is not supported when using the standard docker run --env-file command [3]. Additionally, interpolation is distinct from the behavior of the environment section in a compose.yaml file, where the $$ syntax is used to escape a literal dollar sign [4][5]. If you are working within an env_file, prefer single quotes for literal preservation [2].
Citations:
- 1: https://github.com/compose-spec/compose-spec/blob/master/spec.md
- 2: https://env.dev/guides/env-file-syntax
- 3: https://docs.docker.com/compose/how-tos/environment-variables/set-environment-variables/
- 4: https://github.com/docker/docs/blob/main/content/reference/compose-file/interpolation.md
- 5: https://github.com/compose-spec/compose-spec/blob/main/12-interpolation.md
🌐 Web query:
Compose specification env_file single quotes apostrophe escape dollar sign literal .env interpolation
💡 Result:
To handle dollar signs ($) and prevent unwanted variable interpolation in a Docker Compose.env file, use single quotes around the value [1]. When you define a value in an.env file using single quotes (e.g., VAR='$VALUE'), Docker Compose treats the content as a literal string, effectively disabling interpolation for any character sequences like
Citations:
- 1: https://docs.docker.com/compose/how-tos/environment-variables/variable-interpolation/
- 2: https://env.dev/guides/env-file-syntax
- 3: https://stackoverflow.com/questions/75322493/how-can-i-properly-escape-the-value-of-a-env-variable-that-contains-a-dollar-si
- 4: https://docs.docker.com/reference/compose-file/interpolation/
- 5: https://github.com/compose-spec/compose-spec/blob/master/12-interpolation.md
- 6: https://stackoverflow.com/questions/57773564/how-to-set-environment-variables-in-docker-compose
🌐 Web query:
Docker Compose .env file single quoted values apostrophe escape official docs
💡 Result:
In Docker Compose, environment files (.env) support escaping single quotes within single-quoted values using the backslash character () [1][2]. According to official Docker documentation syntax rules for environment files, you can use the following syntax to include an apostrophe or single quote in a variable value [1][2]: VAR='Let's go!' -> Let's go! [1][2] However, be aware that there have been reported issues in certain versions of Docker Compose where the backslash escape character is incorrectly preserved in the final environment variable value (e.g., resulting in Let's go! instead of Let's go!) [3]. Key points regarding.env file parsing in Docker Compose: 1. Quoting behavior: Unlike some older implementations, modern Docker Compose (Compose V2) parses quoted strings [1][2]. Single-quoted values are treated literally, meaning variable expansion (e.g., $VARIABLE) does not occur within them [1][2]. Double-quoted values support parameter expansion and specific shell escape sequences like \n, \r, \t, and \ [1][2]. 2. Specification versus implementation: While the official Docker Compose documentation and the Compose Specification define these rules [1][2], the underlying parsing library can sometimes exhibit behavior that deviates from standard shell expectations or historical versions [4][5][6]. 3. Troubleshooting: If you encounter issues where quotes or escape characters are not being handled as expected, you can verify how your specific version of Docker Compose parses the file by checking the environment variables inside a running container using the env command [3][6]. If strict raw string behavior is required (where values are used exactly as-is without interpolation or special parsing), you may consider using the raw format for env_file if supported in your version [2][5].
Citations:
- 1: https://github.com/jbampton/docker-docs/blob/main/compose/environment-variables/env-file.md
- 2: https://github.com/compose-spec/compose-spec/blob/master/spec.md
- 3: [BUG] Escape character appears in final value when escaping single quotes in environment file docker/compose#11276
- 4: Variables containing special characters coming from env file are not preserved docker/compose#8607
- 5: Env files parsing docker/compose#12174
- 6: Inconsistent handling of quoted variables in .env between Compose v1 and v2 docker/compose#8740
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Find where the generated env file is consumed.
rg -n "\.phlex-kilo\.env|KILO_CONFIG_CONTENT_DOCKER|KILO_CONFIG_CONTENT" .devcontainer .github . -g '!test/**'
# Show any compose/devcontainer config references if present.
fd -a -t f 'devcontainer.json|compose.yaml|docker-compose.yml|docker-compose.yaml' .Repository: Framework-R-D/phlex
Length of output: 900
🌐 Web query:
site:docs.docker.com/compose env_file single quotes dollar sign literal interpolate
💡 Result:
In Docker Compose, environment files used with the env_file attribute are typically treated as simple key-value pairs and do not perform variable interpolation [1]. While the main.env file (used for Compose file configuration) supports interpolation, the files referenced by the env_file attribute are generally passed directly to the container's environment [1]. If you need a literal dollar sign in an environment file used with env_file, you typically do not need to escape it because the file contents are usually read as literal strings by the container runtime [1]. If you are facing issues with variable expansion, it is important to distinguish where the interpolation is happening: 1. Compose File Interpolation: If you use a dollar sign in your compose.yaml (e.g., environment: - VAR=${MY_VAR}), Compose will attempt to interpolate that value [2][1]. To escape a dollar sign here, you must use a double dollar sign ($$) [2]. 2. Env File Content: If you are setting an environment variable in an.env file or a file referenced by env_file, the contents are generally taken literally by the target process inside the container [1]. If you find that characters are being interpreted, ensure your environment file format matches your expectations (e.g., using quotes if required by your specific shell or application environment) [1]. If you are using tools like dotenv or standard shell sourcing, single quotes are often used to prevent shell expansion, but they are not a universal standard for all env_file implementations [1]. If your specific containerized application is interpreting the file (rather than just setting the environment), check the documentation for that specific application's loader.
Citations:
- 1: https://docs.docker.com/compose/how-tos/environment-variables/set-environment-variables/
- 2: https://docs.docker.com/compose/how-tos/environment-variables/variable-interpolation/
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect the devcontainer files to see how .phlex-kilo.env is consumed.
git ls-files .devcontainerRepository: Framework-R-D/phlex
Length of output: 374
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect the compose file that consumes the generated env file.
sed -n '1,120p' .devcontainer/docker-compose.yml | cat -n
# If the file is referenced elsewhere, show those spots too.
rg -n "\.phlex-kilo\.env|env_file|KILO_CONFIG_CONTENT_DOCKER|KILO_CONFIG_CONTENT" .devcontainerRepository: Framework-R-D/phlex
Length of output: 2242
🌐 Web query:
Docker Compose env_file single quoted apostrophe escape official documentation compose spec
💡 Result:
According to official Docker Compose documentation, single-quoted (') values in an env_file are intended to be used literally, and quotes can be escaped using a backslash () [1][2][3]. Specifically, the documentation provides the following example for escaping a single quote: VAR='Let's go!' -> Let's go! [1][2][3] However, be aware that there have been reported issues where the backslash escape character was not correctly processed, resulting in the literal string including the backslash (e.g., Let's go!) [4]. This behavior has been addressed in recent versions of Docker Compose (specifically via patches in the compose-go library) to restore support for escaped quoted characters [4]. If you encounter issues with parsing in your specific environment, ensure you are using an up-to-date version of the Docker Compose CLI [5]. If the default parsing continues to cause issues, you may alternatively use the 'raw' format attribute for your env_file, which disables interpolation and parsing entirely, passing the value to the container exactly as it appears in the file [1][6][3]. Example of using raw format: services: webapp: env_file: path:.env format: raw [1][6] top_results: [1][2][3][4]
Citations:
- 1: https://docs.docker.com/reference/compose-file/services/
- 2: https://compose-spec.github.io/compose-spec/05-services.html
- 3: https://github.com/compose-spec/compose-spec/blob/main/05-services.md
- 4: [BUG] Escape character appears in final value when escaping single quotes in environment file docker/compose#11276
- 5: https://docs.docker.com/compose/how-tos/environment-variables/set-environment-variables/
- 6: https://github.com/docker/docs/blob/main/content/reference/compose-file/services.md
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Show the devcontainer compose service and env_file usage.
sed -n '1,120p' .devcontainer/docker-compose.yml | cat -nRepository: Framework-R-D/phlex
Length of output: 1449
Escape apostrophes before writing KILO_CONFIG_CONTENT. In .devcontainer/ensure-repos.sh:201, the single quotes are fine for keeping $ literal in Compose env_file, but an embedded ' will still break the value. Either escape apostrophes for Compose (\') or switch this file to a raw env-file format.
🤖 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 @.devcontainer/ensure-repos.sh at line 201, The KILO_CONFIG_CONTENT write in
ensure-repos.sh needs to preserve apostrophes because a raw single-quoted value
will break if the content contains an embedded '. Update the logic around the
ENV_FILE write to either escape apostrophes in KILO_CONFIG_CONTENT for Compose
env_file parsing or change the generated file format to a raw env-file style,
keeping the existing behavior for literal $ intact.
| The `*-fix` workflows (`clang-format-fix`, `clang-tidy-fix`, `cmake-format-fix`, `header-guards-fix`, `jsonnet-format-fix`, `markdown-fix`, `python-fix`, `yaml-fix`) follow a specific trigger model: | ||
|
|
||
| - **Triggers**: `issue_comment` (gated to OWNER/COLLABORATOR/MEMBER), `workflow_dispatch`, and `workflow_call` |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
grep -n "^on:" -A20 .github/workflows/clang-tidy-fix.yamlRepository: Framework-R-D/phlex
Length of output: 157
Drop clang-tidy-fix from the workflow_call list here. The Clang-Tidy Fix section later says it only uses issue_comment and workflow_dispatch, so this intro is inconsistent and implies a reusable-call path that doesn’t exist.
🤖 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 `@docs/dev/WORKFLOW_CALLS.md` around lines 7 - 9, The workflow list in the
`WORKFLOW_CALLS` documentation includes `clang-tidy-fix` under `workflow_call`,
but the later `clang-tidy-fix` section only supports `issue_comment` and
`workflow_dispatch`, so the trigger summary is inconsistent. Update the trigger
list in the introductory `*-fix` workflows section to remove `clang-tidy-fix`
from `workflow_call`, and keep the rest of the workflow names and trigger
references aligned with the `clang-tidy-fix` documentation.
| ### 2.2 `workflow_call` | ||
|
|
||
| All 13 workflows that expose `workflow_call` share the same core set of inputs (see 1.1). The only divergences are: | ||
|
|
||
| | Workflow | Extra input(s) | | ||
| | ---------- | ---------------- | | ||
| | `cmake-build.yaml` | `build-combinations` | | ||
| | `clang-tidy-fix.yaml` | `tidy-checks` (boolean array) – present only here. | | ||
| | `python-fix.yaml` | No extra inputs. | | ||
|
|
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
grep -n "workflow_call" -A10 .github/workflows/clang-tidy-fix.yamlRepository: Framework-R-D/phlex
Length of output: 157
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo '--- clang-tidy-fix workflow ---'
grep -n -C 3 -E 'workflow_call|workflow_dispatch|issue_comment|tidy-checks' .github/workflows/clang-tidy-fix.yaml || true
echo
echo '--- WORKFLOW_CALLS mention ---'
grep -n -C 4 -E 'clang-tidy-fix|workflow_call|tidy-checks' docs/dev/WORKFLOW_CALLS.md || true
echo
echo '--- gating block mention ---'
grep -n -C 4 -E 'clang-tidy-fix|workflow_call|exclude|tidy-checks' scripts/check-gating-block.sh || true
echo
echo '--- audit report section ---'
sed -n '76,96p' docs/dev/workflow-audit-report.mdRepository: Framework-R-D/phlex
Length of output: 9145
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python3 - <<'PY'
from pathlib import Path
for path in [
Path(".github/workflows/clang-tidy-fix.yaml"),
Path("docs/dev/WORKFLOW_CALLS.md"),
Path("scripts/check-gating-block.sh"),
]:
print(f"\n## {path}")
if path.exists():
lines = path.read_text().splitlines()
print(f"lines={len(lines)}")
for i, line in enumerate(lines, 1):
if any(k in line for k in ["workflow_call", "tidy-checks", "clang-tidy-fix", "issue_comment", "workflow_dispatch", "exclude"]):
start = max(1, i - 2)
end = min(len(lines), i + 2)
for j in range(start, end + 1):
print(f"{j}: {lines[j-1]}")
print("---")
else:
print("missing")
PYRepository: Framework-R-D/phlex
Length of output: 12470
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Map the relevant files so I can read just the useful slices if needed.
for f in .github/workflows/clang-tidy-fix.yaml docs/dev/WORKFLOW_CALLS.md scripts/check-gating-block.sh docs/dev/workflow-audit-report.md; do
[ -f "$f" ] && echo "== $f ==" && wc -l "$f"
doneRepository: Framework-R-D/phlex
Length of output: 455
Remove clang-tidy-fix.yaml from the workflow_call table
That workflow doesn’t expose workflow_call; tidy-checks is a workflow_dispatch input. The row belongs in the fix-workflow docs, not in the reusable-workflow list.
🤖 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 `@docs/dev/workflow-audit-report.md` around lines 82 - 91, The `workflow_call`
table incorrectly includes `clang-tidy-fix.yaml` even though that workflow does
not expose `workflow_call`; remove that row from the reusable-workflow list and
keep `tidy-checks` documented only under the `workflow_dispatch`/fix-workflow
section. Update the `workflow_call` summary in this doc so it only lists
workflows that actually share the reusable trigger, using the existing
`clang-tidy-fix.yaml`, `python-fix.yaml`, and `cmake-build.yaml` references to
relocate the entry correctly.
| CHECK_WORKFLOWS=( | ||
| "actionlint-check.yaml" | ||
| "clang-format-check.yaml" | ||
| "cmake-format-check.yaml" | ||
| "header-guards-check.yaml" | ||
| "jsonnet-format-check.yaml" | ||
| "markdown-check.yaml" | ||
| "python-check.yaml" | ||
| "yaml-check.yaml" | ||
| ) | ||
|
|
||
| # clang-tidy-check has an issue_comment-aware gating block on its setup job. | ||
| TIDY_CHECK_WORKFLOWS=( | ||
| "clang-tidy-check.yaml" | ||
| ) | ||
|
|
||
| # Fix workflows that expose workflow_call (use inputs.ref != '' as entry point). | ||
| # clang-tidy-fix is excluded: it has no workflow_call trigger. | ||
| FIX_WORKFLOWS=( | ||
| "clang-format-fix.yaml" | ||
| "cmake-format-fix.yaml" | ||
| "header-guards-fix.yaml" | ||
| "jsonnet-format-fix.yaml" | ||
| "markdown-fix.yaml" | ||
| "python-fix.yaml" | ||
| "yaml-fix.yaml" | ||
| ) | ||
|
|
||
| # cmake-build uses the full event-list gating block on its setup job. | ||
| BUILD_WORKFLOWS=( | ||
| "cmake-build.yaml" | ||
| ) | ||
|
|
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Confirm the actual gating conditions on coverage.yaml and clang-tidy-fix.yaml
fd -e yaml -e yml . .github/workflows --exec grep -l "workflow_call" {} \;
echo "---coverage.yaml if-blocks---"
grep -n "if:" -A6 .github/workflows/coverage.yaml
echo "---clang-tidy-fix.yaml if-blocks---"
grep -n "if:" -A6 .github/workflows/clang-tidy-fix.yamlRepository: Framework-R-D/phlex
Length of output: 12183
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== scripts/check-gating-block.sh =="
cat -n scripts/check-gating-block.sh | sed -n '1,240p'
echo
echo "== docs/dev/WORKFLOW_CALLS.md (coverage + clang-tidy-fix mentions) =="
rg -n "coverage.yaml|clang-tidy-fix.yaml|workflow_call|issue_comment|author_association|inputs.ref" docs/dev/WORKFLOW_CALLS.md .github/workflows scripts/check-gating-block.sh
echo
echo "== workflow inventory =="
git ls-files '.github/workflows/*.y*ml' | sortRepository: Framework-R-D/phlex
Length of output: 20711
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== .github/workflows/coverage.yaml (header/setup excerpt) =="
sed -n '1,90p' .github/workflows/coverage.yaml | cat -n
echo
echo "== .github/workflows/clang-tidy-fix.yaml (header/setup excerpt) =="
sed -n '1,120p' .github/workflows/clang-tidy-fix.yaml | cat -n
echo
echo "== docs/dev/WORKFLOW_CALLS.md relevant excerpts =="
sed -n '280,310p' docs/dev/WORKFLOW_CALLS.md | cat -n
echo
sed -n '548,570p' docs/dev/WORKFLOW_CALLS.md | cat -nRepository: Framework-R-D/phlex
Length of output: 11285
Add the remaining gating families to scripts/check-gating-block.sh scripts/check-gating-block.sh:26-58 skips two workflows that still have setup-job gates worth auditing: coverage.yaml (workflow_dispatch/pull_request/push/schedule/issue_comment, plus the coverage bot command) and clang-tidy-fix.yaml (workflow_dispatch/issue_comment, plus the tidy-fix bot command). A small dedicated phrase list for each would close the blind spots.
🤖 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 `@scripts/check-gating-block.sh` around lines 26 - 58, The gating check in
check-gating-block.sh is missing two workflow families that still use setup-job
gating logic: coverage.yaml and clang-tidy-fix.yaml. Add dedicated entries/small
phrase lists for these workflows in the script’s existing workflow groupings
(alongside CHECK_WORKFLOWS, TIDY_CHECK_WORKFLOWS, FIX_WORKFLOWS, and
BUILD_WORKFLOWS) so their setup-job event gates and bot-command conditions are
audited too.
| def test_long_new_alert_list_is_folded(self) -> None: | ||
| """A new-alerts section above the fold threshold is collapsed.""" | ||
| alerts = [self._alert() for _ in range(M._FOLD_THRESHOLD + 1)] | ||
| body = M.build_comment( | ||
| new_alerts=alerts, | ||
| fixed_alerts=[], | ||
| repo=None, | ||
| max_results=100, | ||
| threshold="warning", | ||
| ) | ||
| assert "<details>" in body | ||
| assert "<summary>" in body | ||
|
|
||
| def test_short_new_alert_list_is_not_folded(self) -> None: | ||
| """A new-alerts section at or below the fold threshold is not collapsed.""" | ||
| alerts = [self._alert() for _ in range(M._FOLD_THRESHOLD)] | ||
| body = M.build_comment( | ||
| new_alerts=alerts, | ||
| fixed_alerts=[], | ||
| repo=None, | ||
| max_results=100, | ||
| threshold="warning", | ||
| ) | ||
| assert "<details>" not in body |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value
Folding tests for build_comment are correct.
Good boundary testing on the new-alerts section. Consider adding a parallel test for fixed_alerts folding in build_comment — it's the same code path but currently untested for the folded case.
🤖 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 `@scripts/test/test_check_codeql_alerts.py` around lines 714 - 737, The folding
coverage in build_comment only tests new_alerts, so add a parallel folded-case
test for fixed_alerts using the same _FOLD_THRESHOLD boundary. Reuse the
existing test pattern in test_long_new_alert_list_is_folded and target the
build_comment path with fixed_alerts populated and new_alerts empty to verify
the details/summary wrapping is applied there too.
| def test_long_new_vs_base_list_is_folded(self) -> None: | ||
| """A new_vs_base section above the fold threshold is collapsed.""" | ||
| alerts = [self._alert(number=i) for i in range(M._FOLD_THRESHOLD + 1)] | ||
| comp = self._comp(new_vs_base=alerts, base_sha="abc1234") | ||
| body = M._build_multi_section_comment(comp, max_results=100) | ||
| assert "<details>" in body | ||
| assert "<summary>" in body | ||
|
|
||
| def test_short_new_vs_base_list_is_not_folded(self) -> None: | ||
| """A new_vs_base section at or below the fold threshold is not collapsed.""" | ||
| alerts = [self._alert(number=i) for i in range(M._FOLD_THRESHOLD)] | ||
| comp = self._comp(new_vs_base=alerts, base_sha="abc1234") | ||
| body = M._build_multi_section_comment(comp, max_results=100) | ||
| assert "<details>" not in body |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value
Folding tests for _build_multi_section_comment are correct.
The new_vs_base folding tests are well-structured. The other three comparison sections (new_vs_prev, fixed_vs_prev, fixed_vs_base) and the fallback paths share the same _render_section call but lack dedicated folding tests. Since _render_section itself is thoroughly tested, the risk is low, but one parametrized test covering all six paths would eliminate any doubt.
🤖 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 `@scripts/test/test_check_codeql_alerts.py` around lines 1220 - 1233, The
`_build_multi_section_comment` folding coverage is incomplete because only
`new_vs_base` has explicit threshold tests. Add a single parametrized test in
`test_check_codeql_alerts.py` that exercises all comparison sections and
fallback paths using the shared `_render_section` flow, including `new_vs_prev`,
`fixed_vs_prev`, `fixed_vs_base`, and the non-comparison branches, so each path
is verified to fold or not fold consistently with `_FOLD_THRESHOLD`.
Details
blocksCI / workflows
scripts/check-gating-block.shand wired a newgating_checkjob intoactionlint-check.cmake-build.yamlto snake_case.codeql-comment.yamlto usegithub.tokeninstead ofWORKFLOW_PAT.<details>blocks.Devcontainer / toolchain
@kilocode/cli.Documentation
WORKFLOW_CALLS.md).Code / tests