Keep live registry lookups out of the default make test flow.
Add a dedicated external suite, workflow, and docs so the check stays opt-in but still gates code CI when enabled.
Add tests/lint/repository/test_markdown_links.py — a hard-fail lint
test that scans all git-tracked markdown files for broken relative and
repo-root-absolute links. Skips external URLs, anchor-only links, fenced
code blocks, and placeholder targets.
Apply documentation.md rules to all staged files: add emojis after
headlines in docs files, remove emojis from role README headings,
standardize Credits sections to the canonical format, remove empty
sections and orphaned sentences referring to missing documentation files,
fix raw URLs and incorrect link text across role READMEs and docs.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The default branch of infinito-nexus-core is main, not master.
Using master caused gh pr create to fail with 'Base ref must be a branch'.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Move flow/security/ghcr.md to tools/ghcr/authentication.md
- Move flow/security/mirror-cleanup.md to tools/ghcr/cleanup.md
- Move flow/security/branch.md to tools/github/branch.md
- Move flow/security/repository.md to tools/github/repository.md
- Move code/frameworks/ansible.md to tools/ansible.md
- Merge code/frameworks/Makefile.md into tools/make.md and extract file rules to artefact/files/makefile.md
- Rename tools/makefile.md to tools/make.md
- Add .github/workflows/images-mirror-cleanup.yml for manual GHCR cleanup
- Apply documentation.md standards: emojis on headlines, no em dashes, filename link text
- Fix all cross-references broken by directory restructuring
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Rename artefact/image.md to artefact/image/origin.md and merge code/role/image.md into it
- Move artefact/mirror.md to artefact/image/mirror.md
- Move docs/contributing/code/role/ to docs/contributing/artefact/files/role/
- Rename readme_base.md to readme_md.md
- Apply documentation.md standards (emojis, RFC 2119, link text) to all modified files
- Fix all cross-references broken by the directory restructuring
- Remove publish section from mirror.md (module deleted in prior commit)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaces GHCR_PAT-based authentication with GITHUB_TOKEN across all
mirror and build workflows. Packages pushed from a public repository
with GITHUB_TOKEN are automatically linked to the repository and
inherit its public visibility — no publish step required.
Removes cli.mirror.publish (used a non-existent GitHub REST API
endpoint for changing package visibility), the associated unit tests,
and the GHCR_PAT debug helper. Cleans up all GHCR_PAT/GHCR_USERNAME
references and rewrites the GHCR authentication documentation.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The publish step was filtering packages by prefix 'mirror/' but images
are pushed to ghcr.io/{ns}/{repo}/mirror/... so the package names in
the GitHub Packages API are '{repo}/mirror/...'. The new packages were
never found and thus remained private.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add scripts/install/skills/install.sh to restore skills from
skills-lock.json via npx skills experimental_install
- Add scripts/install/skills/update.sh to update all skills by
re-running skills add for each source in skills-lock.json
- Add make install-skills and make update-skills targets
- Add .github/workflows/update-skills.yml for daily automated updates
matching Dependabot schedule (00:00 UTC), opens PR on lock changes
- Add docs/agents/meta/caveman.md as SPOT for caveman mode, startup
notification, and token-budget tier progression
- Update AGENTS.md with RFC 2119-compliant skills installation check
- Update docs/agents/action/commit.md: replace ALWAYS with MUST
- Update pyproject.toml: respect-gitignore = true, exclude .agents
- Track skills-lock.json and add .agents to .gitignore
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Usernames are not sensitive — storing them as secrets only adds friction
without security benefit. Replace secrets.GHCR_USERNAME with vars.GHCR_USERNAME
across all workflows and remove GHCR_USERNAME from secrets: input blocks in
reusable workflows. Update ghcr.md to document it as a variable.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
publish only needs namespace + prefix to list and update GHCR packages
via the API. The repository argument was erroneously copied from the sync
step and caused an argparse error.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
All ecosystems now scan all subdirectories automatically instead of
hardcoded paths, so new dependency files are picked up without
manual configuration.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Image names now follow {owner}/{repository}/mirror/{registry}/{name}
instead of {owner}/mirror/{registry}/{name}.
- GHCRProvider: add `repository` param + `add_args()`/`from_args()` classmethods
as SPOT for CLI argument registration and provider construction
- sync, resolver: use GHCRProvider.add_args() / from_args() (no duplication)
- Workflows: resolve repository name via scripts/meta/resolve/repository/name.sh
and pass --ghcr-repository to sync and publish
- mirrors.sh: require and forward GHCR_REPOSITORY env var
- deploy/development/mirrors.py: derive repository from GITHUB_REPOSITORY
- Tests: update expected paths, argv and env fixtures
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Move iter_role_images + all helpers + ImageRef from cli/mirror/util.py and
cli/mirror/model.py into utils/docker/image_discovery.py; add source_file field
to ImageRef to distinguish config/main.yml vs vars/main.yml entries
- Delete cli/mirror/util.py; update all callers to import from utils.docker.image_discovery
- Move utils into subpackages: utils/docker/ (image_ref, paths_utils, hadolint) and
utils/roles/ (dependency_resolver, resource_validation); update all imports
- Reorganise tests into subpackages: tests/lint/docker/dockerfile/, tests/integration/docker/,
tests/unit/utils/docker/, tests/unit/utils/roles/; fix parents[N] offsets after relocation
- tests/lint/docker/test_image_versions.py now uses iter_role_images (same SPOT as mirror)
- Add vars/main.yml images.<name>.{image,version} support for non-application roles
(test-e2e-playwright, sys-ctl-hlth-csp); eliminate hardcoded duplicates in defaults/tasks
- Add web-app-matrix matrix-chatgpt-bot and web-app-mini-qr mini-qr entries in config/main.yml;
replace hardcoded image strings in vars/templates with lookup('config', ...) references
- Fix sync/__main__.py log line to use correct registry prefix for non-Docker-Hub images
- Update docs/contributing/code/role/dockerfile.md with image declaration rules and SPOT reference
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The full test suite (two complete runs of 01–10_teardown) consistently
takes ~212 minutes; the previous 180-minute limit caused premature
cancellation at 08_deploy_performance.sh in the second run.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Opts out of the April 2026 default change that skips file coverage
computation on PRs by setting CODEQL_ACTION_FILE_COVERAGE_ON_PRS=true.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Move _set_public/ensure_public out of GHCRProvider into a new
cli.mirror.publish module that lists all non-public mirror packages
via the GitHub API and sets them public in bulk. The workflow runs
this as a separate step after mirroring. Mirror sync itself no longer
touches visibility.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
CodeQL results only appear on the Security tab when the workflow is
triggered by a push event directly. Adds push trigger on main alongside
the existing workflow_call (double run on main push is harmless).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add debug step to prepare-fork-merge-ref job which runs exclusively
via pull_request_target to verify secrets are passed in that context.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Move inline shell from entry-pull-request-change.yml into
scripts/meta/debug/auth_mode.sh and pass secrets via env vars.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Move utils/gha/annotations.py → utils/annotations/message.py
- Move scripts/gha/summarize_annotations.py → utils/annotations/summarize.py
- Keep utils/gha/annotations.py as compatibility shim
- Update all imports across codebase to utils.annotations.message
- Wire tee + summary step into test-code-lint, unit, and integration workflows
- Add unit tests for utils/annotations/summarize (20 tests)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add utils/gha/annotations.py with warning/error/notice helpers and *_each
variants that emit one annotation per list item
- Use warning() in GHCRProvider._set_public for missing GHCR_PAT case
- Expose GHCR_PAT_SET env var in mirror step to distinguish missing-PAT from
real API failures
- Add unit tests for all annotation functions
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Root cause: GITHUB_TOKEN in Actions is repo-scoped and cannot change package
visibility in user/org namespaces — all 58 mirror operations failed with 404.
- Use GHCR_PAT (which has write:packages scope) as GITHUB_TOKEN in the mirror
step, falling back to GITHUB_TOKEN if GHCR_PAT is not set
- Remove ensure_public() call from the already-exists skip path (wrong place:
existing images were already made public when first mirrored)
- Update test to assert ensure_public is not called for skipped images
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove redundant `images-mirror-missing` job from entry-pull-request-change.yml
(mirroring already runs via ci-orchestrator for same-repo PRs)
- Set GHCR package visibility to public after each successful mirror via GitHub API
- Add `ensure_public` hook to base class (no-op for other providers)
- Also call `ensure_public` for already-existing images to fix any that are still private
- Pass GITHUB_TOKEN explicitly to the mirror step
- Add unit tests for _set_public (user/org endpoint fallback) and sync skip-path
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add ready_for_review trigger so CI starts when a draft PR is marked ready
- Guard detect-pr-scope with draft == false to skip all jobs for draft PRs
- Add converted_to_draft to cancel-pull-request-runs.yml to cancel active
runs when a PR is converted back to draft
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Required so cancel-on-failure jobs in reusable workflows can call
the GitHub API to cancel the run. Permissions propagate down the
workflow_call chain and must be write at every level.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add cancel-on-failure job to test-environment, test-install-make, and
test-install-pkgmgr. After all matrix jobs complete, the job cancels
the entire orchestrator run via the GitHub API if any matrix job failed.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Enables fast failure on test-environment, test-install-make, and
test-install-pkgmgr matrix strategies so the overall CI run fails
immediately when a job fails rather than waiting for all jobs to
complete. Trade-off: no cross-distro comparison on failure.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Aligns the script name with the workflow and its purpose.
Updates all references in test-environment.yml and setup.md.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Aligns the workflow filename with its job name and purpose.
Updates all references in ci-orchestrator.yml and act/workflow.sh.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
test-dev-environment-dashboard was triggering test-development.yml a
second time, causing duplicate Environment jobs in the CI run.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>