Repository navigation
Added local and targeted source artifacts and read every source through one catalog - #64
Conversation
…md and shared-path warnings
There was a problem hiding this comment.
🟡 Changes recommended
Local artifacts outside the content directory or already tracked by Git can still be committed, violating the clone-local guarantee.
2 open findings
What changed in this PR
Implements decision 0021 by adding clone-local and adapter-targeted artifacts through a unified source catalog.
Changes:
- Adds local artifact naming, target filters, collision checks, and routing.
- Updates every built-in adapter and shared source renderer.
- Adds documentation, tests, and the 0.21.0 version bump.
| File | Description |
|---|---|
README.md |
Documents local rules. |
packages/sync/skills/intelligence-update-context/references/rules.md |
Adds local-rule guidance. |
packages/sync/skills/intelligence-review-context/references/audit-checks.md |
Updates machine-fact remediation. |
packages/sync/skills/intelligence-learn-from-repository/SKILL.md |
Migrates local guidance into local rules. |
packages/sync/rules/intelligence-authoring.md |
Documents targeting and locality. |
packages/sync/references/onboarding-migration.md |
Updates migration destinations. |
packages/sync/references/conventions.md |
Defines names, locality, and targeting. |
packages/sync/references/adapters.md |
Documents catalog-based adapter rendering. |
intelligence/skills/dev-build-adapter/SKILL.md |
Requires catalog-based enumeration. |
intelligence/rules/engine.md |
Records engine catalog invariants. |
intelligence.yaml |
Bumps schema and sync package. |
intelligence.lock |
Updates locked engine/package versions. |
examples/with-remote-skills/intelligence.yaml |
Bumps example version. |
examples/platform-with-submodules/intelligence.yaml |
Bumps example version. |
examples/platform-with-submodules/intelligence.lock |
Updates example lock. |
examples/go-api/intelligence.yaml |
Bumps example version. |
examples/go-api/intelligence.lock |
Updates example lock. |
examples/go-api-with-pi-and-codex/intelligence.yaml |
Bumps example version. |
examples/go-api-with-pi-and-codex/intelligence.lock |
Updates example lock. |
examples/go-api-with-opencode/intelligence.yaml |
Bumps example version. |
examples/go-api-with-opencode/intelligence.lock |
Updates example lock. |
examples/go-api-with-antigravity/intelligence.yaml |
Bumps example version. |
examples/go-api-with-antigravity/intelligence.lock |
Updates example lock. |
examples/dotnet-api-with-react-frontend/intelligence.yaml |
Bumps example version. |
examples/dotnet-api-with-react-frontend/intelligence.lock |
Updates example lock. |
examples/cli-project/intelligence.yaml |
Bumps example version. |
engine/VERSION |
Bumps engine to 0.21.0. |
engine/sync.sh |
Adds catalog preflight and policy checks. |
engine/lib/common.sh |
Implements the source catalog and routing. |
engine/adapters/pi.sh |
Adds targeted Pi rule delivery. |
engine/adapters/opencode.sh |
Uses catalog-filtered sources. |
engine/adapters/cursor.sh |
Adds targeted always-on rules. |
engine/adapters/copilot.sh |
Adds targeted instruction files. |
engine/adapters/codex.sh |
Manages AGENTS.override.md. |
engine/adapters/claude.sh |
Uses catalog names and filters. |
engine/adapters/antigravity.sh |
Adds always-on rule routing. |
engine/adapters/agents.sh |
Applies catalog overrides to AGENTS.md. |
engine/adapters/_template.sh |
Updates adapter scaffolding guidance. |
docs/cli.md |
Documents CLI behavior and checks. |
decisions/0021-local-and-targeted-source-artifacts.md |
Records the architecture decision. |
cli/tests/verify.sh |
Registers the new E2E suite. |
cli/tests/unit-gitignore.sh |
Tests local ignore patterns. |
cli/tests/unit-engine.sh |
Tests catalog and target behavior. |
cli/tests/e2e-store-sha.sh |
Aligns fixture ignore policy. |
cli/tests/e2e-packages.sh |
Aligns fixture ignore policy. |
cli/tests/e2e-negative.sh |
Aligns fixture ignore policy. |
cli/tests/e2e-local-artifacts.sh |
Adds end-to-end feature coverage. |
cli/tests/e2e-compat.sh |
Aligns compatibility fixtures. |
cli/lib/gitignore.sh |
Generates local artifact patterns. |
cli/internal/check.sh |
Checks local Git policy. |
cli/commands/init.sh |
Installs local ignore patterns. |
CHANGELOG.md |
Records the 0.21.0 release changes. |
.gitignore |
Ignores repository-local artifacts. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Code review - PASS-WITH-WARNINGShead: a35c698 - base: main - files 53, +2332/-617 Critical(none) Warning
Suggestion(none) Notes
|
Verification - PASShead: a35c698 - steps: PR All fixtures were built fresh under a throwaway scratch directory (deleted after this run), driving the checked-out tree CLI (
FailuresNone. |
…d skills through the catalog
Code review - CLEANhead: 48c9354 - base: main - files 53, +2342/-623 Critical(none) Warning(none) Suggestion(none) Notes
|
Verification - PASShead: 48c9354 - steps: PR
FailuresNone. Workspace confirmed at head 48c9354 with a clean tree both before and after this run; nothing was committed, fetched, or switched in it. All fixtures were built under a scratch directory, deleted at the end of this run. |
Code review - PASS-WITH-WARNINGShead: c8861c5 - base: main - files 53, +2409/-623 Critical(none) Warning(none) Suggestion
Claims axis
Verification performed
Summary
|
Verification - PASShead: c8861c5 - steps: PR top Verification checklist (5 items) + Stage 1 steps 1-7 + Stage 2 steps 8-16, in order; no qa_checks matched (docs/qa-checks.md absent, no other standing-checks source found) - env: local (tree CLI invoked directly as bash cli/intelligence , per the project profile having no qa_env/app_run/app_url keys; never the globally installed intelligence on PATH) All fixtures were built fresh under a throwaway scratch directory (deleted after this run), driving the checked-out tree CLI directly. This head adds one commit since the last-recorded verification (48c9354): cli/internal/check.sh now has status --check name a tracked file whose name makes it local; exercised directly below.
FailuresNone. Workspace confirmed at head c8861c5 with a clean tree both before and after this run; nothing was committed, fetched, switched or worktreed in it. All fixtures were built under a scratch directory, deleted at the end of this run. |

Summary
Implements decision 0021. Nothing in a source could say "only on this machine" or "only for this tool": a gitignored file in a source still leaked into the committed
AGENTS.md(sosync --checkfailed in CI), and tool-specific guidance cost context in every tool.AGENTS.mdalso read sources differently from every other adapter (it rendered dotfiles and listed same-named artifacts once per source).*.local.mdrule or agent and a*.local/skill render only into outputs their adapter's contract ignores.initwrites the three patterns to the managed.gitignoreblock andstatus --checkreports one missing, and names a file with a local name that Git tracks in any project source (a pattern never applies to a tracked file). Every renderer (AGENTS.md, all built-ins, the template) reads sources throughsource_artifacts_var, which names artifacts (no leading.,.md, trailing.local), applies overrides everywhere, and refuses same-name pairs in one directory and local/non-local pairs anywhere, before any output is touched. Contracts are read with the manifest only when a local artifact or thecommittedgroup is present.targets:/exclude_targets:(adapter ids and the groupcommitted, resolved per path) select adapters and are stripped from every copy. An always-on ruleAGENTS.mddoes not carry reaches Cursor (alwaysApply: true), Copilot (applyTo: "**"), Antigravity (trigger: always_on), Pi (its rules extension) and Codex (AGENTS.override.md, marker-managed, ignored, present only while needed). Unknown ids and local artifacts naming a committed output refuse; shared-path deliveries and unreachable targets printWARNING:lines.0.21.0with aCHANGELOG.mdsection; decision 0021 item 9 now records one PR in two stages.Output for a project without local, dotfile or colliding sources is byte-identical to
main(A/B over this repository's content with all eight adapters, and an edge-case fixture). Deliberate behavior changes are listed in the changelog: an overridden skill is replaced whole instead of merged file by file, Pi lists scoped rules in byte order, and a rule that is a symlink to a file is now listed inAGENTS.mdtoo.Type of change
Public CLI check
init,sync,update,upgrade,package,source,adapter,status,registryintelligence syncVerification
bash cli/tests/verify.shreportsverify okand skipped nothing this change neededintelligence status --checksucceeds in the relevant fixture/projectintelligence syncproduces no unexpected diffStage 1 — local artifacts
Start state for every step: an empty Git repository initialized with this branch's CLI —
bash <checkout>/cli/intelligence init --bare --targets agents,claude,cursor,codex,copilot,opencode— plus one committed always-on ruleintelligence/rules/team.md, everything committed.init,.gitignoreholdsintelligence/rules/*.local.md,intelligence/agents/*.local.mdandintelligence/skills/*.local/;git check-ignorereportsintelligence/rules/me.local.md,intelligence/rules/.environment.local.mdandintelligence/skills/deploy.local/SKILL.mdas ignored.intelligence/rules/.environment.local.md, the scoped ruleintelligence/rules/scoped.local.md(withpaths:), the agentintelligence/agents/helper.local.mdand the skillintelligence/skills/deploy.local/SKILL.md, runsync—AGENTS.mdis byte-identical to its committed version and names none of them;git status --porcelainis empty..local:.claude/rules/environment.md,.claude/rules/scoped.md,.claude/agents/helper.md,.claude/skills/deploy/SKILL.md,.cursor/rules/scoped.mdc,.codex/agents/helper.toml,.agents/skills/deploy/SKILL.md; no.opencode/commands/deploy.md(tracked output).targets.copilot.commit_output: true, the local scoped rule is not written to.github/instructions/, andgit status --porcelainstays empty aftersync.git cloneof the project, which has no local artifact, passesintelligence sync --checkwith exit 0 after its firstsync.intelligence/rules/team.local.mdadded besideteam.md,syncexits non-zero naming both files and leaves every generated file unchanged; the same with.team.mdbesideteam.md.intelligence/rules/.draft.mdrenders asdraftboth inAGENTS.mdand in.claude/rules/draft.md; withsources.rules: [shared/rules, intelligence/rules]and astyle.mdin both,AGENTS.mdlistsstyleonce and inlines only theintelligence/rulesbody.Stage 2 — targeted artifacts
Start state: as in stage 1 (empty Git repository initialized with this branch's CLI —
bash <checkout>/cli/intelligence init --bare --targets agents,claude,cursor,codex,copilot,opencode— plus one committed always-on ruleintelligence/rules/team.md, everything committed), with antigravity and pi additionally enabled throughintelligence adapter enable antigravityandintelligence adapter enable piand that change committed after a sync.intelligence/rules/claude-only.mdwithtargets: [claude]: aftersync,.claude/rules/claude-only.mdexists and its frontmatter has notargets:;AGENTS.mdneither names the rule nor contains its body.intelligence/rules/codex-only.mdwithtargets: [codex]: aftersync,AGENTS.override.mdexists besideAGENTS.md, contains the wholeAGENTS.mdcontent plus the rule body, andgit check-ignorereports it ignored;AGENTS.mddoes not contain the body. Deleting the rule and runningsyncremovesAGENTS.override.md.intelligence/rules/tools.mdwithexclude_targets: [agents]: aftersyncit is in.claude/rules/tools.md,.cursor/rules/tools.mdcwithalwaysApply: true,.github/instructions/tools.instructions.mdwithapplyTo: "**",.agents/rules/tools.mdwithtrigger: always_on, Pi's generated rules extension, andAGENTS.override.md; not inAGENTS.md; sync prints aWARNING:line naming opencode as unable to receive it.intelligence/rules/.environment.local.mdfrom stage 1 now also reaches.cursor/rules/environment.mdc(alwaysApply: true),.github/instructions/environment.instructions.mdandAGENTS.override.md;AGENTS.mdstays byte-identical to its committed version andgit status --porcelainis empty.intelligence/skills/ship/withtargets: [codex]in itsSKILL.md: aftersyncit is in.agents/skills/ship/and not in.claude/skills/,.cursor/skills/or.github/skills/; there is no.opencode/commands/ship.md; sync prints aWARNING:line naming antigravity, opencode and pi as other readers of.agents/skills/.intelligence/agents/reviewer.mdwithexclude_targets: [copilot]: aftersyncit is absent from.github/agents/, present in.claude/agents/and.codex/agents/, and listed inAGENTS.md.targets: [agents]andexclude_targets: [cursor]: aftersyncit is inAGENTS.mdand sync prints aWARNING:line naming cursor as still reading it throughAGENTS.md.targets: []: aftersyncit appears in no generated file.targets: [cursr], and separately a local rulex.local.mdwithtargets: [agents]: each makessyncexit non-zero with a message naming the file and the reason (unknown adapter; local artifact naming a committed output), and leaves every generated file unchanged.Versioned artifacts
CHANGELOG.mdversion; there is no[Unreleased]section or duplicated release dateengine/VERSIONrelease state was checked: append while pending, or select the next SemVer after publicationschema_versionand exact@ainova-systems/syncpin changed with itNotes for reviewers
cli/tests/e2e-local-artifacts.sh(new, inverify.sh'sSUITES) covers both stages end to end, including the regressions forAGENTS.mdlisting a same-named rule twice and a dotfile rule reachingAGENTS.mdonly (both fail onmain), a hand-writtenAGENTS.override.mdthat is never touched, and a custom content directory.cli/tests/unit-engine.shcovers the name rule, ignore-pattern matching, catalog overrides/refusals/membership, field parsing in every list form and field stripping;cli/tests/unit-gitignore.shcovers the local patterns. Run withbash cli/tests/verify.sh..gitignorepatterns (andAGENTS.override.mdwith Codex enabled) fromintelligence init; until thenstatus --checkreports them, as the### Breakingchecklist states.AGENTS.md.