* feat: add Trojan Skill Hunter agent for auditing AI customization contributions
Adds a new agent that audits .agent.md, SKILL.md, .instructions.md,
hooks.json, and MCP/plugin manifests for hidden prompt injection, MCP-style
tool poisoning/shadowing, unicode steganography, excessive-agency scope
mismatches, and rug-pull/supply-chain drift before contributions are
merged, installed, or trusted.
Mapped to the OWASP Top 10 for LLM Applications (2025) and Invariant Labs'
MCP Tool Poisoning Attack research. Includes an explicit self-defense rule
so the agent treats reviewed content as untrusted data, never instructions
to obey.
* fix: reword attack-pattern examples to avoid PR risk-scan false positives
The Rule Zero bullet and two rug-pull/unpinned-fetch examples quoted the
exact literal phrases (e.g. 'ignore previous instructions', 'curl | bash')
that the repo's automated PR Risk Scan greps for. Reworded to convey the
identical meaning without the literal trigger strings - confirmed locally
with 'node eng/pr-risk-scan.mjs' (0 high/medium/info findings, was 3 high).
---------
Co-authored-by: Shubham Jiyani <shubham.jiyani@atqor.com>
* Add PR Artifact Explorer canvas
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 33fefd65-ed18-4eda-9c7d-48008f4a9c9d
* Address PR #2341 review feedback and codespell CI failures
PR review fixes:
- zip.mjs: bounded streaming inflate for readZipEntry (output cap = entry.uncompressedSize) to prevent memory exhaustion from malformed entries
- zip.mjs: new bounded verify Transform in streamZipEntry that enforces decompressed byte cap and verifies CRC32 on flush
- zip.mjs: new readEntryPrefix() helper that inflates only up to a byte cap for indexing use cases
- preview.mjs: move URL/path parsing inside the try block so URIError becomes a 400 response instead of an unhandled rejection
- cache.mjs: buildMetadata uses bounded readEntryPrefix (8 KiB) instead of full readEntry+slice, eliminating unbounded decompression during indexing
- cache.mjs: clearArtifactCache aborts and awaits in-flight downloads via AbortController before removing cache dirs so clear cannot be repopulated
- server.mjs / preview.mjs: track static preview servers by canvas origin and stop them on canvas close, preventing loopback server leaks
- trx-preview.js: prefer authoritative ResultSummary.outcome when it is a recognized TRX value; only infer from counters when unknown
- extension.mjs: set_account validates the requested id resolves to the active account before persisting; unknown ids now return an error
- server.mjs: reject progressive-pull offsets that are not multiples of PROGRESSIVE_PULL_BATCH_SIZE to prevent caching incomplete pulls as complete
- README.md: remove Markdown-rendering claim (files are shown as escaped text)
CI fix:
- .codespellrc: skip vendored asciinema-player(*.min.js) and primer-*.css bundles
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 47369ff4-859a-425f-8a47-763cc1a5f25f
* Address second round of PR #2341 review feedback
- github.mjs: request isDraft in the pullRequestSignals GraphQL enrichment and propagate draft into search-sourced pulls (search REST API has no draft field)
- cache.mjs: give each writeJsonAtomic write a unique temp filename via a module sequence and clean up the temp file on failure to avoid concurrent-write races
- cache.mjs: deleteCachedArtifact now aborts and awaits any in-flight download for the artifact before removing files; internal mismatched-metadata purge uses a raw removeArtifactFiles helper to avoid aborting its own operation
- accounts.mjs: skip non-github.com CLI accounts before reading tokens so GitHub Enterprise Server credentials are never sent to api.github.com
- preview.mjs: require the requested entry to be the root index.html before launching a static preview (previously any nested HTML file could start one)
- zip.mjs: validate the EOCD comment length ends exactly at the archive tail so a file comment containing the EOCD signature is not mistaken for the record
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 47369ff4-859a-425f-8a47-763cc1a5f25f
* Address remaining PR artifact explorer feedback
Fix malformed preference normalization, replace artifact-presence request fanout with cached repository artifact pagination, restrict static previews to the root index, and derive completed TRX outcomes from counters. Add focused regression coverage for all four behaviors.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: db486df1-17f1-4623-ac7e-61eff2c76da4
* Fix PR artifact explorer review feedback
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 6ee2bc81-2114-4b1f-987a-cb47ea35e132
* Stabilize artifact discovery and cache cleanup
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 6ee2bc81-2114-4b1f-987a-cb47ea35e132
---------
Co-authored-by: David Pine <7679720+IEvangelist@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 33fefd65-ed18-4eda-9c7d-48008f4a9c9d
Copilot-Session: 47369ff4-859a-425f-8a47-763cc1a5f25f
Copilot-Session: db486df1-17f1-4623-ac7e-61eff2c76da4
Copilot-Session: 6ee2bc81-2114-4b1f-987a-cb47ea35e132
* Enforce external plugin ref/sha consistency
Extract shared ref/sha normalization and consistency checks into eng/lib and reuse them in intake plus quality gate flows.
Add a dedicated ref/sha consistency quality gate surfaced in PR/intake summaries, and add targeted tests for matching and mismatched refs.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 6afe21ad-eafa-4c90-a1f2-053dedac7625
* Address review: tree/blob ref errors and PR workflow ref/sha column
- resolveCommitShaAtReadRef: classify rev-parse failure as 'fail'
instead of 'infra_error' because a successfully-fetched ref that
doesn't dereference to a commit is a submitter problem, not infra.
- validateRemoteRepository (intake): treat HTTP 422 from the commit
endpoint as a submitter error; all other non-404 errors remain
transient warnings requiring maintainer re-run.
- external-plugin-pr-quality-gates.yml: add ref/sha consistency
column to the per-plugin quality table and failure details block.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 6afe21ad-eafa-4c90-a1f2-053dedac7625
---------
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 6afe21ad-eafa-4c90-a1f2-053dedac7625
Update the external plugin catalog to the 1.0.5 source commit and regenerate the marketplace output.
Co-authored-by: Aaron Powell <me@aaron-powell.com>
* Accept nested extensions/<name>/extension.mjs in external-plugin canvas checks
The external-plugin canvas structure check (quality gate) and intake
validation both hardcoded a flat extensions/extension.mjs entry point,
falsely rejecting the documented nested extensions/<name>/extension.mjs
layout that installs and runs fine.
Scan the extensions/ directory for a nested subfolder containing
extension.mjs while still accepting the flat form for backward
compatibility. Applied to both runCanvasStructureGate (git-object
lookups) and validateCanvasPluginMetadata (Contents API), keeping them
behaviorally aligned. Added regression coverage for both paths.
Fixes#2402
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* Harden nested canvas extension detection after adversarial review
Address multi-model review findings on the nested canvas extension fix:
- Quality gate: enumerate extensions/ via 'git ls-tree -z' with spawnSync (NUL-delimited, untruncated) so large directories no longer drop the real entry past the 12KB output cap.
- Intake: decouple the flat extensions/extension.mjs check from the directory listing, require an array listing (Array.isArray) before treating it as a directory, and surface an unverifiable (warning) result instead of a false rejection when the listing or a nested lookup hits a transient API error.
- Add regression tests: nested entry beyond the legacy output cap (gate) and unverifiable/flat-still-accepted paths when the listing errors (intake).
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* Enumerate canvas extensions via a single recursive Git Trees call in intake
Address PR review: the Contents API caps directory listings at 1,000 entries and required one request per extension subfolder, so a nested entry beyond the cap could be falsely rejected (the same truncation class the git gate avoids) and large repos risked latency / rate-limit exhaustion.
Replace the per-subfolder Contents API enumeration with one recursive 'git/trees/<locator>?recursive=1' fetch and inspect 'extensions/extension.mjs' and immediate 'extensions/<name>/extension.mjs' paths locally. A truncated tree without a located entry point is reported as unverifiable (warning) rather than rejected, and refs are normalized so 'refs/tags/<tag>' resolves as a tree-ish.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* Bound canvas extension discovery to plugin scope
Address reviewer feedback on unbounded scaling for untrusted/large repos:
- Quality gate: replace the per-candidate-directory git cat-file spawns in
locateCanvasEntryPoint with a single recursive git ls-tree over the
extensions subtree, classifying flat/nested entry points in memory. Process
count is now constant regardless of how many folders live under extensions/.
- Intake: stop fetching the recursive git tree from the repo root (which a
large unrelated monorepo can push past the Trees API truncation limit and
never validate). Walk to the plugin's extensions directory one level at a
time to resolve its tree SHA, then fetch only that subtree recursively, so
verifiability depends on the plugin's own size, not the whole repository.
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: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: aaronpowell <434140+aaronpowell@users.noreply.github.com>
* fix: add @astrojs/markdown-remark dep and fix build-website CI paths
Astro 7.1.x introduced 'Satteri' as the default Markdown processor and
no longer bundles @astrojs/markdown-remark by default. The website config
uses markdown.remarkPlugins which requires this package to be installed
explicitly.
Also update build-website.yml paths to use explicit ** glob patterns
and include root package.json/package-lock.json changes as triggers,
so dependabot package bumps always run the website build check.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: ed2219f7-f30c-4e24-95af-9c216166f285
* refactor: use explicit unified() processor in astro.config
Astro 7.1+ changed the markdown.remarkPlugins shorthand to require
@astrojs/markdown-remark. Update to the explicit unified() processor API
which is the supported way to use remark/rehype plugins in Astro 7.1+.
Sätteri (the new default processor) is incompatible with remark plugins,
so we stay on unified() to keep remark-github-admonitions-to-directives
working for Learning Hub GitHub admonition syntax.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: ed2219f7-f30c-4e24-95af-9c216166f285
* Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
---------
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>
Copilot-Session: ed2219f7-f30c-4e24-95af-9c216166f285
The issue-body template was wrapped in a three-backtick fence while
containing three-backtick HCL and Bash blocks, so the HCL example's
closing fence terminated the wrapper early and the following fence
swallowed the remaining workflow sections. Use a four-backtick wrapper
so the nested blocks render intact.
Co-authored-by: Aaron Powell <me@aaron-powell.com>
* fix: exclude auto-generated README files from PR risk scan
The scanner was processing README.md and docs/README.*.md which are
auto-generated by \
pm run build\ and shouldn't be reviewed for risk
patterns.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: a278c6bb-22ad-4d43-8e68-60432773f987
* Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
---------
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>
Copilot-Session: a278c6bb-22ad-4d43-8e68-60432773f987
npm install warnings (EBADENGINE, deprecated) were leaking into both
the Summary findings table and the full linter output block, making
the comment noisy. Filter them out when processing raw vally output.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 4c3ca9da-500e-464e-88d3-4c09535ec45c
* Add azure-well-architected-review skill
Adds a skill that performs a structured Azure Well-Architected Framework
review of a workload's IaC (Bicep, Terraform, ARM) and deployed
infrastructure across the 5 WAF pillars, then creates GitHub issues to
track remediation. Mirrors the existing aws-well-architected-review
skill, which had no Azure equivalent.
* Address Copilot review feedback on azure-well-architected-review
- Step 2: always inventory live Azure resources and compare with IaC to
surface drift, instead of scanning IaC only
- Step 5: add an explicit confirmation gate before any GitHub issue
creation; ambiguous or negative responses stop with a console report
- Fix nested code fences in the issue-body template by using a
four-backtick wrapper
- Add /ask and /refine to Essential Slash Commands table
- Add /ask tip and /refine tip after the table
- Add /env to Agent Environment commands table
- Fix shell quoting example: use single quotes for $HOME
- Add 'Esc twice to cancel' to Common Mistakes table
- Update Summary key takeaway to list all essential commands
- Bump lastUpdated to 2026-07-17
Upstream commits:
- 349aac6: fix shell quoting in Common Mistakes table
- 5ae1cbb: docs: add /refine command and /plugins dashboard documentation
- a67a260: docs: remove unverified /plugins command documentation
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Add gitmoji skill and gitmoji-setup agent
Adds two complementary artifacts for the gitmoji commit convention
(https://gitmoji.dev):
- skills/gitmoji: generates gitmoji commit messages from a diff, staged
changes, or a change description. Message-only by design (never runs
git commands), with disambiguation rules and a full reference table of
the 75 official gitmojis generated from the official gitmojis.json.
- agents/gitmoji-setup: sets up gitmoji tooling in a repository. Audits
the existing hook manager and commit convention, then installs either
a non-interactive prepare-commit-msg prefill hook (default, works in
GUI clients and CI), the gitmoji-cli interactive picker, or commitlint
enforcement, without clobbering existing hooks.
Generated README indexes updated via npm start.
* Use local commitlint binary instead of npx in verify step
Addresses the package-exec-command finding from the PR risk scan: the
verification example now calls the locally installed
./node_modules/.bin/commitlint rather than npx, which could fetch and
execute a package on the fly.
* Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Address Copilot review feedback
- Quote the agent description in single quotes per AGENTS.md convention
- Resolve the effective hooks directory via git rev-parse --git-path
hooks for both audit and installation, instead of hard-coding
.git/hooks (core.hooksPath, linked worktrees)
- Correct the prefill-hook compatibility claim: it prefills only when
the message editor opens and silently no-ops for -m/-F, GUI message
boxes, and CI
- Match the official gitmoji set explicitly when detecting an existing
emoji, instead of treating any non-ASCII start as one
- Drop .txt from the docs heuristic (it shadowed requirements.txt) and
remove the dependency-manifest fallback entirely: filenames cannot
distinguish upgrade/add/remove/pin/downgrade
- Restrict gitmoji -i to repos whose effective hooks dir is .git/hooks;
wire the picker through the hook manager otherwise
- Merge gitmoji into an existing commitlint config instead of
overwriting commitlint.config.mjs
- Fix the verification sequence: clean starting state, non-colliding
scratch file, abort by clearing the editor, explicit unstage/remove/
switch-back/branch-delete cleanup
- Skill: ask the user for commit history instead of running git log,
honoring the message-only contract
* Address second round of Copilot review feedback
- Pair the prefill hook with a commit-msg guard: prefilling an empty
COMMIT_EDITMSG defeats git abort-on-empty-message, so an untouched
prefill would create a commit named only with the emoji. The guard
rejects messages that contain nothing but the prefilled gitmoji.
- Extract the gitmoji alternation into a GITMOJI_RE variable shared by
both hooks.
- Document the commitlint-config-gitmoji format mismatch: it enforces
the hybrid <gitmoji> type(scope?): subject format and rejects the
plain gitmoji format produced by Options A/B and the gitmoji skill.
Option C now asks the team to choose a format first, and the
verification example uses a valid hybrid message.
---------
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* website: add legal links and privacy-aware analytics
Add Terms, Privacy, and Security links to the website footer and remove the experimental cookie consent popup to avoid cross-site consent drift with github.com.
Gate Hydro analytics loading on browser privacy signals (Do Not Track and Global Privacy Control) so tracking-disabled users are respected without adding custom consent state.
Update website security notes to match the current non-modal rendering flow.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: d0fdad70-4820-4c24-9e4a-35c82faf31ed
* Adopting the footer design from #2327
* Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
---------
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>
Copilot-Session: d0fdad70-4820-4c24-9e4a-35c82faf31ed
* chore: standardize agent documentation markdown, fix formatting, add MANDATORY clauses, and update output formats across agents
* chore: Update gem-team plugin version to 1.84.0 and refine concurrency language in agent execution steps
* Bump gem-team plugin version to 1.86.0 and update README
* Bump gem-team plugin version to 1.87.0 and update README
runVersionMatchGate and runCanvasStructureGate read locator content with git show/cat-file. For a tag-name locator, `git fetch origin <tag>` only updates FETCH_HEAD and never creates refs/tags/<tag>, so `git show <tag>:...` died with 'invalid object name' and produced a false infra_error.
Read the primary locator via HEAD (already checked out during clone) and non-primary locators via FETCH_HEAD after fetching, instead of the bare locator. This handles SHAs, short tag names, and fully-qualified tag refs uniformly without classifying the locator.
Adds regression coverage for the tag-locator path in both gates.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Update external plugin registration: rename identity and source.path to
microsoft-foundry, bump version to 1.0.3, refresh description and source.sha,
and regenerate marketplace.json.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 68571581-f9d1-4b01-a5d7-0a49c4a6b3b5