Skip to content

pm init --pm-path skips the runtime-cache .gitignore block (residual #598 gap) → runtime files committed & hard-conflict on every merge #659

Closed

Description

@unbraind

Summary

pm init writes the managed # pm-cli:runtime-cache .gitignore block that protects runtime/, search/, locks/, transactions/, checkpoints/ from source control — but only when the tracker path comes from the default discovery location or the PM_PATH env var. When the tracker path is supplied via the global --pm-path (or its --path alias) flag, no .gitignore block is written at all, so runtime cache files (notably runtime/context-usage.jsonl) get committed and then hard-conflict on every concurrent-branch merge.

This is the residual --pm-path case of the otherwise-fixed #598 ("pm init .gitignore hardcodes .agents/pm/ prefix — custom-root workspaces commit runtime cache and conflict on every merge"). #598's fix now correctly honors PM_PATH and the default path; the --pm-path flag was missed.

This matters because agent-facing guidance (and the recovery messaging added for #501/#592) steers agents toward always passing --pm-path explicitly — so the most-recommended invocation is precisely the one left unprotected.

Environment

  • pm-cli 2026.7.23 (installed from npm @unbrained/pm-cli)
  • Linux, git 2.x, fresh git init -b main

Reproduction

Three fresh git repos, three ways of pointing pm at a tracker:

# VARIANT A — PM_PATH env var  → .gitignore CORRECT
mkdir a && cd a && git init -q -b main
PM_PATH="$PWD/track" pm init rec
cat .gitignore
# => # pm-cli:runtime-cache:start
#    track/runtime/
#    track/search/
#    track/locks/
#    track/transactions/
#    track/checkpoints/
#    # pm-cli:runtime-cache:end   ✅

# VARIANT B — default discovery path  → .gitignore CORRECT
mkdir b && cd b && git init -q -b main
pm init rec
cat .gitignore   # => ignores .agents/pm/runtime/ etc.  ✅

# VARIANT C — --pm-path global flag  → NO .gitignore written  ❌
mkdir c && cd c && git init -q -b main
pm --pm-path "$PWD/.pm" init rec
cat .gitignore   # => file does not exist

Downstream impact (the actual failure)

With the --pm-path tracker committed unprotected, a normal two-agent workflow conflicts on runtime state even though pm merge install is set up correctly:

pm --pm-path "$PWD/.pm" merge install         # wires field-aware drivers incl. ".pm/**/*.jsonl merge=pm-relationship"
ID=$(pm --pm-path "$PWD/.pm" --author base create task --title "Shared" --json | jq -r .id)
git add -A && git commit -qm seed

git checkout -qb agent-a
pm --pm-path "$PWD/.pm" --author agent-a notes "$ID" --add "A" ; git commit -aqm a
git checkout -q main
pm --pm-path "$PWD/.pm" --author agent-b notes "$ID" --add "B" ; git commit -aqm b
git merge agent-a --no-edit
# Auto-merging .pm/tasks/<id>.toon        (field-aware, unions fine)
# Auto-merging .pm/history/<id>.jsonl     (history driver, fine)
# CONFLICT (content): Merge conflict in .pm/runtime/context-usage.jsonl   ❌

context-usage.jsonl is routed to the pm-relationship driver by the .pm/**/*.jsonl pattern, but it is runtime telemetry, not a relationship event store — so the driver cannot union it and it hard-conflicts on every merge. The item and history streams merge cleanly; only the runtime cache (which should never have been tracked) blocks the merge.

Expected

pm init should write the managed runtime-cache .gitignore block using the resolved tracker root, regardless of whether that root came from the default discovery, PM_PATH, or the --pm-path/--path flag. The generated entries for the repro above should be .pm/runtime/, .pm/search/, .pm/locks/, .pm/transactions/, .pm/checkpoints/.

(Defense in depth: pm merge install's .pm/**/*.jsonl merge=pm-relationship pattern also matches runtime/*.jsonl; even if a runtime file slips into history, scoping the relationship pattern to the known event-store subpaths — or excluding runtime/ — would prevent the driver from ever being asked to merge telemetry.)

Suggested fix

Resolve the tracker root once in pm init (the same resolution used to create the directories) and feed that into the .gitignore block generator, instead of branching on default-vs-PM_PATH and skipping the flag case.

Filed by an agent operating a multi-package pm fleet; the --pm-path invocation is our standard convention, so every custom-root workspace hits this.

Activity

  1. coderabbitai commented on Jul 23, 2026

    @coderabbitai
    ⚠️ Possible Duplicate Issue(s)
    🔗 Related PRs

    #142 - Guard pm tracker path targeting for agents [closed]
    #491 - Harden init target safety and package install verification [merged]
    #520 - Harden SDK workspace customization and schema boundaries [merged]
    #593 - SDK-first agent UX graph, ownership, and recovery contracts [merged]
    #614 - SDK-first field-aware merge safety and storage integrity [merged]


    📝 Issue Planner

    Check the box below or use the @coderabbitai plan command to generate an implementation plan and prompts that you can use with your favorite coding assistant.

    • Create Plan

    🧪 Issue enrichment is currently in open beta.

    You can configure auto-planning by selecting labels in the issue_enrichment configuration.

    To disable automatic issue enrichment, add the following to your .coderabbit.yaml:

    issue_enrichment:
      auto_enrich:
        enabled: false

    💬 Have feedback or questions? Drop into our discord!

  2. unbraind commented on Jul 23, 2026

    @unbraind
    OwnerAuthor

    Tracked in pm-hous, the canonical ok: true
    path: "/home/steve/GITHUB_RELEASE/pm-cli/.agents/pm"
    target:
    mode: "workspace-discovery"
    tracker_root: "/home/steve/GITHUB_RELEASE/pm-cli/.agents/pm"
    workspace_root: "/home/steve/GITHUB_RELEASE/pm-cli"
    id_prefix: "pm-"
    governance_preset: "default"
    telemetry:
    enabled: true
    capture_level: "redacted"
    output_format: "toon"
    created_dirs_count: 0
    warnings:

    • "already_exists:/home/steve/GITHUB_RELEASE/pm-cli/.agents/pm"
    • "already_exists:/home/steve/GITHUB_RELEASE/pm-cli/.agents/pm/epics"
    • "already_exists:/home/steve/GITHUB_RELEASE/pm-cli/.agents/pm/features"
    • "already_exists:/home/steve/GITHUB_RELEASE/pm-cli/.agents/pm/tasks"
    • "already_exists:/home/steve/GITHUB_RELEASE/pm-cli/.agents/pm/chores"
    • "already_exists:/home/steve/GITHUB_RELEASE/pm-cli/.agents/pm/issues"
    • "already_exists:/home/steve/GITHUB_RELEASE/pm-cli/.agents/pm/schema"
    • "already_exists:/home/steve/GITHUB_RELEASE/pm-cli/.agents/pm/history"
    • "already_exists:/home/steve/GITHUB_RELEASE/pm-cli/.agents/pm/search"
    • "already_exists:/home/steve/GITHUB_RELEASE/pm-cli/.agents/pm/extensions"
    • "already_exists:/home/steve/GITHUB_RELEASE/pm-cli/.agents/pm/locks"
    • "already_exists:/home/steve/GITHUB_RELEASE/pm-cli/.agents/pm/decisions"
    • "already_exists:/home/steve/GITHUB_RELEASE/pm-cli/.agents/pm/events"
    • "already_exists:/home/steve/GITHUB_RELEASE/pm-cli/.agents/pm/reminders"
    • "already_exists:/home/steve/GITHUB_RELEASE/pm-cli/.agents/pm/milestones"
    • "already_exists:/home/steve/GITHUB_RELEASE/pm-cli/.agents/pm/meetings"
    • "already_exists:/home/steve/GITHUB_RELEASE/pm-cli/.agents/pm/plans"
    • "already_exists:/home/steve/GITHUB_RELEASE/pm-cli/.agents/pm/settings.json"
    • "already_exists:/home/steve/GITHUB_RELEASE/pm-cli/.agents/pm/stories"
    • "updated:gitignore:/home/steve/GITHUB_RELEASE/pm-cli/.gitignore"
      wizard_used: false
      next_steps:
    • "Create your first item: pm create --type Task --title "<title>""
    • "List active items: pm list"
    • "Get agent-friendly project context: pm context"
    • "Add optional packages for richer workflows: pm install calendar --project, pm install templates --project, pm install guide-shell --project"
    • "Or install everything bundled: pm init --with-packages (idempotent on re-run)"
    • "Set PM_AUTHOR= so mutations attribute to the right caller."
      agent_guidance:
      mode: "ask"
      present: true
      prompted: false
      applied: false
      skipped: false
      declined: false
      prompt_completed: false
      template_version: 1
      target_file: "AGENTS.md"
      checked_files:
      • "AGENTS.md"
      • "CLAUDE.md"
        files_with_guidance:
      • "AGENTS.md"
        hint: "Re-run with --verbose for the full settings tree." ignore-ownership lineage. The earlier custom-root bootstrap work is linked there through completed item pm-4uqm; this report captures the remaining runtime-cache ignore case.
  3. unbraind commented on Jul 25, 2026

    @unbraind
    OwnerAuthor

    Fixed and verified. Tracked as pm-hous (canonical init ignore ownership plus health/validate detection and safe index-only remediation) with pm-4uqm covering the custom-prefix half. Verified on 2026.7.25 in a fresh repository: pm init --pm-path $PWD/custom-tracker writes the fenced block with the relocated prefix — custom-tracker/runtime/, custom-tracker/search/, custom-tracker/locks/, custom-tracker/transactions/, custom-tracker/checkpoints/. Closing here to keep the tracker and this issue in sync.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions