Skip to content

Added local and targeted source artifacts and read every source through one catalog - #64

Merged
dzykovic merged 8 commits into
mainfrom
feature/local-and-targeted-artifacts
Oct 11, 2026
Merged

dzykovic merged 8 commits into
mainfrom
feature/local-and-targeted-artifacts

Conversation

@dzykovic

@dzykovic dzykovic commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

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 (so sync --check failed in CI), and tool-specific guidance cost context in every tool. AGENTS.md also read sources differently from every other adapter (it rendered dotfiles and listed same-named artifacts once per source).

  • Stage 1 — local artifacts and one catalog. A *.local.md rule or agent and a *.local/ skill render only into outputs their adapter's contract ignores. init writes the three patterns to the managed .gitignore block and status --check reports 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 through source_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 the committed group is present.
  • Stage 2 — targeting. targets: / exclude_targets: (adapter ids and the group committed, resolved per path) select adapters and are stripped from every copy. An always-on rule AGENTS.md does 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 print WARNING: lines.
  • Version moved to 0.21.0 with a CHANGELOG.md section; 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 in AGENTS.md too.

Type of change

  • CLI lifecycle or package behavior
  • Sync engine or adapter
  • Rule, agent, or skill content
  • Documentation
  • Refactor with no behavior change

Public CLI check

  • Uses only the established groups: init, sync, update, upgrade, package, source, adapter, status, registry
  • Keeps preview/apply behavior explicit for planned writes
  • Covers automatic project alignment and CI refusal when project schema/content can change
  • Keeps fresh-clone package restoration behind intelligence sync

Verification

  • bash cli/tests/verify.sh reports verify ok and skipped nothing this change needed
  • intelligence status --check succeeds in the relevant fixture/project
  • A second intelligence sync produces no unexpected diff
  • Adapter changes were checked against the real tool format and preserve hand-authored sibling files
  • User-facing docs and examples use the current public command groups

Stage 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 rule intelligence/rules/team.md, everything committed.

  1. Ignore patterns: after init, .gitignore holds intelligence/rules/*.local.md, intelligence/agents/*.local.md and intelligence/skills/*.local/; git check-ignore reports intelligence/rules/me.local.md, intelligence/rules/.environment.local.md and intelligence/skills/deploy.local/SKILL.md as ignored.
  2. AGENTS.md is untouched: add the always-on rule intelligence/rules/.environment.local.md, the scoped rule intelligence/rules/scoped.local.md (with paths:), the agent intelligence/agents/helper.local.md and the skill intelligence/skills/deploy.local/SKILL.md, run sync — AGENTS.md is byte-identical to its committed version and names none of them; git status --porcelain is empty.
  3. Local artifacts reach ignored outputs under names without .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).
  4. With targets.copilot.commit_output: true, the local scoped rule is not written to .github/instructions/, and git status --porcelain stays empty after sync.
  5. A git clone of the project, which has no local artifact, passes intelligence sync --check with exit 0 after its first sync.
  6. With intelligence/rules/team.local.md added beside team.md, sync exits non-zero naming both files and leaves every generated file unchanged; the same with .team.md beside team.md.
  7. A committed intelligence/rules/.draft.md renders as draft both in AGENTS.md and in .claude/rules/draft.md; with sources.rules: [shared/rules, intelligence/rules] and a style.md in both, AGENTS.md lists style once and inlines only the intelligence/rules body.

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 rule intelligence/rules/team.md, everything committed), with antigravity and pi additionally enabled through intelligence adapter enable antigravity and intelligence adapter enable pi and that change committed after a sync.

  1. An always-on rule intelligence/rules/claude-only.md with targets: [claude]: after sync, .claude/rules/claude-only.md exists and its frontmatter has no targets:; AGENTS.md neither names the rule nor contains its body.
  2. An always-on rule intelligence/rules/codex-only.md with targets: [codex]: after sync, AGENTS.override.md exists beside AGENTS.md, contains the whole AGENTS.md content plus the rule body, and git check-ignore reports it ignored; AGENTS.md does not contain the body. Deleting the rule and running sync removes AGENTS.override.md.
  3. An always-on rule intelligence/rules/tools.md with exclude_targets: [agents]: after sync it is in .claude/rules/tools.md, .cursor/rules/tools.mdc with alwaysApply: true, .github/instructions/tools.instructions.md with applyTo: "**", .agents/rules/tools.md with trigger: always_on, Pi's generated rules extension, and AGENTS.override.md; not in AGENTS.md; sync prints a WARNING: line naming opencode as unable to receive it.
  4. The local always-on rule intelligence/rules/.environment.local.md from stage 1 now also reaches .cursor/rules/environment.mdc (alwaysApply: true), .github/instructions/environment.instructions.md and AGENTS.override.md; AGENTS.md stays byte-identical to its committed version and git status --porcelain is empty.
  5. A skill intelligence/skills/ship/ with targets: [codex] in its SKILL.md: after sync it is in .agents/skills/ship/ and not in .claude/skills/, .cursor/skills/ or .github/skills/; there is no .opencode/commands/ship.md; sync prints a WARNING: line naming antigravity, opencode and pi as other readers of .agents/skills/.
  6. An agent intelligence/agents/reviewer.md with exclude_targets: [copilot]: after sync it is absent from .github/agents/, present in .claude/agents/ and .codex/agents/, and listed in AGENTS.md.
  7. A rule with targets: [agents] and exclude_targets: [cursor]: after sync it is in AGENTS.md and sync prints a WARNING: line naming cursor as still reading it through AGENTS.md.
  8. A rule with targets: []: after sync it appears in no generated file.
  9. A rule with targets: [cursr], and separately a local rule x.local.md with targets: [agents]: each makes sync exit 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

  • The PR records its change under one concrete CHANGELOG.md version; there is no [Unreleased] section or duplicated release date
  • The current engine/VERSION release state was checked: append while pending, or select the next SemVer after publication
  • If a new version was selected, every example's schema_version and exact @ainova-systems/sync pin changed with it
  • No stable release is implied or published without owner approval

Notes for reviewers

  • Automated coverage: cli/tests/e2e-local-artifacts.sh (new, in verify.sh's SUITES) covers both stages end to end, including the regressions for AGENTS.md listing a same-named rule twice and a dotfile rule reaching AGENTS.md only (both fail on main), a hand-written AGENTS.override.md that is never touched, and a custom content directory. cli/tests/unit-engine.sh covers the name rule, ignore-pattern matching, catalog overrides/refusals/membership, field parsing in every list form and field stripping; cli/tests/unit-gitignore.sh covers the local patterns. Run with bash cli/tests/verify.sh.
  • Existing projects get the new .gitignore patterns (and AGENTS.override.md with Codex enabled) from intelligence init; until then status --check reports them, as the ### Breaking checklist states.
  • Warning scope follows item 7's wording "for a local artifact's implicit set": a local scoped rule warns that codex and opencode cannot receive it, since neither has a scoped channel outside AGENTS.md.

Copilot AI balanced review requested due to automatic review settings October 11, 2026 18:13
@dzykovic dzykovic added the ai:processing An agent is working on this pull request label Oct 11, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 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.

Comment thread cli/internal/check.sh
Comment thread cli/lib/gitignore.sh
@dzykovic

Copy link
Copy Markdown
Contributor Author

Code review - PASS-WITH-WARNINGS

head: a35c698 - base: main - files 53, +2332/-617

Critical

(none)

Warning

  • engine/lib/common.sh:1926-1934 (skill_source_rendered) - dead code: every former caller (engine/adapters/claude.sh:78, copilot.sh:183, cursor.sh:119, opencode.sh:105 on main) migrated to source_artifacts_var in this diff, and packages/sync/references/adapters.md dropped the function from the shared-functions table accordingly, but the function itself stays in engine/lib/common.sh with only its own unit test (cli/tests/unit-engine.sh:664-665) still calling it. The comment at engine/lib/common.sh:1876 ("the membership the glob-listing adapters check (skill_source_rendered)") now describes a mechanism nothing in the shipped adapters uses — dev-context-engineering's "documentation that drifts from code is a defect" applies to that comment too. Fix: delete the function (and its test), or if it is being kept for project adapters that still glob their own sources, say so explicitly in its doc comment and in adapters.md.

Suggestion

(none)

Notes

  • Verified empirically in a throwaway project against this exact tree (bash cli/intelligence, never the global CLI): local-artifact ignore patterns, byte-identical AGENTS.md with local rules/agents/skills added, non-.local names reaching ignored outputs (.claude/*, .cursor/*, .codex/agents/helper.toml, .agents/skills/deploy/), same-name and local/non-local refusals, unknown-targets: refusal, local-artifact-naming-committed refusal, AGENTS.override.md creation/content/removal in isolation, exclude_targets: [agents] fan-out to Cursor/Copilot/Antigravity/.agents/rules//AGENTS.override.md with the opencode WARNING:, and skill targets: [codex] landing only in .agents/skills/ with the antigravity/opencode/pi WARNING:. All matched the PR body exactly, including warning text.
  • bash cli/tests/verify.sh lint and bash cli/tests/verify.sh tests (WSL, all suites including e2e-local-artifacts, unit-engine, unit-gitignore) pass clean at this head.
  • Versioning checked against .claude/rules/release.md: v0.20.0 is published non-prerelease (confirmed via gh release view), so selecting 0.21.0 is correct; engine/VERSION, every example's schema_version and its @ainova-systems/sync pin move together.
  • Bash 3.2 patterns checked: every new "${arr[@]}" expansion over a possibly-empty array is guarded ("${arr[@]+"${arr[@]}"}" or a prior count/[ -gt 0 ] check); indexed access (${arr[i]}) bounded by ${#arr[@]} in a C-style for does not hit the bash-3.2 empty-array-under-set -u failure.
  • Process-count discipline preserved: source_catalog_build is memoized by (repo_root, config_file) under IS_SOURCE_FILES_MEMO=1, so every later source_artifacts_var call (one per adapter per section) replays the cached catalog instead of re-forking find/sort/awk; sync-cache's 270 checks pass unchanged.
  • Docs/references updated consistently with the one-source rule: intelligence/rules/engine.md, packages/sync/references/adapters.md, conventions.md, onboarding-migration.md, the adapter template, and decisions/0021-local-and-targeted-source-artifacts.md all describe the same catalog, naming rule and routing without restating it differently.
  • PR body claims axis: every numbered acceptance step (1-16) checked either by direct reproduction or by reading the matching assertions in cli/tests/e2e-local-artifacts.sh; found no undelivered claim and no undeclared scope. The changelog's ### Breaking checklist covers the only user-facing migration (new .gitignore patterns / AGENTS.override.md), so there is no missing deployment-notes item.

@dzykovic dzykovic added the ai:reviewed Diff reviewed on the reported head label Oct 11, 2026
@dzykovic

Copy link
Copy Markdown
Contributor Author

Verification - PASS

head: a35c698 - steps: PR ## Verification top 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 <args>, per the pointer given with this run; no qa_env/app_run/app_url keys in the project profile, resolved for this run as instructed rather than escalated)

All fixtures were built fresh under a throwaway scratch directory (deleted after this run), driving the checked-out tree CLI (cli/intelligence) directly, never the globally installed intelligence.

# Step Source Verdict Observed
A1 bash cli/tests/verify.sh reports verify ok and skipped nothing this change needed PR pass Full run (WSL path, about 2.5 min): lint: engine ok, lint: cli ok, all 20 suites in SUITES (unit-semver, unit-manifest, unit-engine, unit-gitignore, unit-release, unit-fetch, unit-upgrade, unit-verify, e2e-sources, e2e-local-artifacts, e2e-packages, e2e-lifecycle, e2e-negative, e2e-lock-validation, e2e-compat, e2e-sync-cache, e2e-sync-check, e2e-concurrency, e2e-sync-lock, e2e-store-sha) reported ALL OK / N checks passed; ended ok: tests: CLI suites then === verify ok ===, exit 0. No === skipped === banner. Only SKIP line was SKIP Windows junction case: non-Windows host, an in-test documented skip, not a gate-level one.
A2 intelligence status --check succeeds in the relevant fixture/project PR pass Ran directly in both scratch fixtures after full setup: Stage-1 project exit 0 (all good.); Stage-2 project (antigravity+pi enabled) exit 0 (all good.). Negative: deleting one .gitignore pattern line made status --check exit 1 naming it (missing intelligence/agents/*.local.md, told to run intelligence init).
A3 A second intelligence sync produces no unexpected diff PR pass On the fully-populated Stage-2 fixture: sync --check reported up to date (exit 0); a second sync exited 0 and a before/after checksum snapshot of every generated path was byte-identical.
A4 Adapter changes were checked against the real tool format and preserve hand-authored sibling files PR pass Real-format spot checks across steps 8-14 below: Cursor .mdc with alwaysApply: true, GitHub Copilot applyTo: "**" instructions, Codex .toml (name = "helper"), Antigravity trigger: always_on, Pi generated .ts extension, all matched packages/sync/references/conventions.md and adapters.md. Sibling preservation: a hand-written .claude/settings.local.json (outside any owned subdirectory) survived sync and sync --force unchanged; a hand-written AGENTS.override.md was left byte-identical until a Codex-only rule needed one, at which point sync refused instead of overwriting it. Caught and corrected one invalid probe of my own: a hand file dropped directly inside the owned .claude/rules/ directory is deleted on sync by design (packages/sync/references/adapters.md:303, confirmed against the matching case in cli/tests/e2e-sync-cache.sh, "owned-directory additions and preserved siblings"); that is not the sibling-preservation contract and is not a defect.
A5 User-facing docs and examples use the current public command groups PR pass docs/cli.md Public commands section lists exactly init, sync, update, upgrade, package, source, adapter, status, registry, each with the current flag set; grep for migrate/convert/other retired names found nothing in docs/, README.md. All 8 examples/*/intelligence.yaml pin schema_version: "0.21.0" and @ainova-systems/sync version: "0.21.0", matching engine/VERSION.
1 Ignore patterns: after init, .gitignore holds the three local patterns; git check-ignore reports the three example local paths ignored PR (Stage 1) pass .gitignore contained all three patterns verbatim; git check-ignore -q --no-index reported all three example paths ignored. Negative: the same check on the committed, non-local equivalents (team.md, .draft.md, deploy/SKILL.md) correctly reported them not ignored.
2 Adding local rule/agent/skill artifacts and running sync leaves AGENTS.md byte-identical and git status --porcelain empty PR (Stage 1) pass After adding .environment.local.md, scoped.local.md, helper.local.md, deploy.local/SKILL.md and syncing: AGENTS.md diffed identical to the pre-change committed copy; none of environment/scoped/helper/deploy/LOCAL_ appeared in it; git status --porcelain was empty.
3 Local artifacts reach ignored outputs under names without .local; no .opencode/commands/deploy.md PR (Stage 1) pass All 7 listed output paths existed under their non-local names with correct bodies; .opencode/commands/deploy.md was absent; a recursive search for *.local* across every output tree was empty.
4 With targets.copilot.commit_output: true, the local scoped rule is not written to .github/instructions/, and git status --porcelain stays empty PR (Stage 1) pass On a copy with that key set and init plus commit plus sync --force run: .github/instructions/scoped.instructions.md was absent; git status --porcelain was empty.
5 A git clone with no local artifact passes intelligence sync --check with exit 0 after its first sync PR (Stage 1) pass Clone had no local artifact files; first sync exit 0; sync --check exit 0 (up to date); cloned AGENTS.md identical to the committed copy.
6 team.local.md beside team.md, and separately .team.md beside team.md, each make sync exit non-zero naming both files, outputs unchanged PR (Stage 1) pass Both cases: exit 1, error named both files as the rule team colliding in one directory; a before/after checksum snapshot of every generated path was identical in both cases.
7 Committed .draft.md renders as draft in AGENTS.md and .claude/rules/draft.md; with sources.rules: [shared/rules, intelligence/rules] and style.md in both, AGENTS.md lists style once, inlining only the intelligence/rules body PR (Stage 1) pass .draft.md rendered as draft in both places with its body. With the shared-source override set up: exactly one style entry in AGENTS.md, pointing at intelligence/rules/style.md, containing the project body and not the shared one; .claude/rules/style.md held the project body too.
8 targets: [claude] rule: reaches only .claude/rules/, with no targets: in the rendered frontmatter; absent from AGENTS.md (name and body) PR (Stage 2) pass .claude/rules/claude-only.md existed, no targets: line; AGENTS.md unchanged from its committed copy and contained neither the name nor the body.
9 targets: [codex] rule: AGENTS.override.md appears, contains all of AGENTS.md plus the rule body, ignored by git, absent from AGENTS.md; deleting the rule removes the override file PR (Stage 2) pass AGENTS.override.md existed, its first N lines equaled AGENTS.md exactly, contained the rule body, was git-ignored; AGENTS.md lacked the body. Deleting the rule and re-syncing removed AGENTS.override.md.
10 exclude_targets: [agents] rule reaches every always-on channel (Claude, Cursor alwaysApply: true, Copilot applyTo: "**", .agents/ trigger: always_on, Pi extension, AGENTS.override.md) but not AGENTS.md; warns naming opencode PR (Stage 2) pass Confirmed the rule body present (correct format) in every listed channel and absent from AGENTS.md; warning printed naming opencode as unable to receive it.
11 The Stage-1 local always-on rule also reaches Cursor (alwaysApply: true), Copilot instructions, and AGENTS.override.md; AGENTS.md stays byte-identical, git status --porcelain empty PR (Stage 2) pass All three channels carried the local rule body; AGENTS.md unchanged from committed; tracked-file git status (two not-yet-committed source rule files from steps 8/10 were sitting untracked, matching the convention the project own e2e suite uses for this scenario) was empty.
12 ship skill with targets: [codex]: lands only in .agents/skills/, absent elsewhere, no .opencode/commands/ship.md; warns naming antigravity, opencode, pi PR (Stage 2) pass .agents/skills/ship/SKILL.md present with targets: stripped; absent from .claude/skills, .cursor/skills, .github/skills; no opencode command; warning named antigravity, opencode, pi as other readers of .agents/skills/.
13 reviewer agent with exclude_targets: [copilot]: absent from .github/agents/, present in .claude/agents/ and .codex/agents/, listed in AGENTS.md PR (Stage 2) pass Confirmed all four conditions, plus the expected warning that it still reaches copilot through AGENTS.md.
14 targets: [agents] + exclude_targets: [cursor] rule: in AGENTS.md; warns naming cursor PR (Stage 2) pass Body present in AGENTS.md, absent from .claude/rules/; warning line named cursor along with the other non-agents adapters, consistent with the documented rule that a filter can withhold an artifact from a shared path but never from one of its readers.
15 targets: [] rule renders nowhere PR (Stage 2) pass A recursive search for the rule body across every generated path (including AGENTS.override.md, .pi/) was empty.
16 targets: [cursr] (unknown adapter) and a local rule with targets: [agents] each make sync exit non-zero naming the file and reason, outputs unchanged PR (Stage 2) pass Unknown target: exit 1, error named the file and the unknown adapter id. Local rule naming a committed target: exit 1, error named the file and that its named target output Git tracks. Both left every generated path byte-identical to before.

Failures

None.

@dzykovic dzykovic added the ai:verified Declared behavior verified on the reported head label Oct 11, 2026
@dzykovic dzykovic removed ai:verified Declared behavior verified on the reported head ai:reviewed Diff reviewed on the reported head labels Oct 11, 2026
@dzykovic

Copy link
Copy Markdown
Contributor Author

Code review - CLEAN

head: 48c9354 - base: main - files 53, +2342/-623

Critical

(none)

Warning

(none)

Suggestion

(none)

Notes

  • This head's only change since the prior review (at a35c698) is 48c9354, which fixes that review's sole Warning: skill_source_rendered's doc comment now says no built-in adapter calls it and names why it still exists (a project adapter written before decision 0021). Verified the fix: no built-in adapter references it (grep -rn skill_source_rendered), and it is dropped from the shared-function table in packages/sync/references/adapters.md while staying documented as the legacy path in its own comment and in engine/lib/common.sh:1927.
  • Re-reviewed the whole diff fresh (catalog build/override/refusal logic in engine/lib/common.sh, source_frontmatter_scan, every adapter in engine/adapters/, engine/sync.sh's preflight wiring, cli/lib/gitignore.sh, cli/internal/check.sh, the new decisions/0021-local-and-targeted-source-artifacts.md, and the doc updates). No correctness, layering, security or hygiene findings.
  • bash cli/tests/verify.sh lint and bash cli/tests/verify.sh tests (WSL, full suite — unit-engine, unit-gitignore, e2e-local-artifacts, and the Windows-filesystem-limited e2e-lifecycle/e2e-negative, which pass under WSL) all green at this head. CI on this exact head SHA (gh run list) is green on ubuntu-latest and macos-latest (bash 3.2), including repo-purity.
  • Bash 3.2 patterns checked by hand in every new array expansion in common.sh and every adapter: each "${arr[@]}" use is either preceded by a [ "${#arr[@]}" -gt 0 ] || return 0 guard or a [ ... ]+"${arr[@]}" guard, and every bounded loop uses ${#arr[@]} in a C-style for, which is safe on an empty array under set -u. CI's macOS job corroborates this empirically.
  • Verified the byte-identical claim myself, independent of the PR's own A/B: built a fixture project (rule, scoped rule, agent, skill, all 8 adapters) under main (c8058f9, confirmed = origin/main), snapshotted every generated path, reset to source-only, reran init with this PR's tree. Every adapter output (AGENTS.md, .claude/, .cursor/, .codex/, .github/, .opencode/, .pi/, .agents/) came back byte-for-byte identical; the only two differing files were .gitignore (new local-artifact + AGENTS.override.md patterns) and intelligence.yaml's schema_version — exactly the two items the changelog's ### Breaking checklist names.
  • Verified the migration path claim: restored the main-rendered project state (old .gitignore, schema_version: "0.20.0") and ran this tree's intelligence status --check — it reported the manifest behind the engine, the missing AGENTS.override.md Git policy, and all three missing local-artifact patterns individually, exit 1; running intelligence init cleared every one of them (exit 0).
  • Versioning checked against .claude/rules/release.md: gh release view v0.20.0 confirms it is published and non-prerelease, so selecting 0.21.0 is correct. engine/VERSION, every example's schema_version and its exact @ainova-systems/sync pin, and every corresponding intelligence.lock's engine_version all move to 0.21.0 together (checked every example file, not just a sample).
  • Rollback-safety / compatibility for pre-existing project adapters: decision 0021's Consequences section explicitly names the one back-compat gap this feature leaves — a project adapter that still globs sources itself (the pre-PR pattern) does not gain local/target filtering automatically and could in principle copy a local file into its own committed output — and the adapter template, adapters.md and engine.md all point a new or updated adapter at source_artifacts_var instead. This is an accepted, documented consequence of a purely additive feature, not a silent break of existing behavior: nothing already-shipped changes shape for a project adapter that does not opt in. skill_source_rendered is kept, not removed, for the same reason (expand, no contract removed).
  • Claims axis: every one of the PR body's 16 numbered acceptance steps is covered by cli/tests/e2e-local-artifacts.sh (confirmed by reading its sixteen == sections against the steps, including the "leaves every generated file unchanged" assertions on every refusal path) and the new unit-engine.sh/unit-gitignore.sh cases; no claim lacks delivering code, and no undeclared scope appears in the diff. The ### Breaking checklist is the only user-facing migration in this diff, and it is complete.
  • Sibling drift: all seven touched adapters (claude, cursor, codex, copilot, antigravity, opencode, pi) plus agents.sh adopt the same output_rel_var / source_artifacts_var / guarded-array idiom; none departs from its siblings.

@dzykovic dzykovic added the ai:reviewed Diff reviewed on the reported head label Oct 11, 2026
@dzykovic

Copy link
Copy Markdown
Contributor Author

Verification - PASS

head: 48c9354 - steps: PR ## Verification top 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: bash cli/intelligence <args>, never the global intelligence on PATH)

# Step Source Verdict Observed
T1 bash cli/tests/verify.sh reports verify ok and skips nothing this change needed PR pass Full run (lint engine, lint cli, all CLI suites incl. new unit-gitignore, e2e-local-artifacts) ended === verify ok ===; only skip was the pre-existing SKIP Windows junction case: non-Windows host inside the WSL copy, not something this change needs there.
T2 intelligence status --check succeeds in the relevant fixture/project PR pass bash cli/intelligence status --check on a synced fixture (8 adapters enabled) printed all check lines and all good., exit 0.
T3 A second intelligence sync produces no unexpected diff PR pass Re-ran sync on the same fixture; identical md5 of every generated file before/after, output Unchanged: no files needed updating.
T4 Adapter changes checked against the real tool format and preserve hand-authored sibling files PR pass Spot-checked generated syntax against packages/sync/references/conventions.md (Cursor .mdc with alwaysApply/globs, Copilot .instructions.md with applyTo, Codex .toml agent, Antigravity trigger: always_on, Pi .ts extension). Hand-authored .github/workflows/ci.yml, .claude/settings.json, .codex/MY_CODEX_NOTE.md, .cursor/MY_CURSOR_NOTES.md all survived sync untouched. A hand file placed inside an owned subdirectory (.claude/rules/MY_NOTES.md) was removed by sync - this is the documented owned-directory behavior, not sibling preservation, and not a defect.
T5 User-facing docs and examples use the current public command groups PR pass docs/cli.md and README.md only reference init, sync, update, upgrade, package, source, adapter, status, registry (plus builtin help); every examples//intelligence.yaml pins schema_version 0.21.0 and every examples//intelligence.lock pins @ainova-systems/sync at 0.21.0, matching engine/VERSION.
S1-1 Ignore patterns: .gitignore holds the three local patterns; git check-ignore reports the three example paths ignored PR pass All three patterns present; git check-ignore -v confirmed all three example paths ignored. Negative probe: near-miss names (notlocal.md, me.local.mdx, me.localmd, deploy.localx/) are correctly not ignored.
S1-2 AGENTS.md is untouched by the four local artifacts; git status --porcelain empty PR pass AGENTS.md byte-identical (md5 match) before/after adding all four local artifacts and syncing; none named in it; git status --porcelain empty.
S1-3 Local artifacts reach ignored outputs under non-.local names; no .opencode/commands/deploy.md PR pass All seven listed paths existed with correct content; no opencode commands dir/file created.
S1-4 targets.copilot.commit_output: true keeps the local scoped rule out of .github/instructions/; git status --porcelain stays empty PR pass After enabling the setting and syncing, Copilot reported "rules: 0 scoped", no .github/instructions/ dir created, only our own manifest edit showed in git status.
S1-5 A clone with no local artifact passes sync --check exit 0 after first sync PR pass Clone had none of the four local files; first sync exit 0, then sync --check printed "generated files are up to date", exit 0.
S1-6 team.local.md beside team.md (and .team.md beside team.md) makes sync exit non-zero naming both files, generated files unchanged PR pass Both variants: exit 1, ERROR: ...and... are both the rule team in one directory, rename or remove one; md5 of every generated file unchanged.
S1-7 Committed .draft.md renders as draft in AGENTS.md and .claude/rules/draft.md; sources.rules: [shared/rules, intelligence/rules] with style.md in both lists style once, inlining only the intelligence/rules body PR pass AGENTS.md linked to intelligence/rules/.draft.md as draft and .claude/rules/draft.md existed with the same body. With both sources set, AGENTS.md listed style exactly once, linked to intelligence/rules/style.md, and inlined "Intelligence body text." (not the shared/rules body).
S2-8 Rule targets: [claude]: .claude/rules/claude-only.md exists, no targets: in its frontmatter; AGENTS.md names/contains neither PR pass Confirmed on a clean fixture (empty repo + team.md + antigravity/pi enabled, independent of Stage 1 leftover local artifacts).
S2-9 Rule targets: [codex]: AGENTS.override.md appears beside AGENTS.md, contains all of AGENTS.md plus the rule body, is gitignored; AGENTS.md lacks the body; deleting the rule + sync removes AGENTS.override.md PR pass Verified on the same clean fixture: override file was AGENTS.md content as a prefix plus the new section; git check-ignore confirmed ignored; AGENTS.md unaffected; deleting the rule and re-syncing removed AGENTS.override.md entirely (no other contributor pinned it open).
S2-10 Rule exclude_targets: [agents] reaches Claude/Cursor(alwaysApply:true)/Copilot(applyTo:"**")/Antigravity(trigger: always_on)/Pi/AGENTS.override.md, not AGENTS.md; WARNING names opencode PR pass All six channels matched exactly, including frontmatter shapes; single relevant WARNING naming opencode as unable to receive it; absent from AGENTS.md.
S2-11 Local .environment.local.md also reaches .cursor/rules/environment.mdc (alwaysApply:true), .github/instructions/environment.instructions.md, AGENTS.override.md; AGENTS.md byte-identical to committed, git status --porcelain empty PR pass All three channels present with correct frontmatter; AGENTS.md md5-identical to its last commit; git status --porcelain empty.
S2-12 Skill targets: [codex] lands in .agents/skills/ship/, not in .claude/skills/, .cursor/skills/, .github/skills/; no .opencode/commands/ship.md; WARNING names antigravity, opencode, pi PR pass .agents/skills/ship/SKILL.md present; the other three skills dirs absent/empty; no opencode command; WARNING named antigravity, opencode and pi as other readers of .agents/skills/.
S2-13 Agent exclude_targets: [copilot] absent from .github/agents/, present in .claude/agents/ and .codex/agents/, listed in AGENTS.md PR pass .github/agents/ empty; reviewer.md/reviewer.toml present in the other two; AGENTS.md agent table lists it. (An accompanying WARNING that it still reaches copilot through AGENTS.md is expected shared-path behavior, not a contradiction of the declared checks.)
S2-14 Rule targets: [agents] + exclude_targets: [cursor] lands in AGENTS.md; WARNING names cursor as still reading it through AGENTS.md PR pass Listed/inlined in AGENTS.md; WARNING named antigravity, codex, copilot, cursor, opencode and pi as all still reaching it through AGENTS.md - cursor is named, among the full set that also reads AGENTS.md, matching decision 0021's "shared paths are delivered whole" rule.
S2-15 Rule targets: [] appears in no generated file PR pass Unique body marker found in none of AGENTS.md, AGENTS.override.md, or any adapter output; no warning printed for it (clean exclusion, as documented).
S2-16 targets: [cursr] (unknown adapter) and a local artifact targets: [agents] (naming a committed output) each make sync exit non-zero, naming the file and the reason; generated files unchanged PR pass Unknown id: ERROR naming the file and "targets names cursr, which is no adapter", listing valid ids; exit 1. Local-naming-committed: ERROR naming the file, "is local, but its targets name agents, whose output Git tracks"; exit 1. Both left every generated file's md5 unchanged.

Failures

None.

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.

@dzykovic dzykovic added the ai:verified Declared behavior verified on the reported head label Oct 11, 2026
@dzykovic dzykovic removed ai:verified Declared behavior verified on the reported head ai:reviewed Diff reviewed on the reported head labels Oct 11, 2026
@dzykovic

Copy link
Copy Markdown
Contributor Author

Code review - PASS-WITH-WARNINGS

head: c8861c5 - base: main - files 53, +2409/-623

Critical

(none)

Warning

(none)

Suggestion

  • cli/lib/gitignore.sh:166 / engine/lib/common.sh (source_catalog_check_local) - a *.local.md/*.local/ artifact in a project source outside the content directory (e.g. shared/rules/me.local.md added via intelligence source add) has no .gitignore pattern, so Git still offers it for commit; only status --check catches it, after the fact. This is a deliberate, documented tradeoff (decision 0021 item 1 and the "Rejected: Detecting local files with git check-ignore" entry), and it is covered by its own e2e case (cli/tests/e2e-local-artifacts.sh:405-415, matching the still-open Copilot thread at cli/lib/gitignore.sh:323). Not a defect, but worth a reader noticing it is a known, accepted gap rather than an oversight.
  • decisions/0021-local-and-targeted-source-artifacts.md (Consequences) - a project adapter that still enumerates sources with its own glob (written against an earlier release) keeps rendering a local or targeted artifact into committed output, since it has no notion of *.local.md naming. Explicitly disclosed in the decision, packages/sync/references/adapters.md's verify checklist, and skill_source_rendered's own comment (engine/lib/common.sh:1927-1931) — flagging only so it stays visible, since the mitigation is documentation (point the adapter at source_artifacts_var), not an automatic guard.

Claims axis

  • Body and changelog checked claim-by-claim against the diff: byte-identical output for a project with no local/dotfile/colliding sources (reproduced independently: synced an 8-adapter fixture project with main's engine, re-synced the same sources with this branch's engine, cksum-compared every generated file — identical); status --check naming a tracked file with a local name (reproduced); targets:/exclude_targets: routing and the new always-on channels for Cursor/Copilot/Antigravity/Pi/Codex, including AGENTS.override.md (reproduced); the "cannot reach codex, opencode" warning for a local scoped rule the Notes call out specifically (reproduced verbatim). No undeclared scope found; the PR body explains why/what beyond a file list.
  • Versioning: v0.20.0 is published non-prerelease, so selecting 0.21.0 is correct per release.md; engine/VERSION, every example's schema_version and exact @ainova-systems/sync pin all moved to 0.21.0 together.
  • Decision 0021 item 9 ("one PR, two stages of commits") matches the actual commit sequence (b5141df local artifacts/catalog, then 8b43a0d targets/exclude_targets/channels/warnings, plus the version, docs and the follow-up fix for tracked-local detection).
  • Both open Copilot review threads checked against this head: the tracked-local-artifact finding is resolved by the newest commit (cli/internal/check.sh:93-148, verified live); the outside-content-directory finding is a known, tested, documented limitation (see Suggestions above), not newly introduced.

Verification performed

  • bash cli/tests/verify.sh lint - ok (native Git Bash + WSL).
  • bash cli/tests/unit-engine.sh, unit-gitignore.sh, cli/tests/e2e-local-artifacts.sh - all pass, run twice (native Git Bash and WSL).
  • CI on this exact head (c8861c5) is green end to end, including cli-e2e (macos-latest) (bash 3.2) and cli-e2e (ubuntu-latest).
  • Manually probed bash-3.2-sensitive patterns ("${arr[@]}" on possibly-empty arrays) across engine/lib/common.sh and every adapter touched; every expansion is either the ${arr[@]+"${arr[@]}"} guard or preceded by an explicit [ "${#arr[@]}" -gt 0 ] / early-return guard before the unguarded form is reached.
  • Reproduced the local-artifact and targeted-artifact scenarios from the PR's own manual test script in a scratch project (gitignore patterns, tracked-file detection, AGENTS.override.md lifecycle, per-adapter always-on channels, warnings) - all matched the documented behavior.

Summary

  • files: 53, +2409/-623; critical: 0; warning: 0; suggestion: 2
  • verdict: PASS-WITH-WARNINGS

@dzykovic dzykovic added the ai:reviewed Diff reviewed on the reported head label Oct 11, 2026
@dzykovic

Copy link
Copy Markdown
Contributor Author

Verification - PASS

head: 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.

# Step Source Verdict Observed
A1 bash cli/tests/verify.sh reports verify ok and skipped nothing this change needed PR pass Full run (WSL path, ~2.5 min): lint engine ok, lint cli ok, all 20 suites reported OK, including e2e-lifecycle and e2e-negative running to completion under WSL (the NTFS/symlink limits noted for native Git Bash do not apply there). Ended ok: tests: CLI suites then verify ok, exit 0. Only skip: the documented SKIP Windows junction case: non-Windows host.
A2 intelligence status --check succeeds in the relevant fixture/project PR pass Exit 0 on both Stage-1 and Stage-2 fixtures after full setup. Also exercised the new tracked-local-name reporting added in this head's own commit: git add -f on a local-named rule and skill made status --check exit 1 naming both (environment.local.md is tracked by Git..., deploy.local/ is tracked by Git...); git rm --cached on them returned it to exit 0.
A3 A second intelligence sync produces no unexpected diff PR pass On the fully-populated Stage-2 fixture (8 adapters, 6 rules, 1 agent, 1 skill): sync --check reported up to date (exit 0); a second sync exited 0 with Unchanged: no files needed updating, and a before/after md5 snapshot of every generated path was identical.
A4 Adapter changes were checked against the real tool format and preserve hand-authored sibling files PR pass Spot checks matched packages/sync/references/conventions.md and adapters.md: Cursor .mdc with alwaysApply: true, Copilot applyTo: "**", Codex .toml (name = "reviewer"), Antigravity trigger: always_on, Pi's generated .ts extension. Sibling preservation: a hand-written .claude/settings.local.json (outside any owned subdirectory) survived sync and sync --force byte-identical. Negative: a hand file dropped directly inside the owned .claude/rules/ directory was removed by sync --force -- documented owned-directory behavior, not a sibling-preservation defect.
A5 User-facing docs and examples use the current public command groups PR pass docs/cli.md's command section headers are exactly init, sync, update, upgrade, package, source, adapter, status, registry. All 7 examples/*/intelligence.yaml with a lock pin schema_version "0.21.0" and @ainova-systems/sync requested "0.21.0", matching engine/VERSION (0.21.0).
1 Ignore patterns: after init, .gitignore holds the three local patterns; git check-ignore reports the three example local paths ignored PR (Stage 1) pass .gitignore held all three patterns verbatim; git check-ignore -v reported all three example paths ignored. Negative: the non-local equivalents (me.md, environment.md, deploy/SKILL.md) correctly reported not ignored.
2 Adding local rule/agent/skill artifacts and running sync leaves AGENTS.md byte-identical and git status --porcelain empty PR (Stage 1) pass After adding .environment.local.md, scoped.local.md, helper.local.md, deploy.local/SKILL.md and syncing: AGENTS.md md5-identical to the pre-change copy, contained none of the local names; git status --porcelain empty (the new local source files themselves fall under the same .gitignore patterns).
3 Local artifacts reach ignored outputs under names without .local; no .opencode/commands/deploy.md PR (Stage 1) pass All 7 listed output paths existed under their non-local names; .opencode/commands/deploy.md absent.
4 With targets.copilot.commit_output: true, the local scoped rule is not written to .github/instructions/, and git status --porcelain stays empty PR (Stage 1) pass After setting the key, running intelligence init (which withdraws the five Copilot-output ignore patterns per conventions.md), committing, then sync --force: .github/instructions/scoped.instructions.md, .github/agents/helper.agent.md and .github/skills/deploy were all absent; .claude/rules/scoped.md (non-Copilot path) unaffected; git status --porcelain empty.
5 A git clone with no local artifact passes intelligence sync --check with exit 0 after its first sync PR (Stage 1) pass Clone had only intelligence/rules/team.md (no local artifact survives in a clone, since it was never tracked); first sync exit 0; sync --check exit 0.
6 team.local.md beside team.md, and separately .team.md beside team.md, each make sync exit non-zero naming both files, outputs unchanged PR (Stage 1) pass Both cases: exit 1, error named both files as the rule team colliding in one directory; an md5 snapshot of every generated path was identical before/after in both cases.
7 Committed .draft.md renders as draft in AGENTS.md and .claude/rules/draft.md; with sources.rules: [shared/rules, intelligence/rules] and style.md in both, AGENTS.md lists style once, inlining only the intelligence/rules body PR (Stage 1) pass .draft.md rendered as draft in both places with its body. With the shared-source override set up: exactly one style entry in AGENTS.md, pointing at intelligence/rules/style.md, inlining the project body (not the shared one); .claude/rules/style.md held the project body too.
8 targets: [claude] rule: reaches only .claude/rules/, with no targets: in the rendered frontmatter; absent from AGENTS.md (name and body) PR (Stage 2) pass .claude/rules/claude-only.md existed with an empty frontmatter block (no targets: line); AGENTS.md md5-identical to its pre-change copy and contained neither the name nor the body.
9 targets: [codex] rule: AGENTS.override.md appears, contains all of AGENTS.md plus the rule body, ignored by git, absent from AGENTS.md; deleting the rule removes the override file PR (Stage 2) pass AGENTS.override.md existed, its prefix equaled AGENTS.md exactly, contained the rule body, git check-ignore confirmed ignored; AGENTS.md lacked the body. Deleting the rule and re-syncing removed AGENTS.override.md.
10 exclude_targets: [agents] rule reaches every always-on channel (Claude, Cursor alwaysApply: true, Copilot applyTo: "**", .agents/ trigger: always_on, Pi extension, AGENTS.override.md) but not AGENTS.md; warns naming opencode PR (Stage 2) pass Confirmed the rule body present (correct frontmatter shape) in all six channels and absent from AGENTS.md; warning printed naming opencode as unable to receive it.
11 The Stage-1-equivalent local always-on rule also reaches Cursor (alwaysApply: true), Copilot instructions, and AGENTS.override.md; AGENTS.md stays byte-identical, git status --porcelain empty PR (Stage 2) pass All three channels carried the local rule body; AGENTS.md md5-identical to its pre-change copy; git status --porcelain empty once the prior steps' own new rule files were committed (isolating this step's own effect, per its own stated check).
12 ship skill with targets: [codex]: lands only in .agents/skills/, absent elsewhere, no .opencode/commands/ship.md; warns naming antigravity, opencode, pi PR (Stage 2) pass .agents/skills/ship/SKILL.md present with targets: stripped; absent from .claude/skills, .cursor/skills, .github/skills; no opencode command; warning named antigravity, opencode, pi as other readers of .agents/skills/.
13 reviewer agent with exclude_targets: [copilot]: absent from .github/agents/, present in .claude/agents/ and .codex/agents/, listed in AGENTS.md PR (Stage 2) pass Confirmed all four conditions, plus the expected warning that it still reaches copilot through AGENTS.md.
14 targets: [agents] + exclude_targets: [cursor] rule: in AGENTS.md; warns naming cursor PR (Stage 2) pass Body present in AGENTS.md, absent from .claude/rules/; warning line named cursor along with the other non-agents adapters, consistent with shared-path delivery.
15 targets: [] rule renders nowhere PR (Stage 2) pass A recursive search for the rule's unique body marker across every generated path (AGENTS.md, AGENTS.override.md, all adapter output trees) found nothing.
16 targets: [cursr] (unknown adapter) and a local rule with targets: [agents] each make sync exit non-zero naming the file and reason, outputs unchanged PR (Stage 2) pass Unknown target: exit 1, error named the file and "targets names cursr, which is no adapter". Local rule naming a committed target: exit 1, error named the file and "its targets name agents, whose output Git tracks". Both left every generated path's md5 unchanged.

Failures

None.

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.

@dzykovic dzykovic added ai:verified Declared behavior verified on the reported head ai:completed Agent work completed; required factors are fresh and removed ai:processing An agent is working on this pull request labels Oct 11, 2026
@dzykovic
dzykovic merged commit af0a0fd into main Oct 11, 2026
21 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai:completed Agent work completed; required factors are fresh ai:reviewed Diff reviewed on the reported head ai:verified Declared behavior verified on the reported head

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants