For each sync target in manifest:
Claude format (CLAUDE.md)
<!-- Synced from .context-index/constitution.md by adev. Do not edit above the User Additions line. -->
[Full constitution content]
## Context Index
This project uses the Agentic Development Framework (adev).
- Constitution: `.context-index/constitution.md`
- Manifest: `.context-index/manifest.yaml`
- Platform: [summary from platform-context.yaml]
- Available skills: [enumerate every skill under the plugin's `skills/` directory as a comma-separated `/adev:<name>` list โ do not hardcode a subset, since the set grows; append "(see `docs/skill-reference.md`)" when that file exists]
## Task Management (conditional)
<!-- BEGIN TASK MANAGEMENT -->
[Read `tasks.backend` from manifest.yaml. If configured:
- Include the Task Management section from constitution.md.
- If tasks.backend is "beads", include br command reference.
- If tasks.backend is "json" (the default), reference the board at
`.context-index/tasks/tasks.json` (rendered to a readable board on demand).
- If tasks.backend is "file", include the legacy `.context-index/tasks/tasks.md` reference.
- If constitution has no Task Management section, generate from
the default content matching the configured backend.
If tasks.backend is NOT configured in the manifest, omit this
entire section (no empty block, no placeholder).]
<!-- END TASK MANAGEMENT -->
## Learned Lessons (conditional โ see step 3)
# User Additions
<!-- Content below is preserved across syncs. Add Claude-specific instructions here. -->
[preserved content from previous CLAUDE.md below this marker]
OpenCode / Generic agents format (AGENTS.md)
<!-- Synced from .context-index/constitution.md by adev. -->
[Full constitution content]
## Project Context
This project uses the Agentic Development Framework (adev).
- Constitution: `.context-index/constitution.md`
- Manifest: `.context-index/manifest.yaml`
- Platform: [summary from platform-context.yaml]
- Available skills: [enumerate every skill under the plugin's `skills/` directory as a comma-separated `/adev:<name>` list โ do not hardcode a subset, since the set grows; append "(see `docs/skill-reference.md`)" when that file exists]
## Task Management (conditional)
<!-- BEGIN TASK MANAGEMENT -->
[Same logic as Claude format: include if tasks.backend is configured, omit otherwise.]
<!-- END TASK MANAGEMENT -->
Copilot format (.github/copilot-instructions.md + .github/instructions/<module>.instructions.md)
The Copilot format is produced by syncCopilot(...) from <ADEV_ROOT>/lib/sync/copilot.mjs. Do NOT hand-render Copilot artifacts in this skill โ invoke the dispatcher directly so the documented byte caps (4,000 UTF-8 bytes for the repo-wide projection), SHA-256 tamper-evidence pointer, dangerous-pattern guardrail, slug/path validation, and <path>.tmp + fsyncSync + renameSync atomic-write contract are enforced uniformly.
Two artifacts are emitted per run:
.github/copilot-instructions.md โ plain markdown projection of the constitution's ## Identity (never dropped) + ## Non-Negotiable Principles (overflow-trimmed tail-first to fit the 4,000-byte cap) + a trailing <!-- Source: .context-index/constitution.md @ sha256:<16-hex>. Run /adev:sync to refresh. --> comment.
.github/instructions/<module>.instructions.md โ one file per registered module in manifest.yaml:modules[] that has a corresponding charter.md. Each carries YAML frontmatter with applyTo as a double-quoted comma-joined glob list and a description derived from the module name.
Invocation contract (Node usage; the corresponding CLI verb is adev sync โ see API reference below):
import { syncCopilot } from '<ADEV_ROOT>/lib/sync/copilot.mjs';
const summary = syncCopilot({
projectRoot,
manifest,
constitutionText,
charters,
dryRun: false,
});
The dispatcher returns warnings under stable codes (SYNC_OVERFLOW, MODULE_NO_CHARTER, SYNC_PATHS_EMPTY, CHARTER_INCOMPLETE, CHARTER_TOO_LARGE) and throws on fatal conditions (MALFORMED_SYNC_TARGETS, MANIFEST_TOO_LARGE, CONSTITUTION_TOO_LARGE_TO_PARSE, TOO_MANY_MODULES, TOO_MANY_PATHS, INVALID_MODULE_SLUG, INVALID_MODULE_PATH, CONSTITUTION_TOO_LARGE, CONSTITUTION_DANGEROUS_PATTERN, CONSTITUTION_STRUCTURE_INVALID, SYNC_PATH_ESCAPE). Pass each warning into the sync summary under the copilot: block (see step 5).
The Copilot format does NOT touch .github/skills/, .github/hooks/, or .github/.adev-copilot-install.json โ those paths belong to the Copilot adapter (/adev:install --target copilot), not the sync skill.
Cursor format (.cursor/rules/adev.mdc)
Pointer projection of .context-index/constitution.md โ NOT a duplicate of it. Cursor 2.5+ reads always-apply rules from .cursor/rules/*.mdc; adev owns exactly one file under that directory (adev.mdc). Any pre-existing sibling files in .cursor/rules/ MUST NOT be read, modified, or deleted by this writer.
Output path: .cursor/rules/adev.mdc is the default emitted by the setup-charter scaffold (see cli/index.mjs::handleDualSyncTargets). Users may override path: per manifest entry; the format's writer always assumes .mdc extension and Cursor Rules semantics regardless of path.
File composition (in this order):
---
description: <single-line summary; trimmed; โค 200 characters; no embedded newlines>
alwaysApply: true
---
<pointer body โ body word count โค 200 (frontmatter excluded)>
# User Additions
<preserved content from the prior file, if any>
- Frontmatter: YAML block with exactly two keys โ
description (string) and alwaysApply (literal boolean true, not the string "true"). The frontmatter is owned by adev and rewritten wholesale on each sync.
- Pointer body: MUST NOT duplicate the constitution. It directs the reader to
.context-index/constitution.md for the source of truth. The body MAY include: (a) the project identity sentence, (b) a one-line note that non-negotiable principles live in the constitution, (c) the relative path to .context-index/constitution.md, (d) a short pointer to CLAUDE.md and AGENTS.md for sibling agent-file projections.
- Body word count cap: โค 200 words. Count is the number of whitespace-delimited tokens between the frontmatter closing
--- and the # User Additions marker (or EOF when the marker is absent). The ## Learned Lessons heading is excluded from the count; blank lines and the # User Additions heading itself are excluded.
- Body oversize (
CURSOR_BODY_OVERSIZE): if the composed body exceeds 200 words, the writer throws CURSOR_BODY_OVERSIZE carrying the actual count, removes any sibling .tmp file, and writes NO .cursor/rules/adev.mdc. Cursor's always-apply guidance is the reason this limit exists โ the failure is loud by design.
- User Additions preservation: the existing
# User Additions protocol applies verbatim (step 4 below). User Additions are trusted as user-authored content reviewed at edit time, not at sync time โ this matches the established CLAUDE.md/AGENTS.md trust model and is not a new attack surface introduced by this format.
- Sibling-file non-interference: the writer reads and writes only
.cursor/rules/adev.mdc and its .cursor/rules/adev.mdc.tmp sibling. Any other file under .cursor/rules/ is untouched (read or write).
- Atomic write: compose the full content in memory, write to
.cursor/rules/adev.mdc.tmp, then rename to .cursor/rules/adev.mdc. On any thrown error before the rename, unlink the .tmp file before re-raising.
- Dry-run:
/adev:sync --dry-run prints the proposed content (frontmatter + body) and the diff against the existing file (or "new file" when absent); no write occurs.
Body-composition algorithm (reproducible):
description derivation order โ trim the result; strip embedded newlines; cap at 200 characters; the value MUST fit on a single YAML line.
- First H2 heading of
.context-index/constitution.md (heading text without the ## prefix).
- Fallback: the constitution's "Identity" sentence (line 8 in the canonical template at
templates/constitution-template.md).
- Hard fallback:
manifest.yaml :: project.name.
alwaysApply value โ emit the literal YAML boolean true (not the string "true"). Parsers MUST see typeof alwaysApply === "boolean".
- Pointer body structure โ five lines in this order:
- Line 1: project identity sentence (single line, sourced from the constitution's Identity section).
- Line 2: blank.
- Line 3: pointer paragraph โ "Non-negotiable principles, coding standards, and architecture boundaries live in
.context-index/constitution.md โ see that file for the source of truth."
- Line 4: blank.
- Line 5: sibling pointer โ "Companion projections:
CLAUDE.md (Claude Code), AGENTS.md (OpenCode/Codex)."
- Body word-count rule โ sum the whitespace-delimited tokens between the frontmatter closing
--- and the # User Additions marker (or EOF when the marker is absent on first write). Blank lines, the ## Learned Lessons heading, and the # User Additions heading itself are excluded from the count.
- Atomic write protocol โ compose the full content (frontmatter + body + optional
## Learned Lessons + # User Additions block) in memory. Word-count the body before any write. If the count exceeds 200, throw CURSOR_BODY_OVERSIZE carrying the actual count and do NOT create the .tmp file (or if it was speculatively created, unlink it before re-raising); no .cursor/rules/adev.mdc is written. Otherwise, write the bytes to .cursor/rules/adev.mdc.tmp and rename to .cursor/rules/adev.mdc. On any thrown error after the .tmp write but before the rename, unlink the .tmp and re-raise.
- Sibling-file non-interference (SA-1) โ the writer's filesystem surface is exactly two paths:
.cursor/rules/adev.mdc and .cursor/rules/adev.mdc.tmp. The writer MUST NOT read, modify, or delete any other file under .cursor/rules/.