29 Commits

Author SHA1 Message Date
7910b8b12c docs(kyberforge): fix path drift and content gaps from apm conversion
The apm conversion (5e23250) moved skills/agents to plugins/<name>/.apm/
and deleted plugin-author/marketplace-author, but a review against issue
#90's Definition of Done found several stale pre-conversion references
left behind by straight git-mv's, plus one real content gap:

- ADR-0014 still documented the old flat vale-prefilter paths in 6
  places, despite ADR-0015 claiming it had been updated.
- ADR-0015 also overclaimed: it said ADR-0014 had both a skills/ and an
  agents/ path regex updated, but ADR-0014 never had an agents/ path
  regex to begin with (its one "agents" mention is a Vale glob-section
  identifier, not a filesystem path). Corrected the wording.
- CONTEXT.md's Skill glossary entry, its Vale-prefilter section, and its
  plugin-author/marketplace-author forward-pointer all still described
  the pre-conversion layout or a "pending issue #90" state that has since
  landed.
- LESSONS.md and two skill test READMEs pointed at skill-author/
  skill-audit/agent-author paths without the .apm/ segment.
- apm-workflow/references/marketplace.md cited plugin-author/SKILL.md's
  Gotchas for the Claude Code reserved plugin-name-prefix list, but that
  list was never actually carried into apm-workflow during the
  conversion despite ADR-0015 claiming it was. Recovered the list from
  git history and inlined it directly rather than leaving a dangling
  citation.
- agent-author/references/deployment-modes.md had an example
  contradicting its own stated .apm/agents/ convention two lines above.

Refs: #90
2026-08-13 07:50:56 +00:00
5e232503c4 feat(kyberforge): execute plugin-to-apm marketplace conversion
Why:
ADR-0015 established that Microsoft APM (apm.yml + .apm/) should replace
this repo's hand-authored plugin.json/marketplace.json model, with those
files becoming compiled output of `apm pack` instead of files edited by
hand via the (now-retired) plugin-author/marketplace-author skills.
Issue #90 was the deferred execution of that decision, gated on #88
(apm tooling) and #89 (apm-native agent-author/skill-author routing).

Implementation notes:
- All six plugins (bin, core, git, gitea, kyberforge, lint) now carry
  apm.yml + .apm/{skills,agents,hooks} as their authoring source. Skills
  moved with a plain git mv (content-identical across targets). Agents
  were re-authored, not moved: per ADR-0016, .apm/agents/*.agent.md
  compiles verbatim to both Claude and Copilot, so plugin-scope agents
  now carry only name/description/model/source_keys -- no tools: field,
  no Claude-only knobs (isolation, maxTurns, effort, memory,
  permissionMode).
- Root apm.yml registers all 7 marketplace packages (6 local plus
  mattpocock-skills as a remote entry) under versioning: per_package,
  matching this repo's existing independent-plugin-versioning practice.
- .claude-plugin/marketplace.json and every plugin's plugin.json are now
  apm-pack-compiled output, verified against the prior hand-maintained
  content: same names/descriptions/versions/licenses/authors, only
  cosmetic serialization differences (JSON key order, owner email vs.
  url, Unicode escaping).
- plugin-author and marketplace-author are retired now that apm-based
  authoring fully replaces their job; kyberforge bumped 1.3.1 -> 1.4.0
  for that removal, and the root marketplace catalog bumped
  0.3.1 -> 0.3.2 to match, per the version-bump convention now
  documented in apm-workflow's reference docs instead of a dedicated
  script (apm has no native version-bump automation).
- Fixed hardcoded pre-.apm/ path assumptions across
  .pre-commit-config.yaml, .pre-commit-hooks.yaml,
  scripts/check-scope-walkup-sync.sh, scripts/sync-vale-styles.sh,
  scripts/check-vale-style-sync.sh, six plugins' root plugin.json
  (stale skills/hooks/agents pointer fields that check-manifests.sh
  validates), and several tests/*.bats and tests/*.sh fixtures --
  including a bats REPO_ROOT relative-path depth bug (10 files, one
  extra .apm/ directory level to walk up) and a vale probe-path
  isolation regression introduced mid-fix.
- Corrected empirically-wrong assumptions surfaced this session in
  apm-workflow/apm-install's own reference docs: `apm marketplace
  package add` does not accept local paths (only owner/repo remote
  shorthand -- local packages are registered by editing apm.yml's
  marketplace.packages[] directly); `apm compile` is a consumer-side
  AGENTS.md/CLAUDE.md generator, not the plugin.json producer, and
  hard-fails on skill/agent-only packages without --clean; `apm plugin
  init <name>` nests a stray subdirectory when run with a positional
  name arg from inside a same-named directory; no native Copilot
  marketplace output profile exists; .mcp.json is merged into the
  compiled plugin.json content-aware and target-scoped, with no
  dependencies.mcp entry needed for simple passthrough; pipx is the
  correct pip fallback on externally-managed Python environments.
- Renamed agent-author's copilot.agent.md template asset to
  copilot.agent.md.template so apm compile's recursive *.agent.md glob
  stops misparsing the placeholder template as a real agent primitive.

Impact:
plugin.json and marketplace.json are compiled artifacts from here on --
editing them by hand is no longer the workflow; edit apm.yml/.apm/ and
run apm pack. CONTEXT.md's Plugin/Plugin marketplace glossary entries
reflect this. ADR-0001 is marked superseded, ADR-0006 moot, and
ADR-0010 updated for the new .apm/agents/ path (project/user scope
unaffected, per ADR-0016). Full local verification: claude plugin
validate --strict on all 6 plugins, apm audit --ci, apm marketplace
check, check-manifests.sh, and the full test suite (165/165 bats,
13/13 shell scripts) all pass clean.

Fixes: #90
Refs: #88, #89
ADR: 0015
ADR: 0016

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ub96PyaSRD9BHPktotj1pC
2026-08-12 18:21:24 +00:00
50d5c30a3c Merge pull request 'feat(kyberforge): retarget forge skills to author/audit APM content' (#93) from feat/89-apm-native-authoring into main
Reviewed-on: https://git.dev.rkdr.net/Defame1297/holocron/pulls/93
Reviewed-by: Defame1297 <gitea@rkdr.net>
2026-08-12 11:48:50 +00:00
eada85db99 docs(kyberforge): document source_keys as 4th apm-agent-allowlist field
field-inventory.md's apm-agent-allowlist and validate.sh's runtime
check already included source_keys as a 4th allowed field, and the
apm-agent.md template already instructed authors to add it for
provenance tracking — but SKILL.md (x2), README.md, ADR-0016, and
deployment-modes.md still described the allowlist as name/description/
model, "nothing else". The template itself even contradicted its own
source_keys guidance with a header claiming "ONLY the three fields
below — full stop" directly above it.

Updates all six locations to document source_keys as the intentional
4th field, resolving the contradiction.
2026-08-12 11:35:33 +00:00
044b2d3f08 fix(kyberforge): fix HOME/git scope-walkup false-FAILs in agent-audit
validate.sh's detect_scope() and validate-provenance.sh's
find_plugin_root() disagreed with new-agent.sh's already-correct,
documented walk-up semantics on three points, each causing validate.sh
to false-FAIL a legitimately-scaffolded project-scope agent pair:

- a marker-less directory walked up into $HOME (no .git/apm.yml of its
  own) was classified as user scope instead of project scope
- the .git-boundary branch returned the walked-to .git location instead
  of the conventional scope root, breaking any <root> that is a
  subdirectory of a larger git-tracked tree (monorepo package dirs)
- the new conventional-root arithmetic introduced to fix the above two
  cases had no guard against non-conventional/hand-placed file paths,
  which could point it at the wrong ancestor

Also adds scripts/check-scope-walkup-sync.sh, a behavioral drift-guard
(per ADR-0014's no-cross-skill-path precedent) that cross-checks the
four independently hand-ported walk-up implementations (validate.sh,
validate-provenance.sh, new-agent.sh, new-skill.sh) against real
fixture scaffolds, wired into .pre-commit-config.yaml at pre-push so
future drift between the ports is caught automatically.

Verified via bash tests/run-tests.sh (13/13) and targeted before/after
reproduction of each bug this closes.
2026-08-12 11:35:23 +00:00
6f6b70781d fix(kyberforge): fix scope walk-up and manifest-parsing bugs from PR #93 review
A fresh /code-review of the APM-native authoring retarget (PR #93) found
several correctness bugs beyond the ones already fixed on this branch:

- new-agent.sh silently walked a marker-less subdirectory under $HOME up
  to user scope, contradicting its own usage text ("user scope is checked
  directly, no walk-up") and risking scaffolding into shared global
  ~/.claude or ~/.copilot directories instead of the intended local path.
- The hand-copied apm.yml type: manifest detector in new-agent.sh and
  new-skill.sh accepted mismatched quotes (e.g. `type: "skill'`) that
  validate.sh's regex correctly rejects, and silently dropped a final
  apm.yml line lacking a trailing newline — causing the scaffolder and
  validator to disagree on scope for identical input.
- Plugin-scope agent frontmatter could still contain the apm-agent.md
  template's HTML comments at ship time with no audit signal, yet
  apm compile copies frontmatter verbatim and <!-- --> breaks YAML
  parsing on both downstream harnesses.
- ADR-0016 asserted agent-audit already implements a SUGGESTION heuristic
  for tool-restriction-needing plugin-scope agents; it doesn't.
- agent-audit/README.md still described the old plugin-pair model this
  PR replaced with a single-file allowlist model.
- validate.sh's project/user-scope CC-only/Copilot-only field checks and
  counterpart-missing check lost their only test coverage when the old
  plugin-pair fixture was deleted.

Also replaces an echo-into-sed two-value parse (4 forks per call) with a
single space-separated echo + read in both scaffolders.

Regression tests added for every fix above, including one for a bug this
pass introduced and the test suite caught: an initial two-line
echo + `read` attempt silently dropped the second value, since `read`
consumes only one line regardless of embedded newlines.

Full suite: 158 bats tests, 39 shell-script tests, 12/12 summary
categories, 0 failures.

Refs: #89, #93
2026-08-11 21:49:38 +00:00
f037d49b5c fix(kyberforge): fix apm-scope validation gaps in agent/skill authoring scripts
Post-implementation review of PR #93 (issue #89's apm.yml-native retargeting
of skill-author/skill-audit/agent-author/agent-audit) found four confirmed
defects across the four scripts' apm.yml `type:` walk-up logic:

- field-inventory.md's apm-agent-allowlist was missing `source_keys`,
  contradicting agent-author/SKILL.md's own instruction (Step 5 checklist)
  to allow it at plugin/APM scope — a correctly-authored file with
  source_keys failed validate.sh.
- validate.sh's APM_TYPE_RE and validate-provenance.sh's TYPE_RE disagreed:
  the former tolerated a quoted `type: "skill"` value, the latter didn't,
  despite agent-audit/SKILL.md explicitly documenting that
  validate-provenance.sh walks up "the same way validate.sh does". Both
  also used `\b` word-boundary matching, which false-matches a malformed
  value like `type: prompts-only` on the `prompts` prefix. Unified both
  regexes to be quote-tolerant and require an exact value.
- All four scripts' `.git` project-boundary check used isdir()/[[ -d ]],
  which misses git worktrees where `.git` is a regular file (`gitdir: ...`)
  rather than a directory. Switched to exists()/[[ -e ]].
- new-agent.sh and new-skill.sh had the same quote-intolerance as above via
  inline `grep -qE` calls (new-skill.sh's also had the `\b` false-match
  bug); replaced both with a shared-shape `is_apm_package_manifest` bash
  helper matching the Python regex's semantics.

Four other findings from the same review turned out not to be bugs: a
bare `plugin.json` no longer signaling plugin scope is documented,
intentional behavior (agent-audit/SKILL.md:30, agent-author/SKILL.md:87),
deferred to issue #90's real plugin.json-to-apm.yml conversion — not
something this fix should reverse.

Verified via direct reproduction of each defect plus the full test suite:
147/147 bats tests, 39/39 shell-script tests, 12/12 summary categories.

Refs: #89
2026-08-11 19:13:26 +00:00
96bc946030 docs(kyberforge): fix provenance chain gap in agent-primitive-schema.md
The file's body cites APM's Python source directly (apm_cli/models/validation.py,
apm_cli/primitives/models.py) to support its "no dedicated Agent validation"
claim, but source_keys only listed context7-microsoft-apm — the apm-github-repo
source_key was missing, and sources.md's apm-github-repo entry didn't list this
file under Contributing files either. The three sibling schema files from the
same commit (prompt/instructions/hooks) all cited both sources correctly.

Found via post-implementation review of issue #89.
2026-08-11 18:34:36 +00:00
ffebdc6584 fix(kyberforge): stop dotfiles-repo $HOME from shadowing user scope in validate.sh
detect_scope() had the same bug class fixed in new-agent.sh (099bdec):
it checked for a .git directory before checking whether it had reached
$HOME, so a dotfiles-managed home directory (yadm, chezmoi bare-repo,
etc.) made validate.sh misresolve to project scope, deriving the
counterpart as ~/.github/agents/<name>.agent.md instead of the correct
~/.copilot/agents/<name>.agent.md and failing with a false "counterpart
file not found". Check the $HOME boundary before the .git check, same
fix shape as 099bdec.

Found via post-implementation review of issue #89.
2026-08-11 18:34:27 +00:00
dc2a41034e fix(kyberforge): remove dead plugin-scope branch from validate.sh
check_file()'s is_plugin_scope param and its plugin-silently-ignored
field check were unreachable dead code left over from the issue #89
restructure: plugin/APM scope now exits via check_apm_agent_file()
before check_file() is ever called, so is_plugin was always False.
Remove the param, its branch, the unused plugin_ignored_fields parse,
the now-stale field-inventory.md section, and the SKILL.md mention.

Found via post-implementation review of issue #89.
2026-08-11 18:21:51 +00:00
099bdec1b2 fix(kyberforge): stop dotfiles-repo $HOME from shadowing user scope
new-agent.sh's walk-up checked for a .git directory before checking
whether it had reached $HOME, so a dotfiles-managed home directory
(e.g. `~/.git` from yadm or a bare-repo checkout) made `new-agent.sh
<name> ~` silently resolve to project scope instead of user scope,
writing .github/agents/ instead of ~/.copilot/agents/. Check the
$HOME boundary before the .git check so it can no longer be shadowed.

Found via post-implementation review of issue #89.
2026-08-11 18:21:44 +00:00
239ea41842 fix(kyberforge): swap plugin.json signals for apm.yml in skill-audit/forge
skill-audit's cross-plugin path check now also recognizes .apm/skills/
<other-skill>/ as a breaking reference shape, alongside the existing
plugins/<plugin>/skills/<other-skill>/ pattern — the APM-native equivalent
of the same cache-isolation problem.

forge.md's Step 4 plugin-version-bump detection switches from "any
directory containing a plugin.json" to the same apm.yml+type: walk-up
used elsewhere in this batch, and hands off to apm-workflow (bump the
single apm.yml version) instead of the deprecated plugin-author.

Refs: #89
2026-08-11 18:05:45 +00:00
675ba40238 feat(kyberforge): restructure agent-audit for plugin-scope apm agents
Validates the new single-file .apm/agents/<name>.agent.md shape agent-author
now produces at plugin/APM scope: frontmatter allowlist (name/description/
model only, from a new apm-agent-allowlist entry in field-inventory.md),
no counterpart derivation, and Pair Consistency dropped from that scope's
report entirely (nothing to pair by design). Adds a plugin/APM-scope-only
SUGGESTION when an agent's description/body implies a tool restriction or
Claude-only behavior the vendor-neutral frontmatter can no longer express
(ADR-0016).

Scope detection in both validate.sh and validate-provenance.sh switches
from a flat plugin.json/.claude-plugin/plugin.json check to a walk-up for
the nearest ancestor apm.yml with a top-level type: field, skipping
type:-less marketplace-only manifests — full switch, no dual-mode fallback
to the old plugin.json signal. validate-provenance.sh's walk-up was fixed
to match validate.sh's (it still used the old plugin.json check, and its
counterpart-merge logic was rewritten to read a single file's source_keys
instead of merging a CC+Copilot pair, since plugin/APM scope has no
counterpart). Project/user scope validation is unchanged in both scripts.

Refs: #89
2026-08-11 18:05:33 +00:00
8cd5c79c0a feat(kyberforge): retarget agent-author to plugin-scope .apm/agents/
Plugin scope now authors a single vendor-neutral .apm/agents/<name>.agent.md
file (name/description/model/body only) instead of a Claude Code + Copilot
CLI pair, per ADR-0016: apm compile has no per-target field integrator, so
tools: and all Claude-only fields (isolation/maxTurns/effort/memory/
permissionMode) are omitted entirely rather than shipping a value that's
guaranteed wrong on one harness. Scope detection switches from a flat
plugin.json check to the same apm.yml+type: walk-up agent-audit's
validate.sh already uses. Project scope and user scope are unaffected —
both keep the existing dual-file pair model.

Refs: #89
2026-08-11 18:05:23 +00:00
922eff3960 feat(kyberforge): retarget skill-author to author into .apm/skills/
Skills now migrate from hand-authored plugin.json to Microsoft APM
(apm.yml + .apm/) per ADR-0015/issue #89. skill-author's write location
switches accordingly: walk up from the destination to the nearest
ancestor apm.yml declaring a type: field (skipping type:-less
marketplace-only manifests) and scaffold into <package-root>/.apm/skills/
<name>/. Standalone authoring (no apm.yml/.git anywhere, e.g.
~/.agents/skills/) is unchanged — only the old plugin.json-based path is
replaced, not standalone mode.

Refs: #89
2026-08-11 18:03:25 +00:00
0dd044a782 docs(kyberforge): add ADR-0016, agent tools-field omitted at plugin scope
#89's grilling session surfaced a real upstream gap: APM's agent
primitive has no per-target compile integrator, so tools: and every
Claude-only field (isolation, maxTurns, effort, memory, permissionMode)
would verbatim-copy into Copilot's file with an incompatible or
unrecognized shape. Omitting them entirely is the only option that
never ships a wrong value to a real harness.

Scoped to plugin-scope agent-author only — project/user scope keep
today's Claude+Copilot pair model unchanged. Partially supersedes
ADR-0005 and ADR-0008's plugin-scope clauses (addenda appended to
both); ADR-0009's field-inventory.md mechanism is unaffected, only
its plugin-scope content shape changes.

Refs: #89
2026-08-11 17:17:32 +00:00
5e296bcfef docs(kyberforge): research all five APM primitive schemas
skill-author/agent-author's #89 retarget needs to know exactly how each
.apm/ primitive compiles to Claude Code and Copilot CLI output. The
existing microsoft-apm corpus only had a full schema for skills and one
minimal example for agents, and nothing for prompts/instructions/hooks.

Deepened via APM's own Python source (not just docs) where prose was
thin. Key finding for #89: agents have no per-target integrator, so
apm compile does a naive verbatim copy to both Claude and Copilot,
unlike prompts/instructions/hooks which each get real per-target
reconstruction. That means the agent primitive's `tools:` field can't
express both harnesses' incompatible vocabularies at once — a real
upstream gap, not something we can schema our way around.
2026-08-11 16:39:54 +00:00
Claude Code AI - Gitea MCP
7a5c50fecc Merge pull request 'feat(kyberforge): add apm-install/apm-workflow/apm-orchestrate, ADR-0015' (#91) from feat/88-marketplace-apm-conversion into main 2026-08-11 16:05:56 +00:00
591b9cccb8 fix(kyberforge): resolve second round of PR #91 review findings
Two review passes on PR #91 (correctness + simplification) found the
prior fixup commit (d6fd9b6) left the deprecation notice it added
half-applied, cited a nonexistent ADR, and introduced/compounded a
few duplicate restatements of the same facts across apm-workflow's
skill files and apm-orchestrate's Hard rules.

- plugin-author/SKILL.md cited ADR-0016 (doesn't exist) instead of
  ADR-0006 for the version-parity invariant.
- The deprecation banner on plugin-author/marketplace-author wasn't
  reflected in their routing `description:` frontmatter, forge's
  routing table, either kyberforge README skill table, or CONTEXT.md
  — now propagated consistently; routing behavior is unchanged since
  issue #90 (repo-wide apm conversion) hasn't landed yet.
- apm-orchestrate's `configure` operation only covered scaffolding a
  new package, not editing an existing apm.yml (e.g. removing a
  marketplace.packages[] entry, which has no dedicated `apm` CLI verb
  and is just a manifest edit). Added `edit-config`, intentionally
  ungated — a local file edit isn't the same class of irreversible
  action as `apm publish`, and normal review already gates the commit.
- Deduplicated facts restated 3-4x across SKILL.md/references/ADR
  boundaries (audit semantics, reserved name prefixes, marketplace-add
  direction, registries precondition), and trimmed configure.md's
  ~55-line apm.yml schema dump — copied near-verbatim from the
  research doc — down to a compact key list with a pointer, matching
  install.md's existing terse cross-referencing style.

Deliberately left as-is: apm-orchestrate's parallel/sequential
fan-out logic stays inline rather than extracted to a shared
reference, since neither git-orchestrate nor gitea-orchestrate need
it yet — premature extraction for a single caller.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0186ERbyACLRuRxPRnqwpa4m
2026-08-11 15:20:46 +00:00
d6fd9b6770 fix(kyberforge): resolve PR #91 review findings in apm docs and orchestrators
Addresses 7 verified findings from the /code-review pass on PR #91's
APM-conversion changes:

- apm-workflow's description omitted install triggers, misrouting
  "install my apm dependencies" requests to apm-install instead
- `apm marketplace check` was listed under both the marketplace and
  audit dispatch rows, breaking the "one reference file per action"
  contract; kept under marketplace.md, its real usage-sequence home
- ADR-0015 claimed apm-workflow docs are generic/repo-agnostic while
  marketplace.md cited this repo's AGENTS.md and git-commits/
  git-remotes skills by name; stripped the holocron-specific
  citations (marketplace.md, compile.md) so the claim now holds
- plugin-author/marketplace-author are superseded per ADR-0015 with
  deletion deferred to #90; added deprecation notices pointing to
  the replacing apm-workflow dispatch actions
- apm-orchestrate/gitea-orchestrate/git-orchestrate all instruct
  dispatch "via Skill" without granting the Skill tool; added it to
  all three
- apm-orchestrate mandated strictly sequential fan-out across
  independent packages with no shared state; relaxed to permit
  parallel dispatch, matching this repo's own subagent-parallelization
  guidance

Refs: #91
2026-08-11 14:22:31 +00:00
92e7ff26aa docs(kyberforge): narrow issue #89 scope, migrate CC platform facts to apm-workflow
A grill-me session determined plugin-author/marketplace-author are fully
superseded by the landed apm-install/apm-workflow/apm-orchestrate artifacts
and will be deleted (not adapted) under issue #90, narrowing issue #89 to
skill-author/agent-author only; forge stays untouched. ADR-0015 is amended
to record this correction plus a three-way content-migration audit.

Claude Code platform-constraint facts that lived only in
plugin-author/marketplace-author (reserved name prefixes, the ADR-0010
agents/ stray-.md validator gotcha, claude plugin validate as a terminal
check, and a removal/re-pack confirm-before-proceeding note) remain true
post-conversion and are migrated into apm-workflow's reference docs via
kyberforge:skill-author, which also updated the skill's README and
sources.md provenance records. Dual-manifest-specific conventions (ADR-0006
parity, CC/Copilot field-placement split) do not carry forward since they
no longer apply.

ADR: 0015
2026-08-11 12:09:43 +00:00
394052ff66 docs(kyberforge): fix remaining PR #91 review findings, add apm install routing
Re-review (comment 24) of fix commit e16c3dc found six new issues, mostly
introduced by that fix commit itself: a dangling reference to a Hard Rule
bullet the same commit deleted (apm-orchestrate.md/.agent.md Process step
2 still named "secret indirection"), and an ADR-0015 Decision bullet that
claimed "this ADR does not update CONTEXT.md" while the same commit had
just added a forward-pointer sentence to CONTEXT.md's Plugin/Plugin
marketplace entries. Both reworded to match what actually happened.

apm-install's APM_INSTALL_DIR escape-hatch example dropped the curl pipe
entirely (`APM_INSTALL_DIR=... sh` with nothing piped into it) — fixed in
both apm-install/SKILL.md and the installation.md research doc, verified
against the upstream Microsoft APM docs via Context7.

Neither apm-workflow nor apm-orchestrate routed to plain `apm install
[PACKAGE_REF]`, the CLI command that actually resolves/fetches
dependencies declared in apm.yml — apm-install only bootstraps the apm
binary/runtime, not per-package deps. Added a 5th "install" dispatch
action to apm-workflow (new references/install.md, SKILL.md table row,
README usage/files sync, sources.md provenance entry) and a matching
"install" operation group on apm-orchestrate so it can route there.

configure.md's apm.yml schema block was also missing the "legacy singular
`target:` CSV form is still accepted" caveat its sibling research doc
documents for the same field — added for consistency.

The sixth finding (paired .md/.agent.md Output-contract disagreement) was
checked against git-orchestrate and gitea-orchestrate's existing pairs and
found to match established repo convention (JSON schema in .md, prose
summary without the enum in .agent.md) — left unchanged as a false
positive rather than "fixed."

kyberforge bumped 1.3.0 -> 1.3.1 via agent-author's normal improve flow.

Refs: #91

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0186ERbyACLRuRxPRnqwpa4m
2026-08-11 11:09:43 +00:00
e16c3dc95f docs(kyberforge): fix PR #91 review findings in ADR-0015 and apm docs
ADR-0015's Decision bullet stated ADR-0001 was superseded as present
fact while Consequences framed it as conditional on issue #90 —
reworded Decision to match, and added a Supersedes header (repo
convention per ADR-0007/ADR-0010) so the pending change is visible
from the title. Also fixed a forward-note that misattributed the
pre-existing .agent.md convention (ADR-0005/0010) to the APM move,
and reworded the rejected-plugins/apm/ rationale to acknowledge the
shipped skills are actually generic rather than repo-specific.

CONTEXT.md's Plugin/Plugin-marketplace glossary entries got a
forward-pointer to ADR-0015 so a session-start read surfaces the
pending manifest-authoring change.

apm-orchestrate.md/.agent.md: removed a Hard Rule requiring ${VAR}
secret indirection that can never fire (the orchestrator has no
Edit/Write tool and never touches apm.yml — apm-workflow's SKILL.md
already owns this rule where content is actually written); removed
compile-manifest-check, an operation with no backing apm CLI command
anywhere in the research docs; added explicit CLI mappings for
add-package/add-marketplace so an executing agent can't invert them.

marketplace.md's release steps shelled out to raw git add/commit/
tag/push — replaced with a pointer to the git-commits/git-remotes
skills per AGENTS.md's "prefer plugin skills over raw shell" rule.

compile.md now states audit runs after compile/pack (audit scans
deployed output, not the source apm.yml) — answers a reviewer
question that had no documented answer.

Refs: #91

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0186ERbyACLRuRxPRnqwpa4m
2026-08-10 21:23:07 +00:00
2305f1c315 chore(config): enable lint plugin in settings
Adds lint@holocron to enabledPlugins so Vale-based prose linting
skills are available in this repo.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0186ERbyACLRuRxPRnqwpa4m
2026-08-10 19:27:34 +00:00
0aa66fe65d feat(kyberforge): add apm-orchestrate agent
Deterministic counterpart to apm-workflow for subagent dispatch,
mirroring git-orchestrate/gitea-orchestrate. Scoped to
configure/marketplace/compile/audit, with fan-out across multiple
packages for the future multi-plugin conversion; apm-install has no
orchestrator counterpart since it's a one-time machine bootstrap.

Bumps kyberforge 1.2.8 -> 1.3.0 (new agent, first in the plugin).
2026-08-10 17:49:12 +00:00
fc69553ba7 feat(kyberforge): add apm-workflow skill
Human-facing dispatch over apm's configure/marketplace/compile/audit
lifecycle, one reference file per concern, gitea-issues-style
dispatch table. apm-install handles the one-time binary/runtime
bootstrap that precedes this loop.
2026-08-10 17:46:03 +00:00
c48c9f5490 feat(kyberforge): add apm-install skill
Wraps apm CLI binary install and agent-runtime setup
(apm runtime setup/list/status/remove), the bootstrap step
ahead of apm-workflow's configure/compile/audit loop.
2026-08-10 17:43:23 +00:00
0e421acdbb docs(adr): add ADR-0015 for outright APM conversion
Records the grill-with-docs decision on issue #88: replace the
hand-authored plugin/marketplace manifest model with Microsoft APM
(apm.yml + .apm/) as this repo's authoring source of truth. The
plugins/<name>/ monorepo-hybrid layout survives; marketplace.json and
provider plugin.json files become compiled output. Supersedes
ADR-0001; touches but does not resolve ADR-0006/0010/0014. Follow-up
work tracked in issues #89 and #90.
2026-08-10 17:42:31 +00:00
1d07d1a76b docs(kyberforge): add Microsoft APM research reference set
Capture Microsoft's Agent Package Manager (APM) — overview, install,
config, CLI reference, registries/marketplace, monorepo shapes,
testing/validation, troubleshooting, and examples — as structured
reference docs under plugins/kyberforge/docs/research/docs/microsoft-apm/.

Lays the groundwork for issue #88 (build agents/skills to execute a
marketplace-to-APM conversion of this repo).
2026-08-10 17:06:07 +00:00
317 changed files with 5506 additions and 3372 deletions

View File

@@ -2,48 +2,57 @@
"description": "AI development skills for Claude Code and GitHub Copilot CLI \u2014 factory, design, implement, review, and cross-cutting workflows.",
"name": "holocron",
"owner": {
"email": "defame1297@rkdr.net",
"name": "Defame1297"
"name": "Defame1297",
"url": "https://git.dev.rkdr.net/Defame1297/"
},
"plugins": [
{
"description": "Skills and agents for creating, maintaining, and managing a Claude Code / Copilot CLI plugin marketplace.",
"name": "kyberforge",
"source": "./plugins/kyberforge"
"source": "./plugins/kyberforge",
"version": "1.4.0"
},
{
"description": "A place for things to be binned",
"name": "bin",
"source": "./plugins/bin"
"source": "./plugins/bin",
"version": "1.1.1"
},
{
"description": "Skills for working with Git \u2014 conventional commits, branch management, pull requests, and feature flow.",
"name": "git",
"source": "./plugins/git"
"source": "./plugins/git",
"version": "1.3.2"
},
{
"description": "Skills for managing Gitea repositories \u2014 issues, pull requests, milestones, releases, and wikis.",
"name": "gitea",
"source": "./plugins/gitea"
"source": "./plugins/gitea",
"version": "1.3.3"
},
{
"description": "Cross-cutting utility skills for everyday AI-assisted coding \u2014 triage, diagnosis, architecture review, and session navigation.",
"name": "core",
"source": "./plugins/core"
"source": "./plugins/core",
"version": "1.1.0"
},
{
"description": "Skills for Real Engineers \u2014 planning, TDD, architecture, and debugging workflows from Matt Pocock's .claude directory.",
"name": "mattpocock-skills",
"source": {
"ref": "v1.2.3",
"repo": "mattpocock/skills",
"source": "github"
"sha": "835450ef244ab7335f75d95b83e7d979eae22a6d",
"source": "github",
"tag_pattern": "v{version}"
}
},
{
"description": "Skills and agents for configuring and running linters.",
"name": "lint",
"source": "./plugins/lint"
"source": "./plugins/lint",
"version": "1.1.5"
}
],
"version": "0.3.1"
"version": "0.3.2"
}

View File

@@ -4,7 +4,8 @@
"core@holocron": true,
"git@holocron": true,
"gitea@holocron": true,
"kyberforge@holocron": true
"kyberforge@holocron": true,
"lint@holocron": true
},
"hooks": {
"PreToolUse": []

View File

@@ -2,48 +2,57 @@
"description": "AI development skills for Claude Code and GitHub Copilot CLI \u2014 factory, design, implement, review, and cross-cutting workflows.",
"name": "holocron",
"owner": {
"email": "defame1297@rkdr.net",
"name": "Defame1297"
"name": "Defame1297",
"url": "https://git.dev.rkdr.net/Defame1297/"
},
"plugins": [
{
"description": "Skills and agents for creating, maintaining, and managing a Claude Code / Copilot CLI plugin marketplace.",
"name": "kyberforge",
"source": "./plugins/kyberforge"
"source": "./plugins/kyberforge",
"version": "1.4.0"
},
{
"description": "A place for things to be binned",
"name": "bin",
"source": "./plugins/bin"
"source": "./plugins/bin",
"version": "1.1.1"
},
{
"description": "Skills for working with Git \u2014 conventional commits, branch management, pull requests, and feature flow.",
"name": "git",
"source": "./plugins/git"
"source": "./plugins/git",
"version": "1.3.2"
},
{
"description": "Skills for managing Gitea repositories \u2014 issues, pull requests, milestones, releases, and wikis.",
"name": "gitea",
"source": "./plugins/gitea"
"source": "./plugins/gitea",
"version": "1.3.3"
},
{
"description": "Cross-cutting utility skills for everyday AI-assisted coding \u2014 triage, diagnosis, architecture review, and session navigation.",
"name": "core",
"source": "./plugins/core"
"source": "./plugins/core",
"version": "1.1.0"
},
{
"description": "Skills for Real Engineers \u2014 planning, TDD, architecture, and debugging workflows from Matt Pocock's .claude directory.",
"name": "mattpocock-skills",
"source": {
"ref": "v1.2.3",
"repo": "mattpocock/skills",
"source": "github"
"sha": "835450ef244ab7335f75d95b83e7d979eae22a6d",
"source": "github",
"tag_pattern": "v{version}"
}
},
{
"description": "Skills and agents for configuring and running linters.",
"name": "lint",
"source": "./plugins/lint"
"source": "./plugins/lint",
"version": "1.1.5"
}
],
"version": "0.3.1"
"version": "0.3.2"
}

View File

@@ -70,6 +70,15 @@ repos:
pass_filenames: false
always_run: true
- id: check-scope-walkup-sync
name: Check scope walk-up implementations agree
description: Behaviorally cross-check validate.sh, validate-provenance.sh, new-agent.sh, and new-skill.sh's independent $HOME/.git/apm.yml walk-up ports against each other
entry: bash scripts/check-scope-walkup-sync.sh
language: system
stages: [pre-push]
pass_filenames: false
always_run: true
- id: check-release-needed
name: Check a release tag covers .pre-commit-hooks.yaml's paths
description: On push to main only, fail if files exposed via .pre-commit-hooks.yaml changed since the last tag
@@ -122,25 +131,25 @@ repos:
description: Enforce agentskills.io's 500-line/5,000-token SKILL.md size ceiling
entry: scripts/skill-size-check.sh
language: script
files: '^plugins/[^/]+/skills/[^/]+/SKILL\.md$'
files: '^plugins/[^/]+/\.apm/skills/[^/]+/SKILL\.md$'
pass_filenames: true
- id: vale-audit-prefilter-skill
stages: ['pre-commit']
name: Vale audit prefilter (SKILL.md)
description: Run Vale against SKILL.md files as a deterministic prefilter for skill-audit, via skill-audit's own bundled copy
entry: plugins/kyberforge/skills/skill-audit/scripts/vale-wrap.sh
entry: plugins/kyberforge/.apm/skills/skill-audit/scripts/vale-wrap.sh
language: script
files: '^plugins/[^/]+/skills/[^/]+/SKILL\.md$'
files: '^plugins/[^/]+/\.apm/skills/[^/]+/SKILL\.md$'
pass_filenames: true
- id: vale-audit-prefilter-agent
stages: ['pre-commit']
name: Vale audit prefilter (agent files)
description: Run Vale against agent markdown files as a deterministic prefilter for agent-audit, via agent-audit's own bundled copy
entry: plugins/kyberforge/skills/agent-audit/scripts/vale-wrap.sh
entry: plugins/kyberforge/.apm/skills/agent-audit/scripts/vale-wrap.sh
language: script
files: '^plugins/[^/]+/agents/[^/]+\.md$'
files: '^plugins/[^/]+/\.apm/agents/[^/]+\.agent\.md$'
pass_filenames: true
- repo: meta

View File

@@ -1,14 +1,14 @@
- id: kyberforge-vale-audit-skill
name: Kyberforge Vale prose audit (SKILL.md)
description: Deterministic prose-pattern prefilter for kyberforge's skill-audit, via its own bundled Vale config/styles
entry: plugins/kyberforge/skills/skill-audit/scripts/vale-wrap.sh
entry: plugins/kyberforge/.apm/skills/skill-audit/scripts/vale-wrap.sh
language: script
files: '(^|/)SKILL\.md$'
- id: kyberforge-vale-audit-agent
name: Kyberforge Vale prose audit (agent files)
description: Deterministic prose-pattern prefilter for kyberforge's agent-audit, via its own bundled Vale config/styles
entry: plugins/kyberforge/skills/agent-audit/scripts/vale-wrap.sh
entry: plugins/kyberforge/.apm/skills/agent-audit/scripts/vale-wrap.sh
language: script
files: '(^|/)agents/[^/]+\.md$|\.agent\.md$'

View File

@@ -22,7 +22,7 @@ Fall back to raw shell only when no skill covers it.
## Setup and testing
- Install git hooks via `git:pc-run`, wiring all three stages — this repo's `.pre-commit-config.yaml` has no `default_install_hook_types`, so a plain install silently skips `commit-msg` (Conventional Commits) and `pre-push` (tests, manifest check).
- Install the `vale` binary — required by the `vale-audit-prefilter-skill`/`-agent` pre-commit hooks, which run on every commit touching a `SKILL.md` or agent `.md` file. Without it the hooks fail with a bare "command not found" and no install pointer. `brew install vale` (macOS), `snap install vale` (Linux), `choco install vale` (Windows), or see https://vale.sh/docs/vale-cli/installation/. No `vale sync` needed — the `Kyberforge` styles are committed under `plugins/kyberforge/skills/{skill-audit,agent-audit}/assets/vale/styles/`, not downloaded packages (see ADR-0014).
- Install the `vale` binary — required by the `vale-audit-prefilter-skill`/`-agent` pre-commit hooks, which run on every commit touching a `SKILL.md` or agent `.md` file. Without it the hooks fail with a bare "command not found" and no install pointer. `brew install vale` (macOS), `snap install vale` (Linux), `choco install vale` (Windows), or see https://vale.sh/docs/vale-cli/installation/. No `vale sync` needed — the `Kyberforge` styles are committed under `plugins/kyberforge/.apm/skills/{skill-audit,agent-audit}/assets/vale/styles/`, not downloaded packages (see ADR-0014).
- Run `bash tests/run-tests.sh` before considering any change done — it runs every `test-*.sh` script in the repo plus the bats suite (`--bats-only` for just bats). First run auto-initializes the bats submodules; no manual `git submodule update` needed.
- Pushing re-runs the full suite plus `scripts/check-manifests.sh` via the pre-push hook — same commands, so run them locally first.
- Author commits with `git:git-commits` — it validates Conventional Commits (enforced at `commit-msg`) for you.

View File

@@ -24,13 +24,13 @@ Before answering any design or architecture question, check for existing decisio
A separate product (separate repo) for browsing, editing, and configuring AI development configs through a proper product UI. Git is the persistence layer, invisible to the user. The app is repo-agnostic — it works with any git repo that follows these conventions. This repo is the canonical default content (the official starter). See `docs/VISION.md` for the phased roadmap.
### Skills
Reusable slash commands for AI coding tools, defined as `SKILL.md` files following the [Agent Skills open standard](https://agentskills.io). Deployed via plugin — `plugins/<plugin-name>/skills/<skill-name>/SKILL.md`, available after the plugin is installed (`claude plugin install <name>@<marketplace>`). Skills are self-contained — they cannot reference files outside the plugin directory after install-time caching.
Reusable slash commands for AI coding tools, defined as `SKILL.md` files following the [Agent Skills open standard](https://agentskills.io). Deployed via plugin — `plugins/<plugin-name>/.apm/skills/<skill-name>/SKILL.md`, available after the plugin is installed (`claude plugin install <name>@<marketplace>`). Skills are self-contained — they cannot reference files outside the plugin directory after install-time caching.
### Plugin
The deployable unit in the plugin marketplace. A plugin bundles one or more skills, agents, hooks, prompts, MCP servers, and optionally a `bin/` directory into a single installable directory. Each plugin has two manifests: `.claude-plugin/plugin.json` (Claude Code) and `plugin.json` at the plugin root (Copilot CLI). Plugins are copied to a cache on install — they cannot reference files outside their own directory. In this repo, plugins live under `plugins/<name>/`. Install a plugin with `claude plugin install <name>@<marketplace>`.
The deployable unit in the plugin marketplace. A plugin bundles one or more skills, agents, hooks, prompts, MCP servers, and optionally a `bin/` directory into a single installable directory. In this repo, plugins live under `plugins/<name>/`, each with its own `apm.yml` + `.apm/{skills,agents,hooks,...}` — this is the authoring source of truth for the plugin's content (ADR-0015). `.claude-plugin/plugin.json` (Claude Code) and `.github/plugin/plugin.json` (Copilot CLI) are **compiled output** of `apm pack`/`apm compile`, generated from `apm.yml` + `.apm/` — they are not hand-edited. Plugins are copied to a cache on install — they cannot reference files outside their own directory. Install a plugin with `claude plugin install <name>@<marketplace>`.
### Plugin marketplace
A Git repository with a `marketplace.json` manifest listing installable plugins. No backend, registry, or SaaS required — the Git repo is the marketplace. This repo is the `holocron` marketplace. The manifest lives at `.claude-plugin/marketplace.json` (read by both Claude Code and Copilot CLI) and is mirrored to `.github/plugin/marketplace.json`.
A Git repository with a `marketplace.json` manifest listing installable plugins. No backend, registry, or SaaS required — the Git repo is the marketplace. This repo is the `holocron` marketplace. The manifest at `.claude-plugin/marketplace.json` (read by both Claude Code and Copilot CLI, mirrored to `.github/plugin/marketplace.json`) is **compiled output** of `apm pack`, generated from the root `apm.yml`'s `marketplace:` block (owner, build/output config, versioning strategy, and the `packages:` list of installable plugins) — it is not hand-edited. See ADR-0015.
### HITL (human-in-the-loop)
Agent pauses before a consequential action; human approves before execution. Required for irreversible or high-stakes actions (architecture changes, production deployments, security configuration). The agent drafts the change plan and waits — it does not proceed autonomously. Contrast with HOTL.
@@ -49,7 +49,7 @@ The provider-agnostic always-on instruction entry point. Two files:
Contains always-on rules in plain markdown with no provider-specific syntax (no `@import`). Provider-specific files (`CLAUDE.md`) are thin adapters that import the relevant `AGENTS.md` and add only Claude Code-specific syntax. This pattern means a single source of truth can serve multiple providers without duplication. See ADR-0003.
### Skill composition
A skill calling another skill by name to delegate a sub-task. The calling skill focuses on the orchestration decision ("when to do X"); the called skill owns the mechanics ("how to do X"). Established compositions: `grill-me` calls `write-adr` when a decision crystallises; `implement-feature` calls `tdd` as its implementation methodology; `forge` calls `grill-with-docs` to refine intent, classifies the target artifact type (skill / agent / plugin / marketplace entry), then routes to the matching `*-author` skill — which owns its own create/improve logic and, where applicable, its own inline audit closeout (`skill-author` runs `/skill-audit`, `agent-author` runs `kyberforge:agent-audit`, both in the same context as the authoring work). Reserve `forge` for genuinely undecided "which artifact type is this" questions — an already-fully-specified corrective edit (exact file, line, and fix already known) should call the target author skill directly instead (`skill-author`, `plugin-author`, `agentsmd-author`, etc.); routing a known fix through `forge`'s grill-and-classify layer adds unnecessary indirection and, in practice, has been observed to lose track of hard constraints handed down the chain (e.g. "don't commit yet," "edit in this worktree") because each hop re-derives instructions from a shorter brief. `forge` additionally runs its own independent recheck after a skill/agent route finishes: a clean-context subagent (not forked, no inherited context) re-runs the same audit skill against the finished artifact, as a distinct verification layer from the author skill's inline audit — the two can share blind spots since the inline audit runs in the same context as the work it checks. If the clean audit surfaces any unresolved finding, `forge` loops — re-invoke the author skill to resolve it, re-run the clean audit — until the clean audit comes back with nothing unresolved; only then is the route done. `plugin-author` and `marketplace-author` have no audit counterpart and get no recheck; their terminal check is `claude plugin validate`.
A skill calling another skill by name to delegate a sub-task. The calling skill focuses on the orchestration decision ("when to do X"); the called skill owns the mechanics ("how to do X"). Established compositions: `grill-me` calls `write-adr` when a decision crystallises; `implement-feature` calls `tdd` as its implementation methodology; `forge` calls `grill-with-docs` to refine intent, classifies the target artifact type (skill / agent / plugin / marketplace entry), then routes to the matching `*-author` skill — which owns its own create/improve logic and, where applicable, its own inline audit closeout (`skill-author` runs `/skill-audit`, `agent-author` runs `kyberforge:agent-audit`, both in the same context as the authoring work). Reserve `forge` for genuinely undecided "which artifact type is this" questions — an already-fully-specified corrective edit (exact file, line, and fix already known) should call the target author skill directly instead (`skill-author`, `plugin-author`, `agentsmd-author`, etc.); routing a known fix through `forge`'s grill-and-classify layer adds unnecessary indirection and, in practice, has been observed to lose track of hard constraints handed down the chain (e.g. "don't commit yet," "edit in this worktree") because each hop re-derives instructions from a shorter brief. `forge` additionally runs its own independent recheck after a skill/agent route finishes: a clean-context subagent (not forked, no inherited context) re-runs the same audit skill against the finished artifact, as a distinct verification layer from the author skill's inline audit — the two can share blind spots since the inline audit runs in the same context as the work it checks. If the clean audit surfaces any unresolved finding, `forge` loops — re-invoke the author skill to resolve it, re-run the clean audit — until the clean audit comes back with nothing unresolved; only then is the route done. `plugin-author` and `marketplace-author` had no audit counterpart and got no recheck; their terminal check was `claude plugin validate`. Both were deprecated per ADR-0015, superseded by `apm-workflow`, and deleted entirely once issue #90 landed.
### Provider-agnostic issue tracker
Skills and workflows reference "linked issue" generically rather than a specific provider. Gitea is the canonical issue tracker for this repo (see ADR-0017). "Issue" is the cross-provider term (GitHub, GitLab, Gitea all use it).
@@ -70,7 +70,7 @@ A companion skill (`core` plugin) that detects a target repo's provider-specific
A standalone, repo-agnostic plugin (`plugins/lint/`) for configuring and running linters — not scoped to kyberforge's own meta-tooling. First linter is Vale (prose style linting), split into two skills per the git/gitea per-concern pattern: `vale-config` (setup — `.vale.ini`, `StylesPath`, styles) and `vale-run` (invoke Vale, interpret/report findings). A `lint-runner` agent composes these for isolated-context lint sweeps; it is report-only (no `Edit` tool) — it flags findings, it does not rewrite prose. Vale's research docs (`docs/research/docs/vale/`) moved from `plugins/kyberforge/` to `plugins/lint/` to keep the provenance chain same-plugin.
### Vale audit prefilter (skill-audit / agent-audit)
Wiring Vale as a deterministic prefilter for `skill-audit`/`agent-audit`'s Description dimension (ADR motivation: issue #84) is repo-specific, not part of the generic `lint` plugin, so it doesn't live in `plugins/lint/` — but per ADR-0014 it also doesn't live at the repo root anymore. Two copies live inside `plugins/kyberforge/`, one per skill, since a plugin's cache-install only copies each skill's own files (no cross-skill sharing): `plugins/kyberforge/skills/agent-audit/assets/vale/` is canonical (`.vale.ini` plus a custom `Kyberforge` style covering description-opener banning ("This skill/agent..."), vague-capability wording ("helps with", "utilize", ...), and generic "see references/ for details" padding — and a `KyberforgeCopilot` style scoped only to `.agent.md` files for the Copilot-only "Use proactively has no effect" check), and `plugins/kyberforge/skills/skill-audit/assets/vale/` is a smaller duplicate (`Kyberforge` only, scoped to `SKILL.md`) kept in sync by `scripts/check-vale-style-sync.sh` (pre-push). A root-level `.pre-commit-hooks.yaml` exposes both copies (plus `skill-size-check`) so any external repo can enforce the same rules via `repo: <this-repo-url>, rev: <tag>` in its own `.pre-commit-config.yaml` — pre-commit clones the pinned rev into its own cache, independent of whether Claude Code or the `kyberforge` plugin is installed at all, and the same mechanism covers CI (`pre-commit run --all-files`). This repo's own `vale-audit-prefilter-skill`/`-agent` pre-commit hooks consume the identical plugin-bundled copies via `repo: local` (not a third root copy, and not a pinned self-reference — a pinned self-reference would lint working-tree edits against the last tagged release rather than the change being made). Every rule is `level: error` and every alert is a FAIL — no ignorable tier, same as shellcheck, the test suite, and conventional-pre-commit. Graded severities do not work here: Vale's exit code keys on `error` alerts alone, so `warning`/`suggestion` rules exit 0 and pre-commit swallows the output of a passing hook, leaving them invisible and blocking nothing. `MinAlertLevel` and `--minAlertLevel` are correspondingly absent from `.vale.ini` and the hook, being no-ops under this model. Vale covers the pattern-matchable sub-checks named in issue #84 (imperative opener, vague filler, `Use proactively`, generic reference-pointer padding) plus, per ADR-0013, one body-wide prose-pattern check ("There is/are" sentence openers) — everything else about body discipline (defaults-vs-menus, why-rationale, non-pattern-matchable judgment calls), near-miss exclusion strength, and control calibration stays LLM judgment.
Wiring Vale as a deterministic prefilter for `skill-audit`/`agent-audit`'s Description dimension (ADR motivation: issue #84) is repo-specific, not part of the generic `lint` plugin, so it doesn't live in `plugins/lint/` — but per ADR-0014 it also doesn't live at the repo root anymore. Two copies live inside `plugins/kyberforge/`, one per skill, since a plugin's cache-install only copies each skill's own files (no cross-skill sharing): `plugins/kyberforge/.apm/skills/agent-audit/assets/vale/` is canonical (`.vale.ini` plus a custom `Kyberforge` style covering description-opener banning ("This skill/agent..."), vague-capability wording ("helps with", "utilize", ...), and generic "see references/ for details" padding — and a `KyberforgeCopilot` style scoped only to `.agent.md` files for the Copilot-only "Use proactively has no effect" check), and `plugins/kyberforge/.apm/skills/skill-audit/assets/vale/` is a smaller duplicate (`Kyberforge` only, scoped to `SKILL.md`) kept in sync by `scripts/check-vale-style-sync.sh` (pre-push). A root-level `.pre-commit-hooks.yaml` exposes both copies (plus `skill-size-check`) so any external repo can enforce the same rules via `repo: <this-repo-url>, rev: <tag>` in its own `.pre-commit-config.yaml` — pre-commit clones the pinned rev into its own cache, independent of whether Claude Code or the `kyberforge` plugin is installed at all, and the same mechanism covers CI (`pre-commit run --all-files`). This repo's own `vale-audit-prefilter-skill`/`-agent` pre-commit hooks consume the identical plugin-bundled copies via `repo: local` (not a third root copy, and not a pinned self-reference — a pinned self-reference would lint working-tree edits against the last tagged release rather than the change being made). Every rule is `level: error` and every alert is a FAIL — no ignorable tier, same as shellcheck, the test suite, and conventional-pre-commit. Graded severities do not work here: Vale's exit code keys on `error` alerts alone, so `warning`/`suggestion` rules exit 0 and pre-commit swallows the output of a passing hook, leaving them invisible and blocking nothing. `MinAlertLevel` and `--minAlertLevel` are correspondingly absent from `.vale.ini` and the hook, being no-ops under this model. Vale covers the pattern-matchable sub-checks named in issue #84 (imperative opener, vague filler, `Use proactively`, generic reference-pointer padding) plus, per ADR-0013, one body-wide prose-pattern check ("There is/are" sentence openers) — everything else about body discipline (defaults-vs-menus, why-rationale, non-pattern-matchable judgment calls), near-miss exclusion strength, and control calibration stays LLM judgment.
Both skills' Step 1, and the `vale-audit-prefilter-skill`/`-agent` pre-commit hooks, call each copy's own `scripts/vale-wrap.sh` rather than `vale` directly — a workaround for a confirmed Vale 3.15.2 limitation (see `vale-config`'s Gotchas): `text.frontmatter.description` silently stops matching on most — not all — multi-line descriptions. Verified by reproduction, not assumed: `>` folded scalars, plain (unquoted) continuation lines, and single- or double-quoted multi-line scalars all yield 0 alerts and exit 0 on a deliberately-bad fixture, while a `|` literal block spanning the same 2+ lines lints normally (alerts fire, exit 1). The wrapper flattens those three broken forms to one physical line in a scratch copy (padding with blank lines so every other line number is unchanged) before handing off to real `vale`; `|` literal blocks and single-line descriptions pass through untouched, already linting correctly. The plain and quoted forms previously passed silently — unflattened and unmatched — so a bad description in either sailed through the prefilter. Handed no `--config` at all, the wrapper falls back to its own sibling `assets/vale/.vale.ini`, located from `${BASH_SOURCE[0]}` rather than from the cwd — which is why both manifests' `entry:` is now the bare script path with no argument after it. pre-commit prefixes only `entry[0]` with the hook-repo clone path (`cmd = (prefix.path(cmd[0]), *cmd[1:])`), so every later argument resolves against the *consuming* repo's root: a `--config` in `.pre-commit-hooks.yaml` pointed at a path no consumer has and hard-failed every external run with `E100 [--config] Runtime error`. `.pre-commit-config.yaml` drops the argument too, deliberately keeping the two entries identical — the local `repo: local` hook resolved its `--config` correctly only because the consuming repo *was* this repo, and that divergence is why three review rounds exercised a path no external consumer takes and missed the defect. An explicit `--config` still wins, in all three argv forms (`--config X`, `--config=/abs`, `--config=rel`), and a relative one still resolves against the caller's cwd, matching bare `vale`, not the repo root. Both audit skills' Step 1 now passes no `--config` either: it resolves the script relative to the skill's own directory so the call works from an installed plugin cache, but a relative `--config` alongside it would still resolve against the cwd, yielding `E100 Runtime error ... does not exist` and exit 2 — which both skills' fallback misreads as "vale unavailable" and silently downgrades to full LLM judgment. `tests/test-vale-wrap.sh` regression-tests this against skill-audit's copy specifically (its fixtures are all `SKILL.md`-shaped, and only skill-audit's `.vale.ini` has that glob section). Each `.vale.ini`'s section globs are path-agnostic (`[**/SKILL.md]` for skill-audit's copy; `[**/agents/*.md]`/`[**/*.agent.md]` for agent-audit's) and do no scoping on their own: Vale's `*` crosses `/`. Scoping comes from each pre-commit hook's own `files:` regex and from the audit skills passing one explicit file per invocation. The two manifests scope differently on purpose: this repo's `.pre-commit-config.yaml` pins its own layout — `^plugins/[^/]+/skills/[^/]+/SKILL\.md$` for `-skill`, `^plugins/[^/]+/agents/[^/]+\.md$` for `-agent` — while the shipped `.pre-commit-hooks.yaml` stays layout-agnostic for external consumers whose skills live anywhere, using `(^|/)SKILL\.md$` and `(^|/)agents/[^/]+\.md$|\.agent\.md$`. Both manifests split the prefilter into two hooks precisely because one combined hook pointed at only one copy would silently 0-file-skip the other file type. A `SKILL.md` outside `plugins/` (e.g. project-scope `.claude/skills/foo/SKILL.md`) still matches `[**/SKILL.md]` and gets linted normally — the globs constrain filename shape, not location. Vale reports 0 files only when the path it is handed matches no glob section at all: a differently-named file, or a directory argument holding nothing that matches. That run prints `✔ 0 errors ... in 0 files.` and exits 0, indistinguishable from a clean pass, so both audits treat a 0-file Vale run as NOT RUN and fall back to full LLM judgment.

View File

@@ -124,7 +124,7 @@ Two forks independently fixed `references/sources.md` with different approaches
## 2026-06-28 — Implementation agents must invoke /skill-author, not write skill files directly
When briefing an agent to implement a new skill, the instinct is to tell it to write the SKILL.md and supporting files directly. This bypasses Step 5 of the skill-author process (provenance), which requires reading all research `sources.md` files and recording every `extracted` slug in META.md. The `validate-provenance.sh` script catches the gap — but only after the commit, requiring a fix round. This pattern recurred twice in one session (plugin-author and marketplace-author initial implementation, then again in the first round of fix agents). Fix: briefs for implementation agents must explicitly say "invoke `/skill-author` (read and follow `plugins/kyberforge/skills/skill-author/SKILL.md`)" — not "write the skill files." Invoking the skill is the only reliable way to ensure all process gates, including provenance, run.
When briefing an agent to implement a new skill, the instinct is to tell it to write the SKILL.md and supporting files directly. This bypasses Step 5 of the skill-author process (provenance), which requires reading all research `sources.md` files and recording every `extracted` slug in META.md. The `validate-provenance.sh` script catches the gap — but only after the commit, requiring a fix round. This pattern recurred twice in one session (plugin-author and marketplace-author initial implementation, then again in the first round of fix agents). Fix: briefs for implementation agents must explicitly say "invoke `/skill-author` (read and follow `plugins/kyberforge/.apm/skills/skill-author/SKILL.md`)" — not "write the skill files." Invoking the skill is the only reliable way to ensure all process gates, including provenance, run.
## 2026-07-05 — Repo root is a bare checkout; work happens in worktrees only

71
apm.yml Normal file
View File

@@ -0,0 +1,71 @@
name: holocron
version: 0.3.2
description: AI development skills for Claude Code and GitHub Copilot CLI — factory, design, implement, review, and cross-cutting workflows.
license: MIT
marketplace:
# apm's Claude marketplace mapper only emits description:/version: into the
# compiled marketplace.json when set explicitly here (an override) — the
# top-level apm.yml description:/version: above are NOT inherited into the
# compiled output despite being used elsewhere (e.g. by `apm audit`).
description: AI development skills for Claude Code and GitHub Copilot CLI — factory, design, implement, review, and cross-cutting workflows.
version: 0.3.2
owner:
name: Defame1297
url: https://git.dev.rkdr.net/Defame1297/
# Default tag pattern used to resolve version ranges for each package.
build:
tagPattern: "v{version}"
# Output targets (map form). 'claude' is enabled by default;
# uncomment 'codex' below to publish the Codex artifact too.
# Each output writes to its profile default path; add 'path:'
# under a key to override.
outputs:
claude: {}
# codex: {}
#
# Note: enabling codex requires every package below to declare
# 'category:' (e.g. category: Productivity).
# CI tip: build one or all formats with a machine-readable manifest:
# apm pack --marketplace=claude,codex --json | jq -r '.marketplace.outputs[].path'
versioning:
strategy: per_package
packages:
- name: kyberforge
description: Skills and agents for creating, maintaining, and managing a Claude Code / Copilot CLI plugin marketplace.
source: ./plugins/kyberforge
version: 1.4.0
- name: bin
description: A place for things to be binned
source: ./plugins/bin
version: 1.1.1
- name: git
description: Skills for working with Git — conventional commits, branch management, pull requests, and feature flow.
source: ./plugins/git
version: 1.3.2
- name: gitea
description: Skills for managing Gitea repositories — issues, pull requests, milestones, releases, and wikis.
source: ./plugins/gitea
version: 1.3.3
- name: core
description: Cross-cutting utility skills for everyday AI-assisted coding — triage, diagnosis, architecture review, and session navigation.
source: ./plugins/core
version: 1.1.0
- name: mattpocock-skills
description: Skills for Real Engineers — planning, TDD, architecture, and debugging workflows from Matt Pocock's .claude directory.
source: mattpocock/skills
version: "^1.2.0"
- name: lint
description: Skills and agents for configuring and running linters.
source: ./plugins/lint
version: 1.1.5

View File

@@ -1,5 +1,16 @@
# Skills are distributed via plugins, not monolithic repo deployment
**Superseded by:** ADR-0015 (Microsoft APM replaces the hand-authored plugin/marketplace model
as this repo's authoring source of truth) and, for plugin-scope agent files specifically,
ADR-0016 (plugin-scope `.apm/agents/*.agent.md` drops provider-specific fields). Since issue
#90's conversion executed, plugin content is authored under `plugins/<name>/apm.yml` +
`.apm/{skills,agents,hooks}/` — not the flat `skills/`/`agents/` layout this ADR describes —
and `.claude-plugin/plugin.json`/`.github/plugin/plugin.json` are compiled output of `apm pack`,
not hand-authored. This ADR's content is kept below as the historical record of the
pre-APM decision; it is no longer the current model.
---
Skills (slash commands) are authored and distributed as part of **plugins** — each plugin contains its own `skills/` directory alongside agents and other artifacts. Plugins are installed via `claude plugin install <name>@holocron` rather than deployed from the repo's local tree. This decision decouples skill authoring cadence from core provider deployments and allows independent versioning per plugin.
## Context

View File

@@ -44,3 +44,8 @@ separate single-provider skill, adding complexity with no benefit.
file now lives at `<plugin-root>/sources.md`, outside the `agents/` directory, because
`claude plugin validate --strict` auto-discovers every `.md` under `agents/` as an agent
requiring frontmatter. See ADR-0010 for the empirical finding and rationale.
**Update (ADR-0016):** the plugin-scope clause above is superseded. Plugin scope is no longer
detected via `plugin.json`, and no longer produces a Claude+Copilot file pair — a directory
containing `apm.yml` now gets a single vendor-neutral `.apm/agents/<name>.agent.md` file with
no provider-specific fields. Project scope and user scope are unaffected. See ADR-0016.

View File

@@ -1,5 +1,18 @@
# version field is present in both plugin manifests
**Moot as of ADR-0015.** This ADR addressed drift risk between two independently
*hand-maintained* manifests. Since issue #90's conversion executed, `.claude-plugin/plugin.json`
and `.github/plugin/plugin.json` are both **compiled output** of `apm pack`, generated in the
same pass from a single `apm.yml` per plugin — there is no longer a second hand-authored file
that could drift out of parity. The invariant this ADR required (`version` present and
identical in both manifests) still holds in the compiled output, but structurally, not because
a skill enforces it: both files are derived from the same `apm.yml` `version:` field, so
divergence is no longer possible by construction. `plugin-author`, the skill that enforced this
invariant, is deleted per ADR-0015 rather than adapted. Kept below as the historical record of
the pre-APM decision.
---
Each plugin has two manifests: `plugin.json` (Copilot CLI) and `.claude-plugin/plugin.json` (Claude Code). Both tools support a `version` field. Prior to this decision, only the CC manifest carried `version`; the Copilot manifest omitted it.
We now require `version` in both manifests, always identical. A reader of `plugin.json` alone should be able to determine the plugin version without consulting the CC manifest. The `plugin-author` skill enforces this invariant on every create, update, and release operation.

View File

@@ -14,3 +14,9 @@
- Scope detection walks up from the input file: first directory containing `plugin.json` → plugin scope; first directory containing `.git` without `plugin.json` → project scope; path under `~` with neither → user scope.
- At user scope the derivation crosses filesystem locations (`~/.claude/agents/` ↔ `~/.copilot/agents/`); the script must handle the home directory case explicitly.
- The invocation signature is the public contract. Changing it is a breaking change to any caller — treat it as such.
**Update (ADR-0016):** the plugin-scope clause above is superseded. Plugin scope is no longer
detected via `plugin.json`, and there is no counterpart to derive — a directory containing
`apm.yml` produces a single `.apm/agents/<name>.agent.md` file, and `agent-audit` validates it
directly with no pair-consistency check. Project scope and user scope keep the pair-derivation
mechanism described above unchanged. See ADR-0016.

View File

@@ -5,6 +5,21 @@ claim that "both files share a single `agents/sources.md` for provenance." The r
ADR-0005 (dual-provider generation, scope detection, single-root script interface) is
unaffected and remains in force.
**Path update per ADR-0016:** at plugin scope, agent files no longer live at
`<plugin-root>/agents/<name>.md`. The authoring source is now
`<plugin-root>/.apm/agents/<name>.agent.md` — a single vendor-neutral file (no dual Claude/
Copilot pair) compiled to both targets via `apm pack`. See ADR-0016 for why (the field-dropping
rationale, `tools:` incompatibility, the compiled-output mechanics) — not restated here. This
ADR's own conclusion is unaffected by that move: the provenance file still belongs at
`<plugin-root>/sources.md`, outside any directory `claude plugin validate --strict`
auto-scans, and `.apm/agents/` is, if anything, further removed from plugin-root than the old
flat `agents/` directory was, so the reasoning below still holds. References below to
`<plugin-root>/agents/` describe the pre-APM layout in effect when this decision was made.
**Scope boundary (per ADR-0016):** this path change is plugin scope only. Project scope
(`.claude/agents/` + `.github/agents/`) and user scope (`~/.claude/agents/` +
`~/.copilot/agents/`) are unaffected — they are not APM packages and keep the dual-file
Claude+Copilot pair model this ADR originally described.
`claude plugin validate --strict` auto-discovers every `.md` file directly under a plugin's
`agents/` directory and treats it as an agent definition requiring YAML frontmatter (`name`,
`description`, etc.). A flat provenance file at `agents/sources.md` — no frontmatter, by

View File

@@ -18,9 +18,9 @@ full LLM judgment every time outside this repo — the exact gap ADR-0013 named
the plugin itself, following the no-cross-skill-path rule already established in
`skill-author/references/deployment-modes.md` (a plugin's cache-install only copies each skill's
own files; there is no plugin-level shared directory). `agent-audit` needs both `Kyberforge` and
`KyberforgeCopilot` (it lints `.agent.md` files), so `plugins/kyberforge/skills/agent-audit/assets/vale/`
`KyberforgeCopilot` (it lints `.agent.md` files), so `plugins/kyberforge/.apm/skills/agent-audit/assets/vale/`
is the canonical, superset copy. `skill-audit` needs a second, smaller copy
(`plugins/kyberforge/skills/skill-audit/assets/vale/`, `Kyberforge` only) since it cannot
(`plugins/kyberforge/.apm/skills/skill-audit/assets/vale/`, `Kyberforge` only) since it cannot
reference agent-audit's copy across the skill boundary. Both skills' Step 1 now resolve
`scripts/vale-wrap.sh`/`assets/vale/.vale.ini` relative to their own directory, the same way
`scripts/validate.sh <skill-dir>` already does — no new resolution mechanism, just applying the
@@ -38,7 +38,7 @@ and gets all three, fully decoupled from Claude Code. CI is the identical `pre-c
**This repo's own dev-time gate** consumes the same plugin-bundled copies instead of a third
root-level copy — per explicit instruction, this repo should be set up like any other consumer
would be, not dogfood a special root-only path. The existing `repo: local` hook is retargeted
(not removed): `entry:` now points at `plugins/kyberforge/skills/{skill-audit,agent-audit}/scripts/vale-wrap.sh`.
(not removed): `entry:` now points at `plugins/kyberforge/.apm/skills/{skill-audit,agent-audit}/scripts/vale-wrap.sh`.
`repo: local` is kept rather than switching to a pinned self-reference
(`repo: <own-url>, rev: <tag>`) — a pinned self-reference would lint working-tree edits against
the *last tagged release*, not the change actually being made, which is wrong for the repo that
@@ -58,7 +58,7 @@ single hook at agent-audit's copy silently scanned 0 SKILL.md files.)
**The hook `entry:` is the wrapper alone; the wrapper self-locates its config.** pre-commit
prefixes only `entry[0]` with the hook-repo clone path (`cmd = (prefix.path(cmd[0]), *cmd[1:])`);
every later argument is handed to the process untouched and so resolves against the *consuming*
repo's root. A `--config plugins/kyberforge/skills/…/assets/vale/.vale.ini` in
repo's root. A `--config plugins/kyberforge/.apm/skills/…/assets/vale/.vale.ini` in
`.pre-commit-hooks.yaml` therefore named a path no consumer has, and every external run died with
`E100 [--config] Runtime error`. The external-consumer contract this ADR exists to establish
cannot be expressed as a `--config` argument at all — the config path has to be derived inside
@@ -105,8 +105,8 @@ doesn't wonder if it was overlooked.
## Consequences
- Root `.vale.ini`, `styles/`, `scripts/vale-wrap.sh` are deleted. Two copies remain:
`plugins/kyberforge/skills/agent-audit/assets/vale/` (canonical, superset) and
`plugins/kyberforge/skills/skill-audit/assets/vale/` (subset, `Kyberforge` only).
`plugins/kyberforge/.apm/skills/agent-audit/assets/vale/` (canonical, superset) and
`plugins/kyberforge/.apm/skills/skill-audit/assets/vale/` (subset, `Kyberforge` only).
- `plugins/kyberforge`'s `plugin.json` and `.claude-plugin/plugin.json` both patch-bump for every
shipped content change (per ADR-0006's version-parity invariant): `1.2.5` for the relocation
itself, `1.2.6` for the self-locating `vale-wrap.sh` that followed.

View File

@@ -0,0 +1,124 @@
# Microsoft APM replaces the hand-authored plugin/marketplace model as this repo's authoring source of truth
**Status: executed (2026-08-12, issue #90).** All six plugins now carry `apm.yml` + `.apm/` as
their authoring source; `.claude-plugin/marketplace.json` and every plugin's `plugin.json` are
`apm pack`-compiled output. **Supersedes ADR-0001** ("Skills are distributed via plugins... each
plugin contains its own `skills/` directory") — in effect.
This repo replaces its hand-maintained Claude Code plugin/marketplace authoring model
(`.claude-plugin/marketplace.json` + per-plugin `plugin.json`) with Microsoft APM (`apm.yml` +
`.apm/`) as the authoring source of truth — an outright replacement of the authoring layer, not an
additive overlay. This ADR records the decision from a `grill-with-docs` session on issue #88.
## Context
Every plugin under `plugins/<name>/` currently ships two hand-maintained manifests
(`.claude-plugin/plugin.json` for Claude Code, root `plugin.json` for Copilot CLI) plus a
hand-maintained root `.claude-plugin/marketplace.json` listing all plugins. Adding a provider means
hand-authoring a third manifest shape; keeping the two existing ones in parity is itself a tracked
concern (ADR-0006).
Research on Microsoft APM (`plugins/kyberforge/docs/research/docs/microsoft-apm/`) found that its
documented "monorepo-hybrid" repo shape maps directly onto this repo's existing `plugins/<name>/`
layout: each plugin becomes its own `apm.yml` + `.apm/{skills,agents,hooks,prompts,instructions}/`
package, listed from a root `apm.yml`'s `marketplace:` block. `apm compile`/`apm pack` generate
per-target output — including a `.claude-plugin/marketplace.json` — from that vendor-neutral
`.apm/` tree, so provider manifests become compiled artifacts instead of hand-authored files, and
new providers (Copilot, Gemini, Codex — all supported by `apm runtime setup`) no longer require a
new hand-maintained manifest format.
## Decision
- **The `plugins/<name>/` monorepo-hybrid directory layout survives.** `.claude-plugin/marketplace.json`
and per-provider `plugin.json` files become **compiled output** via `apm compile`/`apm pack`,
generated from `apm.yml` + `.apm/` per plugin, extensible to other `apm runtime`-supported
providers without hand-maintaining a separate manifest per provider.
- **This supersedes ADR-0001** ("Skills are distributed via plugins... each plugin
contains its own `skills/` directory"). Executed in issue #90: skills and agents physically moved
to `plugins/<name>/.apm/skills/` and `plugins/<name>/.apm/agents/*.agent.md`.
- New operational tooling — `apm-install` (skill), `apm-workflow` (skill), `apm-orchestrate`
(agent) — lands in `kyberforge`, tracked in issue #88
(https://git.dev.rkdr.net/Defame1297/holocron/issues/88).
- Adapting `skill-author`/`agent-author`'s routing to author `.apm/`-native content (retargeting to
`.apm/skills/`, `.apm/agents/` paths — the content these two skills author is still meaningful
post-conversion) is deferred to issue #89
(https://git.dev.rkdr.net/Defame1297/holocron/issues/89). `forge` is out of scope for #89 — it
stays untouched by this whole conversion effort and keeps routing to whatever the live author
skills are at the time.
- **`plugin-author`/`marketplace-author` are not adapted — they are superseded and deleted.**
Unlike `skill-author`/`agent-author`, nothing in these two skills carries forward as authoring
routing: `apm compile`/`apm pack` will generate `.claude-plugin/marketplace.json` and
per-provider `plugin.json` directly from `apm.yml` + `.apm/`, so `apm-install`/`apm-workflow`/
`apm-orchestrate` (issue #88, already landed on this branch) fully replace what these two skills
did. `plugin-author`/`marketplace-author` were deleted in issue #90's execution.
- Translating the existing plugins into `apm.yml` + `.apm/` and running the real conversion was
executed in issue #90 (https://git.dev.rkdr.net/Defame1297/holocron/issues/90, closed).
- `CONTEXT.md`'s "Plugin"/"Plugin marketplace" glossary entries were rewritten in issue #90 to
describe the compiled-output model directly, rather than carrying a forward-pointer to this ADR.
## Considered options
**Additive/compile-layer only, no `apm.yml` (rejected).** Keep `plugin.json`/`marketplace.json`
hand-authored and bolt APM on top as an optional extra. Rejected: doesn't achieve the multi-provider
compile-reuse goal APM's package model provides, and leaves the existing dual-manifest hand
maintenance in place unchanged.
**New standalone `plugins/apm/` plugin (rejected).** `plugins/lint/` was split out of `kyberforge`
specifically because Vale tooling is generic and repo-agnostic, not holocron-marketplace-specific
(see `CONTEXT.md`'s "lint plugin" entry) — the same argument applies to a generic `apm` CLI
wrapper. The shipped `apm-install`/`apm-workflow` skills are, in fact, generic, repo-agnostic APM
CLI documentation with no holocron-specific content, so a standalone `plugins/apm/` would have
been a defensible split on artifact content alone. Rejected anyway, in favor of `kyberforge`,
because holocron is currently the only repo that needs this tooling — standing up a separate
plugin for a single consumer isn't worth it yet. Accepted as an explicit tradeoff (same pattern
as ADR-0011's `gitea-workflow` naming tradeoff) — worth revisiting if this tooling is ever reused
outside holocron's own conversion.
## Content migration out of `plugin-author`/`marketplace-author`
A content audit of `plugin-author`/`marketplace-author` (same `grill-with-docs` session as this
correction) sorted what they document into three buckets:
- **Claude Code platform constraints — carried forward.** Facts that stay true regardless of
authoring model (reserved plugin-name prefixes; the `agents/`-directory stray-`.md`-file
validator gotcha, ADR-0010; `claude plugin validate` as a required terminal check) have been
added into `apm-workflow`'s reference docs, since compiled output still has to satisfy these
constraints post-conversion.
- **Dual-manifest artifacts — obsolete, not carried forward.** Conventions that existed only
because of hand-authored dual manifests (ADR-0006's version-parity/patch-bump rule, the
CC-vs-Copilot field-placement split, dual-file mirroring) are obsolete under `apm.yml`'s
single-manifest model and were deliberately dropped.
- **Holocron policy choice — resolved in #90.** `marketplace-author`'s catalog-version convention
(minor bump for package add/remove, patch bump for field-only updates) isn't an APM mechanic —
`apm` doesn't enforce it, and has no native version-bump automation at all — so rather than
building a new script, the convention is now documented as guidance inside `apm-workflow`'s
reference docs (`references/marketplace.md` for the root catalog version rule,
`references/configure.md` for the per-package version-bump-on-content-edit rule), applied
manually by whoever edits `apm.yml`.
## Consequences
- ADR-0001 is superseded (issue #90).
- ADR-0006 (plugin-version-parity) is moot (issue #90): `plugin.json`/`marketplace.json` are now
compiled output of a single `apm.yml`, so there's no second hand-authored file left to keep in
parity, and `plugin-author` — the skill that enforced ADR-0006 — was deleted rather than adapted
(see "Content migration" above).
- ADR-0010 (agent sources relocated outside agents dir) was updated (issue #90) for agents now
living at `plugins/<name>/.apm/agents/*.agent.md` — the directory path changed; the pre-existing
`.agent.md` extension convention (ADR-0005/ADR-0010) and project/user scope are unaffected, per
ADR-0016.
- ADR-0014 (Vale prefilter ships from the plugin) had its hardcoded `plugins/<name>/skills/...`
paths (the Vale prefilter is skill-scoped only; ADR-0014 never referenced a
`plugins/<name>/agents/...` path) updated for the `.apm/` nesting as part of issue #90's
execution.
- `kyberforge` gained three new artifacts (issue #88) before any conversion of existing content
happened, then lost two (`plugin-author`/`marketplace-author`, deleted once issue #90 verified
parity) — net version bump 1.3.1 → 1.4.0. The root marketplace catalog bumped 0.3.1 → 0.3.2 to
match.
- ADR-0016 (a narrower decision discovered while designing issue #89) turned out to gate how
issue #90 had to re-author plugin-scope agents: `.apm/agents/*.agent.md` compiles verbatim to
both Claude and Copilot, so those files carry only `name`/`description`/`model`/`source_keys` —
existing dual-file `<name>.md`+`<name>.agent.md` pairs could not be raw-moved, only re-authored.
- Two follow-up issues tracked the remaining work, both done: #89 (`skill-author`/`agent-author`
routing adaptation, merged in #93) and #90 (the actual repo conversion, which also deleted
`plugin-author`/`marketplace-author`).

View File

@@ -0,0 +1,92 @@
# Plugin-scope agent-author omits `tools:` and all Claude-only fields from `.apm/agents/*.agent.md`
This ADR is a narrower, downstream consequence discovered while designing issue #89's
implementation under ADR-0015's broader direction (Microsoft APM replaces hand-authored
plugin/marketplace authoring). It does not restate ADR-0015's rationale — see that ADR for
the parent decision.
## Context
APM's agent primitive (`.apm/agents/<name>.agent.md`) has no per-target integrator in
`apm compile` — confirmed via APM's own Python source (`integration/targets.py` and related
files, cited in `plugins/kyberforge/docs/research/docs/microsoft-apm/agent-primitive-schema.md`).
Compilation does a naive verbatim copy of the whole frontmatter and body to both the Claude
Code and Copilot CLI targets. This is unlike:
- The **skill** primitive, which is also a straight copy (confirmed in the same research doc)
but has no field semantics to conflict — `SKILL.md`'s content is target-agnostic already.
- The **prompt**, **instructions**, and **hooks** primitives, which each get real per-target
reconstruction through a dedicated integrator (field allowlisting, key renaming, dropped-field
warnings).
Because the agent primitive ships the same frontmatter unchanged to both harnesses, two
concrete incompatibilities surface:
1. **`tools:`** — Claude Code expects a space-separated tool-name string; Copilot CLI expects a
list drawn from its own alias vocabulary (`execute`/`read`/`edit`/`search`/`agent`/`web`). A
value correct for one harness is wrong for the other.
2. **Claude-only knobs with no Copilot equivalent** — `isolation`, `maxTurns`, `effort`,
`memory`, `permissionMode`. Writing any of these means Copilot's copy carries frontmatter
keys it doesn't recognize at all. Whether Copilot's agent loader ignores unknown keys or
errors on them is unconfirmed by research.
## Decision
At **plugin scope only** (destination package has an `apm.yml` at its root — an APM producer
package compiled via `apm compile`), `.apm/agents/<name>.agent.md` carries only `name`,
`description`, `model`, and the prose body. No `tools:` field, no Claude-only fields, at all.
Absent `tools:` means inherit-all-tools on both harnesses — the one value that is never wrong
on either target, unlike a present, harness-specific value that is guaranteed wrong on at least
one of them.
`agent-audit`, at plugin scope, is intended to flag — as a **SUGGESTION**, not a FAIL, since
this is an upstream schema limitation rather than an authoring mistake — any agent whose
description or body implies a need for tool restriction or a Claude-only behavior the
frontmatter can no longer express. This would give visibility into the gap without pretending
the schema can do something it can't. **Not yet implemented**: `check_apm_agent_file()` in
`validate.sh` currently validates only the field allowlist, `name`, `description`, and
body-emptiness/length — it has no heuristic for this case. Tracked as follow-up work.
### Scope boundary
This decision applies to **plugin-scope `agent-author` only**. Project scope (`.claude/agents/`
+ `.github/agents/`) and user scope (`~/.claude/agents/` + `~/.copilot/agents/`) are not APM
packages — neither goes through `apm compile` — so both keep today's dual-file Claude+Copilot
pair model exactly as ADR-0005 and ADR-0008 already describe. Those two ADRs remain fully
authoritative for project and user scope; only their plugin-scope clauses are affected by this
ADR (see the update notes appended to each).
## Considered options
**Pick one harness's vocabulary and accept breakage on the other (rejected).** E.g. always
write Claude's space-separated `tools:` string. Rejected because it ships a value that is
silently wrong (or possibly a hard error) on Copilot, and which harness "wins" would be an
arbitrary, undocumented asymmetry.
**Same as above, but `agent-audit` flags the cross-harness breakage as a tracked finding
(rejected).** Rejected for the same core reason — it still ships a wrong value to a real
harness. Tracking the breakage doesn't prevent it, and the chosen decision already gets
equivalent visibility (a SUGGESTION finding) without ever shipping the wrong value in the first
place.
## Consequences
- Every plugin-scope APM agent loses per-agent tool restriction and any Claude-only capability
(isolation, maxTurns, effort, memory, permissionMode) until APM ships a real per-target
integrator for the agent primitive. This is a known, accepted regression, not an oversight.
- **ADR-0005 is partially superseded** — its plugin-scope clause ("directory containing
`plugin.json` is plugin scope → both files land in `<root>/agents/`") no longer applies.
Plugin scope is now "directory containing `apm.yml` → single vendor-neutral file lands in
`<root>/.apm/agents/`." Project and user scope, and the rest of ADR-0005, are unaffected.
- **ADR-0008 is partially superseded** — its counterpart-derivation/pair-validation mechanism
no longer applies at plugin scope; `agent-audit` takes the single file directly there. Project
and user scope, where a real pair still exists, are unaffected.
- **ADR-0009 is not superseded.** The mechanism it established — `agent-audit` reading field
lists from `references/field-inventory.md` rather than hardcoding them, with a `source_keys`
provenance chain — survives and is reused. Only the *content shape* changes for plugin scope:
`field-inventory.md` shifts from two side-by-side CC-only/Copilot-only blocklists to one
vendor-neutral allowlist (`name`/`description`/`model`/`source_keys` — the last for provenance
tracking, validated separately by `validate-provenance.sh` against `sources.md`, not a
provider-specific field) for plugin-scope agents, while
continuing to serve its original two-blocklist role for project/user-scope validation.

View File

@@ -1,12 +1,21 @@
{
"author": {
"email": "defame1297@rkdr.net",
"name": "Defame1297",
"url": "https://git.dev.rkdr.net/Defame1297/"
},
"description": "A place for things to be binned",
"displayName": "bin",
"keywords": [],
"license": "MIT",
"mcpServers": {
"obsidian": {
"args": [
"@bitbonsai/mcpvault@latest",
"docs/"
],
"command": "npx",
"type": "stdio"
}
},
"name": "bin",
"version": "1.1.1"
}

11
plugins/bin/.github/plugin/plugin.json vendored Normal file
View File

@@ -0,0 +1,11 @@
{
"author": {
"email": "defame1297@rkdr.net",
"name": "Defame1297",
"url": "https://git.dev.rkdr.net/Defame1297/"
},
"description": "A place for things to be binned",
"license": "MIT",
"name": "bin",
"version": "1.1.1"
}

26
plugins/bin/apm.yml Normal file
View File

@@ -0,0 +1,26 @@
name: bin
version: 1.1.1
description: A place for things to be binned
author:
name: Defame1297
email: defame1297@rkdr.net
url: https://git.dev.rkdr.net/Defame1297/
license: MIT
keywords: []
# Constrains what .apm/ may contain: instructions, skill, hybrid, or prompts
type: skill
# Which agent platforms to deploy to.
# Resolution order: --target flag > this field > auto-detect from filesystem.
# Accepted values: agent-skills, antigravity, claude, codex, copilot, cursor, gemini, grok-build, kiro, opencode, windsurf
targets:
- claude
- copilot
dependencies:
apm: []
mcp: []
includes: auto
devDependencies:
apm: []
scripts: {}

View File

@@ -1,15 +1,12 @@
{
"author": {
"email": "defame1297@rkdr.net",
"name": "Defame1297"
"name": "Defame1297",
"url": "https://git.dev.rkdr.net/Defame1297/"
},
"description": "A place for things to be binned",
"keywords": [],
"license": "MIT",
"mcpServers": ".mcp.json",
"name": "bin",
"skills": [
"skills/"
],
"version": "1.1.1"
}

View File

@@ -18,7 +18,7 @@ git clone https://github.com/bats-core/bats-assert tests/test_helper/bats-assert
Run all tests for this skill (from the repo root):
```bash
bats plugins/core/skills/agentsmd-audit/tests/
bats plugins/core/.apm/skills/agentsmd-audit/tests/
```
## Files

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env bats
setup() {
REPO_ROOT="$(cd "$BATS_TEST_DIRNAME/../../../../../" && pwd)"
REPO_ROOT="$(cd "$BATS_TEST_DIRNAME/../../../../../../" && pwd)"
load "$REPO_ROOT/tests/test_helper/bats-support/load"
load "$REPO_ROOT/tests/test_helper/bats-assert/load"

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env bats
setup() {
REPO_ROOT="$(cd "$BATS_TEST_DIRNAME/../../../../../" && pwd)"
REPO_ROOT="$(cd "$BATS_TEST_DIRNAME/../../../../../../" && pwd)"
load "$REPO_ROOT/tests/test_helper/bats-support/load"
load "$REPO_ROOT/tests/test_helper/bats-assert/load"

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env bats
setup() {
REPO_ROOT="$(cd "$BATS_TEST_DIRNAME/../../../../../" && pwd)"
REPO_ROOT="$(cd "$BATS_TEST_DIRNAME/../../../../../../" && pwd)"
load "$REPO_ROOT/tests/test_helper/bats-support/load"
load "$REPO_ROOT/tests/test_helper/bats-assert/load"

View File

@@ -18,7 +18,7 @@ git clone https://github.com/bats-core/bats-assert tests/test_helper/bats-assert
Run all tests for this skill (from the repo root):
```bash
bats plugins/core/skills/provider-adapter-author/tests/
bats plugins/core/.apm/skills/provider-adapter-author/tests/
```
## Files

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env bats
setup() {
REPO_ROOT="$(cd "$BATS_TEST_DIRNAME/../../../../../" && pwd)"
REPO_ROOT="$(cd "$BATS_TEST_DIRNAME/../../../../../../" && pwd)"
load "$REPO_ROOT/tests/test_helper/bats-support/load"
load "$REPO_ROOT/tests/test_helper/bats-assert/load"

View File

@@ -1,10 +1,10 @@
{
"author": {
"email": "defame1297@rkdr.net",
"name": "Defame1297",
"url": "https://git.dev.rkdr.net/Defame1297/"
},
"description": "Cross-cutting utility skills for everyday AI-assisted coding \u2014 triage, diagnosis, architecture review, and session navigation.",
"displayName": "Core",
"keywords": [
"cross-cutting",
"triage",

18
plugins/core/.github/plugin/plugin.json vendored Normal file
View File

@@ -0,0 +1,18 @@
{
"author": {
"email": "defame1297@rkdr.net",
"name": "Defame1297",
"url": "https://git.dev.rkdr.net/Defame1297/"
},
"description": "Cross-cutting utility skills for everyday AI-assisted coding \u2014 triage, diagnosis, architecture review, and session navigation.",
"keywords": [
"cross-cutting",
"triage",
"diagnose",
"architecture",
"debug"
],
"license": "MIT",
"name": "core",
"version": "1.1.0"
}

32
plugins/core/apm.yml Normal file
View File

@@ -0,0 +1,32 @@
name: core
version: 1.1.0
description: Cross-cutting utility skills for everyday AI-assisted coding — triage, diagnosis, architecture review, and session navigation.
author:
name: Defame1297
email: defame1297@rkdr.net
url: https://git.dev.rkdr.net/Defame1297/
license: MIT
keywords:
- cross-cutting
- triage
- diagnose
- architecture
- debug
# Constrains what .apm/ may contain: instructions, skill, hybrid, or prompts
type: skill
targets:
- claude
- copilot
# "auto" publishes the authoritative local source layout, or list explicit
# repo paths to define the complete publication set.
includes: auto
dependencies:
apm: []
mcp: []
devDependencies:
apm: []
scripts: {}

View File

@@ -1,10 +1,10 @@
{
"author": {
"email": "defame1297@rkdr.net",
"name": "Defame1297"
"name": "Defame1297",
"url": "https://git.dev.rkdr.net/Defame1297/"
},
"description": "Cross-cutting utility skills for everyday AI-assisted coding \u2014 triage, diagnosis, architecture review, and session navigation.",
"hooks": "hooks.json",
"keywords": [
"cross-cutting",
"triage",
@@ -13,10 +13,6 @@
"debug"
],
"license": "MIT",
"mcpServers": ".mcp.json",
"name": "core",
"skills": [
"skills/"
],
"version": "1.1.0"
}

View File

@@ -3,8 +3,6 @@ name: git-orchestrate
description: Orchestrates git workflow operations for other agents. Invoke when a caller needs a multi-step or destructive git operation (rebase, force-push, branch deletion) coordinated across domain skills with safety gates, session context, and structured results.
tools: ["execute", "read", "edit"]
source_keys:
- context7-git-htmldocs
- git-scm-docs
@@ -12,7 +10,6 @@ source_keys:
- git-scm-submodule-docs
- git-scm-remote-docs
- conventional-commits-spec
---
You are the orchestrator for the git plugin—a composable workflow dispatcher designed for other agents to invoke multi-step git operations reliably. Your one job is routing and safety-gating: you do not execute git logic yourself, you delegate to domain skills and enforce confirmation on destructive operations.
@@ -44,7 +41,7 @@ Sub-skills carry their own local copies of these rules for humans who invoke the
When invoked, you:
1. Parse the incoming workflow request (operation type, parameters, context overrides)
2. Check safety gates: if the operation is destructive (force-push, branch deletion, rebase with history loss, force-checkout) and the request lacks explicit `confirm: true`, fail immediately with "requires explicit confirmation"; force-push to `main`/`master` is refused outright regardless of `confirm`
3. Route to the appropriate domain skill: git-commits, git-branches, git-history, git-submodules, git-worktrees, git-remotes
3. Route to the appropriate domain skill: `git-commits`, `git-branches`, `git-history`, `git-submodules`, `git-worktrees`, `git-remotes`
4. Manage session context: carry forward the current branch, workflow intent, and configuration, passing explicitly to each skill
5. Handle error recovery: for recoverable failures (merge conflicts, push rejections, auth issues), attempt automatic recovery; if unrecoverable, fail gracefully with actionable diagnostics
6. Aggregate results and return structured JSON output suitable for agent chaining
@@ -67,11 +64,27 @@ When invoked, you:
2. Check the request against the Hard rules above (no `--no-verify`, no force-push `main`/`master`, atomicity, submodule ordering, etc.) — refuse outright on violation, independent of `confirm`
3. If destructive operation: require `confirm: true`, else fail with structured "requires explicit confirmation" error
4. Read plugin config from `.claude/plugins/git/config.json` if present — see `config.example.json` in the plugin root for the expected shape (`branching_pattern`, `commit_style`, `rebase_strategy`) — or fall back to sensible defaults
5. Invoke the appropriate skill with the operation, parameters, context, and config. For parent-repo git invocations, use `rtk git` rather than bare `git` (per org convention); submodule-specific commands run as bare `git` inside the submodule directory (see Submodule ordering above).
5. Invoke the appropriate skill via `Skill` or direct bash call with the operation, parameters, context, and config. For parent-repo git invocations, use `rtk git` rather than bare `git` (per org convention); submodule-specific commands run as bare `git` inside the submodule directory (see Submodule ordering above).
6. Catch and handle git errors: attempt automatic recovery (offer rebase strategies for conflicts, suggest `--force-with-lease` for rejections)
7. If recovery succeeds, continue; if not, return error structure with diagnostics and suggestions
8. Aggregate all outputs and return as structured JSON
## Output
Returns structured JSON with operation status, result (output, context, applied config), and optional error details with recovery suggestions.
```json
{
"status": "success" | "error",
"operation": "<operation_name>",
"result": {
"output": "<command output or result>",
"context": { "current_branch": "...", "workflow_intent": "..." },
"applied_config": { "commit_style": "...", "rebase_strategy": "..." }
},
"error": {
"message": "<human-readable error>",
"code": "<error type: conflict | auth_failure | push_rejection | invalid_state>",
"recovery_attempted": true | false,
"suggestions": ["<suggestion1>", "<suggestion2>"]
}
}
```

Some files were not shown because too many files have changed in this diff Show More