@event4u/agent-config 8.13.0 → 9.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +183 -0
- package/MIGRATION.md +14 -0
- package/README.md +2 -2
- package/dist/agent-src/commands/agent-handoff.md +35 -0
- package/dist/agent-src/commands/agents/init.md +1 -0
- package/dist/agent-src/commands/agents/optimize.md +1 -0
- package/dist/agent-src/commands/agents/user/accept.md +3 -2
- package/dist/agent-src/commands/agents/user/init.md +5 -4
- package/dist/agent-src/commands/agents/user/update.md +3 -2
- package/dist/agent-src/commands/agents/user.md +1 -0
- package/dist/agent-src/commands/agents.md +1 -0
- package/dist/agent-src/commands/analytics/show.md +1 -0
- package/dist/agent-src/commands/analytics.md +1 -0
- package/dist/agent-src/commands/analyze/decision.md +1 -0
- package/dist/agent-src/commands/analyze/incident.md +1 -0
- package/dist/agent-src/commands/analyze/near-miss.md +1 -0
- package/dist/agent-src/commands/analyze/postmortem.md +1 -0
- package/dist/agent-src/commands/analyze/premortem.md +1 -0
- package/dist/agent-src/commands/analyze/reference-repo.md +1 -0
- package/dist/agent-src/commands/analyze.md +3 -2
- package/dist/agent-src/commands/brand/identity.md +6 -5
- package/dist/agent-src/commands/brand/review.md +6 -5
- package/dist/agent-src/commands/brand/strategy.md +6 -4
- package/dist/agent-src/commands/brand/tokens.md +7 -6
- package/dist/agent-src/commands/brand/voice.md +5 -4
- package/dist/agent-src/commands/brand.md +9 -7
- package/dist/agent-src/commands/bug/fix.md +1 -0
- package/dist/agent-src/commands/bug/investigate.md +1 -0
- package/dist/agent-src/commands/bug.md +2 -1
- package/dist/agent-src/commands/challenge-me/vision.md +1 -0
- package/dist/agent-src/commands/challenge-me/with-docs.md +1 -0
- package/dist/agent-src/commands/challenge-me.md +28 -6
- package/dist/agent-src/commands/chat-history.md +1 -0
- package/dist/agent-src/commands/check-current-md.md +1 -0
- package/dist/agent-src/commands/commit.md +1 -0
- package/dist/agent-src/commands/context/create.md +3 -2
- package/dist/agent-src/commands/context.md +1 -0
- package/dist/agent-src/commands/cost/profile.md +1 -0
- package/dist/agent-src/commands/cost.md +2 -1
- package/dist/agent-src/commands/council/analysis.md +1 -0
- package/dist/agent-src/commands/council/debate.md +1 -0
- package/dist/agent-src/commands/council/default.md +21 -20
- package/dist/agent-src/commands/council/design.md +1 -0
- package/dist/agent-src/commands/council/optimize.md +1 -0
- package/dist/agent-src/commands/council/pr.md +1 -0
- package/dist/agent-src/commands/council.md +1 -0
- package/dist/agent-src/commands/estimate-ticket.md +1 -0
- package/dist/agent-src/commands/explain-run.md +88 -0
- package/dist/agent-src/commands/feature/dev.md +1 -0
- package/dist/agent-src/commands/feature/explore.md +1 -0
- package/dist/agent-src/commands/feature/plan.md +1 -0
- package/dist/agent-src/commands/feature/refactor.md +1 -0
- package/dist/agent-src/commands/feature/roadmap.md +1 -0
- package/dist/agent-src/commands/feature.md +2 -1
- package/dist/agent-src/commands/fix/pr-comments.md +19 -0
- package/dist/agent-src/commands/fix.md +2 -1
- package/dist/agent-src/commands/ghostwriter/delete.md +1 -0
- package/dist/agent-src/commands/ghostwriter/fetch.md +1 -0
- package/dist/agent-src/commands/ghostwriter/show.md +1 -0
- package/dist/agent-src/commands/ghostwriter/write.md +1 -0
- package/dist/agent-src/commands/ghostwriter.md +1 -0
- package/dist/agent-src/commands/grill-me.md +17 -12
- package/dist/agent-src/commands/humanize.md +1 -0
- package/dist/agent-src/commands/image/analyse.md +2 -1
- package/dist/agent-src/commands/image/create.md +1 -0
- package/dist/agent-src/commands/image/verify.md +1 -0
- package/dist/agent-src/commands/image.md +16 -12
- package/dist/agent-src/commands/implement-ticket.md +1 -0
- package/dist/agent-src/commands/judge/on-diff.md +1 -0
- package/dist/agent-src/commands/judge/solo.md +1 -0
- package/dist/agent-src/commands/judge/steps.md +1 -0
- package/dist/agent-src/commands/judge.md +1 -0
- package/dist/agent-src/commands/knowledge/cross-repo.md +1 -0
- package/dist/agent-src/commands/knowledge/forget.md +1 -0
- package/dist/agent-src/commands/knowledge/ingest.md +1 -0
- package/dist/agent-src/commands/knowledge/list.md +10 -0
- package/dist/agent-src/commands/knowledge.md +1 -0
- package/dist/agent-src/commands/memory/learn-low-impact.md +1 -0
- package/dist/agent-src/commands/memory/mine-session.md +1 -0
- package/dist/agent-src/commands/memory/promote.md +3 -2
- package/dist/agent-src/commands/memory.md +1 -0
- package/dist/agent-src/commands/mission/upgrade.md +45 -24
- package/dist/agent-src/commands/mode.md +1 -0
- package/dist/agent-src/commands/module/create.md +1 -0
- package/dist/agent-src/commands/module/explore.md +1 -0
- package/dist/agent-src/commands/module.md +1 -0
- package/dist/agent-src/commands/optimize/agents-dir.md +1 -0
- package/dist/agent-src/commands/optimize/project.md +1 -0
- package/dist/agent-src/commands/optimize/prompt.md +1 -0
- package/dist/agent-src/commands/optimize.md +2 -1
- package/dist/agent-src/commands/orchestrate.md +1 -0
- package/dist/agent-src/commands/override.md +1 -0
- package/dist/agent-src/commands/package.md +2 -1
- package/dist/agent-src/commands/post-as/ghostwriter.md +1 -0
- package/dist/agent-src/commands/post-as/me.md +1 -0
- package/dist/agent-src/commands/post-as.md +1 -0
- package/dist/agent-src/commands/pr/create/description-only.md +139 -8
- package/dist/agent-src/commands/pr/create.md +35 -22
- package/dist/agent-src/commands/prediction-pool.md +7 -6
- package/dist/agent-src/commands/prepare-for-review.md +1 -0
- package/dist/agent-src/commands/profile/activate.md +1 -0
- package/dist/agent-src/commands/profile/deactivate.md +1 -0
- package/dist/agent-src/commands/profile.md +1 -0
- package/dist/agent-src/commands/project.md +2 -1
- package/dist/agent-src/commands/refine-ticket.md +7 -0
- package/dist/agent-src/commands/research/deep.md +1 -0
- package/dist/agent-src/commands/research.md +1 -0
- package/dist/agent-src/commands/review/routing.md +1 -0
- package/dist/agent-src/commands/review.md +2 -1
- package/dist/agent-src/commands/roadmap/ai-council.md +1 -0
- package/dist/agent-src/commands/roadmap/materialize.md +1 -0
- package/dist/agent-src/commands/roadmap/process-full.md +1 -0
- package/dist/agent-src/commands/roadmap/process-phase.md +1 -0
- package/dist/agent-src/commands/roadmap/process-step.md +1 -0
- package/dist/agent-src/commands/roadmap.md +1 -0
- package/dist/agent-src/commands/security-audit-config.md +2 -1
- package/dist/agent-src/commands/skill/preview.md +1 -0
- package/dist/agent-src/commands/skill.md +1 -0
- package/dist/agent-src/commands/skills/discover.md +1 -0
- package/dist/agent-src/commands/skills.md +1 -0
- package/dist/agent-src/commands/sync/agent-settings.md +1 -0
- package/dist/agent-src/commands/sync.md +2 -1
- package/dist/agent-src/commands/team/adversarial.md +3 -2
- package/dist/agent-src/commands/team/delegate.md +3 -2
- package/dist/agent-src/commands/team/review.md +3 -2
- package/dist/agent-src/commands/team/status.md +49 -18
- package/dist/agent-src/commands/team-knowledge.md +8 -6
- package/dist/agent-src/commands/team.md +21 -16
- package/dist/agent-src/commands/tests/e2e-heal.md +1 -0
- package/dist/agent-src/commands/tests/e2e-plan.md +1 -0
- package/dist/agent-src/commands/tests/execute.md +1 -0
- package/dist/agent-src/commands/tests.md +2 -1
- package/dist/agent-src/commands/update-form-request-messages.md +1 -0
- package/dist/agent-src/commands/upstream-contribute.md +1 -0
- package/dist/agent-src/commands/video/from-script.md +3 -2
- package/dist/agent-src/commands/video/from-song.md +22 -21
- package/dist/agent-src/commands/video/scene.md +1 -0
- package/dist/agent-src/commands/video/stitch.md +2 -1
- package/dist/agent-src/commands/video/storyboard.md +1 -0
- package/dist/agent-src/commands/video.md +1 -0
- package/dist/agent-src/commands/work.md +1 -0
- package/dist/agent-src/commands/worktree/cleanup.md +8 -7
- package/dist/agent-src/commands/worktree/create.md +1 -0
- package/dist/agent-src/commands/worktree/verify.md +1 -0
- package/dist/agent-src/commands/worktree.md +1 -0
- package/dist/agent-src/rules/active-remediation.md +12 -36
- package/dist/agent-src/rules/artifact-drafting-protocol.md +7 -64
- package/dist/agent-src/rules/context-hygiene.md +19 -113
- package/dist/agent-src/rules/design-fidelity.md +4 -60
- package/dist/agent-src/rules/domain-adoption-policy.md +10 -106
- package/dist/agent-src/rules/framework-neutrality-in-generic-skills.md +12 -60
- package/dist/agent-src/rules/improve-before-implement.md +4 -0
- package/dist/agent-src/rules/minimal-safe-diff.md +6 -86
- package/dist/agent-src/rules/size-enforcement.md +10 -0
- package/dist/agent-src/rules/tool-safety.md +17 -3
- package/dist/agent-src/skills/agent-security-review/SKILL.md +12 -1
- package/dist/agent-src/skills/ai-council/SKILL.md +11 -0
- package/dist/agent-src/skills/bug-analyzer/SKILL.md +24 -2
- package/dist/agent-src/skills/code-review/SKILL.md +105 -93
- package/dist/agent-src/skills/code-review/checklists/backend.md +50 -0
- package/dist/agent-src/skills/code-review/checklists/database.md +19 -0
- package/dist/agent-src/skills/code-review/checklists/dependency.md +18 -0
- package/dist/agent-src/skills/code-review/checklists/docs.md +14 -0
- package/dist/agent-src/skills/code-review/checklists/frontend.md +19 -0
- package/dist/agent-src/skills/code-review/checklists/infra.md +17 -0
- package/dist/agent-src/skills/code-review/checklists/producing-the-review.md +62 -0
- package/dist/agent-src/skills/code-review/checklists/test-only.md +13 -0
- package/dist/agent-src/skills/code-review/evals/evals.json +53 -15
- package/dist/agent-src/skills/condense-memory/SKILL.md +3 -2
- package/dist/agent-src/skills/conventional-commits-writing/evals/evals.json +15 -0
- package/dist/agent-src/skills/docker/SKILL.md +10 -0
- package/dist/agent-src/skills/docx-authoring/SKILL.md +102 -0
- package/dist/agent-src/skills/github-ci/evals/evals.json +25 -0
- package/dist/agent-src/skills/humanizer/SKILL.md +79 -3
- package/dist/agent-src/skills/humanizer/references/anti-aiisms.md +112 -0
- package/dist/agent-src/skills/humanizer/references/fixtures.md +70 -0
- package/dist/agent-src/skills/judge-bug-hunter/SKILL.md +7 -1
- package/dist/agent-src/skills/laravel/SKILL.md +10 -0
- package/dist/agent-src/skills/launch-readiness/SKILL.md +35 -0
- package/dist/agent-src/skills/llm-provider-knowledge/SKILL.md +146 -0
- package/dist/agent-src/skills/llm-provider-knowledge/evals/triggers.json +20 -0
- package/dist/agent-src/skills/merge-conflicts/SKILL.md +30 -0
- package/dist/agent-src/skills/pdf-tools/SKILL.md +101 -0
- package/dist/agent-src/skills/quality-tools/evals/evals.json +15 -0
- package/dist/agent-src/skills/security-audit/SKILL.md +29 -0
- package/dist/agent-src/skills/security-maturity-assessment/SKILL.md +90 -0
- package/dist/agent-src/skills/security-maturity-assessment/evals/triggers.json +52 -0
- package/dist/agent-src/skills/skill-writing/SKILL.md +79 -0
- package/dist/agent-src/skills/spreadsheet-authoring/SKILL.md +11 -3
- package/dist/agent-src/skills/subagent-orchestration/prompts/README.md +11 -0
- package/dist/agent-src/skills/subagent-orchestration/schemas/team-review-status.json +103 -0
- package/dist/agent-src/skills/terraform/SKILL.md +10 -0
- package/dist/agent-src/skills/test-driven-development/SKILL.md +31 -0
- package/dist/agent-src/skills/threat-modeling/SKILL.md +15 -0
- package/dist/agent-src/skills/token-optimizer/SKILL.md +10 -4
- package/dist/agent-src/templates/agent-settings.md +28 -0
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/agent-src/templates/scripts/telemetry/aggregator.ts +0 -0
- package/dist/agent-src/templates/scripts/telemetry/engagement.ts +30 -0
- package/dist/agent-src/templates/scripts/telemetry/report_renderer.ts +22 -9
- package/dist/agent-src/templates/scripts/telemetry_record.ts +5 -0
- package/dist/agent-src/templates/scripts/work_engine/_lib/agent_settings.ts +4 -1
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +314 -194
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +5 -5
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +23 -18
- package/dist/discovery/trust-report.md +8 -8
- package/dist/discovery/workspaces.json +18 -13
- package/dist/install/install.mjs +48 -33
- package/dist/mcp/registry-manifest.json +3 -3
- package/dist/router.json +1 -1
- package/dist/scripts/_lib/agent_settings.js +4 -1
- package/dist/scripts/_lib/agent_settings.js.map +1 -1
- package/dist/scripts/condense.js +5 -0
- package/dist/scripts/condense.js.map +1 -1
- package/dist/server/schemas/settings.js +10 -1
- package/dist/server/schemas/settings.js.map +1 -1
- package/docs/CLAIMS.md +9 -2
- package/docs/MIGRATION.md +20 -0
- package/docs/SKILL_CENSUS.md +8 -0
- package/docs/architecture.md +3 -3
- package/docs/benchmark.md +67 -2
- package/docs/catalog.md +2 -2
- package/docs/command-flows.md +1 -1
- package/docs/contracts/agents-layout.md +1 -1
- package/docs/contracts/ai-council-config.md +9 -2
- package/docs/contracts/ai-team-config.md +37 -4
- package/docs/contracts/consumer-bridge.md +55 -63
- package/docs/contracts/install-layout.md +1 -1
- package/docs/contracts/migrate-command.md +1 -1
- package/docs/contracts/prelaunch-diagnostics.md +151 -0
- package/docs/contracts/release-pr-gating.md +1 -0
- package/docs/customization.md +22 -1
- package/docs/decisions/ADR-020-global-only-consumer-scope.md +34 -0
- package/docs/decisions/ADR-049-configuration-trust-boundary.md +9 -1
- package/docs/featured-skills.md +2 -2
- package/docs/getting-started-by-role.md +1 -1
- package/docs/getting-started.md +17 -6
- package/docs/governance-advantage.md +1 -1
- package/docs/guidelines/agent-infra/active-remediation-mechanics.md +45 -0
- package/docs/guidelines/agent-infra/agent-interaction-and-decision-quality.md +28 -0
- package/docs/guidelines/agent-infra/api-cost-levers.md +126 -0
- package/docs/guidelines/agent-infra/artifact-drafting-protocol-mechanics.md +76 -0
- package/docs/guidelines/agent-infra/context-hygiene-mechanics.md +90 -0
- package/docs/guidelines/agent-infra/domain-adoption-gates.md +112 -0
- package/docs/guidelines/agent-infra/framework-neutrality-patterns.md +66 -0
- package/docs/guidelines/agent-infra/minimal-safe-diff-mechanics.md +99 -0
- package/docs/guidelines/agent-infra/skill-quality-checklist.md +13 -0
- package/docs/guidelines/design-fidelity-mechanics.md +76 -0
- package/docs/installation.md +2 -1
- package/docs/maintainers/dev-mode.md +3 -2
- package/docs/parity/command-frontmatter.md +60 -0
- package/docs/proof.md +7 -6
- package/package.json +1 -1
- package/src/agent-src/templates/scripts/telemetry/aggregator.ts +0 -0
- package/src/agent-src/templates/scripts/telemetry/engagement.ts +30 -0
- package/src/agent-src/templates/scripts/telemetry/report_renderer.ts +22 -9
- package/src/agent-src/templates/scripts/telemetry_record.ts +5 -0
- package/src/agent-src/templates/scripts/work_engine/_lib/agent_settings.ts +4 -1
- package/src/config/agent-settings.template.yml +73 -10
- package/src/config/gitignore-block.txt +16 -6
- package/src/config/prelaunch-areas.yml +36 -0
- package/src/scripts/_cli/cmd_conformance.ts +2 -2
- package/src/scripts/_cli/cmd_doctor.ts +280 -39
- package/src/scripts/_cli/cmd_refresh.ts +35 -118
- package/src/scripts/_lib/agent_settings.ts +4 -1
- package/src/scripts/_lib/claude_plugin.ts +77 -2
- package/src/scripts/_lib/orchestration_record.ts +5 -0
- package/src/scripts/_lib/tool_adapter_registry.ts +120 -0
- package/src/scripts/ai_council/clients.ts +68 -6
- package/src/scripts/ai_council/pricing.ts +62 -0
- package/src/scripts/ai_team/config.ts +73 -1
- package/src/scripts/ai_team/review_gate.ts +636 -0
- package/src/scripts/ai_team/team_dispatch.ts +612 -0
- package/src/scripts/bench_ab_task_runner.ts +11 -1
- package/src/scripts/bench_parity_count.ts +279 -0
- package/src/scripts/build_linear_digest.ts +3 -1
- package/src/scripts/check_bridge_derivation.ts +172 -0
- package/src/scripts/check_consumer_scope_flip.ts +179 -0
- package/src/scripts/check_council_config_location.ts +115 -15
- package/src/scripts/check_host_loadability.ts +81 -0
- package/src/scripts/condense.ts +5 -0
- package/src/scripts/council_cli.ts +19 -3
- package/src/scripts/hook_manifest.yaml +12 -1
- package/src/scripts/install.ts +44 -45
- package/src/scripts/lint_agents_layout.ts +10 -4
- package/src/scripts/lint_breaking_changes_index.ts +303 -0
- package/src/scripts/lint_handoffs.ts +42 -0
- package/src/scripts/lint_skill_descriptions.ts +228 -0
- package/src/scripts/lint_skill_descriptions_allowlist.json +1 -0
- package/src/scripts/lint_skill_scripts_readonly.ts +145 -0
- package/src/scripts/lint_skill_scripts_readonly_allowlist.json +8 -0
- package/src/scripts/lint_supported_tools_matrix.ts +35 -0
- package/src/scripts/mcp_server/tools.ts +1 -3
- package/src/scripts/optimize_skill_description.ts +144 -0
- package/src/scripts/orchestration_record.ts +2 -1
- package/src/scripts/prelaunch_diagnostics.ts +248 -0
- package/src/scripts/run_skill_evals.ts +70 -4
- package/src/scripts/schemas/agent-settings.schema.json +17 -0
- package/src/scripts/schemas/command.schema.json +7 -0
- package/src/scripts/schemas/evals.schema.json +105 -14
- package/src/scripts/schemas/prelaunch-report.schema.json +107 -0
- package/src/scripts/schemas/skill.schema.json +18 -1
- package/src/scripts/schemas/subagent.schema.json +6 -0
- package/src/scripts/self_review_gate.test.ts +11 -0
- package/src/scripts/self_review_gate.ts +7 -1
- package/src/scripts/skill_eval_coverage.ts +4 -1
- package/src/scripts/skill_linter.ts +43 -3
- package/src/scripts/smoke_host_loadability.sh +73 -0
- package/src/scripts/team_review_gate_hook.ts +115 -0
- package/src/scripts/trigger_eval_grandfather.json +1 -2
- package/src/scripts/utilization_report.ts +225 -0
- package/src/server/schemas/settings.ts +24 -1
|
@@ -3,11 +3,17 @@
|
|
|
3
3
|
* CI guard: council config lives in `.ai-council.yml`, never `.agent-settings.yml`.
|
|
4
4
|
*
|
|
5
5
|
* Ported from the retired Python `src/scripts/check_council_config_location.py` (ADR-200).
|
|
6
|
-
* The
|
|
7
|
-
* 1 at least one violation), byte-identical finding
|
|
8
|
-
* (sorted), same fence tracking, same negation /
|
|
9
|
-
* and the same `<!-- council-config-allowed -->`
|
|
10
|
-
*
|
|
6
|
+
* The original two checks keep their pinned CLI contract — `--quiet` flag,
|
|
7
|
+
* exit codes (0 clean, 1 at least one violation), byte-identical finding
|
|
8
|
+
* messages, same `SCAN_GLOBS` (sorted), same fence tracking, same negation /
|
|
9
|
+
* `ai_council:` block detection, and the same `<!-- council-config-allowed -->`
|
|
10
|
+
* escape pragma.
|
|
11
|
+
*
|
|
12
|
+
* Additive since ADR-104: a third check (§3 below) flags project-tree
|
|
13
|
+
* *placement* of the council file. The original two checks are unchanged; the
|
|
14
|
+
* path check runs over its own `PATH_CHECK_GLOBS` (the council surfaces + the
|
|
15
|
+
* settings template + the `.ai-council.yml.example`) so the settings template's
|
|
16
|
+
* many legitimate `.agent-settings.yml` self-references never trip check §1.
|
|
11
17
|
*
|
|
12
18
|
* Per ADR-104 (superseding ADR-093) the council reads a dedicated
|
|
13
19
|
* `.ai-council.yml` resolved ALWAYS from the user-global location
|
|
@@ -16,19 +22,26 @@
|
|
|
16
22
|
* path). Keys are top-level in that file; the legacy `ai_council.*` block
|
|
17
23
|
* under `.agent-settings.yml` was removed in Phase 0.
|
|
18
24
|
*
|
|
19
|
-
* What it flags
|
|
25
|
+
* What it flags:
|
|
20
26
|
*
|
|
21
27
|
* 1. A `.agent-settings.yml` reference that is NOT negated — i.e. an
|
|
22
28
|
* instruction to read/use it for council config. Corrective mentions
|
|
23
29
|
* ("NOT in `.agent-settings.yml`", "was removed", "never read") carry a
|
|
24
|
-
* negation marker on the same line and are allowed.
|
|
30
|
+
* negation marker on the same line and are allowed. (SCAN_GLOBS)
|
|
25
31
|
* 2. A bare `ai_council:` YAML parent-block declaration — post-ADR-093 the
|
|
26
32
|
* keys are top-level in `.ai-council.yml`; there is no `ai_council:`
|
|
27
|
-
* namespace to nest under.
|
|
33
|
+
* namespace to nest under. (SCAN_GLOBS)
|
|
34
|
+
* 3. A project-tree PLACEMENT of the council file — `agents/.ai-council.yml`,
|
|
35
|
+
* `agents/settings/.ai-council.yml`, or a `<project_root>/…/.ai-council.yml`
|
|
36
|
+
* path — that is NOT negated. The council file is user-global ONLY
|
|
37
|
+
* (ADR-104); any project-tree path is drift. Corrective mentions ("is
|
|
38
|
+
* ignored", "never read", "no project-local", "superseded") pass on the
|
|
39
|
+
* same line. (PATH_CHECK_GLOBS)
|
|
28
40
|
*
|
|
29
41
|
* Escape hatch: a line carrying `<!-- council-config-allowed -->` is exempt
|
|
30
42
|
* (for a legitimate non-council `.agent-settings.yml` reference, e.g.
|
|
31
|
-
* `personal.autonomy
|
|
43
|
+
* `personal.autonomy`, or a historical placement mention in a section
|
|
44
|
+
* explicitly marked superseded).
|
|
32
45
|
*
|
|
33
46
|
* Exit codes:
|
|
34
47
|
* 0 — clean.
|
|
@@ -61,6 +74,35 @@ const NEGATION_RE = /\b(not|never|removed|no\s+longer|neither|instead)\b/i;
|
|
|
61
74
|
const AI_COUNCIL_BLOCK_RE = /^\s*ai_council:\s*(#.*)?$/;
|
|
62
75
|
const ALLOW_PRAGMA = '<!-- council-config-allowed -->';
|
|
63
76
|
|
|
77
|
+
// ── §3 project-tree placement check (ADR-104) ──────────────────────
|
|
78
|
+
// The council file is user-global ONLY. These are the surfaces where a
|
|
79
|
+
// stray project-tree placement instruction does real damage — the council
|
|
80
|
+
// command/skill surfaces + contract (SCAN_GLOBS) PLUS the settings template
|
|
81
|
+
// and the copy-from example. The template carries countless legitimate
|
|
82
|
+
// `.agent-settings.yml` self-references, so it is scanned ONLY by §3, never
|
|
83
|
+
// by §1.
|
|
84
|
+
const PATH_CHECK_GLOBS = [
|
|
85
|
+
...SCAN_GLOBS,
|
|
86
|
+
'src/config/agent-settings.template.yml',
|
|
87
|
+
'agents/templates/.ai-council.yml.example',
|
|
88
|
+
] as const;
|
|
89
|
+
|
|
90
|
+
// A project-tree PLACEMENT of the council file: `agents/.ai-council.yml`,
|
|
91
|
+
// `agents/settings/.ai-council.yml`, or any `<project_root>/…/.ai-council.yml`.
|
|
92
|
+
// Deliberately does NOT match the user-global `…/agent-config/settings/
|
|
93
|
+
// .ai-council.yml` (no literal `agents/` segment) nor the copy-from
|
|
94
|
+
// `agents/templates/.ai-council.yml.example` (segment is `templates/`, and
|
|
95
|
+
// `.example` is not the config file).
|
|
96
|
+
const PROJECT_PATH_COUNCIL_RE =
|
|
97
|
+
/(?:agents\/(?:settings\/)?\.ai-council\.yml(?!\.example)|<project[_-]?root>[^\n`]*\.ai-council\.yml)/;
|
|
98
|
+
|
|
99
|
+
// Broader negation set for §3 — corrective placement mentions use vocabulary
|
|
100
|
+
// the §1 NEGATION_RE does not cover ("is ignored", "no project-local
|
|
101
|
+
// lookup", "superseded"). A match on the same line marks the reference
|
|
102
|
+
// corrective and is allowed.
|
|
103
|
+
const PATH_NEGATION_RE =
|
|
104
|
+
/\b(not|never|removed|no\s+longer|neither|instead|ignored|superseded|no\s+project-local|not\s+read|does\s+not\s+read)\b/i;
|
|
105
|
+
|
|
64
106
|
/**
|
|
65
107
|
* Mirror Python `str.lstrip()` — strips all leading Unicode whitespace.
|
|
66
108
|
* Python's `str.lstrip()` (no args) strips the Unicode whitespace class;
|
|
@@ -79,9 +121,12 @@ function _lstrip(s: string): string {
|
|
|
79
121
|
* the same sort (component-wise via Path comparison). We approximate with a
|
|
80
122
|
* recursive walk per glob pattern, sorting POSIX paths.
|
|
81
123
|
*/
|
|
82
|
-
function* iter_files(
|
|
124
|
+
function* iter_files(
|
|
125
|
+
root: string,
|
|
126
|
+
globs: readonly string[] = SCAN_GLOBS,
|
|
127
|
+
): Generator<string> {
|
|
83
128
|
const seen = new Set<string>();
|
|
84
|
-
for (const pattern of
|
|
129
|
+
for (const pattern of globs) {
|
|
85
130
|
for (const p of _glob(root, pattern)) {
|
|
86
131
|
if (_isFile(p) && !seen.has(p)) {
|
|
87
132
|
seen.add(p);
|
|
@@ -220,18 +265,69 @@ function find_violations(root: string): string[] {
|
|
|
220
265
|
return findings;
|
|
221
266
|
}
|
|
222
267
|
|
|
268
|
+
/**
|
|
269
|
+
* §3 — flag project-tree PLACEMENT of the council config file (ADR-104).
|
|
270
|
+
*
|
|
271
|
+
* The council file is user-global only; any `agents/(settings/)?.ai-council.yml`
|
|
272
|
+
* or `<project_root>/…/.ai-council.yml` path is drift. Corrective mentions
|
|
273
|
+
* (same-line `PATH_NEGATION_RE`) and the `<!-- council-config-allowed -->`
|
|
274
|
+
* pragma pass. Fenced code is skipped, mirroring §1/§2.
|
|
275
|
+
*/
|
|
276
|
+
function find_path_violations(root: string): string[] {
|
|
277
|
+
const findings: string[] = [];
|
|
278
|
+
for (const p of iter_files(root, PATH_CHECK_GLOBS)) {
|
|
279
|
+
const rel = _relPosix(root, p);
|
|
280
|
+
let in_fence = false;
|
|
281
|
+
const lines = fs.readFileSync(p, 'utf-8').split('\n');
|
|
282
|
+
if (lines.length > 0 && lines[lines.length - 1] === '') {
|
|
283
|
+
lines.pop();
|
|
284
|
+
}
|
|
285
|
+
for (let i = 0; i < lines.length; i++) {
|
|
286
|
+
const lineno = i + 1;
|
|
287
|
+
const raw = lines[i]!;
|
|
288
|
+
const stripped = _lstrip(raw);
|
|
289
|
+
if (stripped.startsWith('```') || stripped.startsWith('~~~')) {
|
|
290
|
+
in_fence = !in_fence;
|
|
291
|
+
continue;
|
|
292
|
+
}
|
|
293
|
+
if (in_fence || raw.includes(ALLOW_PRAGMA)) {
|
|
294
|
+
continue;
|
|
295
|
+
}
|
|
296
|
+
// Corrective sentences often wrap, leaving the negation
|
|
297
|
+
// ("never reads", "no project-local lookup") on the previous
|
|
298
|
+
// line and the path on this one. Check both lines for negation
|
|
299
|
+
// so a correctly-negated wrapped mention is not flagged. A real
|
|
300
|
+
// "place it here" instruction never carries a negation one line up.
|
|
301
|
+
const prev = i > 0 ? lines[i - 1]! : '';
|
|
302
|
+
const negated =
|
|
303
|
+
PATH_NEGATION_RE.test(raw) || PATH_NEGATION_RE.test(prev);
|
|
304
|
+
if (PROJECT_PATH_COUNCIL_RE.test(raw) && !negated) {
|
|
305
|
+
findings.push(
|
|
306
|
+
`${rel}:${lineno}: council config placed in the project tree ` +
|
|
307
|
+
'— the `.ai-council.yml` file is user-global ONLY ' +
|
|
308
|
+
'(`~/.event4u/agent-config/settings/.ai-council.yml`, ADR-104). ' +
|
|
309
|
+
'The project tree is never searched. Point at the user-global ' +
|
|
310
|
+
'path, add a negation marker, or add ' +
|
|
311
|
+
`\`${ALLOW_PRAGMA}\` for a historical/superseded reference.`,
|
|
312
|
+
);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
return findings;
|
|
317
|
+
}
|
|
318
|
+
|
|
223
319
|
function main(): number {
|
|
224
320
|
const root = process.cwd();
|
|
225
|
-
const findings = find_violations(root);
|
|
321
|
+
const findings = [...find_violations(root), ...find_path_violations(root)];
|
|
226
322
|
if (findings.length) {
|
|
227
323
|
process.stdout.write('❌ Council config-location violations:\n\n');
|
|
228
324
|
for (const f of findings) {
|
|
229
325
|
process.stdout.write(` - ${f}\n`);
|
|
230
326
|
}
|
|
231
327
|
process.stdout.write(
|
|
232
|
-
'\nRule: council config lives in `.ai-council.yml` ' +
|
|
233
|
-
'(
|
|
234
|
-
'`.agent-settings.yml
|
|
328
|
+
'\nRule: council config lives in the user-global `.ai-council.yml` ' +
|
|
329
|
+
'(`~/.event4u/agent-config/settings/.ai-council.yml`, ADR-104) — ' +
|
|
330
|
+
'never in `.agent-settings.yml`, never in a project `agents/` tree.\n',
|
|
235
331
|
);
|
|
236
332
|
return 1;
|
|
237
333
|
}
|
|
@@ -270,11 +366,15 @@ if (_isCliEntry() || process.argv[1] === _HERE) {
|
|
|
270
366
|
|
|
271
367
|
export {
|
|
272
368
|
SCAN_GLOBS,
|
|
369
|
+
PATH_CHECK_GLOBS,
|
|
273
370
|
AGENT_SETTINGS_RE,
|
|
274
371
|
NEGATION_RE,
|
|
275
372
|
AI_COUNCIL_BLOCK_RE,
|
|
373
|
+
PROJECT_PATH_COUNCIL_RE,
|
|
374
|
+
PATH_NEGATION_RE,
|
|
276
375
|
ALLOW_PRAGMA,
|
|
277
376
|
iter_files,
|
|
278
377
|
find_violations,
|
|
378
|
+
find_path_violations,
|
|
279
379
|
main,
|
|
280
380
|
};
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* check_host_loadability.ts — U4 real-host loadability smoke
|
|
3
|
+
* (road-to-ecosystem-harvest-reliability-measurement).
|
|
4
|
+
*
|
|
5
|
+
* The condensation-hash + linter gates prove the SOURCE tree's shape; this
|
|
6
|
+
* check proves the GENERATED host trees are actually loadable by their hosts:
|
|
7
|
+
* - .claude/skills/<dir>/SKILL.md — frontmatter parses, has name +
|
|
8
|
+
* description, and name matches the directory (Claude Code's load rule).
|
|
9
|
+
* - .cursor/rules/*.mdc — frontmatter parses (Cursor rejects the file
|
|
10
|
+
* silently otherwise).
|
|
11
|
+
* Run AFTER the projection is generated (CI: the sync-consistency job).
|
|
12
|
+
* Exit 1 on the first malformed artefact, naming it.
|
|
13
|
+
*/
|
|
14
|
+
import * as fs from 'node:fs';
|
|
15
|
+
import * as path from 'node:path';
|
|
16
|
+
|
|
17
|
+
import { parse as parseYaml } from 'yaml';
|
|
18
|
+
|
|
19
|
+
export function check_claude_skills(root: string, errors: string[]): void {
|
|
20
|
+
const dir = path.join(root, '.claude', 'skills');
|
|
21
|
+
if (!fs.existsSync(dir)) return;
|
|
22
|
+
for (const name of fs.readdirSync(dir)) {
|
|
23
|
+
const skillMd = path.join(dir, name, 'SKILL.md');
|
|
24
|
+
if (!fs.existsSync(skillMd)) {
|
|
25
|
+
errors.push(`${skillMd}: missing SKILL.md`);
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
const src = fs.readFileSync(skillMd, 'utf-8');
|
|
29
|
+
const m = src.match(/^---\n([\s\S]*?)\n---/);
|
|
30
|
+
if (!m) { errors.push(`${skillMd}: no frontmatter`); continue; }
|
|
31
|
+
let meta: Record<string, unknown>;
|
|
32
|
+
try { meta = parseYaml(m[1] ?? '') as Record<string, unknown>; }
|
|
33
|
+
catch (e) { errors.push(`${skillMd}: frontmatter YAML invalid (${(e as Error).message})`); continue; }
|
|
34
|
+
if (typeof meta['name'] !== 'string' || !meta['name']) errors.push(`${skillMd}: missing name`);
|
|
35
|
+
else if (meta['name'] !== name) errors.push(`${skillMd}: name '${meta['name']}' != dir '${name}'`);
|
|
36
|
+
if (typeof meta['description'] !== 'string' || !meta['description']) errors.push(`${skillMd}: missing description`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function check_cursor_rules(root: string, errors: string[]): void {
|
|
41
|
+
const dir = path.join(root, '.cursor', 'rules');
|
|
42
|
+
if (!fs.existsSync(dir)) return;
|
|
43
|
+
for (const name of fs.readdirSync(dir)) {
|
|
44
|
+
if (!name.endsWith('.mdc')) continue;
|
|
45
|
+
const p = path.join(dir, name);
|
|
46
|
+
const src = fs.readFileSync(p, 'utf-8');
|
|
47
|
+
const m = src.match(/^---\n([\s\S]*?)\n---/);
|
|
48
|
+
if (!m) { errors.push(`${p}: no frontmatter`); continue; }
|
|
49
|
+
// Cursor's documented .mdc format writes `globs: *.php` UNQUOTED —
|
|
50
|
+
// valid for Cursor's parser, invalid strict YAML (`*` starts an
|
|
51
|
+
// alias). Quote the globs value before the strict parse so the check
|
|
52
|
+
// mirrors the host's acceptance, not the YAML spec's.
|
|
53
|
+
const lenient = (m[1] ?? '').replace(
|
|
54
|
+
/^(globs:[ \t]*)([^"'\s[][^\n]*)$/m,
|
|
55
|
+
(_all, key: string, val: string) => `${key}"${val.trim()}"`,
|
|
56
|
+
);
|
|
57
|
+
try { parseYaml(lenient); }
|
|
58
|
+
catch (e) { errors.push(`${p}: frontmatter YAML invalid (${(e as Error).message})`); }
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function run(root: string): string[] {
|
|
63
|
+
const errors: string[] = [];
|
|
64
|
+
check_claude_skills(root, errors);
|
|
65
|
+
check_cursor_rules(root, errors);
|
|
66
|
+
return errors;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const isMain = process.argv[1] !== undefined
|
|
70
|
+
&& path.resolve(process.argv[1]) === path.resolve(new URL(import.meta.url).pathname);
|
|
71
|
+
if (isMain) {
|
|
72
|
+
const rootIdx = process.argv.indexOf('--root');
|
|
73
|
+
const root = rootIdx !== -1 ? process.argv[rootIdx + 1] ?? '.' : '.';
|
|
74
|
+
const errors = run(root);
|
|
75
|
+
if (errors.length > 0) {
|
|
76
|
+
for (const e of errors) process.stderr.write(`❌ ${e}\n`);
|
|
77
|
+
process.exit(1);
|
|
78
|
+
}
|
|
79
|
+
process.stdout.write('✅ host trees loadable (.claude skills + .cursor mdc)\n');
|
|
80
|
+
process.exit(0);
|
|
81
|
+
}
|
package/src/scripts/condense.ts
CHANGED
|
@@ -1670,6 +1670,10 @@ export function generate_claude_subagents(): number {
|
|
|
1670
1670
|
const tools = Array.isArray(toolsRaw) ? toolsRaw.map((t) => String(t)).join(', ') : String(toolsRaw ?? '');
|
|
1671
1671
|
const tier = typeof fm['model_tier'] === 'string' ? (fm['model_tier'] as string) : 'inherit';
|
|
1672
1672
|
const model = tier === 'inherit' ? 'inherit' : (_TIER_TO_CLAUDE_MODEL[tier] ?? 'inherit');
|
|
1673
|
+
// Optional pinned reasoning effort (skill-quality-gates Phase 4, Source S):
|
|
1674
|
+
// pass through to the native frontmatter only when the source declares it —
|
|
1675
|
+
// hosts without an effort knob never see the key.
|
|
1676
|
+
const effort = typeof fm['effort'] === 'string' ? (fm['effort'] as string) : null;
|
|
1673
1677
|
|
|
1674
1678
|
const guardedBody =
|
|
1675
1679
|
defense !== '' && !body.includes('prompt-defense-preamble')
|
|
@@ -1681,6 +1685,7 @@ export function generate_claude_subagents(): number {
|
|
|
1681
1685
|
`description: ${description}\n` +
|
|
1682
1686
|
`tools: ${tools}\n` +
|
|
1683
1687
|
`model: ${model}\n` +
|
|
1688
|
+
(effort !== null ? `effort: ${effort}\n` : '') +
|
|
1684
1689
|
'---\n' +
|
|
1685
1690
|
guardedBody;
|
|
1686
1691
|
|
|
@@ -603,8 +603,13 @@ function build_members(settings: Dict, opts: BuildMembersOptions = {}): External
|
|
|
603
603
|
);
|
|
604
604
|
}
|
|
605
605
|
const api_key_ref = (cfg['api_key_ref'] as string | null) ?? null;
|
|
606
|
+
// Council opts in explicitly (caching is client-default OFF): on
|
|
607
|
+
// unless the operator sets `prompt_cache: false` on the member.
|
|
608
|
+
const enable_prompt_cache = cfg['prompt_cache'] !== false;
|
|
606
609
|
for (const sib_model of siblings[name] as string[]) {
|
|
607
|
-
members.push(
|
|
610
|
+
members.push(
|
|
611
|
+
_construct_api_member(name, sib_model, { api_key_ref, enable_prompt_cache }),
|
|
612
|
+
);
|
|
608
613
|
}
|
|
609
614
|
continue;
|
|
610
615
|
}
|
|
@@ -613,6 +618,9 @@ function build_members(settings: Dict, opts: BuildMembersOptions = {}): External
|
|
|
613
618
|
members.push(
|
|
614
619
|
_construct_api_member(name, model, {
|
|
615
620
|
api_key_ref: (cfg['api_key_ref'] as string | null) ?? null,
|
|
621
|
+
// Council opts in explicitly (client-default OFF); on unless
|
|
622
|
+
// the operator sets `prompt_cache: false`.
|
|
623
|
+
enable_prompt_cache: cfg['prompt_cache'] !== false,
|
|
616
624
|
}),
|
|
617
625
|
);
|
|
618
626
|
} else if (mode === 'cli' && _CLI_PROVIDERS.has(name)) {
|
|
@@ -747,14 +755,18 @@ function _format_advisor_summary(
|
|
|
747
755
|
function _construct_api_member(
|
|
748
756
|
name: string,
|
|
749
757
|
model: string | null,
|
|
750
|
-
opts: { api_key_ref?: string | null } = {},
|
|
758
|
+
opts: { api_key_ref?: string | null; enable_prompt_cache?: boolean | undefined } = {},
|
|
751
759
|
): ExternalAIClient {
|
|
752
760
|
const api_key_ref = opts.api_key_ref ?? null;
|
|
753
761
|
if (name === 'anthropic') {
|
|
754
762
|
const api_key = api_key_ref
|
|
755
763
|
? resolve_api_key(api_key_ref, 'ai_council.members.anthropic')
|
|
756
764
|
: load_anthropic_key();
|
|
757
|
-
return new AnthropicClient({
|
|
765
|
+
return new AnthropicClient({
|
|
766
|
+
model: model || 'claude-sonnet-4-5',
|
|
767
|
+
api_key,
|
|
768
|
+
enable_prompt_cache: opts.enable_prompt_cache,
|
|
769
|
+
});
|
|
758
770
|
}
|
|
759
771
|
if (name === 'openai') {
|
|
760
772
|
const api_key = api_key_ref
|
|
@@ -1409,6 +1421,8 @@ function _serialise_responses(responses: CouncilResponse[]): Dict[] {
|
|
|
1409
1421
|
text: r.text,
|
|
1410
1422
|
input_tokens: r.input_tokens,
|
|
1411
1423
|
output_tokens: r.output_tokens,
|
|
1424
|
+
cache_creation_input_tokens: r.cache_creation_input_tokens,
|
|
1425
|
+
cache_read_input_tokens: r.cache_read_input_tokens,
|
|
1412
1426
|
latency_ms: r.latency_ms,
|
|
1413
1427
|
error: r.error,
|
|
1414
1428
|
metadata,
|
|
@@ -1427,6 +1441,8 @@ function _deserialise_responses(items: Dict[]): CouncilResponse[] {
|
|
|
1427
1441
|
text: (d['text'] as string) ?? '',
|
|
1428
1442
|
input_tokens: _pyInt(d['input_tokens'] ?? 0, 0),
|
|
1429
1443
|
output_tokens: _pyInt(d['output_tokens'] ?? 0, 0),
|
|
1444
|
+
cache_creation_input_tokens: _pyInt(d['cache_creation_input_tokens'] ?? 0, 0),
|
|
1445
|
+
cache_read_input_tokens: _pyInt(d['cache_read_input_tokens'] ?? 0, 0),
|
|
1430
1446
|
latency_ms: _pyInt(d['latency_ms'] ?? 0, 0),
|
|
1431
1447
|
error: (d['error'] as string | null) ?? null,
|
|
1432
1448
|
metadata: (d['metadata'] as Dict) || {},
|
|
@@ -134,6 +134,17 @@ concerns:
|
|
|
134
134
|
script: src/scripts/surface_probe_hook.ts
|
|
135
135
|
args: []
|
|
136
136
|
fail_closed: false
|
|
137
|
+
# road-to-team-mode Phase 4 — managed Review-Gate circuit breaker.
|
|
138
|
+
# Runs AFTER the plugin's own Stop gate: reads the persisted gate job
|
|
139
|
+
# record, counts consecutive BLOCK verdicts per session, injects the
|
|
140
|
+
# circuit-breaker notice exactly once at ai_team.review_gate.
|
|
141
|
+
# max_consecutive_blocks. No-op (byte-identical Stop path) while
|
|
142
|
+
# ai_team.review_gate.managed is false — the shipped default.
|
|
143
|
+
# Never blocks, exit 0 always.
|
|
144
|
+
team-review-gate:
|
|
145
|
+
script: src/scripts/team_review_gate_hook.ts
|
|
146
|
+
args: []
|
|
147
|
+
fail_closed: false
|
|
137
148
|
|
|
138
149
|
platforms:
|
|
139
150
|
augment:
|
|
@@ -146,7 +157,7 @@ platforms:
|
|
|
146
157
|
claude:
|
|
147
158
|
session_start: [chat-history, hot-context, first-run-gate, onboarding-gate, verify-before-complete, minimal-safe-diff, profile-staleness, wrapper-freshness, surface-probe]
|
|
148
159
|
session_end: [chat-history]
|
|
149
|
-
stop: [chat-history, hot-context, verify-before-complete]
|
|
160
|
+
stop: [chat-history, hot-context, verify-before-complete, team-review-gate]
|
|
150
161
|
user_prompt_submit: [chat-history, verify-before-complete, minimal-safe-diff]
|
|
151
162
|
pre_tool_use: [block-no-verify, rtk-wrap, design-slop]
|
|
152
163
|
post_tool_use: [chat-history, roadmap-progress, context-hygiene, verify-before-complete, minimal-safe-diff, injection-scan]
|
package/src/scripts/install.ts
CHANGED
|
@@ -2494,7 +2494,11 @@ function _detect_legacy_for_migration(project_root: string): string[] {
|
|
|
2494
2494
|
return [];
|
|
2495
2495
|
}
|
|
2496
2496
|
|
|
2497
|
-
|
|
2497
|
+
// Migration-idempotency sentinel. Previously the consumer bridge marker;
|
|
2498
|
+
// that file was retired (ADR-020 amendment 2026-07-13), so the durable
|
|
2499
|
+
// "this project has already been installed / migrated" signal is now the
|
|
2500
|
+
// install-mode marker, written on every full or minimal install.
|
|
2501
|
+
if (isFile(path.join(project_root, INSTALL_MODE_MARKER_REL))) return [];
|
|
2498
2502
|
|
|
2499
2503
|
const found: string[] = [];
|
|
2500
2504
|
for (const name of MIGRATE_LEGACY_YAML_FILES) {
|
|
@@ -2573,38 +2577,34 @@ function _format_global_root_for_marker(global_root: string): string {
|
|
|
2573
2577
|
}
|
|
2574
2578
|
|
|
2575
2579
|
/**
|
|
2576
|
-
*
|
|
2577
|
-
*
|
|
2578
|
-
*
|
|
2580
|
+
* Remove a legacy `agents/.event4u-bridge.yml` if a previous install wrote
|
|
2581
|
+
* one. The bridge marker was retired (ADR-020 dated amendment 2026-07-13):
|
|
2582
|
+
* it carried no project-specific data — `global_root` is derived directly
|
|
2583
|
+
* from the well-known `~/.event4u/agent-config` path — yet was committed to
|
|
2584
|
+
* the shared project tree, so every developer's install rewrote its volatile
|
|
2585
|
+
* `installed_at` / `installer_version` fields and overwrote each other's.
|
|
2586
|
+
* The global root is now resolved from the well-known path; the migration
|
|
2587
|
+
* idempotency sentinel moved to `agents/.agent-state/install-mode.txt`.
|
|
2588
|
+
*
|
|
2589
|
+
* Skipped under `AGENT_CONFIG_DEV_MODE=1` and inside the agent-config source
|
|
2590
|
+
* repo (detected by the uncondensed-source marker dir) — the same gate the
|
|
2591
|
+
* writer used. Returns the removed path (so the caller can report it) or null.
|
|
2579
2592
|
*/
|
|
2580
|
-
function
|
|
2593
|
+
function _remove_legacy_consumer_bridge_marker(
|
|
2581
2594
|
project_root: string,
|
|
2582
|
-
installer_version: string,
|
|
2583
2595
|
env: NodeJS.ProcessEnv | null = null,
|
|
2584
|
-
now: Date | null = null,
|
|
2585
2596
|
): string | null {
|
|
2586
2597
|
const env_map = env ?? process.env;
|
|
2587
2598
|
if (env_map['AGENT_CONFIG_DEV_MODE'] === '1') return null;
|
|
2588
2599
|
if (isDir(path.join(project_root, '.agent-src.uncondensed'))) return null;
|
|
2589
2600
|
|
|
2590
|
-
const global_root_str = _format_global_root_for_marker(
|
|
2591
|
-
user_global_paths.event4u_root(env_map),
|
|
2592
|
-
);
|
|
2593
|
-
const stamp = utcStamp(now ?? undefined);
|
|
2594
|
-
|
|
2595
|
-
const body =
|
|
2596
|
-
'# event4u/agent-config — consumer bridge marker (auto-written).\n' +
|
|
2597
|
-
'# Spec: docs/contracts/consumer-bridge.md (event4u-bridge/v1).\n' +
|
|
2598
|
-
'# Reader contract: expand ~ against the current $HOME; fail closed\n' +
|
|
2599
|
-
'# when global_root is missing on disk; never write back through it.\n' +
|
|
2600
|
-
'schema: event4u-bridge/v1\n' +
|
|
2601
|
-
`global_root: ${global_root_str}\n` +
|
|
2602
|
-
`installed_at: ${stamp}\n` +
|
|
2603
|
-
`installer_version: ${installer_version}\n`;
|
|
2604
|
-
|
|
2605
2601
|
const target = path.join(project_root, CONSUMER_BRIDGE_MARKER_RELPATH);
|
|
2606
|
-
|
|
2607
|
-
|
|
2602
|
+
if (!isFile(target)) return null;
|
|
2603
|
+
try {
|
|
2604
|
+
fs.rmSync(target);
|
|
2605
|
+
} catch {
|
|
2606
|
+
return null;
|
|
2607
|
+
}
|
|
2608
2608
|
return target;
|
|
2609
2609
|
}
|
|
2610
2610
|
|
|
@@ -2641,16 +2641,14 @@ function _write_per_tool_project_anchors(
|
|
|
2641
2641
|
const target = path.join(project_root, rel_path);
|
|
2642
2642
|
mkdirp(path.dirname(target));
|
|
2643
2643
|
|
|
2644
|
-
const bridge_abs = path.join(project_root, CONSUMER_BRIDGE_MARKER_RELPATH);
|
|
2645
|
-
const bridge_rel = path.relative(path.dirname(target), bridge_abs);
|
|
2646
|
-
|
|
2647
2644
|
const body =
|
|
2648
2645
|
'# event4u/agent-config — per-tool project anchor (auto-written).\n' +
|
|
2649
2646
|
'# Spec: docs/contracts/consumer-bridge.md § Per-tool anchor strategy.\n' +
|
|
2650
|
-
`# Tool: ${tool_id}.
|
|
2647
|
+
`# Tool: ${tool_id}. Resolves the global install directly — no\n` +
|
|
2648
|
+
'# project-local bridge marker (retired, ADR-020 amendment 2026-07-13).\n' +
|
|
2649
|
+
'# This anchor is gitignored: each developer regenerates it on install.\n' +
|
|
2651
2650
|
'schema: event4u-bridge/v1\n' +
|
|
2652
2651
|
`tool: ${tool_id}\n` +
|
|
2653
|
-
`bridge: ${bridge_rel}\n` +
|
|
2654
2652
|
`global_root: ${global_root_str}\n` +
|
|
2655
2653
|
`installed_at: ${stamp}\n`;
|
|
2656
2654
|
|
|
@@ -3377,15 +3375,15 @@ function install_global(
|
|
|
3377
3375
|
const rc = _update_installed_tools_manifest(project_root, tools, 'global', force, files_by_tool);
|
|
3378
3376
|
if (rc !== 0) return rc;
|
|
3379
3377
|
|
|
3380
|
-
// Consumer bridge marker (
|
|
3381
|
-
//
|
|
3382
|
-
//
|
|
3383
|
-
const
|
|
3384
|
-
if (
|
|
3385
|
-
const rel = isRelativeTo(
|
|
3386
|
-
? path.relative(project_root,
|
|
3387
|
-
:
|
|
3388
|
-
info(`
|
|
3378
|
+
// Consumer bridge marker retired (ADR-020 amendment 2026-07-13):
|
|
3379
|
+
// clean up any legacy `agents/.event4u-bridge.yml` a prior install
|
|
3380
|
+
// committed. The global root is resolved from the well-known path.
|
|
3381
|
+
const removed_marker = _remove_legacy_consumer_bridge_marker(project_root);
|
|
3382
|
+
if (removed_marker !== null && !state.QUIET) {
|
|
3383
|
+
const rel = isRelativeTo(removed_marker, project_root)
|
|
3384
|
+
? path.relative(project_root, removed_marker)
|
|
3385
|
+
: removed_marker;
|
|
3386
|
+
info(`Removed legacy bridge marker: ${rel}`);
|
|
3389
3387
|
}
|
|
3390
3388
|
|
|
3391
3389
|
const anchor_paths = _write_per_tool_project_anchors(project_root, tools);
|
|
@@ -3800,13 +3798,14 @@ function install_minimal(target_root_in: string, force: boolean, user_type: stri
|
|
|
3800
3798
|
}
|
|
3801
3799
|
}
|
|
3802
3800
|
|
|
3803
|
-
|
|
3804
|
-
|
|
3805
|
-
|
|
3806
|
-
|
|
3807
|
-
|
|
3808
|
-
|
|
3809
|
-
|
|
3801
|
+
// Bridge marker retired (ADR-020 amendment 2026-07-13) — clean up any
|
|
3802
|
+
// legacy `agents/.event4u-bridge.yml` a prior install left behind.
|
|
3803
|
+
const removed_marker = _remove_legacy_consumer_bridge_marker(target_root);
|
|
3804
|
+
if (removed_marker !== null) {
|
|
3805
|
+
const rel = isRelativeTo(removed_marker, target_root)
|
|
3806
|
+
? path.relative(target_root, removed_marker)
|
|
3807
|
+
: removed_marker;
|
|
3808
|
+
success(`Removed legacy bridge marker: ${rel}`);
|
|
3810
3809
|
}
|
|
3811
3810
|
|
|
3812
3811
|
_write_install_mode_marker(target_root, 'minimal');
|
|
@@ -42,7 +42,11 @@ const ALLOWED_FLAT_FILES: ReadonlySet<string> = new Set([
|
|
|
42
42
|
// separate violation caught by check_tracked_but_ignored.ts.
|
|
43
43
|
'.ai-video.xml', // operator AI-video config; gitignored per .gitignore § AI Video
|
|
44
44
|
'installed-tools.lock', // installer per-user inventory; gitignored per ADR-020
|
|
45
|
-
|
|
45
|
+
// Retired marker (ADR-020 amendment 2026-07-13). No longer written; the
|
|
46
|
+
// global root resolves from `~/.event4u/agent-config`. Kept tolerated so a
|
|
47
|
+
// legacy leftover in a not-yet-reinstalled consumer is not flagged as a
|
|
48
|
+
// violation — the next install deletes it.
|
|
49
|
+
'.event4u-bridge.yml',
|
|
46
50
|
]);
|
|
47
51
|
|
|
48
52
|
// All directories allowed at the agents/ root in the SOURCE REPO.
|
|
@@ -75,6 +79,8 @@ const ALLOWED_SOURCE_DIRS: ReadonlySet<string> = new Set([
|
|
|
75
79
|
const CONSUMER_EXPECTED_ENTRIES: ReadonlySet<string> = new Set([
|
|
76
80
|
// Required consumer entries
|
|
77
81
|
'overrides',
|
|
82
|
+
// Retired marker (ADR-020 amendment 2026-07-13) — no longer written, but
|
|
83
|
+
// kept in the tolerated set so a legacy leftover does not warn.
|
|
78
84
|
'.event4u-bridge.yml',
|
|
79
85
|
'.gitkeep',
|
|
80
86
|
// Optional but legitimate consumer entries (will not trigger warnings)
|
|
@@ -93,9 +99,9 @@ const CONSUMER_EXPECTED_ENTRIES: ReadonlySet<string> = new Set([
|
|
|
93
99
|
const MIGRATE_HINT =
|
|
94
100
|
'Run `npx @event4u/agent-config migrate` to sweep legacy project-scope ' +
|
|
95
101
|
'artefacts in one pass. The unified `migrate` command (see ' +
|
|
96
|
-
'`docs/contracts/migrate-command.md`) leaves `agents/overrides/`
|
|
97
|
-
'
|
|
98
|
-
'
|
|
102
|
+
'`docs/contracts/migrate-command.md`) leaves `agents/overrides/` as the ' +
|
|
103
|
+
'only consumer-side agent surface; the wizard recreates fresh config on ' +
|
|
104
|
+
'`agent-config setup`.';
|
|
99
105
|
|
|
100
106
|
function _isDir(p: string): boolean {
|
|
101
107
|
try {
|