Skip to content

Add make rpm, fix SELinux policy, add CI RPM builds and GitHub Pages repo#5

Merged
maxamillion merged 7 commits into
LobsterTrap:mainfrom
maxamillion:rpm
Mar 27, 2026
Merged

Add make rpm, fix SELinux policy, add CI RPM builds and GitHub Pages repo#5
maxamillion merged 7 commits into
LobsterTrap:mainfrom
maxamillion:rpm

Conversation

@maxamillion

@maxamillion maxamillion commented Mar 27, 2026

Copy link
Copy Markdown
Contributor

Summary

  • make rpm target: Builds all 7 RPM packages locally via mock with auto-detected Fedora version. Also adds make srpm-all for local SRPM builds.
  • SELinux policy fix: Introduces puzzlepod_agent_t type to separate daemon and agent sandbox domains, resolving 10 allow/neverallow contradictions and multiple compilation errors on Fedora 43.
  • CI RPM build validation: Matrix job builds RPMs against Fedora 42, Fedora 43, and CentOS Stream+EPEL 10 on every push/PR.
  • GitHub Pages RPM repository: Automated workflow publishes a dnf-installable RPM repo on every merge to main, with per-distro repos and source tarball.

Key changes

Build infrastructure

  • Add rpm and srpm-all Makefile targets
  • Fix build-srpm.sh: correct spec filename, inject %global macros via sed, use working-tree tarballs, preserve source tarball for CI
  • Add git-core BuildRequires and git init in %prep for regorus build.rs compatibility
  • Upgrade CI container from Fedora 42 to Fedora 43, add mock and createrepo_c

SELinux policy (selinux/puzzlepod.te, .if)

  • Split puzzlepod_t into puzzlepod_t (daemon) + puzzlepod_agent_t (sandbox)
  • Remove duplicate type declaration, invalid corenet_tcp_connect_dbus_port interface
  • Use proper SELinux interfaces for cgroup/quota access
  • Add require block for base policy types used in neverallow rules
  • All neverallow rules now target puzzlepod_agent_t only

CI/CD (.github/workflows/)

  • ci.yml: Add rpm-build matrix job (3 targets)
  • rpm-repo.yml: Three-stage pipeline (build-source → build-rpms matrix → publish to GitHub Pages)
  • Reference .repo files for Fedora and EL

Documentation (13 files)

  • All docs updated to reflect puzzlepod_agent_t as the agent sandbox domain

One-time setup required

Enable GitHub Pages in repo Settings → Pages → Source: GitHub Actions

Test plan

  • make rpm builds all 7/7 packages successfully on Fedora 43
  • SELinux module compiles locally with checkmodule
  • CI rpm-build matrix passes for all 3 targets
  • RPM repo workflow deploys to GitHub Pages after merge
  • dnf install puzzlepod works from the published repo

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Local multi-target RPM build and a Make target to rebuild all source RPMs into binary RPMs.
    • Automated RPM repository assembly and publishing to GitHub Pages with install snippets.
  • Documentation

    • Updated security and architecture docs to use a distinct SELinux domain for agent processes.
  • Chores

    • CI moved to configurable containerized builds and now produces and uploads SRPM/RPM artifacts for release.

maxamillion and others added 3 commits March 27, 2026 11:59
Add rpm and srpm-all Makefile targets for local RPM builds via mock.
Fix build-srpm.sh: correct puzzlepod-selinux spec filename, inject
%global macros via sed (survives SRPM re-extraction), use tar instead
of git archive for working-tree tarballs, preserve source tarball for
CI artifact upload. Add git-core BuildRequires and git init in %prep
for regorus build.rs compatibility in puzzlectl.spec and puzzled.spec.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Adam Miller <admiller@redhat.com>
Split the single puzzlepod_t type into puzzlepod_t (daemon) and
puzzlepod_agent_t (sandboxed agents). Resolves 10 allow/neverallow
contradictions, fixes duplicate type declaration, replaces invalid
corenet_tcp_connect_dbus_port interface, uses proper SELinux interfaces
for cgroup and quota access, and adds require block for base policy
types. Update all documentation and diagrams to reflect the new type.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Adam Miller <admiller@redhat.com>
Add rpm-build matrix job to CI workflow validating builds against
Fedora 42, Fedora 43, and CentOS Stream+EPEL 10 via mock. Add
rpm-repo.yml workflow that builds RPMs on push to main and publishes
a dnf repository to GitHub Pages with per-distro repos and source
tarball. Upgrade CI container to Fedora 43 with mock and createrepo_c.
Add reference .repo files for Fedora and EL.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Adam Miller <admiller@redhat.com>
maxamillion and others added 3 commits March 27, 2026 12:09
Switch ci and integration jobs back to using the pre-built Fedora CI
container image instead of inline ubuntu apt-get installs. Use
vars.CI_IMAGE with fedora42 fallback for all jobs so the image tag
can be updated via repository variables without code changes.

Signed-off-by: Adam Miller <admiller@redhat.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Skip test_machine_id_fallback_deterministic when /etc/machine-id is
too short (< 32 chars), as commonly occurs in containers. The test
already skipped when the file was missing but not when it had
truncated content.

Signed-off-by: Adam Miller <admiller@redhat.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Update unicode-segmentation to unyanked version. Add RUSTSEC-2026-0002
(lru unsoundness) to deny.toml ignore list — transitive dep of ratatui
v0.29, fix requires ratatui >= 0.30 breaking update. No practical
impact as lru is used internally for layout caching.

Signed-off-by: Adam Miller <admiller@redhat.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@maxamillion

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Mar 27, 2026

Copy link
Copy Markdown
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Mar 27, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

This PR containerizes CI jobs, adds workflows to build and publish RPM repositories to GitHub Pages, refactors SRPM/RPM packaging (including source tarball behavior and spec tweaks), introduces a new SELinux domain puzzlepod_agent_t for agent sandboxes, and updates docs/tests to reflect those changes.

Changes

Cohort / File(s) Summary
CI Workflows & Container
.github/workflows/ci.yml, .github/workflows/rpm-repo.yml, ci/Containerfile
Moved CI jobs into configurable Fedora container images (default Fedora 43), removed in-job OS/toolchain installs, added rpm-build job, and introduced rpm-repo.yml to build per-target RPM repos and publish to GitHub Pages. ci/Containerfile updated (Fedora 43, added mock and createrepo_c, added root to mock group).
Makefile & Local RPM Targets
Makefile
Added srpm-all and rpm targets; rpm rebuilds SRPMs via mock with per-SRPM failure tracking and help/check-deps updates.
SRPM/RPM Packaging Script
packaging/build-srpm.sh
Changed source tarball generation to include working-tree (uncommitted changes), inject git metadata into specs for non-release builds (via sed), renamed selinux spec to puzzlepod-selinux.spec, and persist source tarball into packaging/source-tarball/.
RPM Spec Prep Changes
packaging/puzzlectl.spec, packaging/puzzled.spec
Added git-core BuildRequires and added %prep steps initializing a temporary git repo and an empty commit so git rev-parse HEAD resolves during RPM builds.
Repository Files
packaging/puzzlepod.repo, packaging/puzzlepod-el.repo, .gitignore
Added Fedora/EPEL repo config files (packaging/puzzlepod*.repo) and added packaging output dirs (packaging/srpms/, packaging/rpms/, packaging/source-tarball/) to .gitignore.
SELinux Policy & Podman Integration
selinux/puzzlepod.te, selinux/puzzlepod.if, podman/puzzle-podman, podman/quadlet/puzzlepod-agent.container
Introduced new puzzlepod_agent_t type and moved agent execution/allow/neverallow rules to it; updated interface to require/manage puzzlepod_agent_t; Podman scripts/quadlet now use type:puzzlepod_agent_t for agent containers.
Docs & Diagrams
docs/PRD.md, docs/admin-guide.md, docs/developer-guide.md, docs/technical-design.md, docs/security-guide.md, docs/compliance/*, docs/diagrams/*, docs/podman_puzzled_architecture.md, docs/rogue-agent-test-report.md
Updated documentation and diagrams across the repo to reference puzzlepod_agent_t for sandboxed agents and adjusted SELinux policy descriptions accordingly.
Cargo Deny & Tests
deny.toml, crates/puzzled/src/config.rs
Added RUSTSEC-2026-0002 to cargo-deny ignores; strengthened test_machine_id_fallback_deterministic to validate /etc/machine-id content length before proceeding.
Packaging Repo Workflow Artifacts
packaging/* (artifact directories)
CI/workflows now upload SRPMs, per-target repos, and source tarball artifacts; Makefile/script changes align local packaging with CI behavior.

Sequence Diagram(s)

sequenceDiagram
    participant GH as GitHub Actions
    participant Container as Container (Fedora 43)
    participant Mock as mock (in Container)
    participant Artifacts as Actions Artifacts
    participant Pages as GitHub Pages

    GH->>Container: run `build-source` (build SRPMs, source tarball)
    Container->>Artifacts: upload SRPMs + source tarball
    GH->>Container: run `build-rpms` matrix (each target)
    Container->>Mock: rebuild SRPMs -> produce RPMs
    Mock->>Container: RPMs & repo metadata (createrepo_c)
    Container->>Artifacts: upload `repo-<target>` artifacts
    GH->>GH: `publish` job downloads SRPMs + repo artifacts
    GH->>Pages: assemble `pages/` (repo dirs + index) and deploy to GitHub Pages
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 I nibbled code where containers grow,

SRPMs sprouted where wild commits go.
Agents now hop in their own little pen,
RPMs roll out to Pages again.
A tiny rabbit claps — builds pass, and then 🥕

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly captures the three main changes: Makefile rpm target addition, SELinux policy split (puzzlepod_agent_t), and CI/GitHub Pages RPM repository automation.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (5)
packaging/build-srpm.sh (1)

122-130: Verify tarball preservation timing.

The source tarball is correctly preserved for CI before cleanup. However, consider adding error handling if the copy fails, since the original is deleted immediately after.

🔧 Optional: Add copy verification
 # Preserve source tarball for CI artifact upload
 TARBALL_DIR="$SCRIPT_DIR/source-tarball"
 mkdir -p "$TARBALL_DIR"
-cp "/tmp/${TARBALL}" "$TARBALL_DIR/"
+cp "/tmp/${TARBALL}" "$TARBALL_DIR/" || {
+    echo "ERROR: Failed to preserve source tarball" >&2
+    exit 1
+}
 echo ""
 echo "Source tarball: $TARBALL_DIR/${TARBALL}"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packaging/build-srpm.sh` around lines 122 - 130, The script copies the source
tarball to TARBALL_DIR but immediately deletes the original; add verification
and error handling around the cp of "/tmp/${TARBALL}" to ensure we don't remove
the only copy on failure: after attempting the copy (the cp command that
references TARBALL and TARBALL_DIR), check the command exit status and if it
failed, log an error message and exit non‑zero without running the subsequent rm
-rf on RPMBUILD_DIR and "/tmp/${TARBALL}"; only proceed to the cleanup step when
the copy succeeded.
.github/workflows/ci.yml (1)

336-344: Glob expansion may fail if no SRPMs exist.

If packaging/srpms/*.src.rpm matches nothing (e.g., if build-srpm.sh fails silently), the loop iterates with the literal string *.src.rpm, causing mock to fail confusingly. Consider adding a check or enabling nullglob.

♻️ Proposed fix to handle empty glob
       - name: Build RPMs with mock
         run: |
+          shopt -s nullglob
           mkdir -p packaging/rpms
           for srpm in packaging/srpms/*.src.rpm; do
             echo "--- mock: $srpm ---"
             mock -r ${{ matrix.mock_root }} --enable-network --isolation=simple \
               --rebuild "$srpm" --resultdir=packaging/rpms/ || {
               echo "FAILED: $srpm"
               cat packaging/rpms/build.log 2>/dev/null || true
               exit 1
             }
           done
+          if [ ! -f packaging/rpms/*.rpm ]; then
+            echo "ERROR: No RPMs produced"
+            exit 1
+          fi
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/ci.yml around lines 336 - 344, The for-loop in the CI job
that iterates over packaging/srpms/*.src.rpm can run with the literal glob when
no SRPMs exist; update the loop in .github/workflows/ci.yml to guard against
empty globs by either enabling shell nullglob/shopt -s nullglob before the loop
or by adding an explicit existence check (e.g., test -e
packaging/srpms/*.src.rpm or listing files into an array) so the mock invocation
only runs when there are actual .src.rpm files to process.
.github/workflows/rpm-repo.yml (2)

167-169: Use find instead of ls for safer filename handling.

Per static analysis (SC2012), using ls with globs can misbehave with filenames containing special characters. While unlikely here, find is more robust.

♻️ Proposed fix
           # Determine tarball filename for the index page
-          TARBALL=$(ls pages/source/puzzlepod-*.tar.gz 2>/dev/null | head -1)
+          TARBALL=$(find pages/source/ -maxdepth 1 -name 'puzzlepod-*.tar.gz' -print -quit 2>/dev/null)
           TARBALL_NAME=$(basename "$TARBALL" 2>/dev/null || echo "puzzlepod-source.tar.gz")
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/rpm-repo.yml around lines 167 - 169, Replace the fragile
ls-based lookup for TARBALL/TARBALL_NAME with a robust find-based search: use
find to locate the first matching file under pages/source (maxdepth 1) for the
'puzzlepod-*.tar.gz' pattern and assign its path to TARBALL, then derive
TARBALL_NAME from that path (falling back to "puzzlepod-source.tar.gz" if no
match). Update the TARBALL and TARBALL_NAME assignments to use this find
approach so filenames with special characters are handled safely.

101-109: Silently ignoring copy errors may hide real failures.

The 2>/dev/null || true on the cp command suppresses all errors, including cases where no RPMs were built. If mock succeeds but produces no output (unusual but possible), the repo would be empty without indication.

♻️ Proposed improvement to validate RPM presence
       - name: Prepare repo directory
         run: |
           mkdir -p ${{ matrix.repo_path }}
           cp rpms/*.noarch.rpm rpms/*.x86_64.rpm \
             ${{ matrix.repo_path }}/ 2>/dev/null || true
+          # Verify at least one RPM was copied
+          if ! ls ${{ matrix.repo_path }}/*.rpm >/dev/null 2>&1; then
+            echo "ERROR: No RPMs found for repo"
+            exit 1
+          fi
           # Strip debug packages (large, not needed for users)
           rm -f ${{ matrix.repo_path }}/*-debuginfo-* \
                 ${{ matrix.repo_path }}/*-debugsource-*
           createrepo_c ${{ matrix.repo_path }}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/rpm-repo.yml around lines 101 - 109, Remove the silent
suppression on the cp step and add an explicit existence check after copying to
fail the job if no RPMs were placed into the repo dir; specifically modify the
block that runs mkdir -p ${{ matrix.repo_path }}, cp rpms/*.noarch.rpm
rpms/*.x86_64.rpm ${{ matrix.repo_path }}, rm -f ... and createrepo_c ${{
matrix.repo_path }} so that cp errors are not redirected to /dev/null, and add a
test (e.g., check for globs like ${{ matrix.repo_path }}/*.rpm) that calls exit
1 or prints an error before createrepo_c when no RPMs are found.
Makefile (1)

299-328: Good error aggregation pattern; consider adding --isolation=simple for consistency.

The rpm target properly aggregates failures and reports them at the end. However, the CI workflow uses --isolation=simple with mock, while this local target does not. This could lead to different behavior between local and CI builds.

♻️ Proposed fix for consistency with CI
-		if mock -r "$$MOCK_ROOT" --enable-network --rebuild "$$srpm" --resultdir=packaging/rpms/; then \
+		if mock -r "$$MOCK_ROOT" --enable-network --isolation=simple --rebuild "$$srpm" --resultdir=packaging/rpms/; then \
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Makefile` around lines 299 - 328, The rpm Makefile target runs mock --rebuild
for each SRPM but omits the --isolation=simple flag used in CI, which can cause
differing local vs CI behavior; update the mock invocation in the rpm target
(the line invoking mock -r "$$MOCK_ROOT" --enable-network --rebuild "$$srpm"
--resultdir=packaging/rpms/) to include --isolation=simple so mock is invoked
consistently with CI (leave the rest of the command, variables like MOCK_ROOT
and the packaging/rpms resultdir unchanged).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/podman_puzzled_architecture.md`:
- Around line 169-170: Update the runtime SELinux label references from
puzzlepod_t to puzzlepod_agent_t: replace the string --security-opt
"label=type:puzzlepod_t" (in podman/puzzle-podman) with --security-opt
"label=type:puzzlepod_agent_t" and replace SecurityOpt=label=type:puzzlepod_t
(in podman/quadlet/puzzlepod-agent.container) with
SecurityOpt=label=type:puzzlepod_agent_t so the runtime configs match the docs.

In `@docs/technical-design.md`:
- Line 896: The sentence wrongly uses the agent sandbox domain name
puzzlepod_agent_t for the daemon; change puzzlepod_agent_t to the daemon domain
puzzlepod_t so the hardening line accurately describes the daemon (puzzled)
confinement; update the string in the paragraph containing "puzzlepod_agent_t"
to "puzzlepod_t" and ensure it now matches the daemon domain used elsewhere
(e.g., puzzlepod_t in selinux policy).

In `@selinux/puzzlepod.te`:
- Around line 14-17: Podman-managed agents are being started with
label=type:puzzlepod_t so they bypass the intended puzzlepod_agent_t domain;
update the Podman launch files (podman/puzzle-podman and
podman/quadlet/puzzlepod-agent.container) to use label=type:puzzlepod_agent_t
instead of puzzlepod_t, and ensure the SELinux policy includes the corresponding
transition via application_domain(puzzlepod_agent_t, puzzlepod_exec_t) (and
mirror any other declarations around the duplicated block at lines noted, e.g.,
the types at 96-99) so Podman-launched agents enter the puzzlepod_agent_t domain
rather than puzzlepod_t.
- Around line 166-169: The puzzlepod_agent_t SELinux domain is missing baseline
file/read and execute allows; update the selinux policy for puzzlepod_agent_t
(where files_read_usr_files(puzzlepod_agent_t), libs_use_ld_so,
libs_use_shared_libs are declared) to explicitly allow read access to
/etc/localtime, /etc/resolv.conf, /proc/self/**, /dev/null, and /dev/urandom and
to grant execute permission for the documented toolchain binaries (python3,
node, git, grep, make, cargo, curl) — i.e., add the appropriate allow rules or
use/extend macros so that puzzlepod_agent_t can read those config/device paths
and execute the binaries (ensure execute bit/context types for /usr/bin/*
entries are covered rather than only files_read_usr_files()).

---

Nitpick comments:
In @.github/workflows/ci.yml:
- Around line 336-344: The for-loop in the CI job that iterates over
packaging/srpms/*.src.rpm can run with the literal glob when no SRPMs exist;
update the loop in .github/workflows/ci.yml to guard against empty globs by
either enabling shell nullglob/shopt -s nullglob before the loop or by adding an
explicit existence check (e.g., test -e packaging/srpms/*.src.rpm or listing
files into an array) so the mock invocation only runs when there are actual
.src.rpm files to process.

In @.github/workflows/rpm-repo.yml:
- Around line 167-169: Replace the fragile ls-based lookup for
TARBALL/TARBALL_NAME with a robust find-based search: use find to locate the
first matching file under pages/source (maxdepth 1) for the 'puzzlepod-*.tar.gz'
pattern and assign its path to TARBALL, then derive TARBALL_NAME from that path
(falling back to "puzzlepod-source.tar.gz" if no match). Update the TARBALL and
TARBALL_NAME assignments to use this find approach so filenames with special
characters are handled safely.
- Around line 101-109: Remove the silent suppression on the cp step and add an
explicit existence check after copying to fail the job if no RPMs were placed
into the repo dir; specifically modify the block that runs mkdir -p ${{
matrix.repo_path }}, cp rpms/*.noarch.rpm rpms/*.x86_64.rpm ${{ matrix.repo_path
}}, rm -f ... and createrepo_c ${{ matrix.repo_path }} so that cp errors are not
redirected to /dev/null, and add a test (e.g., check for globs like ${{
matrix.repo_path }}/*.rpm) that calls exit 1 or prints an error before
createrepo_c when no RPMs are found.

In `@Makefile`:
- Around line 299-328: The rpm Makefile target runs mock --rebuild for each SRPM
but omits the --isolation=simple flag used in CI, which can cause differing
local vs CI behavior; update the mock invocation in the rpm target (the line
invoking mock -r "$$MOCK_ROOT" --enable-network --rebuild "$$srpm"
--resultdir=packaging/rpms/) to include --isolation=simple so mock is invoked
consistently with CI (leave the rest of the command, variables like MOCK_ROOT
and the packaging/rpms resultdir unchanged).

In `@packaging/build-srpm.sh`:
- Around line 122-130: The script copies the source tarball to TARBALL_DIR but
immediately deletes the original; add verification and error handling around the
cp of "/tmp/${TARBALL}" to ensure we don't remove the only copy on failure:
after attempting the copy (the cp command that references TARBALL and
TARBALL_DIR), check the command exit status and if it failed, log an error
message and exit non‑zero without running the subsequent rm -rf on RPMBUILD_DIR
and "/tmp/${TARBALL}"; only proceed to the cleanup step when the copy succeeded.
🪄 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

Run ID: 6e7db488-6e67-4e62-877c-c415f2dd64a6

📥 Commits

Reviewing files that changed from the base of the PR and between bbb8210 and 519b01f.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (25)
  • .github/workflows/ci.yml
  • .github/workflows/rpm-repo.yml
  • .gitignore
  • Makefile
  • ci/Containerfile
  • crates/puzzled/src/config.rs
  • deny.toml
  • docs/PRD.md
  • docs/admin-guide.md
  • docs/compliance/fedramp.md
  • docs/compliance/iso27001.md
  • docs/developer-guide.md
  • docs/diagrams/01-system-architecture.drawio
  • docs/diagrams/06-defense-in-depth.drawio
  • docs/podman_puzzled_architecture.md
  • docs/rogue-agent-test-report.md
  • docs/security-guide.md
  • docs/technical-design.md
  • packaging/build-srpm.sh
  • packaging/puzzlectl.spec
  • packaging/puzzled.spec
  • packaging/puzzlepod-el.repo
  • packaging/puzzlepod.repo
  • selinux/puzzlepod.if
  • selinux/puzzlepod.te

Comment thread docs/podman_puzzled_architecture.md
Comment thread docs/technical-design.md Outdated
Comment thread selinux/puzzlepod.te
Comment thread selinux/puzzlepod.te
Comment on lines +166 to 169
files_read_usr_files(puzzlepod_agent_t)
libs_use_ld_so(puzzlepod_agent_t)
libs_use_shared_libs(puzzlepod_agent_t)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🌐 Web query:

In SELinux reference policy, does the files_read_usr_files(domain)macro grantexecuteorexecute_no_transon/usr/bin/*, or is a separate execution interface required for a custom domain?

💡 Result:

In the SELinux reference policy, the files_read_usr_files(domain) macro does not grant execute or execute_no_trans permissions on /usr/bin/*. It provides read access (e.g., read, getattr, search on usr_t directories and files), but execution permissions require a separate interface, such as corecmd_exec_bin(domain) or files_execute_usr_files(domain) if it exists, or explicit allow rules for execute on bin_t or usr_t files. Custom domains typically need additional execution interfaces like domain_entry_file(domain, { bin_t usr_t }) or specific exec macros to run binaries from /usr/bin without denials.

Citations:


🏁 Script executed:

# First, check if the documentation file exists and examine the referenced lines
fd -t f "technical-design.md" --exec wc -l {} \;

Repository: LobsterTrap/puzzlepod

Length of output: 96


🏁 Script executed:

# Get the referenced lines from the technical design doc (617-625 and 647-655)
sed -n '617,625p;647,655p' docs/technical-design.md

Repository: LobsterTrap/puzzlepod

Length of output: 453


🏁 Script executed:

# Check the full puzzlepod.te file to see all permissions granted to puzzlepod_agent_t
cat -n selinux/puzzlepod.te | grep -A 50 "puzzlepod_agent_t"

Repository: LobsterTrap/puzzlepod

Length of output: 11498


puzzlepod_agent_t is missing critical baseline runtime access documented in the design.

The domain lacks SELinux allows for the baseline reads specified in docs/technical-design.md (lines 617-625): /etc/localtime, /etc/resolv.conf, /proc/self/**, /dev/null, and /dev/urandom. Additionally, there are no execute permissions for the toolchain binaries documented in lines 647-655 (python3, node, git, grep, make, cargo, curl). The files_read_usr_files() macro grants read access to /usr/* but does not include execute permissions. Without these permissions, DNS resolution will fail (missing /etc/resolv.conf), timezone operations will break (missing /etc/localtime), and none of the documented toolchain executables will run when agents transition to this domain.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@selinux/puzzlepod.te` around lines 166 - 169, The puzzlepod_agent_t SELinux
domain is missing baseline file/read and execute allows; update the selinux
policy for puzzlepod_agent_t (where files_read_usr_files(puzzlepod_agent_t),
libs_use_ld_so, libs_use_shared_libs are declared) to explicitly allow read
access to /etc/localtime, /etc/resolv.conf, /proc/self/**, /dev/null, and
/dev/urandom and to grant execute permission for the documented toolchain
binaries (python3, node, git, grep, make, cargo, curl) — i.e., add the
appropriate allow rules or use/extend macros so that puzzlepod_agent_t can read
those config/device paths and execute the binaries (ensure execute bit/context
types for /usr/bin/* entries are covered rather than only
files_read_usr_files()).

Fix Podman runtime configs to use puzzlepod_agent_t SELinux label
(puzzle-podman, quadlet container). Revert daemon hardening description
to puzzlepod_t. Add corecmd_exec_bin for agent binary execution.
Add error handling on tarball copy, nullglob guard for SRPM globs,
find-based tarball lookup, RPM existence validation, and
--isolation=simple to Makefile mock invocation for CI consistency.

Signed-off-by: Adam Miller <admiller@redhat.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (4)
.github/workflows/rpm-repo.yml (2)

82-99: Consider adding a nullglob guard for robustness.

Similar to the Makefile, if srpms/*.src.rpm doesn't match (e.g., artifact download issue), the loop will iterate with the literal glob string. While unlikely since artifacts come from the previous job, adding a guard improves resilience.

♻️ Proposed fix
       - name: Build RPMs via mock
         run: |
           mkdir -p rpms
           FAILED=""
+          shopt -s nullglob
           for srpm in srpms/*.src.rpm; do
             echo "--- mock: $srpm ---"
             if mock -r ${{ matrix.mock_root }} --enable-network --isolation=simple \
               --rebuild "$srpm" --resultdir=rpms/; then
               echo "--- OK: $srpm ---"
             else
               echo "--- FAILED: $srpm ---"
               FAILED="$FAILED $srpm"
             fi
           done
+          shopt -u nullglob
           if [ -n "$FAILED" ]; then
             echo "=== FAILED builds ===$FAILED"
             exit 1
           fi
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/rpm-repo.yml around lines 82 - 99, The loop over
srpms/*.src.rpm can iterate the literal glob when there are no matches; enable a
nullglob guard before the loop or explicitly check for matches: set shell to
ignore unmatched globs (e.g., run shopt -s nullglob) or test for files (e.g.,
compgen -G "srpms/*.src.rpm" >/dev/null) before the for-loop that assigns to
srpm and uses FAILED; ensure to restore the shell option if you change it and
keep the rest of the loop logic (the for srpm in srpms/*.src.rpm; do ...
FAILED=...; done and the subsequent if [ -n "$FAILED" ]; then ... fi) unchanged.

172-174: Fallback tarball name may produce broken link.

If find returns no results, TARBALL_NAME defaults to puzzlepod-source.tar.gz, which may not exist, creating a broken link in the index. Consider adding validation or using a more defensive pattern.

♻️ Proposed improvement
           # Determine tarball filename for the index page
           TARBALL=$(find pages/source/ -maxdepth 1 -name 'puzzlepod-*.tar.gz' -print -quit 2>/dev/null)
-          TARBALL_NAME=$(basename "$TARBALL" 2>/dev/null || echo "puzzlepod-source.tar.gz")
+          if [ -n "$TARBALL" ]; then
+            TARBALL_NAME=$(basename "$TARBALL")
+          else
+            echo "WARNING: No source tarball found, index link may be broken"
+            TARBALL_NAME="puzzlepod-source.tar.gz"
+          fi
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/rpm-repo.yml around lines 172 - 174, The fallback sets
TARBALL_NAME to a hardcoded "puzzlepod-source.tar.gz" even when TARBALL is
empty, which can create a broken link; update the workflow to validate TARBALL
after the find call (check that the variable is non-empty and that the file
exists) and then only derive TARBALL_NAME from basename("$TARBALL") when valid,
otherwise handle the missing artifact defensively (for example: set TARBALL_NAME
to empty and skip index link generation, or fail the job with a clear error
message). Ensure you modify the logic referring to the TARBALL and TARBALL_NAME
variables so downstream steps that build the index either skip the link or fail
fast with an informative message.
Makefile (1)

311-318: Add a guard for empty SRPM glob expansion.

If packaging/srpms/*.src.rpm matches no files (e.g., srpm-all produces nothing), the loop iterates once with the literal glob string, causing a confusing mock error. Consider adding a nullglob guard or explicit check.

♻️ Proposed fix
 	mkdir -p packaging/rpms; \
 	FAILED=""; \
+	shopt -s nullglob; \
 	for srpm in packaging/srpms/*.src.rpm; do \
 		echo "--- mock: $$srpm ---"; \
 		if mock -r "$$MOCK_ROOT" --enable-network --isolation=simple --rebuild "$$srpm" --resultdir=packaging/rpms/; then \
 			echo "--- OK: $$srpm ---"; \
 		else \
 			echo "--- FAILED: $$srpm ---"; \
 			FAILED="$$FAILED $$srpm"; \
 		fi; \
 	done; \
+	shopt -u nullglob; \
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Makefile` around lines 311 - 318, The SRPM loop iterates even when the glob
yields no files (causing mock to receive the literal pattern); replace the
direct shell glob in the for-loop with a Makefile-side check using the wildcard
function: compute SRPMS := $(wildcard packaging/srpms/*.src.rpm) and then
iterate for srpm in $(SRPMS) or early-exit/echo when SRPMS is empty. Update the
loop that uses the srpm variable and preserves the FAILED and MOCK_ROOT usage so
mock only runs when real .src.rpm files exist.
podman/puzzle-podman (1)

584-587: SELinux label correctly updated to puzzlepod_agent_t with graceful fallback.

This addresses the prior feedback. The conditional check allows the script to work on systems without the puzzlepod SELinux policy installed.

Minor nit: &>/dev/null 2>&1 is redundant — &>/dev/null already redirects both stdout and stderr. Consider simplifying to just &>/dev/null.

,

Optional cleanup
     # Only apply puzzlepod_agent_t SELinux label if the type exists on the host
-    if seinfo -t puzzlepod_agent_t &>/dev/null 2>&1; then
+    if seinfo -t puzzlepod_agent_t &>/dev/null; then
         NATIVE_ARGS+=(--security-opt "label=type:puzzlepod_agent_t")
     fi
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@podman/puzzle-podman` around lines 584 - 587, The seinfo check currently uses
a redundant redirection `&>/dev/null 2>&1`; simplify the command by removing the
duplicate redirection so it only redirects both stdout and stderr once (e.g.,
use `&>/dev/null` or `>/dev/null 2>&1`) in the `seinfo -t puzzlepod_agent_t`
test that controls appending `--security-opt "label=type:puzzlepod_agent_t"` to
NATIVE_ARGS; update the `seinfo` conditional accordingly so the logic and
behavior remain unchanged but the redirection is clean.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/rpm-repo.yml:
- Around line 155-170: Update the repository generation to document the current
disabled signature checks: add a clear comment above the two heredocs that
create pages/puzzlepod.repo and pages/puzzlepod-el.repo stating that gpgcheck is
intentionally set to 0 for now and that GPG signing will be enabled in a future
release (and/or include a TODO with the expected gpgkey location), and also add
a short note to the repo index page (index.html) documenting this limitation so
users are aware; reference the files/pages created by the heredocs
(pages/puzzlepod.repo and pages/puzzlepod-el.repo) and the gpgcheck setting to
locate where to insert the comments and index note.

In `@selinux/puzzlepod.te`:
- Around line 98-101: The entrypoint permission is incorrectly granted to the
source domain; change the SELinux rule so the entrypoint permission is granted
to the target domain by replacing the current allow that uses puzzlepod_t with
one that uses puzzlepod_agent_t so it reads as an allow for puzzlepod_agent_t
against puzzlepod_exec_t:file entrypoint; keep the type_transition and the
read/getattr/execute allow for puzzlepod_t as-is.
- Around line 14-16: The type_transition rule referencing puzzlepod_exec_t
(type_transition puzzlepod_t puzzlepod_exec_t:process puzzlepod_agent_t) is dead
because puzzlepod_exec_t has no file context in selinux/puzzlepod.fc; either add
a file context entry that assigns puzzlepod_exec_t to the agent binary (e.g.,
the agent path used at runtime) so the automatic domain transition can occur, or
remove the type_transition rule (or document that Podman must label the process
with --security-opt label=type:puzzlepod_agent_t) — update selinux/puzzlepod.fc
to include the appropriate gen_context mapping for puzzlepod_exec_t or drop the
transition rule in the policy where puzzlepod_exec_t and puzzlepod_agent_t are
declared.

---

Nitpick comments:
In @.github/workflows/rpm-repo.yml:
- Around line 82-99: The loop over srpms/*.src.rpm can iterate the literal glob
when there are no matches; enable a nullglob guard before the loop or explicitly
check for matches: set shell to ignore unmatched globs (e.g., run shopt -s
nullglob) or test for files (e.g., compgen -G "srpms/*.src.rpm" >/dev/null)
before the for-loop that assigns to srpm and uses FAILED; ensure to restore the
shell option if you change it and keep the rest of the loop logic (the for srpm
in srpms/*.src.rpm; do ... FAILED=...; done and the subsequent if [ -n "$FAILED"
]; then ... fi) unchanged.
- Around line 172-174: The fallback sets TARBALL_NAME to a hardcoded
"puzzlepod-source.tar.gz" even when TARBALL is empty, which can create a broken
link; update the workflow to validate TARBALL after the find call (check that
the variable is non-empty and that the file exists) and then only derive
TARBALL_NAME from basename("$TARBALL") when valid, otherwise handle the missing
artifact defensively (for example: set TARBALL_NAME to empty and skip index link
generation, or fail the job with a clear error message). Ensure you modify the
logic referring to the TARBALL and TARBALL_NAME variables so downstream steps
that build the index either skip the link or fail fast with an informative
message.

In `@Makefile`:
- Around line 311-318: The SRPM loop iterates even when the glob yields no files
(causing mock to receive the literal pattern); replace the direct shell glob in
the for-loop with a Makefile-side check using the wildcard function: compute
SRPMS := $(wildcard packaging/srpms/*.src.rpm) and then iterate for srpm in
$(SRPMS) or early-exit/echo when SRPMS is empty. Update the loop that uses the
srpm variable and preserves the FAILED and MOCK_ROOT usage so mock only runs
when real .src.rpm files exist.

In `@podman/puzzle-podman`:
- Around line 584-587: The seinfo check currently uses a redundant redirection
`&>/dev/null 2>&1`; simplify the command by removing the duplicate redirection
so it only redirects both stdout and stderr once (e.g., use `&>/dev/null` or
`>/dev/null 2>&1`) in the `seinfo -t puzzlepod_agent_t` test that controls
appending `--security-opt "label=type:puzzlepod_agent_t"` to NATIVE_ARGS; update
the `seinfo` conditional accordingly so the logic and behavior remain unchanged
but the redirection is clean.
🪄 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

Run ID: 3cee689d-6266-4877-a718-031a06910be8

📥 Commits

Reviewing files that changed from the base of the PR and between 519b01f and 23e4afd.

📒 Files selected for processing (8)
  • .github/workflows/ci.yml
  • .github/workflows/rpm-repo.yml
  • Makefile
  • docs/technical-design.md
  • packaging/build-srpm.sh
  • podman/puzzle-podman
  • podman/quadlet/puzzlepod-agent.container
  • selinux/puzzlepod.te
✅ Files skipped from review due to trivial changes (1)
  • docs/technical-design.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • packaging/build-srpm.sh
  • .github/workflows/ci.yml

Comment on lines +155 to +170
cat > pages/puzzlepod.repo << 'EOF'
[puzzlepod]
name=PuzzlePod - Governance for AI Agent Containers
baseurl=https://lobstertrap.github.io/puzzlepod/repo/fedora/$releasever/x86_64/
enabled=1
gpgcheck=0
EOF

# EL .repo
cat > pages/puzzlepod-el.repo << 'EOF'
[puzzlepod]
name=PuzzlePod - Governance for AI Agent Containers
baseurl=https://lobstertrap.github.io/puzzlepod/repo/epel/$releasever/x86_64/
enabled=1
gpgcheck=0
EOF

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Document or plan for GPG signing.

Both .repo files set gpgcheck=0, which means RPM signatures won't be verified during installation. While acceptable for early-stage projects, this reduces security guarantees for users installing from this repository. Consider adding a comment noting the intent to enable GPG signing in the future, or documenting this limitation in the index page.

📝 Suggested documentation addition to index.html
           <h2>Repository Files</h2>
           <ul>
             <li><a href="puzzlepod.repo">puzzlepod.repo</a> (Fedora)</li>
             <li><a href="puzzlepod-el.repo">puzzlepod-el.repo</a> (RHEL/EL)</li>
           </ul>
+
+          <p><strong>Note:</strong> Packages are not GPG-signed. GPG verification is disabled in the repository configuration.</p>
           </body>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/rpm-repo.yml around lines 155 - 170, Update the repository
generation to document the current disabled signature checks: add a clear
comment above the two heredocs that create pages/puzzlepod.repo and
pages/puzzlepod-el.repo stating that gpgcheck is intentionally set to 0 for now
and that GPG signing will be enabled in a future release (and/or include a TODO
with the expected gpgkey location), and also add a short note to the repo index
page (index.html) documenting this limitation so users are aware; reference the
files/pages created by the heredocs (pages/puzzlepod.repo and
pages/puzzlepod-el.repo) and the gpgcheck setting to locate where to insert the
comments and index note.

Comment thread selinux/puzzlepod.te
Comment on lines +14 to +16
type puzzlepod_agent_t;
type puzzlepod_exec_t;
application_domain(puzzlepod_t, puzzlepod_exec_t)
application_domain(puzzlepod_agent_t, puzzlepod_exec_t)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify if puzzlepod_exec_t has any file context assignment
echo "=== Searching for puzzlepod_exec_t in .fc files ==="
rg -n "puzzlepod_exec_t" --type-add 'fc:*.fc' --type=fc

echo ""
echo "=== All file context entries in puzzlepod.fc ==="
fd -t f "puzzlepod.fc" --exec cat {}

Repository: LobsterTrap/puzzlepod

Length of output: 1625


🏁 Script executed:

#!/bin/bash

# Verify 1: Check for all .fc files in repository
echo "=== All .fc files in repository ==="
fd -t f "\.fc$"

echo ""
echo "=== Total .fc files found ==="
fd -t f "\.fc$" | wc -l

echo ""
echo "=== Verify: Extract type_transition rule from puzzlepod.te around line 99 ==="
if [ -f selinux/puzzlepod.te ]; then
  sed -n '95,105p' selinux/puzzlepod.te
else
  echo "puzzlepod.te not found"
fi

echo ""
echo "=== Search for puzzlepod_exec_t usage in .te files ==="
rg -n "puzzlepod_exec_t" --type-add 'te:*.te' --type=te --context=2

Repository: LobsterTrap/puzzlepod

Length of output: 1732


puzzlepod_exec_t has no file context assignment — type transition will never trigger.

The type_transition puzzlepod_t puzzlepod_exec_t:process puzzlepod_agent_t rule on line 99 requires that an agent binary be labeled puzzlepod_exec_t at runtime. However, examining selinux/puzzlepod.fc, there is no file context entry assigning puzzlepod_exec_t to any path — only puzzled_exec_t (for /usr/bin/puzzled) and puzzlectl_exec_t (for /usr/bin/puzzlectl) are defined.

Without a corresponding .fc entry like:

/usr/libexec/puzzle-agent    --    gen_context(system_u:object_r:puzzlepod_exec_t,s0)

The type transition rule is dead code. Agents will either:

  1. Run in the caller's domain (if exec'd directly), or
  2. Only receive puzzlepod_agent_t via explicit Podman --security-opt label=type:puzzlepod_agent_t

If the intent is Podman-only labeling (no automatic domain transition), document this or remove the dead type_transition rule. Otherwise, add a file context entry for the agent executable.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@selinux/puzzlepod.te` around lines 14 - 16, The type_transition rule
referencing puzzlepod_exec_t (type_transition puzzlepod_t
puzzlepod_exec_t:process puzzlepod_agent_t) is dead because puzzlepod_exec_t has
no file context in selinux/puzzlepod.fc; either add a file context entry that
assigns puzzlepod_exec_t to the agent binary (e.g., the agent path used at
runtime) so the automatic domain transition can occur, or remove the
type_transition rule (or document that Podman must label the process with
--security-opt label=type:puzzlepod_agent_t) — update selinux/puzzlepod.fc to
include the appropriate gen_context mapping for puzzlepod_exec_t or drop the
transition rule in the policy where puzzlepod_exec_t and puzzlepod_agent_t are
declared.

Comment thread selinux/puzzlepod.te
Comment on lines +98 to 101
# Domain transition: puzzlepod_t -> puzzlepod_agent_t when spawning agent processes
type_transition puzzlepod_t puzzlepod_exec_t:process puzzlepod_agent_t;
allow puzzlepod_t puzzlepod_exec_t:file { read getattr execute };
allow puzzlepod_t puzzlepod_exec_t:file entrypoint;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

entrypoint permission is on wrong domain.

Line 101 grants entrypoint to puzzlepod_t, but this permission should be on the target domain (puzzlepod_agent_t) that is being transitioned into. The entrypoint permission controls which executables a domain can use as entry points when transitioning into that domain.

Proposed fix
 # Domain transition: puzzlepod_t -> puzzlepod_agent_t when spawning agent processes
 type_transition puzzlepod_t puzzlepod_exec_t:process puzzlepod_agent_t;
 allow puzzlepod_t puzzlepod_exec_t:file { read getattr execute };
-allow puzzlepod_t puzzlepod_exec_t:file entrypoint;
+allow puzzlepod_agent_t puzzlepod_exec_t:file entrypoint;
📝 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.

Suggested change
# Domain transition: puzzlepod_t -> puzzlepod_agent_t when spawning agent processes
type_transition puzzlepod_t puzzlepod_exec_t:process puzzlepod_agent_t;
allow puzzlepod_t puzzlepod_exec_t:file { read getattr execute };
allow puzzlepod_t puzzlepod_exec_t:file entrypoint;
# Domain transition: puzzlepod_t -> puzzlepod_agent_t when spawning agent processes
type_transition puzzlepod_t puzzlepod_exec_t:process puzzlepod_agent_t;
allow puzzlepod_t puzzlepod_exec_t:file { read getattr execute };
allow puzzlepod_agent_t puzzlepod_exec_t:file entrypoint;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@selinux/puzzlepod.te` around lines 98 - 101, The entrypoint permission is
incorrectly granted to the source domain; change the SELinux rule so the
entrypoint permission is granted to the target domain by replacing the current
allow that uses puzzlepod_t with one that uses puzzlepod_agent_t so it reads as
an allow for puzzlepod_agent_t against puzzlepod_exec_t:file entrypoint; keep
the type_transition and the read/getattr/execute allow for puzzlepod_t as-is.

@maxamillion maxamillion merged commit 2188953 into LobsterTrap:main Mar 27, 2026
12 checks passed
maxamillion added a commit that referenced this pull request Mar 30, 2026
…repo (#5)

* Add make rpm target and fix SRPM/RPM build pipeline

Add rpm and srpm-all Makefile targets for local RPM builds via mock.
Fix build-srpm.sh: correct puzzlepod-selinux spec filename, inject
%global macros via sed (survives SRPM re-extraction), use tar instead
of git archive for working-tree tarballs, preserve source tarball for
CI artifact upload. Add git-core BuildRequires and git init in %prep
for regorus build.rs compatibility in puzzlectl.spec and puzzled.spec.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Adam Miller <admiller@redhat.com>

* Introduce puzzlepod_agent_t SELinux type for agent sandbox

Split the single puzzlepod_t type into puzzlepod_t (daemon) and
puzzlepod_agent_t (sandboxed agents). Resolves 10 allow/neverallow
contradictions, fixes duplicate type declaration, replaces invalid
corenet_tcp_connect_dbus_port interface, uses proper SELinux interfaces
for cgroup and quota access, and adds require block for base policy
types. Update all documentation and diagrams to reflect the new type.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Adam Miller <admiller@redhat.com>

* Add CI RPM build validation and GitHub Pages RPM repository

Add rpm-build matrix job to CI workflow validating builds against
Fedora 42, Fedora 43, and CentOS Stream+EPEL 10 via mock. Add
rpm-repo.yml workflow that builds RPMs on push to main and publishes
a dnf repository to GitHub Pages with per-distro repos and source
tarball. Upgrade CI container to Fedora 43 with mock and createrepo_c.
Add reference .repo files for Fedora and EL.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Adam Miller <admiller@redhat.com>

* Restore Fedora CI container for all jobs

Switch ci and integration jobs back to using the pre-built Fedora CI
container image instead of inline ubuntu apt-get installs. Use
vars.CI_IMAGE with fedora42 fallback for all jobs so the image tag
can be updated via repository variables without code changes.

Signed-off-by: Adam Miller <admiller@redhat.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Fix machine-id test for container environments

Skip test_machine_id_fallback_deterministic when /etc/machine-id is
too short (< 32 chars), as commonly occurs in containers. The test
already skipped when the file was missing but not when it had
truncated content.

Signed-off-by: Adam Miller <admiller@redhat.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Update deps and ignore lru advisory (transitive via ratatui)

Update unicode-segmentation to unyanked version. Add RUSTSEC-2026-0002
(lru unsoundness) to deny.toml ignore list — transitive dep of ratatui
v0.29, fix requires ratatui >= 0.30 breaking update. No practical
impact as lru is used internally for layout caching.

Signed-off-by: Adam Miller <admiller@redhat.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Address CodeRabbit review findings

Fix Podman runtime configs to use puzzlepod_agent_t SELinux label
(puzzle-podman, quadlet container). Revert daemon hardening description
to puzzlepod_t. Add corecmd_exec_bin for agent binary execution.
Add error handling on tarball copy, nullglob guard for SRPM globs,
find-based tarball lookup, RPM existence validation, and
--isolation=simple to Makefile mock invocation for CI consistency.

Signed-off-by: Adam Miller <admiller@redhat.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Signed-off-by: Adam Miller <admiller@redhat.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Adam Miller <admiller@redhat.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant