Skip to content

feat: dogfood APM on microsoft/apm -- .apm/ primitives, compile, --check gate#934

Open
sergio-sisternes-epam wants to merge 10 commits intomainfrom
feat/792-dogfood-apm
Open

feat: dogfood APM on microsoft/apm -- .apm/ primitives, compile, --check gate#934
sergio-sisternes-epam wants to merge 10 commits intomainfrom
feat/792-dogfood-apm

Conversation

@sergio-sisternes-epam
Copy link
Copy Markdown
Collaborator

Supersedes #842 (moved branch from fork to upstream repo).

Summary

Closes #695, closes #792. Supersedes closed #754, #842.

Dogfoods APM on microsoft/apm itself:

  • The repo's own agent primitives move from hand-maintained .github/instructions/** + .github/agents/** into a .apm/ source tree (9 instructions, 10 agents, 8 skills).
  • A new apm.yml at the repo root (name: apm-cli, target: all) drives compilation.
  • apm compile now regenerates every agent-tool output: root AGENTS.md + CLAUDE.md, distributed AGENTS.md + CLAUDE.md under .github/, docs/src/, src/apm_cli/, src/apm_cli/integration/, tests/, and the new .github/copilot-instructions.md.
  • CI enforces sync via apm compile --check in Tier 1 so hand-edits to generated files or forgotten recompiles fail the build with a clear remediation hint.

What's new

  • feat(compile): .github/copilot-instructions.md emitter (apm compile should emit .github/copilot-instructions.md (dogfood gap) #792). Root-scoped instructions (no applyTo) now compile into a single aggregated file that Copilot reads natively. Root-scoping is a first-class primitive -- the No 'applyTo' warning was a bug masquerading as a lint.
  • feat(compile): apm compile --check flag. Read-only drift verification. Exit codes 0 match / 1 drift / 2 unrecoverable error. Drift report to stderr (stdout reserved for future --json), silent on success. Distinguishes content drift (apm compile) from stale files (apm compile --clean).
  • fix(compilation): link_resolver._resolve_path containment. Three independent gates (is_absolute, validate_path_segments, ensure_path_within) fail closed on traversal, symlink escape, and absolute paths. Supply-chain-security review: 0 blockers.
  • fix(compilation): route timing output through logger and use deterministic base_dir for sort stability across platforms.

How the dogfood works

  1. Edit any primitive under .apm/**.
  2. Run apm compile locally; commit the regenerated outputs in the same PR.
  3. CI Tier 1 runs apm compile --check -- drift fails the build and tells the contributor exactly which command to run.

See CONTRIBUTING.md -- Recompiling agent outputs and the new ## Dogfooding section in the README.

Commit structure

# Commit Summary
1 fbaa469 fix(compilation): route timing output through logger; deterministic sort
2 79389ab fix(compilation): path containment in link_resolver._resolve_path
3 8372876 feat(compile): emit .github/copilot-instructions.md (#792)
4 7f8f95d feat(compile): add --check flag
5 1ce108f chore: root apm.yml + populate .apm/ with repo primitives
6 74b772b chore: regenerate agent-tool outputs via apm compile
7 6d09d4e ci: add apm compile --check gate to Tier 1
8 8f6aded docs: document --check and the .apm/ workflow
9 125c48b docs(readme): add ## Dogfooding section

Each commit is atomic and green.

Validation

  • Full unit suite: 4829 tests passing in ~12s (uv run pytest tests/unit tests/test_console.py).
  • uv run apm compile --check exits 0 on HEAD.
  • Generated file count: 13 (root + 5 distributed AGENTS.md/CLAUDE.md pairs + .github/copilot-instructions.md).
  • .gitattributes marks all generated outputs linguist-generated=true so GitHub diffs collapse them and language stats ignore them.

Reviews run

Before opening this PR the following reviews were run and all findings addressed:

  • python-architect -- pre-impl review of commit 3 (copilot-instructions emitter design).
  • cli-logging-expert -- pre-impl review of commit 4 (--check contract, exit codes, stderr, symbols).
  • supply-chain-security-expert -- post-impl review of commit 2 (containment): 0 blockers; minor nits filed as chore(compile): tighten link_resolver._resolve_path input guards #841.
  • rubber-duck -- gated commit 7 before regen; caught a source-scoping blocker (fixture / template primitives leaking into repo outputs) which we fixed by adding compilation.exclude in apm.yml.
  • code-review -- whole-branch final review: approve, no blockers.

Follow-ups (filed, out of scope here)

Breaking changes

None for consumers of APM.

For microsoft/apm contributors: .github/instructions/** and .github/agents/** no longer exist as source directories. Edit under .apm/ instead, then apm compile. CONTRIBUTING.md covers the workflow.

Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com

Sergio Sisternes and others added 10 commits April 24, 2026 17:26
…istic sort base_dir

Two foundational fixes required before apm compile --check can enforce a strict
stdout contract and round-trip determinism:

1. context_optimizer.py: replace bare print() with logger.debug(). Timing
   output is opt-in via --verbose/DEBUG level and must never leak to default
   stdout.

2. template_builder.py: build_conditional_sections() now takes a required
   base_dir parameter. Previously Path.cwd() was used in the sort key and
   relative-path display, making compile output depend on the user's current
   working directory. Sort order must be deterministic regardless of where
   apm is invoked from.

Updated the single caller in agents_compiler.py to pass self.base_dir. Added
unit tests covering logger routing (caplog vs capsys) and deterministic sort
behaviour.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The apm compile --check flag (landing in a later commit) will run in Tier 1
CI and read user-authored markdown from .apm/ primitives. _resolve_path
previously accepted absolute paths unguarded and performed naive base_path/path
joins with no traversal or symlink-escape checks. This is the first path_security
import into the compilation/ subsystem.

New contract (3-gate fail-closed):
1. Absolute paths are rejected outright (return None).
2. validate_path_segments rejects '..' at parse time; './' is allowed since it
   is legitimate in markdown links (allow_current_dir=True).
3. ensure_path_within resolves symlinks and asserts containment after the join;
   the resolved path is returned on success.

PathTraversalError / OSError / ValueError all map to None, which the caller
surfaces as 'Referenced file not found' via the existing validate_link_targets
flow.

Three other pre-existing path-traversal gaps in the compilation subsystem
(apm.yml output_path, applyTo patterns, full path_security integration across
compile) are explicitly deferred to a labelled security follow-up issue filed
pre-merge.

Supply-chain-security-expert review: 0 blockers, 0 majors, 3 minors (all
non-exploitable edge cases filed under the follow-up).

Tests: TestResolvePathSecurity covers absolute rejection, traversal at depth,
current-directory allowance, symlink escape, and an integration check via
validate_link_targets.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…instructions (#792)

Closes #792. Instructions with empty or missing applyTo frontmatter
were previously silently dropped by both the distributed compiler and the
single-file template builder. They now aggregate into .github/copilot-instructions.md
for the vscode-family targets (vscode, copilot, agents, opencode, codex, all,
minimal).

Design (approved by python-architect pre-implementation):

- New AgentsCompiler._compile_copilot_instructions() sibling emitter called
  between _compile_agents_md and _compile_claude_md in the target-routing block.
  Returns Optional[CompilationResult]; None when no root-scoped instructions
  exist so no empty file is written and _merge_results stays clean.
- New should_compile_copilot_instructions() predicate in target_detection so
  the gate can diverge from should_compile_agents_md later if needed.
- New build_root_sections() helper in template_builder mirrors
  build_conditional_sections but without pattern headers; filters empty-applyTo
  instructions, deterministic sort by portable_relpath(path, base_dir).
- Hardcoded path .github/copilot-instructions.md (GitHub Copilot convention);
  no new CompilationConfig field needed.
- Prefixed stat key 'copilot_instructions_written' to avoid _merge_results
  collisions.

Also standardises the generated-file header across all three emitters. New
constant GENERATED_HEADER in compilation/constants.py:

Replaces the inconsistent AGENTS.md ('from distributed .apm/ primitives'),
CLAUDE.md ('Generated by APM CLI') and template-builder variants. Updates the
target-description strings in target_detection so apm init / status output
reflects the new file.

Tests: new tests/unit/compilation/test_copilot_instructions.py with 12 cases
covering mixed fixture, empty case, deterministic sort, round-trip stability,
header presence, source attribution, dry-run mode, target gating, and an
integration test asserting both AGENTS.md and copilot-instructions.md are
produced with the correct content split. Existing tests updated for the header
standardisation.

Full suite: 4804 passed.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add a CI-friendly --check mode to `apm compile` that compares the
expected compiler output against on-disk generated files and exits:
  0 – all outputs match,  1 – drift or stale files,  2 – unrecoverable.

Implementation highlights:
- New CATEGORY_DRIFT diagnostic level with drift() / drift_count
- AgentsCompiler.preview_all_outputs() dry-runs the full pipeline and
  returns Dict[Path, str] without writing to disk
- _run_check() / _render_drift_report() in the CLI compare previews to
  disk, detect stale well-known outputs, and emit a concise report
- --check implies --local-only and is mutually exclusive with --validate,
  --watch, --dry-run, --single-agents, --clean
- Remove 'No applyTo pattern specified' validation warning – root-scoped
  instructions are now first-class primitives

Co-authored-by: Claude <noreply@anthropic.com>
Creates the first APM manifest for microsoft/apm itself and ports all
26 existing agent primitives from .github/** into .apm/:

  .apm/instructions/ (9)  - 8 copied from .github/instructions/ plus
                            new contributing.instructions.md aggregating
                            .github/copilot-instructions.md as a
                            root-scoped (applyTo-less) instruction.
  .apm/agents/      (10)  - byte-identical copies of .github/agents/.
  .apm/skills/       (8)  - byte-identical copies of .github/skills/.

This commit adds sources only; it does NOT regenerate .github/** outputs.
apm compile --check now reports drift for every .github/** file, which
the next commit resolves by running `apm compile` for real.

Refs #695, #792.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Removes legacy .github/instructions/ and .github/agents/ source trees
(ported to .apm/ in the previous commit) and regenerates all
agent-tool outputs from .apm/ primitives:

- Root AGENTS.md and CLAUDE.md (aggregated)
- Distributed AGENTS.md and CLAUDE.md in .github/, docs/src/,
  src/apm_cli/, src/apm_cli/integration/, tests/
- .github/copilot-instructions.md (root-scoped instructions)

Adds compilation.exclude patterns to apm.yml to scope discovery to
first-party primitives (excludes tests/, templates/, packages/,
build/, docs/node_modules/).

Marks generated outputs as linguist-generated in .gitattributes so
GitHub's diff views collapse them by default and language stats
exclude them.

Removes AGENTS.md from .gitignore since it is now a committed
compile artifact.

Closes #695, closes #792.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Runs 'apm compile --check' on every PR and merge_group event to
ensure AGENTS.md, CLAUDE.md, and .github/copilot-instructions.md
stay in sync with .apm/ primitives.

Read-only check: exit 0 when outputs match, exit 1 on drift. The
error message directs contributors to run 'apm compile' locally
and commit the regenerated outputs.

Part of the #695 / #792 dogfooding PR.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- CONTRIBUTING.md: new "Recompiling agent outputs" section explaining
  .apm/ is source of truth and the compile workflow
- docs/.../cli-commands.md: document apm compile --check flag and
  exit-code contract
- docs/.../manifest-schema.md: document compilation.exclude patterns
- CHANGELOG.md: entries under [Unreleased] for --check, copilot-
  instructions compile target, root-scoped instructions, dogfood
  switch, and link_resolver containment fix

README callout proposal written to session files for user approval
(per doc-sync rule 2).

Part of the #695 / #792 dogfooding PR.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
APM uses APM to manage its own agent primitives. The new section
points readers at the .apm/ source tree, the apm compile workflow,
and the CI gate -- linking to CONTRIBUTING.md for the full procedure.

Part of the #695 / #792 dogfooding PR.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Compiled outputs fall into two groups:

- GitHub-hosted consumers (Copilot in PR/chat, Agentic Workflows, Cloud Agents)
  read AGENTS.md and .github/** directly from the repo -- no build step runs
  on their side, so we MUST commit these files.
- Claude Code runs exclusively on a developer's machine. Contributors can
  regenerate CLAUDE.md locally via apm compile.

This commit implements that split:

- .gitignore: gitignore CLAUDE.md / **/CLAUDE.md (with exceptions for template
  fixtures, docs-site pages, and test fixtures).
- Untrack the 5 previously-tracked CLAUDE.md files.
- .gitattributes: drop CLAUDE.md linguist-generated entries (no longer tracked);
  keep AGENTS.md and copilot-instructions.md markers.
- .github/workflows/ci.yml: scope the drift gate to 'apm compile -t copilot
  --check' so CI only asserts sync on the outputs we actually commit.
- CONTRIBUTING.md / README.md / cli-commands.md: document the policy
  explicitly ('pre-built for GitHub Copilot; other platforms run apm compile
  on checkout') including a note on how local -t copilot --check interacts
  with a full-target local compile.
- CHANGELOG.md: clarify the Unreleased dogfood entry.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings April 25, 2026 09:21
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Dogfoods APM on the microsoft/apm repo by making .apm/ the source of truth for agent primitives, extending apm compile to generate Copilot-native root instructions, and adding a CI drift gate (apm compile --check) to prevent generated output drift.

Changes:

  • Added apm compile --check (read-only drift verification) and supporting diagnostics/reporting.
  • Added compilation support for .github/copilot-instructions.md from root-scoped instructions (empty applyTo).
  • Migrated repo primitives to .apm/, regenerated compiled outputs, and enforced sync in Tier 1 CI.

Reviewed changes

Copilot reviewed 56 out of 58 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
src/apm_cli/commands/compile/cli.py Implements --check, drift detection, and drift report rendering.
src/apm_cli/compilation/agents_compiler.py Adds copilot-instructions emitter and preview_all_outputs() for --check.
src/apm_cli/compilation/template_builder.py Makes instruction ordering deterministic via base_dir; adds root-scoped section builder.
src/apm_cli/core/target_detection.py Adds gating/description updates for copilot-instructions output.
src/apm_cli/compilation/link_resolver.py Hardens link resolution with validate_path_segments + ensure_path_within.
src/apm_cli/compilation/context_optimizer.py Routes timing output through logging (avoids stdout print).
src/apm_cli/compilation/constants.py Introduces unified generated-file header constant.
src/apm_cli/compilation/claude_formatter.py Switches CLAUDE.md header to the unified generated header.
src/apm_cli/compilation/distributed_compiler.py Switches AGENTS.md header to the unified generated header.
src/apm_cli/utils/diagnostics.py Adds drift diagnostics category + counter for compile --check.
src/apm_cli/utils/__init__.py Re-exports CATEGORY_DRIFT.
src/apm_cli/primitives/models.py Removes validation warning/error for missing applyTo (root-scoped now allowed).
tests/unit/commands/compile/test_check_flag.py Adds CLI tests for apm compile --check exit codes and remediation hints.
tests/unit/compilation/test_copilot_instructions.py Adds unit/integration tests for .github/copilot-instructions.md generation.
tests/unit/compilation/test_preview_outputs.py Adds tests for preview mode used by --check.
tests/unit/compilation/test_template_builder.py Adds deterministic sort tests for template building.
tests/unit/compilation/test_link_resolver.py Adds security-focused tests for _resolve_path containment/traversal rejection.
tests/unit/compilation/test_context_optimizer.py Adds tests ensuring timing output goes to logger, not stdout.
tests/unit/test_diagnostics.py Adds drift category tests for DiagnosticCollector.
tests/unit/core/test_target_detection.py Adds tests for should_compile_copilot_instructions() and updates descriptions.
tests/unit/primitives/test_primitives.py Updates instruction validation tests for root-scoped instructions.
tests/unit/compilation/test_compile_target_flag.py Updates CLI warning expectations for missing applyTo.
tests/unit/compilation/test_compilation.py Updates call sites for new build_conditional_sections(..., base_dir) signature.
tests/unit/compilation/test_claude_formatter.py Updates header expectation to GENERATED_HEADER.
tests/unit/commands/compile/__init__.py Package marker for new compile command tests.
apm.yml Adds repo-root manifest with target: all and compilation.exclude.
.github/workflows/ci.yml Adds Tier 1 step to gate drift via uv run apm compile -t copilot --check.
docs/src/content/docs/reference/cli-commands.md Documents apm compile --check behavior and exit codes.
docs/src/content/docs/reference/manifest-schema.md Documents compilation.exclude semantics and examples.
README.md Adds Dogfooding section describing .apm/ workflow and CI gate.
CONTRIBUTING.md Documents the .apm/ source-of-truth and regeneration workflow.
CHANGELOG.md Adds Unreleased entries for --check, copilot-instructions emission, and hardening fixes.
.gitattributes Marks generated outputs as linguist-generated=true.
.gitignore Gitignores CLAUDE.md outputs while keeping committed Copilot outputs.
AGENTS.md New compiled root AGENTS.md (generated from .apm/ primitives).
.github/copilot-instructions.md New/updated compiled Copilot-native root instructions output.
.github/AGENTS.md Updated compiled AGENTS.md for workflow/CI instructions.
src/apm_cli/AGENTS.md Updated compiled AGENTS.md for CLI module guidance.
src/apm_cli/integration/AGENTS.md Updated compiled AGENTS.md for integrator architecture guidance.
tests/AGENTS.md Updated compiled AGENTS.md for test conventions guidance.
docs/src/AGENTS.md Adds compiled AGENTS.md under docs tree (generated output).
docs/src/CLAUDE.md Adds compiled CLAUDE.md under docs tree (generated output).
.github/instructions/python.instructions.md Removes legacy hand-maintained instruction file (migrated to .apm/).
.github/instructions/encoding.instructions.md Removes legacy hand-maintained instruction file (migrated to .apm/).
.github/instructions/doc-sync.instructions.md Removes legacy hand-maintained instruction file (migrated to .apm/).
.github/instructions/changelog.instructions.md Removes legacy hand-maintained instruction file (migrated to .apm/).
.github/agents/supply-chain-security-expert.agent.md Removes legacy hand-maintained agent file (migrated to .apm/).
.github/agents/python-architect.agent.md Removes legacy hand-maintained agent file (migrated to .apm/).
.github/agents/oss-growth-hacker.agent.md Removes legacy hand-maintained agent file (migrated to .apm/).
.github/agents/doc-writer.agent.md Removes legacy hand-maintained agent file (migrated to .apm/).
.github/agents/doc-analyser.agent.md Removes legacy hand-maintained agent file (migrated to .apm/).
.github/agents/devx-ux-expert.agent.md Removes legacy hand-maintained agent file (migrated to .apm/).
.github/agents/cli-logging-expert.agent.md Removes legacy hand-maintained agent file (migrated to .apm/).
.github/agents/auth-expert.agent.md Removes legacy hand-maintained agent file (migrated to .apm/).
.github/agents/apm-primitives-architect.agent.md Removes legacy hand-maintained agent file (migrated to .apm/).
.github/agents/apm-ceo.agent.md Removes legacy hand-maintained agent file (migrated to .apm/).
.github/agents/agentic-workflows.agent.md Removes legacy hand-maintained agent file (migrated to .apm/).
.apm/instructions/contributing.instructions.md Adds .apm/ source instruction used to generate root copilot instructions.

Comment on lines +15 to +17
- Install in development mode: `cd /path/to/awd-cli && uv run pip install -e .`
- Use absolute path: `/Users/danielmeppiel/Repos/awd-cli/.venv/bin/apm compile --verbose --dry-run`
- Or create alias: `alias apm-dev='/Users/danielmeppiel/Repos/awd-cli/.venv/bin/apm'`
Copy link

Copilot AI Apr 25, 2026

Choose a reason for hiding this comment

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

This contributor instruction includes repo- and machine-specific paths (awd-cli, /Users/.../Repos/...) which won't apply to most contributors and will quickly drift. Suggest replacing with repo-agnostic commands (e.g., uv run pip install -e ., ./.venv/bin/apm ..., or uv run apm ...) and removing personal absolute paths.

Suggested change
- Install in development mode: `cd /path/to/awd-cli && uv run pip install -e .`
- Use absolute path: `/Users/danielmeppiel/Repos/awd-cli/.venv/bin/apm compile --verbose --dry-run`
- Or create alias: `alias apm-dev='/Users/danielmeppiel/Repos/awd-cli/.venv/bin/apm'`
- From the repository root, install in development mode: `uv run pip install -e .`
- Run the CLI from the repo-managed environment with `uv run apm compile --verbose --dry-run`
- Or invoke the virtualenv entrypoint directly with `./.venv/bin/apm compile --verbose --dry-run`

Copilot uses AI. Check for mistakes.
self.assertEqual(instruction.validate(), [])

# Missing applyTo (instruction will apply globally)
# Empty applyTo — root-scoped instructions are now first-class (no warning).
Copy link

Copilot AI Apr 25, 2026

Choose a reason for hiding this comment

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

Non-ASCII punctuation is introduced here (the em dash in the comment). The repo's encoding rule requires all source files (including comments) to stay within printable ASCII to avoid Windows encoding issues. Replace the em dash with ASCII characters (e.g., --).

Copilot uses AI. Check for mistakes.
Comment on lines +292 to +305
actual = p.read_text(encoding="utf-8")
exp = expected.get(p, "")
diff_lines = list(
difflib.unified_diff(
actual.splitlines(keepends=True),
exp.splitlines(keepends=True),
fromfile=str(p),
tofile=str(p) + " (expected)",
n=3,
)
)
for line in diff_lines[:30]:
_rich_echo(line.rstrip("\n"), color="dim")

Copy link

Copilot AI Apr 25, 2026

Choose a reason for hiding this comment

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

In _render_drift_report(), the verbose unified-diff lines are emitted via _rich_echo(), which writes to stdout. That contradicts the documented/implemented contract that the drift report is written to stderr (stdout reserved for future machine-readable output). Consider using click.echo(..., err=True) for diff lines (and/or pass a stderr console to Rich) so the entire report stays on stderr.

Copilot uses AI. Check for mistakes.
Comment on lines 456 to +465
try:
if Path(path).is_absolute():
return Path(path)
else:
return base_path / path
except (OSError, ValueError):
return None

validate_path_segments(
path, context="link target", allow_current_dir=True,
)

return ensure_path_within(base_path / path, base_path)
except (PathTraversalError, OSError, ValueError):
Copy link

Copilot AI Apr 25, 2026

Choose a reason for hiding this comment

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

_resolve_path() currently accepts empty strings because validate_path_segments() defaults to reject_empty=False; Path("") becomes "." so the function resolves to base_path instead of rejecting. This makes markdown links like (or other empty targets) appear to resolve successfully. Add an early guard for empty/whitespace-only input and/or call validate_path_segments(..., reject_empty=True) so empty targets fail closed.

Copilot uses AI. Check for mistakes.
Comment on lines +72 to +76
compiler = AgentsCompiler(".")
config = CompilationConfig(local_only=True, target="all")
result = compiler.preview_all_outputs(config)
assert result == {} or all(v.strip() == "" for v in result.values()) or isinstance(result, dict)
finally:
Copy link

Copilot AI Apr 25, 2026

Choose a reason for hiding this comment

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

This assertion is effectively a no-op because the final disjunct isinstance(result, dict) is always true (preview_all_outputs() always returns a dict). Tighten this test to assert the intended behavior explicitly (e.g., result == {} for an empty project, or assert specific expected keys/values).

Copilot uses AI. Check for mistakes.
Comment thread AGENTS.md
Comment on lines +25 to +31
All source code files and CLI output strings must stay within **printable ASCII** (U+0020–U+007E).

Do NOT use:
- Emojis (e.g. `🚀`, `✨`, `❌`)
- Unicode box-drawing characters (e.g. `─`, `│`, `┌`)
- Em dashes (`—`), en dashes (`–`), curly quotes (`"`, `"`, `'`, `'`)
- Any character outside the ASCII range (codepoint > U+007E)
Copy link

Copilot AI Apr 25, 2026

Choose a reason for hiding this comment

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

This repo's ASCII-only rule is violated in the generated content here (e.g., the en dash in U+0020–U+007E and the emoji examples). If these files are committed and consumed on Windows cp1252 terminals, they can still trigger UnicodeEncodeError. Consider rewriting the examples to be ASCII-only (e.g., refer to codepoints like U+2014 / U+2013 and describe emojis in words) and re-run apm compile to regenerate outputs.

Copilot uses AI. Check for mistakes.
Comment thread AGENTS.md

---
*This file was generated by APM CLI. Do not edit manually.*
*To regenerate: `specify apm compile`*
Copy link

Copilot AI Apr 25, 2026

Choose a reason for hiding this comment

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

The regeneration hint says specify apm compile, but this repository's CLI is apm and the docs/CI in this PR reference apm compile. Update the generated footer wording at the template source so it consistently instructs apm compile (then regenerate the committed outputs).

Suggested change
*To regenerate: `specify apm compile`*
*To regenerate: `apm compile`*

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants