Skip to content

[BUG] apm install rewrites apm.lock.yaml on every run when project has local .apm/instructions/ + remote APM dep #1702

Description

@AllySummers

Describe the bug

apm install unconditionally rewrites apm.lock.yaml on every run, updating only the generated_at timestamp, when the project has both a local .apm/instructions/ directory and at least one remote APM dependency. No files have changed — remote deps report (files unchanged) — but the lockfile is always dirtied.

This is the third instance of the same pattern:

  • Previously fixed for remote APM deps in PR #456 (closes #450)
  • Previously fixed for MCP deps in PR #1568 (closes #1532)

The <project root> local integration code path appears to unconditionally mark the install as modified, triggering a lockfile rewrite regardless of whether the local file content hashes changed.

To Reproduce

Minimal reproduction repo: https://github.com/AllySummers/apm-generatedat-repro

The repo contains:

  • apm.yml with one pinned remote APM dep and one local .apm/instructions/ file
  • apm.lock.yaml committed from a clean install
git clone https://github.com/AllySummers/apm-generatedat-repro
cd apm-generatedat-repro
apm install
git diff apm.lock.yaml

The diff will show only generated_at has changed. Run apm install again — it changes again. Every run dirties the lockfile.

Trigger conditions (bisected)

Config Lockfile dirtied?
remote APM dep (files unchanged) + local .apm/instructions/ yes
local .apm/instructions/ only (no remote deps) no
remote APM dep only (no local instructions) no
MCP server (already configured) + local .apm/instructions/ no

The bug requires both a remote APM dep and a local instructions directory.

Expected behavior

When no files have changed, apm install should be a no-op:

[i] No changes -- install state already up to date in 0.4s.

git diff apm.lock.yaml should produce an empty diff.

Actual behavior

apm install output:

[>] Installing dependencies from apm.yml...
[i] Targets: claude, copilot, cursor  (source: apm.yml)
  [+] github.com/vercel-labs/agent-skills/skills/react-best-practices#4ec6f84b (cached)
  |-- (files unchanged)
  [+] <project root> (local)
  |-- 2 rule(s) integrated (1 adopted) -> 3 targets

[*] Installed 1 APM dependency in 0.4s.

git diff apm.lock.yaml (only generated_at changes, everything else is identical):

-generated_at: '2026-06-09T03:54:35.441602+00:00'
+generated_at: '2026-06-09T03:54:54.674005+00:00'

Note: [*] Installed 1 APM dependency in 0.4s. — the "1" counted here is the local <project root> entry, not the remote dep (which correctly reported files unchanged).

Environment

  • OS: macOS 26.5.1
  • Python Version: 3.14.5
  • APM Version: 0.18.0 (c393f33)

Additional context

The apm.yml for the minimal repro:

name: apm-generatedat-repro
version: 1.0.0

targets:
  - cursor
  - claude
  - copilot

dependencies:
  apm:
    - vercel-labs/agent-skills/skills/react-best-practices#4ec6f84b61cd3c931046c3e6e398f3ae7de372f7

The single .apm/instructions/coding-conventions.instructions.md:

---
description: General coding conventions
applyTo: 'src/**/*.ts'
---

All TypeScript files must:

- Use named exports (not default exports) for consistency.
- Validate external input with Zod before using it.
- Prefer `const` over `let`; never use `var`.
- Use `async`/`await` over raw Promise chains.

This issue was filed with AI assistance.

Metadata

Metadata

Assignees

No one assigned

    Labels

    type/bugSomething does not work as documented.

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    Status
    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions