agentic-praxis-grimoire

Project-Local APG Skill Projection

Purpose

apg-project-skills manages opt-in Codex project discovery links from a target Git worktree to the nineteen APG v0.3 release skills. It installs, adopts, checks, and removes local symbolic links without copying skill content, changing tracked target files, or modifying user-level Codex or Superpowers state.

ADR 0004 defines the normative ownership, conflict, and rollback design.

ADR 0019 broadens the accepted current release set while retaining version-1 state. New install and adopt default to nineteen; explicit subsets and existing state continue to own only their recorded names. No existing six-skill state is expanded implicitly.

Distribution scopes

Public v0.3.0 is the resulting canonical source for the maintainer’s separately managed user-global Codex integration. Historical v0.2.0 remains a verified six-skill release and compatibility source. The active integration projects the public checkout’s skill directory into the user discovery root. It is distinct from this repository-local command: apg-project-skills owns only opted-in target worktrees and their Git-local state, does not install globally, and does not retarget an existing project-local projection when the global source changes.

A repository may therefore expose the same canonical skill name through its project scope and the user-global scope. Discovery clients own precedence and deduplication behavior. APG must keep the sources and ownership boundaries explicit rather than infer which instance produced an invocation.

Canonical and projected skills

Canonical procedure content remains in the APG checkout:

<apg-root>/skills/<skill-name>/SKILL.md

An opted-in target receives only a symbolic-link projection:

<target-root>/.agents/skills/<skill-name> -> <apg-root>/skills/<skill-name>

Cross-repository links use machine-local absolute targets because the two repositories may be unrelated filesystem siblings. Those paths are local state and must not be copied into public documentation, fixtures, or reports.

Prerequisites

The current verified environment is macOS. The command requires no network, Homebrew package, Nix-only tool, or third-party Python package.

Commands

List the nineteen managed v0.3 release names without a target repository:

<apg-root>/bin/apg-project-skills list

Install every skill in a target:

<apg-root>/bin/apg-project-skills install --repo <target-path>

Install a subset by repeating --skill:

<apg-root>/bin/apg-project-skills install \
  --repo <target-path> \
  --skill <skill-name> \
  --skill <another-skill-name>

Adopt compatible manually created links:

<apg-root>/bin/apg-project-skills adopt --repo <target-path>

Verify all locally managed skills:

<apg-root>/bin/apg-project-skills check --repo <target-path>

Remove selected or all locally managed skills:

<apg-root>/bin/apg-project-skills uninstall \
  --repo <target-path> \
  --skill <skill-name>

<apg-root>/bin/apg-project-skills uninstall --repo <target-path>

When --repo is omitted, Git resolves the worktree containing the current directory. Install and adopt default to all nineteen v0.3 release skills. Check and uninstall default to the valid locally managed set, so an existing six-skill or other explicit subset does not expand implicitly. Unknown names outside the current release set are rejected.

APG19A preserves this exact managed/unmanaged boundary. Its semantic-identity policy and Bats counting correction add no project-lifecycle owner, state field, or managed skill.

APG20A preserves the boundary while adding Go and Ruby as canonical development skills and known-unmanaged names. It changes no managed name, state field, or lifecycle operation.

APG21 preserves the same boundary while adding PostgreSQL and SQLite as canonical development skills and known-unmanaged names. Nix is deferred and is not added. The phase changes no managed name, state field, or lifecycle operation.

APG21A preserves the boundary while adding corrected Nix as one canonical development skill and known-unmanaged name. It changes no managed name, state field, or lifecycle operation.

APG22 preserves the same 17-skill development catalog and six-skill managed project contract. Its read-only RepoMap dogfood and migration proposal do not install, adopt, update, retarget, or remove any target projection. A future target-authorized shadow or cutover must wait for public v0.3 distribution and must prove discovery, non-trigger, project-override, and byte-restorable rollback behavior; APG22 grants no such authority.

APG22A expands private development to 18 skills by adding the provisional approved-roadmap manager-assignment leaf as known unmanaged. The six-skill project lifecycle, version-1 state, target effects, and rollback behavior are unchanged.

APG22B expands private development to 19 skills by adding the provisional, version-bounded ZUnit test profile as known unmanaged. The six-skill managed project contract, version-1 state, target effects, and rollback behavior remain unchanged.

APG22C corrects only the publication-excluded ZUnit compatibility harness and its evidence records. The 19-skill development catalog, six managed project skills, known-unmanaged set, version-1 state, target effects, and rollback behavior remain unchanged. No external target projection is installed, checked, or mutated by the correction.

APG23 changes maturity and readiness records only. The development projection remains nineteen relative links and the managed project contract remains the six stable v0.2 process skills under state version 1. All thirteen v0.3 skills are release-ready, but APG23 installs, checks, or mutates no external target. APG24 owns any future public projection and target-authorized shadow evidence.

APG24 makes all nineteen release-included names available to this lifecycle and retains state version 1. New default installation and adoption use all nineteen. Explicit six-skill and mixed process/profile subsets remain valid. Existing six-skill managed state checks and uninstalls only those six owned links. APG24 performs no implicit real-project expansion and mutates no target repository.

Target effects

The command may create or update only:

<target-root>/.agents/skills/
<target-git-path>/info/exclude
<target-git-path>/info/apg-project-skills-v1

The version-1 JSON state records the physical APG root, physical target worktree, sorted managed names, the empty parent containers the tool created, and one exclusion-preservation flag. It is private Git metadata with mode 0600 in the verified environment. It is the only authority for destructive uninstall.

Git may return one shared info path for linked worktrees. The target-root field prevents a sibling worktree from claiming that state. Version 1 permits only one managed target per shared state path; check or uninstall from the recorded target before enrolling its sibling.

The Git-local exclusion block is exact and narrow:

# BEGIN APG PROJECT SKILLS V1
/.agents/skills/<skill-name>
# END APG PROJECT SKILLS V1

It contains one line per managed projection. The tool preserves unrelated exclude bytes, never edits tracked .gitignore, and does not ignore all of .agents/.

Install, adopt, check, and uninstall

Install creates only missing links and is idempotent when state, links, exclusion, and the effective normal Git status of the complete managed set agree. An exact pre-existing link without ownership state is not silently claimed; use adopt.

Adopt verifies every requested manual link before writing ownership state. Each link must be untracked, resolve to the exact matching current canonical leaf, and expose a readable SKILL.md with the matching frontmatter name. Adopt does not replace or retarget a link. Repeated adopt reports idempotent success only when the complete managed set also remains hidden from normal Git status.

Check is read-only. It validates the complete state schema, source root, canonical leaves, requested membership, exact links, tracked-path absence, exclusion agreement, and normal Git status for managed paths. A compatible manual link without state is not reported as managed. An entirely absent state and APG exclusion block is a compliant uninstalled state for default check.

Uninstall removes only links proven owned by valid local state and still exact at removal time. A selected missing, retargeted, non-symlink, or tracked path stops the operation before any selected link is removed. Subset removal updates state and exclusion. Final removal deletes state and its exclusion block and removes only empty parent directories recorded as tool-created. Unrelated .agents/skills content and manually created parent directories remain.

Successful install, adopt, and uninstall commands remind the operator that a full Codex application restart may be needed before the observed project-skill set changes. The command does not control Codex process lifetime, discovery caching, or plugin state.

Conflict and refusal behavior

The command fails closed on:

There is no --force, automatic repair, broad ignore pattern, or destructive stale-lock recovery. Preserve the reported path, inspect the failed invariant, and restore exact agreement before retrying.

Moving the APG checkout

Managed links and state record the physical APG root. Before moving or removing the checkout:

  1. run check in each managed target;
  2. run uninstall while the recorded APG root remains available;
  3. move the APG checkout;
  4. run install from its new location; and
  5. restart Codex when needed in the observed environment.

If the checkout moved first, restore the old location long enough to perform the proven uninstall. When that is impossible, inspect the local state, each link, and the exact exclusion block before a separately reviewed manual cleanup. Do not fabricate or edit ownership state to make uninstall proceed.

Migrating manually linked repositories

For a repository with existing manual links:

  1. inspect every link and confirm it resolves to the matching current APG leaf;
  2. confirm each link is untracked and no broad tracked ignore rule is required;
  3. run adopt for the intended names;
  4. run check;
  5. verify normal Git status is clean for those paths; and
  6. restart Codex if the application has not refreshed project discovery.

A mismatch is not a migration candidate. Preserve or remove it manually after determining its owner; the APG command will not retarget it.

APG8 records one real-project application of this sequence in RepoMap. Six existing exact manual links were adopted as the default canonical set. Link identity and targets were preserved, pre-existing exact manual exclusion lines remained user-owned and byte-identical outside the new APG block, default and explicit checks passed, and the tracked repository remained unchanged. This is one deployment observation, not a general compatibility or invocation claim.

Troubleshooting and rollback

The ordinary rollback is apg-project-skills uninstall. It removes only proven local ownership and leaves canonical skills, history, evaluations, and global Codex or Superpowers state unchanged.

v0.4 nested-canonical boundary

ADR 0022 and APG30 support source-declared canonical paths for ChatGPT-manager leaves while keeping target discovery names flat. Current-development sources resolve either skills/<name> or skills/chatgpt/<name> from verified source metadata; the command no longer reconstructs a source path from the flat name. Schema-version-1 historical v0.1.0 through v0.3.0 sources retain their direct-child declarations. Focused install, explicit-subset, check, and rollback tests cover both path classes without changing target state format.

Limitations

APG28A adopted test ownership

The project-projection integration owner is mirrored under src/test/int/python/agentic-praxis-grimoire/bin/. It exercises an exact nineteen-skill disposable public-shaped source and real disposable Git targets. The adopted implementation measures copied helpers through direct parallel coverage collection and canonical path equivalence. APG28A adopts this test infrastructure without changing project-skill command or schema behavior.