fix(ci): repair advisory locks and platform regressions - #3021
Merged
Merged
Conversation
Regenerate advisory workflow metadata without changing runtime pins. Preserve root-local discovery scope during scratch drift replay and make the Windows alias fixture assert the on-disk directory name. Add source-freshness and replay regression coverage. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Daniel Meppiel (danielmeppiel)
requested a review
from Sergio Sisternes (sergio-sisternes-epam)
as a code owner
September 18, 2026 09:00
Copilot started reviewing on behalf of
Daniel Meppiel (danielmeppiel)
September 18, 2026 09:00
View session
Contributor
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
The new Windows/hash regression tests have cross-platform robustness gaps (CRLF hashing stability, unguarded symlink creation, and MagicMock attribute defaults) that could cause false CI failures.
Get a fresh assessment by requesting another Copilot review.
Review effort: Lite
Findings: 3
Open (3)
What changed in this PR
Repairs CI regressions by refreshing gh-aw advisory workflow lock metadata, hardening repository tests that detect stale lock/source drift, and fixing platform-specific discovery/scoping behavior (Windows dotted-alias directories; drift replay root-local discovery).
Changes:
- Regenerated advisory workflow lock metadata and added a unit guard that compares lock hashes against workflow source/import contents.
- Adjusted Windows alias fixture expectations to use the on-disk directory name and selected it into the
windows_compatgate. - Updated
BaseIntegratorroot-local detection to preserve source scoping during drift replay into scratch, plus corresponding tests and docs clarifications.
| File | Description |
|---|---|
.github/workflows/triage-panel.lock.yml |
Refreshed gh-aw metadata hashes for triage advisory lock. |
.github/workflows/pr-review-panel.lock.yml |
Refreshed gh-aw metadata hashes and compiler header for PR review advisory lock. |
tests/unit/test_triage_panel_lock.py |
Added regression test to ensure advisory lock metadata matches workflow source/import hashes. |
tests/unit/test_deps_utils.py |
Fixed Windows trailing-dot alias expectation by asserting the actual on-disk directory name; marked windows_compat. |
src/apm_cli/integration/base_integrator.py |
Treated root_local_project_root as identity root during scratch replay to avoid over-scanning. |
tests/unit/integration/test_base_integrator.py |
Extended scoping tests to cover install vs scratch-replay contexts. |
docs/src/content/docs/contributing/development-guide.md |
Documented lock regeneration guidance and the new freshness check. |
docs/src/content/docs/enterprise/drift-detection.md |
Clarified that scratch affects deployment destination, not root-local source discovery scope. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Recompile PR review with gh-aw v0.87.8 and verify the generated banner against the repository pin. Set explicit package deployment defaults and assert resolver initialization, isolate symlink-only prerequisites, and prove workflow hashes normalize LF, CRLF, and CR input. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Daniel Meppiel (danielmeppiel)
deleted the
danielmeppiel-pr-analysis
branch
September 18, 2026 10:59
Daniel Meppiel (danielmeppiel)
added a commit
that referenced
this pull request
Sep 18, 2026
…ass (#2893) * Initial plan * build(deps): bump setuptools to 83.0.0 in uv lockfile Co-authored-by: sergio-sisternes-epam <207026618+sergio-sisternes-epam@users.noreply.github.com> * Fix skills subset installs for manifestless Git collections (#2891) * Initial plan * Fix manifestless skill collection subset resolution Co-authored-by: danielmeppiel <51440732+danielmeppiel@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: danielmeppiel <51440732+danielmeppiel@users.noreply.github.com> * test: restore complete architecture guard mutation coverage (#2892) * Initial plan * test: cover missing architecture owner guard mutations Co-authored-by: danielmeppiel <51440732+danielmeppiel@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: danielmeppiel <51440732+danielmeppiel@users.noreply.github.com> * fix(registry): exact version selectors must match published build metadata (#2894) * fix(registry): exact version selectors must match published build metadata A version selector with no range operator (e.g. 1.0.2+fa163e16) was routed through semver range matching, which ignores build metadata in every comparison. Two published builds sharing the same major.minor.patch (e.g. 1.0.2+fa163e16 and 1.0.2+863e11af) tied under that comparison, so the resolver could silently return a different build than the one requested. Check for an exact string match against the published version list before falling into range matching. Real ranges (^, ~, >=, wildcards) are unaffected, since none of them can ever equal a published version string literally. Fixes #2877 * test(registry): give each build-metadata test its own matching tarball Addresses review feedback: the fixture previously reused one tarball (declared apm.yml version 1.0.2, no build metadata) for both published VersionEntry builds. Build a distinct tarball per build whose apm.yml version matches its VersionEntry, and return the right bytes for the requested version, so the test stays accurate if package validation later cross-checks the extracted version against the resolved one. * fix(install): fail loudly when a package deploys to no target (closes #2796) (#2806) * fix(install): fail target-excluded plugin no-ops Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: preserve agent plugin recovery refs Addresses panel follow-ups to keep Agent Plugin target-exclusion recovery commands pinned to the selected ref, document the breaking no-op contract, and add real CLI lifecycle coverage for total no-op failure plus mixed-install success. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * test: update plugin target no-op lifecycle Addresses the CI regression from the legacy exit-0 expectation by rewriting the Agent Plugin non-Copilot target test for issue #2796: a total target-exclusion no-op now fails and commits no durable state. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: ground plugin recovery hints in declared skills Fold #2806 advisory follow-ups: select an inventoried skill directory, quote POSIX command operands, assert mixed-install skill bytes, and document dry-run behavior. Drop release-note duplicates resurrected while incorporating main. Mutation probes reject missing outcome, inventory and quoting guards. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: danielmeppiel <danielmeppiel@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * docs: Add WinGet method installation (#2520) * docs: Add WinGet method installation * docs: clarify WinGet installation and upgrades Address review follow-ups with exact registry selection, prerequisites, separate Windows examples, and matching upgrade guidance. Keep Scoop and the contributor's additive distribution intent. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: danielmeppiel <danielmeppiel@users.noreply.github.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * chore(deps): bump svgo from 4.0.2 to 4.1.0 in /docs (#2914) Bumps [svgo](https://github.com/svg/svgo) from 4.0.2 to 4.1.0. - [Release notes](https://github.com/svg/svgo/releases) - [Commits](svg/svgo@v4.0.2...v4.1.0) --- updated-dependencies: - dependency-name: svgo dependency-version: 4.1.0 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix(deps): preserve GitLab sparse-fetch transport (#2939) * fix(deps): preserve GitLab sparse-fetch transport Execute the shared transport plan using prepared remotes and per-attempt authentication. Gate REST on executed effective HTTPS, isolate live checkout identities, and add real-Git, architecture and mutation regression proof. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * test(spec): bind GitLab sparse fetch to port and cache requirements Reuse the real-Git transport contract as executable evidence for req-sc-013 and req-rs-016, rather than waiving the Mode B conformance gate. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * docs(spec): regenerate GitLab sparse conformance evidence Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * test(deps): align legacy REST fixtures with selected Git attempts Configure a real strict HTTPS transport plan and a typed Git failure in REST tests, and include the new sparse-plan rule in the frozen architecture inventory. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(deps): fold bounded sparse transport review feedback Address CEO docs and diagnostics follow-ups on PR #2939: distinguish requested SSH from effective Git rewrites, correct packaged REST guidance, repair fallback recovery advice, and expose admitted protocol switches. Add a warning regression and isolated mutation proof without changing validation auth or other provider policy. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * test(deps): fold GitLab sparse Copilot regression fixes Fix both legacy integration REST fixtures to execute a real HTTPS selector plan and raise only typed Git failures. Probe symlink capability rather than skipping Windows unconditionally, and qualify the canonical sparse-fetch credential documentation. Addresses Copilot review 5167472317 without changing validation auth or shared selector dedup semantics. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * test(deps): align clone fallback warning regression CI recovery 1: the shared custom-port warning now correctly explains disabling all fallback configuration sources and points at the live docs route. Update its older clone consumer assertion to this reviewed wording without changing runtime behavior. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: danielmeppiel <danielmeppiel@users.noreply.github.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * feat(init): onboard existing local packages without rewriting source (#2937) * feat(init): onboard existing local packages without conversion Build on the read-only discovery work from #2857 while keeping apply metadata-only. Prove discover, declare, install, rerun, and collision protection through the existing APMLifecycle runner. Co-authored-by: Ron Izraeli <35386615+chkp-roniz@users.noreply.github.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * test(onboarding): bind native collision safety to local priority Cover the existing req-pr-002 local-priority contract with the native-skill collision regression and assert its recorded diagnostic. No normative requirements or specification prose change. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(onboarding): reject existing collisions and report successful targets Reject conflicting pre-existing dependency slots before applying any manifest delta. Report native skill metadata from the first successful target, preserving skipped author-owned destinations. Refresh owned-collision fixtures and the architecture rule inventory. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(onboarding): preserve global handoff and discovery boundaries Addresses scoped panel follow-ups: preserve user scope in the separate install hint, document declined consent, and defend the existing init discovery facade and target-selection boundary without expanding admission or installation behavior. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: danielmeppiel <danielmeppiel@users.noreply.github.com> Co-authored-by: Ron Izraeli <35386615+chkp-roniz@users.noreply.github.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * chore(deps): bump astro from 7.2.7 to 7.3.2 in /docs (#2922) Bumps [astro](https://github.com/withastro/astro/tree/HEAD/packages/astro) from 7.2.7 to 7.3.2. - [Release notes](https://github.com/withastro/astro/releases) - [Changelog](https://github.com/withastro/astro/blob/main/packages/astro/CHANGELOG.md) - [Commits](https://github.com/withastro/astro/commits/astro@7.3.2/packages/astro) --- updated-dependencies: - dependency-name: astro dependency-version: 7.3.2 dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump smol-toml from 1.6.1 to 1.8.0 in /docs (#2942) Bumps [smol-toml](https://github.com/squirrelchat/smol-toml) from 1.6.1 to 1.8.0. - [Release notes](https://github.com/squirrelchat/smol-toml/releases) - [Commits](squirrelchat/smol-toml@v1.6.1...v1.8.0) --- updated-dependencies: - dependency-name: smol-toml dependency-version: 1.8.0 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * docs: establish issue-first contribution and governance policy (#2954) * docs: establish issue-first contribution and governance policy Implement the approved Phase 1 scope in #2953. Separate human scope approval from automated recommendations, document the maintainer roster and progression, and preserve technical reference material in the development guide. Live automation and backlog migration remain later phases. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * docs: fix rendered OpenAPM specification link Use Astro's openapm-v01 route rather than the source filename spelling. Fix the broken link reported by the Deploy Docs workflow for #2954. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: danielmeppiel <danielmeppiel@users.noreply.github.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(triage): make automated recommendations advisory (#2956) * docs: establish issue-first contribution and governance policy Implement the approved Phase 1 scope in #2953. Separate human scope approval from automated recommendations, document the maintainer roster and progression, and preserve technical reference material in the development guide. Live automation and backlog migration remain later phases. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * docs: fix rendered OpenAPM specification link Use Astro's openapm-v01 route rather than the source filename spelling. Fix the broken link reported by the Deploy Docs workflow for #2954. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(triage): make automated recommendations advisory Constrain workflow outputs to classification and processing metadata, retain legacy deduplication, and preserve human scope approval in direct consumers. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: danielmeppiel <danielmeppiel@users.noreply.github.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * docs: define issue-backed roadmap and release planning (#2959) * docs: establish issue-first contribution and governance policy Implement the approved Phase 1 scope in #2953. Separate human scope approval from automated recommendations, document the maintainer roster and progression, and preserve technical reference material in the development guide. Live automation and backlog migration remain later phases. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * docs: fix rendered OpenAPM specification link Use Astro's openapm-v01 route rather than the source filename spelling. Fix the broken link reported by the Deploy Docs workflow for #2954. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(triage): make automated recommendations advisory Constrain workflow outputs to classification and processing metadata, retain legacy deduplication, and preserve human scope approval in direct consumers. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * docs: define issue-backed roadmap and release planning Closes #2958. Document the approved planning model; live Project rollout remains separately gated. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: danielmeppiel <danielmeppiel@users.noreply.github.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(governance): require human scope and add neutral eligibility evidence (#2964) * fix(governance): require human scope and add neutral eligibility evidence Refs #2960. Keep implementation authority human, make daily docs discovery-only, and deploy compatible triage consumers with regression coverage. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(governance): make workflow trust and manual scope boundaries explicit Use a verified literal default-branch checkout and bind policy to its actual commit. Remove remaining docs workflow label-ratification instructions; keep companion work outside unattended runs. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix: harden governance event and child-wave boundaries Address the six bounded review contracts: default-branch entrypoints, fresh child-wave confirmation, trusted gh resolution, complete approval records, visible references, and bounded metadata reads. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: danielmeppiel <danielmeppiel@users.noreply.github.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(git-env): skip the HTTP header probe for non-HTTP effective URLs (#2906) * fix(git-env): skip the HTTP header probe for non-HTTP effective URLs An `insteadOf` rule that rewrites the fetched HTTPS URL to SSH, such as `url."git@github.com:".insteadOf = https://github.com/`, made every private dependency download fail on the authenticated retry. `_validated_git_url_rewrite_policy` asked whether an HTTP `extraHeader` applied to the effective URL. With an SCP-style target that probe ran `git config --get-urlmatch http.extraHeader git@github.com:owner/repo`, which git rejects with `invalid URL scheme name or missing '://' suffix` and exit status 128, so the probe raised `GitUrlRewriteProbeError`. An HTTP header can never reach a non-HTTP transport, so the answer is already known: report no authorization and do not spawn the probe. The remaining non-zero branch now names the exit status instead of only saying the probe failed. Fixes #2898 * docs(changelog): reference the pull request number * fix(git-env): keep malformed rewrite targets on the wrapped safety error The non-HTTP guard added in the previous commit was the first urlsplit applied to the effective URL, and it is evaluated as an argument to validate_resolved_git_url_rewrite -- so before that function's try/except. An insteadOf rule whose replacement carries unbalanced brackets, such as url."https://[::1/".insteadOf, therefore surfaced a raw ValueError("Invalid IPv6 URL") instead of the module's "Unable to verify Git URL rewrite safety", and the CPython message for a bracketed non-address embeds the host unredacted. Guarding the scheme lookup cannot fail open: both callers pass the same URL straight to validate_resolved_git_url_rewrite, which re-splits it inside its try and raises the wrapped error. * fix: complete SCP rewrite consumer coverage and recovery Address panel follow-ups on PR #2906 with real Git config resolver and authenticated-retry regressions, HTTP origin controls, and probe-specific recovery guidance. Preserve unsafe-rule recovery for proven policy failures and synchronize authentication documentation. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: danielmeppiel <danielmeppiel@users.noreply.github.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * docs: publish the active issue-backed roadmap (#2988) Publish Project 2304 from the README and contribution entry points, replace pending-rollout prose, and preserve issue-owned scope and milestone-owned release planning. Refs #2960 Co-authored-by: danielmeppiel <danielmeppiel@users.noreply.github.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(uninstall): preserve unmanaged skills with an empty inventory (#2947) * fix(uninstall): preserve unmanaged skills with an empty inventory * docs(changelog): link unmanaged skill cleanup fix * test(ci): repair stale daily release smoke fixtures (#2987) Cover the two registered owner guards, exercise GitLab REST through real transport selection, and align Windows fixtures with canonical home/path and deployed-file hash contracts. Preserve production behavior and strengthen regression witnesses for #2965. Co-authored-by: danielmeppiel <danielmeppiel@users.noreply.github.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(cache): pin core.autocrlf=false on GitCache checkouts (#2982) * fix(cache): pin core.autocrlf=false on GitCache checkouts (closes #2971) Git-subpath materialization went through GitCache without the CRLF pin that bare_cache already set, so Windows hosts with system core.autocrlf=true recorded non-portable content_hash values. Add a -c pin that outranks env-frozen host config, persist it on the checkout, and rematerialize unpinned shards. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * docs(changelog): cite #2982 for GitCache autocrlf pin Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(cache): heal GitCache autocrlf pin under shard lock Defer unpinned SHA-valid eviction until _create_checkout holds the shard lock, parse the local core.autocrlf key, fail closed on land races, and document legacy lockfile regeneration. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * test(cache): isolate autocrlf host fixture and fail closed Drop inherited GIT_CONFIG_NOSYSTEM/PARAMETERS before the hostile-host regression, assert system autocrlf=true, document lock --update recovery, and reject unremovable unpinned shards. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * chore: release v0.31.0 (#2989) Bump pyproject.toml and the apm-cli uv.lock entry to 0.31.0, and curate the dated changelog for the minor release. Current CI lint mirror passes locally; dependency versions, public registry URLs, and hashes remain unchanged. Post-merge: tag v0.31.0 to trigger the release workflow. Co-authored-by: danielmeppiel <danielmeppiel@users.noreply.github.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * feat(autopilot): origin-aware skills with CODEOWNERS-safe review (#3003) * feat: add ORIGIN x INTENT autopilot for triage, delivery, and review Replay the actor-aware autopilot surface onto origin/main as one commit: unattended runs never assign; actor-session delivery assigns the working user; standalone review requests that user as reviewer. Schedulers own the queue scripts and fan-out; workers advise or implement one item. Keep CODEOWNERS additive and require full conversation context before new advice. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(autopilot): align tags and delivery with human-scope governance Keep triage/requested as the only request trigger. status/needs-triage stays human state. Delivery still queues on status/accepted, then probes scripts/governance/eligibility.cjs and requires fresh confirmation. Unattended ORIGIN never implements. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * refactor(autopilot): turn monolith orchestrators into sequencing aliases apm-issue-autopilot and batch-bug-shepherd no longer implement. They dispatch the canonical schedulers in-session, with a hard stop so triage advice is not implementation permission. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(autopilot): treat FANOUT_LIMIT as concurrency, not batch size Schedulers must persist and drain the full helper-selected list, refilling a slot when it returns. Two slots is parallelism only. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(autopilot): stop spam-skipping bug forms; workers own writes Sweep markup strip no longer lets a heading eat the rest of the body, so valid GitHub bug forms stay eligible. Issue and PR triage workers own comments and processing labels; schedulers only queue and fan out. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * feat(autopilot): add worker activation card with optional writes Issue-triage worker declares activation_card: on. Writes default on; write: off returns the template without commenting or labeling. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * feat(autopilot): move PR-review writes off the scheduler PR-review scheduler only queues and fans out. Reviewing sessions own comments, labels, and the actor-session @me reviewer request. The composed worker gets an activation card with write default on. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(autopilot): gate PR review on panel-review Unfiltered open-PR listing queued every pull request. Fresh review now requires the panel-review label or an explicit named list. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(autopilot): require status/accepted before PR review panel-review only requests a pass. Without status/accepted on the PR or a linked issue, the reviewing session comments, clears the request label, and stops. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * refactor(autopilot): rename review panel; silent unaccepted stop Rename apm-review-panel to autopilot-pr-review-panel and keep the old name as a compatibility alias. Scheduler, worker, and panel all stop when status/accepted is missing. Scheduler and worker leave no comment; panel/worker may clear panel-review. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * refactor(autopilot): review-worker is advisory; merge-worker is drive-to-merge Keep autopilot-pr-review-scheduler advisory-only. It composes autopilot-pr-review-worker and never spawn autopilot-pr-merge-worker. Summon merge-worker by name. Old panel names stay aliases. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * feat(autopilot): require Autogenesis activation cards on canonical skills Enter before work, Exit after. Do not load Autogenesis path modules. Schedulers are write off; workers default write on. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * refactor(autopilot): drop Autogenesis wording from activation cards Keep Enter/Exit cards. Do not name the source discipline. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * feat(autopilot): declare activation_card on for every autopilot skill Aliases and canonical skills both set the flag. Canonical skills still own the Enter/Exit card body. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * docs: add maintainer map for autopilot skills Internal package map only. Not product documentation. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * refactor(autopilot): nest skill packages under packages/autopilot Keep leaf package names. Move the maintainer map to packages/autopilot/README.md. Point pr-description-skill deps up one more directory. Leave .agents/skills/ deploy layout flat. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * feat(autopilot): require scheduler queue tables with labels Schedulers must emit keep-set and drop-set rows (number, kind, labels, rationale, slot) before any spawn. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(autopilot): invocation is harness, not origin Copilot App, local, Cloud, and Remote Agent fill actor-session. agentic-workflow is only gh-aw / Actions. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(autopilot): exclude completed-advice from triage sweeps Sweep fetch skips triage/recommended and status/triaged at GitHub so already-advised open issues and PRs are not re-listed. Do not write status/triaged. Named requests still fetch the one item. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(autopilot): name worker sessions Domain stage #n Issue triage #2993, PR triage #1017, Issue delivery #2902, PR review #2741. No GitHub title. Do not rename in-flight sessions. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * Keep issue-triage JSON internal, not on GitHub comments. The public advisory is prose plus the HTML receipt. Workers still fill schema_version 2 JSON for the parent Exit, not the issue thread. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * Make triage JSON receipts optional, default off. Enter/Exit cards take json: off|on. Omitted or unknown is off, not a missing-field stop. json: on stays an internal payload; GitHub comments stay prose. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * Stop the Triage Panel AW from requiring a JSON comment tail. Pass json: off into autopilot-issue-triage-worker. GitHub comments stay prose plus the HTML receipt. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * Route the PR Review Panel AW through the review scheduler. Load autopilot-pr-review-scheduler (write off) then run autopilot-pr-review-worker in-thread. Do not compose the merge worker. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * Auto-defer PRs with no accepted issue and thank the author. PR triage writes status/deferred unless a same-repo linked issue is status/accepted, and asks the author to open an issue first. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * Queue accepted PRs for advisory review without a named list. Unsteered PR review now unions panel-review with status/accepted on the PR, then still applies the accepted gate and CODEOWNERS last-comment conditions. Named list is not required when a maintainer already accepted the PR. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * Deliver accepted issues even when the author is a bot. status/accepted from a CODEOWNER is the queue gate. Author type is not a drop reason. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * Remove autopilot compatibility alias stubs. Keep the nine canonical autopilot-{domain}-{stage}-{role} packages. Drop the 22 installable aliases, retarget tests to merge-worker and delivery, and refresh the lockfile. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * docs: retarget leftover alias names to canonical autopilot skills PRINCIPLES.md, delivery/merge worker assets, and the cut-release eval note now name autopilot-{domain}-{stage}-{role} only. Historical CHANGELOG entries stay as written. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * style: ruff-format autopilot unit tests after main merge Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * chore: refresh lock deployment hashes after alias-name retarget Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(autopilot): align review sweep, auto-defer, and lock orphans Copilot App queue-open now unions panel-review with status/accepted on the PR. PR triage auto-defers only when neither the PR nor a linked issue is accepted. Drop deleted alias packages from the lockfile and retarget merge-worker eval fixtures. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(lock): rewrite deployed test-coverage-expert instruction link Install replay retargets the relative markdown link from .github/agents to .apm/instructions. The committed copy still used the source-relative path, which failed APM Self-Check drift. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(autopilot): sole-assignee claim and trusted gh lookup Actor-session delivery continues only when @me is the sole human assignee after add, and re-checks before implement or PR. Triage queue helpers resolve gh through get_gh_executable so a project-controlled binary is never used. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * perf(cli): lazy-load heavyweight command modules (#3001) * perf(cli): lazy-load heavyweight command modules Defer install, audit, pack, marketplace, uninstall, update, and prune until the matching verb is dispatched so apm --help, apm doctor, and apm config get no longer import those graphs. Closes #2996 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * docs(changelog): link lazy CLI dispatch to #3001 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(cli): freeze lazy verbs and keep completion light PyInstaller cannot follow importlib string paths, so collect apm_cli.commands into hiddenimports. Complete from stubs, match stub short_help to the real command, and advertise doctor --help. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Co-authored-by: Daniel Meppiel <51440732+danielmeppiel@users.noreply.github.com> * fix(alias): reject path-traversing dependency aliases — fixes #2900 (#2901) * fix(alias): reject path-traversing dependency aliases Aliases were only matched against a lax character regex, letting values like "..", "./x", or "foo/../bar" escape apm_modules at download and integrate time. Now validating every parsed alias through path_security's segment checks and guarding the resolved install path inside the download/integrate phases. Adds unit coverage for traversal and safe aliases. * fix(alias): surface friendly error for traversal aliases Wrap validate_path_segments in parse_alias_override so '.'/'..' aliases translate PathTraversalError into the existing allowed-character message instead of leaking a low-level technical error. Strengthen traversal tests to assert the friendly message. * test(alias): prove install-phase symlink escape is blocked A valid alias like 'safe-name' passes parse-time validation, but apm_modules_dir/safe-name can itself be a symlink pointing outside apm_modules_dir. ensure_path_within is the only guard that resolves symlinks before containment (download.py:65, integrate.py:622); this test proves the escape raises PathTraversalError and never writes outside the managed tree. * test(alias): trap ensure_path_within guards end-to-end at install tier The parser rejects traversal aliases (parse_alias_override), and the ensure_path_within containment guards exist at download.py:65 and integrate.py:622 as the defense-in-depth last line. But no test drove those guards through the real phase entry points -- the PR "Scenario 4" claim (install path can never escape apm_modules even if the parser is bypassed) was proven only at unit tier. Add install-tier regression traps that route malicious aliases through the actual phase run() functions: - tests/red_team/install/test_alias_path_escape.py * download.run() rejects a '..' traversal alias and a symlink that resolves outside apm_modules_dir via PathTraversalError, asserting no download bytes land. * integrate.run() rejects the same two vectors before materialization. * Safe-alias controls confirm no false positive. - tests/unit/test_registry_entry_alias_traversal.py * Covers the secondary parse_registry_object_entry alias validation (registry_entry.py:86): regex layer (%2e%2e) and validate_path_segments layer ('..', 'pkg/..'), plus a safe-alias affirmative control. * Refactor install path handling for dependencies Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * fix(alias): centralize safe destinations without restricting sources Address the PR #2901 panel and Copilot follow-ups: route all alias ingress and materialization through existing owners, reject root-equal destinations, preserve local sibling sources, and defend real reinstall metadata and hashes with regression and architecture tests. Include actionable diagnostics and migration guidance. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(alias): preserve normalized roots and legacy cache preflight Address round-two architecture/security and lifecycle findings. Compare both roots through path_security, give safe alias recovery guidance, and preserve existing legacy-plugin validation before alias-aware resolution can normalize cached files. Main passes the legacy missing-metadata cases; added preflight keeps that behavior. Windows prefix and legacy-preflight mutation controls fail with guards removed. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(alias): preserve remote source anchors and cache replacement Keep authenticated remote coordinates separate from flat aliases. Inject the existing read-only legacy cache admission at actual reuse after canonical fetch decisions, not preparation; retain same-ref failure and transactional replacement. Extend real resolver and CLI lifecycle contracts with aliased remote siblings and invalid-cache ref changes. Mutation controls detect both source-anchor regression and misplaced or missing admission. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(alias): preserve placement and current ref replay after install Continue the existing PR #2901 CI recovery without resetting its run. Preserve the recovered implementation and review folds: durable alias projection, contained alias scanning, specification conformance, and current-remote ref observations after successful checkout. Original contributor and follow-up commits remain in the lineage. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * test(cache): exercise stale bare fallback under corrupt receipts The mutation gate showed the previous fixture passed even when receipt handling was removed because no bare-cache directory existed. Materialize the canonical shard directory so the stale-ref fallback is reachable and the regression fails without the receipt guard. Production code is unchanged. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * test(lockfile): declare absent alias in dev dependency fixtures Continue CI recovery2 after Linux shard2 exposed four generic Mock dependency references whose undeclared alias attribute became another Mock. Model the real unaliased DependencyReference default explicitly instead of weakening production alias validation. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(spec): preserve published alias schema identities Keep existing public v0.1 schemas byte-identical and select independent v0.1.41 schemas for alias validation. Accept the new exact manifest ID through the existing contract owner while retaining old-ID compatibility and fail-closed unknowns. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(alias): clarify compatibility and recovery after main integration Fold specification editorial fixes, keep the unshipped security note under Unreleased, document schema opt-in compatibility, and defend actionable diagnostics with regression assertions. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Co-authored-by: danielmeppiel <danielmeppiel@users.noreply.github.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(ci): repair advisory locks and platform regressions (#3021) * fix(ci): repair advisory locks and platform regressions Regenerate advisory workflow metadata without changing runtime pins. Preserve root-local discovery scope during scratch drift replay and make the Windows alias fixture assert the on-disk directory name. Add source-freshness and replay regression coverage. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(ci): honor pinned workflow compiler and harden regression fixtures Recompile PR review with gh-aw v0.87.8 and verify the generated banner against the repository pin. Set explicit package deployment defaults and assert resolver initialization, isolate symlink-only prerequisites, and prove workflow hashes normalize LF, CRLF, and CR input. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: danielmeppiel <danielmeppiel@users.noreply.github.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * chore(deps): bump gitpython from 3.1.58 to 3.1.59 (#2921) Bumps [gitpython](https://github.com/gitpython-developers/GitPython) from 3.1.58 to 3.1.59. - [Release notes](https://github.com/gitpython-developers/GitPython/releases) - [Changelog](https://github.com/gitpython-developers/GitPython/blob/main/CHANGES) - [Commits](gitpython-developers/GitPython@3.1.58...3.1.59) --- updated-dependencies: - dependency-name: gitpython dependency-version: 3.1.59 dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump js-yaml from 4.3.1 to 4.3.2 in /docs (#2920) Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 4.3.1 to 4.3.2. - [Changelog](https://github.com/nodeca/js-yaml/blob/4.3.2/CHANGELOG.md) - [Commits](nodeca/js-yaml@4.3.1...4.3.2) --- updated-dependencies: - dependency-name: js-yaml dependency-version: 4.3.2 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump devalue from 5.8.1 to 5.9.2 in /docs (#3019) Bumps [devalue](https://github.com/sveltejs/devalue) from 5.8.1 to 5.9.2. - [Release notes](https://github.com/sveltejs/devalue/releases) - [Changelog](https://github.com/sveltejs/devalue/blob/main/CHANGELOG.md) - [Commits](sveltejs/devalue@v5.8.1...v5.9.2) --- updated-dependencies: - dependency-name: devalue dependency-version: 5.9.2 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix(build): support setuptools 83 in binary packaging Require PyInstaller 6.17.0 and lock its minimum compatible hooks to avoid altgraph importing the removed pkg_resources module. Preserve the setuptools 83.0.0 security upgrade. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: sergio-sisternes-epam <207026618+sergio-sisternes-epam@users.noreply.github.com> Co-authored-by: danielmeppiel <51440732+danielmeppiel@users.noreply.github.com> Co-authored-by: Nadav Yogev <nadavy@jfrog.com> Co-authored-by: danielmeppiel <danielmeppiel@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Gijs Reijn <26114636+Gijsreyn@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Ron Izraeli <35386615+chkp-roniz@users.noreply.github.com> Co-authored-by: Arnaud <arnaudoisel@users.noreply.github.com> Co-authored-by: Marco Frömbgen <23717573+mfroembgen@users.noreply.github.com> Co-authored-by: Sergio Sisternes <sergio_sisternes@epam.com> Co-authored-by: Daniel <47431549+Danvs60@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

fix(ci): repair advisory locks and platform regressions
TL;DR
Repair stale advisory-workflow metadata and the Windows/macOS failures found
while investigating main after #3003. Regenerate both advisory locks with the
repository-pinned compiler, correct the Windows filesystem fixture,
and keep drift replay scoped to the original project's primitive directories.
Important
These are separate causes: the build immediately after #3003 passed.
The stale triage lock came from that migration; the Windows assertion came
from #2901, and the replay over-scan was latent.
Hosted PR checks pass at
0b169f4518, including the Windows compatibilitygate and both Linux shards. Post-merge macOS Intel remains unverified.
Problem (WHY)
stopped before agent execution with
E009 CONFIG_HASH_MISMATCH.Both triage and PR-review lock headers were stale against current source.
failed the Windows alias fixture: the filesystem created
safe, but theassertion expected the input spelling
safe..10.092998506000072 < 10.0failed. Replay treated the scratch destination asthe source identity, causing unnecessary full-project discovery.
the compiler contract:
PR-review metadata used
v0.88.2, but repository tooling pinsv0.87.8.The correction recompiles the entire lock rather than relabeling its header.
The repair uses concrete failure evidence and regression assertions rather
than bypassing gates. Agent Skills recommends:
"do the work, run a validator (a script, a reference checklist, or a self-check), fix any issues, and repeat until validation passes."
Approach (WHAT)
v0.87.8generator, retaining actionSHAs and permissions while restoring its matching runtime defaults.
shared import, including LF/CRLF/CR coverage and compiler-header consistency.
existing Windows compatibility gate.
retain normal discovery for external packages.
introducing a second fixture suite or relaxing the timing budget.
isolate symlink prerequisites so they cannot skip alias coverage.
Implementation (HOW)
.github/workflows/triage-panel.lock.yml.github/workflows/pr-review-panel.lock.ymlsrc/apm_cli/integration/base_integrator.pyroot_local_project_rootwhen the deployment destination is scratch.tests/unit/integration/test_base_integrator.pytests/unit/test_deps_utils.pywindows_compat.tests/unit/test_triage_panel_lock.pytests/unit/test_shared_apm_workflow_contract.pydocs/src/content/docs/contributing/development-guide.mddocs/src/content/docs/enterprise/drift-detection.mdThe Python runtime change is confined to
BaseIntegrator._is_root_local_package.No CLI flags, Python dependency versions, acceptance rules, or permissions change.
PR-review's generated firewall defaults return from 0.28.12 to 0.28.7 and
MCP gateway from 0.4.15 to 0.4.12, matching the pinned compiler and other locks.
There is no CHANGELOG edit or primitive-source change.
Diagrams
The dashed step preserves root-local source identity when replay uses a different deployment destination.
flowchart LR subgraph Replay["Drift replay"] P["Root-local package"] S["Scratch deployment root"] end subgraph Discovery["Source discovery"] I["BaseIntegrator._is_root_local_package"] R["Compare recorded root_local_project_root"] N["Scan original .apm and .github"] E["External package: scan install_path"] end P --> I S --> I I -->|"Destination differs from source"| R R -->|"Recorded root matches install_path"| N R -->|"Not root-local"| E classDef new stroke-dasharray: 5 5; class R new;Trade-offs
discovery rather than raising the threshold or skipping macOS.
upgrading the compiler across all workflows or weakening its contract.
This is a full regeneration, not a metadata-only change.
shape. Structural changes fail explicitly and require updating the guard.
worktree on
PYTHONPATH, because fresh PyPI downloads failed. NativemacOS Intel timing remains unverified; the hosted Windows gate passes.
Benefits
test before the workflow reaches activation.
and scratch replay, including real directory-walk coverage.
without requiring symlink privileges; a separate test retains symlink exclusion.
Validation
Current
origin/mainwas integrated before validation and commit.Local and hosted PR checks pass at
0b169f4518.CI run 35334185992
passed both Linux shards, Windows compatibility, lint, architecture ratchets,
and smoke checks. The merge gate
also passed. All three Copilot review threads are answered and resolved.
Focused suite and local lint evidence
Executed with
VIRTUAL_ENV=/Users/danielmeppiel/Repos/awd-cli/.venv,PYTHONPATH=src, anduv run --active --no-sync --extra dev.This binds production imports to the repair worktree without modifying
the existing dependency environment.
pytest -qselectedtest_base_integrator.py,test_drift.py,test_drift_perf.py,test_triage_panel_lock.py,test_shared_apm_workflow_contract.py,test_workflow_actor_contract.py,test_deps_utils.py, andtest_alias_traversal.py:Ruff check and format over the canonical CI paths:
Pylint R0801 over the canonical CI paths:
The auth and architecture boundary scripts, YAML/file-length/relative-path
guards, assertion-quality and duplicate-test ratchets, and
git diff --checkalso completed successfully.
Both original stale metadata snapshots were rejected by the new hash guard.
An in-memory replacement with the original root-local predicate made all
four replay regression cases fail; restored production code passes.
The Mermaid diagram was rendered successfully with
mmdc.The strengthened compiler test rejects main's mismatched generated banner.
Disabling universal-newline translation makes the CRLF fixture fail.
Simulating denied symlink privileges yields four alias passes and only
one skip, for the isolated symlink test.
Scenario Evidence
tests/unit/test_triage_panel_lock.py::test_advisory_lock_metadata_matches_source(regression trap for the #3003 migration)tests/unit/test_deps_utils.py::test_scan_includes_flattened_alias_without_nested_packagestests/unit/integration/test_base_integrator.py::TestInitLinkResolverLocalScoping::test_real_walk_does_not_traverse_noise_subtree[replay]tests/unit/integration/test_base_integrator.py::TestInitLinkResolverHomeScoping::test_uses_install_path_when_not_hometests/unit/install/test_drift_perf.py::test_drift_replay_under_10s_for_100_primitivestests/unit/test_shared_apm_workflow_contract.py::test_repository_pins_exact_gh_aw_compiler_and_generated_locksHow to test
uv run --frozen --extra dev pytest -q tests/unit/test_triage_panel_lock.py tests/unit/test_shared_apm_workflow_contract.py tests/unit/test_workflow_actor_contract.py; both advisory locks must match source and the repository compiler pin.uv run --frozen --extra dev pytest -q tests/unit/test_deps_utils.py tests/unit/test_alias_traversal.py; dotted aliases remain accepted and discoverable.uv run --frozen --extra dev pytest -q tests/unit/integration/test_base_integrator.py tests/unit/install/test_drift.py tests/unit/install/test_drift_perf.py; install/replay scoping and the unchanged timing budget must pass.Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com