@event4u/agent-config 7.5.0 → 8.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 +8 -1
- package/AGENTS.md +9 -9
- package/CHANGELOG.md +317 -260
- package/README.md +35 -5
- package/dist/agent-src/commands/analytics/prune.md +1 -1
- package/dist/agent-src/commands/analytics/show.md +1 -1
- package/dist/agent-src/commands/analyze/decision.md +2 -2
- package/dist/agent-src/commands/analyze/incident.md +2 -2
- package/dist/agent-src/commands/analyze/near-miss.md +2 -2
- package/dist/agent-src/commands/analyze/postmortem.md +2 -2
- package/dist/agent-src/commands/analyze/premortem.md +2 -2
- package/dist/agent-src/commands/cost-report.md +25 -0
- package/dist/agent-src/commands/evals/analyze.json +30 -0
- package/dist/agent-src/commands/evals/mission-upgrade.json +30 -0
- package/dist/agent-src/commands/implement-ticket.md +1 -1
- package/dist/agent-src/commands/knowledge/forget.md +1 -1
- package/dist/agent-src/commands/knowledge/ingest.md +1 -1
- package/dist/agent-src/commands/knowledge/list.md +1 -1
- package/dist/agent-src/commands/memory/load.md +12 -11
- package/dist/agent-src/commands/memory/promote.md +30 -0
- package/dist/agent-src/commands/memory/propose.md +16 -2
- package/dist/agent-src/commands/mission/upgrade.md +1 -1
- package/dist/agent-src/commands/module/explore.md +11 -7
- package/dist/agent-src/commands/optimize-project.md +243 -0
- package/dist/agent-src/commands/optimize.md +5 -0
- package/dist/agent-src/commands/pr/create.md +37 -8
- package/dist/agent-src/commands/prediction-pool.md +2 -2
- package/dist/agent-src/commands/profile/activate.md +3 -3
- package/dist/agent-src/commands/profile/deactivate.md +2 -2
- package/dist/agent-src/commands/profile/show.md +3 -3
- package/dist/agent-src/commands/research/deep.md +5 -0
- package/dist/agent-src/commands/research/report.md +2 -1
- package/dist/agent-src/commands/roadmap/create.md +88 -10
- package/dist/agent-src/commands/roadmap/materialize.md +1 -1
- package/dist/agent-src/commands/roadmap/process-full.md +15 -2
- package/dist/agent-src/commands/roadmap/process-phase.md +18 -6
- package/dist/agent-src/commands/roadmap/process-step.md +4 -0
- package/dist/agent-src/commands/roadmap.md +1 -1
- package/dist/agent-src/commands/security-audit-config.md +1 -1
- package/dist/agent-src/commands/sync-agent-settings.md +1 -1
- package/dist/agent-src/commands/sync-gitignore/fix.md +42 -6
- package/dist/agent-src/commands/team-knowledge/bootstrap.md +106 -0
- package/dist/agent-src/commands/team-knowledge/consolidate.md +105 -0
- package/dist/agent-src/commands/team-knowledge.md +64 -0
- package/dist/agent-src/contexts/authority/commit-mechanics.md +8 -0
- package/dist/agent-src/contexts/authority/destructive-mechanics.md +11 -0
- package/dist/agent-src/contexts/authority/scope-mechanics.md +25 -0
- package/dist/agent-src/contexts/communication/rules-auto/reply-close-mechanics.md +43 -0
- package/dist/agent-src/contexts/contracts/agents-md-anatomy.md +1 -1
- package/dist/agent-src/contexts/contracts/artifact-engagement-flow.md +2 -2
- package/dist/agent-src/contexts/contracts/frugality-charter.md +1 -0
- package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +14 -4
- package/dist/agent-src/contexts/execution/autonomy-mechanics.md +11 -0
- package/dist/agent-src/contexts/execution/orchestration-telemetry.md +32 -8
- package/dist/agent-src/contexts/execution/roadmap-execution-contract.md +107 -0
- package/dist/agent-src/contexts/execution/roadmap-process-loop.md +71 -15
- package/dist/agent-src/contexts/execution/subagent-steering.md +41 -1
- package/dist/agent-src/contexts/override-system.md +1 -1
- package/dist/agent-src/personas/brand-strategist.md +0 -1
- package/dist/agent-src/personas/data-integrity.md +66 -0
- package/dist/agent-src/personas/design-director.md +0 -1
- package/dist/agent-src/personas/performance-engineer.md +66 -0
- package/dist/agent-src/personas/production-validator.md +73 -0
- package/dist/agent-src/rules/agent-authority.md +3 -4
- package/dist/agent-src/rules/analysis-skill-routing.md +3 -5
- package/dist/agent-src/rules/architecture.md +2 -4
- package/dist/agent-src/rules/artifact-drafting-protocol.md +35 -6
- package/dist/agent-src/rules/artifact-engagement-recording.md +2 -4
- package/dist/agent-src/rules/ask-when-uncertain.md +10 -14
- package/dist/agent-src/rules/augment-edit-discipline.md +3 -5
- package/dist/agent-src/rules/autonomous-execution.md +3 -5
- package/dist/agent-src/rules/brand-consistency.md +3 -5
- package/dist/agent-src/rules/brand-source-of-truth.md +3 -5
- package/dist/agent-src/rules/cli-output-handling.md +4 -6
- package/dist/agent-src/rules/command-suggestion-policy.md +3 -5
- package/dist/agent-src/rules/commit-conventions.md +3 -5
- package/dist/agent-src/rules/commit-policy.md +18 -10
- package/dist/agent-src/rules/content-quoting-floor.md +88 -0
- package/dist/agent-src/rules/context-hygiene.md +3 -5
- package/dist/agent-src/rules/copilot-routing.md +4 -6
- package/dist/agent-src/rules/decision-revisit-gate.md +120 -0
- package/dist/agent-src/rules/delegation-policy.md +10 -6
- package/dist/agent-src/rules/design-fidelity.md +3 -5
- package/dist/agent-src/rules/devcontainer-routing.md +4 -6
- package/dist/agent-src/rules/direct-answers.md +13 -17
- package/dist/agent-src/rules/docker-commands.md +3 -5
- package/dist/agent-src/rules/domain-adoption-policy.md +3 -5
- package/dist/agent-src/rules/domain-safety-disclaimer.md +3 -5
- package/dist/agent-src/rules/domain-safety-pii.md +3 -5
- package/dist/agent-src/rules/domain-safety-retention.md +3 -5
- package/dist/agent-src/rules/downstream-changes.md +3 -4
- package/dist/agent-src/rules/engineering-safety-floor.md +3 -5
- package/dist/agent-src/rules/external-reference-deep-dive.md +3 -5
- package/dist/agent-src/rules/fast-path-marker-visibility.md +3 -5
- package/dist/agent-src/rules/finance-safety-floor.md +3 -6
- package/dist/agent-src/rules/framework-neutrality-in-generic-skills.md +3 -5
- package/dist/agent-src/rules/git-history-discipline.md +3 -5
- package/dist/agent-src/rules/guidelines.md +2 -4
- package/dist/agent-src/rules/icon-consistency.md +3 -5
- package/dist/agent-src/rules/image-likeness-and-rights.md +3 -5
- package/dist/agent-src/rules/improve-before-implement.md +5 -5
- package/dist/agent-src/rules/invite-challenge.md +3 -5
- package/dist/agent-src/rules/language-and-tone.md +13 -15
- package/dist/agent-src/rules/laravel-routing.md +3 -5
- package/dist/agent-src/rules/laravel-translations.md +3 -5
- package/dist/agent-src/rules/legal-safety-floor.md +3 -5
- package/dist/agent-src/rules/lethal-trifecta-guard.md +3 -5
- package/dist/agent-src/rules/linked-projects-onboarding-gate.md +4 -7
- package/dist/agent-src/rules/low-impact-corpus-privacy-floor.md +3 -5
- package/dist/agent-src/rules/markdown-safe-codeblocks.md +2 -4
- package/dist/agent-src/rules/media-governance-routing.md +3 -5
- package/dist/agent-src/rules/media-sync-ground-truth.md +3 -5
- package/dist/agent-src/rules/minimal-safe-diff.md +5 -5
- package/dist/agent-src/rules/missing-tool-handling.md +3 -5
- package/dist/agent-src/rules/model-recommendation.md +4 -6
- package/dist/agent-src/rules/no-attribution-footers.md +3 -5
- package/dist/agent-src/rules/no-cheap-questions.md +5 -8
- package/dist/agent-src/rules/no-decorative-emojis-in-git-surfaces.md +3 -6
- package/dist/agent-src/rules/no-pr-progress-comments.md +3 -6
- package/dist/agent-src/rules/no-roadmap-references.md +3 -5
- package/dist/agent-src/rules/non-destructive-by-default.md +11 -13
- package/dist/agent-src/rules/notes-first-reasoning.md +3 -5
- package/dist/agent-src/rules/onboarding-gate.md +4 -6
- package/dist/agent-src/rules/output-discipline.md +3 -5
- package/dist/agent-src/rules/package-ci-checks.md +3 -5
- package/dist/agent-src/rules/persona-governance.md +2 -4
- package/dist/agent-src/rules/php-coding.md +3 -5
- package/dist/agent-src/rules/preservation-guard.md +2 -4
- package/dist/agent-src/rules/provider-lifecycle-discipline.md +3 -5
- package/dist/agent-src/rules/reviewer-awareness.md +5 -6
- package/dist/agent-src/rules/roadmap-ci-steps-policy.md +3 -5
- package/dist/agent-src/rules/roadmap-progress-sync.md +5 -5
- package/dist/agent-src/rules/role-mode-adherence.md +2 -4
- package/dist/agent-src/rules/rule-type-governance.md +3 -5
- package/dist/agent-src/rules/runtime-safety.md +2 -4
- package/dist/agent-src/rules/scope-control.md +10 -11
- package/dist/agent-src/rules/security-sensitive-stop.md +4 -5
- package/dist/agent-src/rules/size-enforcement.md +2 -4
- package/dist/agent-src/rules/skill-improvement-trigger.md +3 -5
- package/dist/agent-src/rules/skill-quality.md +3 -5
- package/dist/agent-src/rules/slash-command-routing-policy.md +3 -5
- package/dist/agent-src/rules/source-confidentiality.md +3 -5
- package/dist/agent-src/rules/source-discovery-gate.md +3 -5
- package/dist/agent-src/rules/source-of-truth.md +3 -5
- package/dist/agent-src/rules/strategy-safety-floor.md +3 -5
- package/dist/agent-src/rules/symfony-routing.md +4 -6
- package/dist/agent-src/rules/telegraph-speak.md +4 -5
- package/dist/agent-src/rules/think-before-action.md +7 -4
- package/dist/agent-src/rules/token-budget-discipline.md +29 -5
- package/dist/agent-src/rules/token-efficiency.md +3 -5
- package/dist/agent-src/rules/token-optimizer-maintenance.md +3 -5
- package/dist/agent-src/rules/tool-safety.md +2 -4
- package/dist/agent-src/rules/ui-audit-gate.md +3 -6
- package/dist/agent-src/rules/untrusted-input-defense.md +3 -5
- package/dist/agent-src/rules/upstream-proposal.md +4 -6
- package/dist/agent-src/rules/user-interaction.md +7 -5
- package/dist/agent-src/rules/user-interrupt-priority.md +17 -8
- package/dist/agent-src/rules/verify-before-complete.md +12 -22
- package/dist/agent-src/scripts/archive_completed_roadmaps.ts +3 -3
- package/dist/agent-src/scripts/update_roadmap_progress.ts +197 -7
- package/dist/agent-src/skills/adr-create/SKILL.md +48 -42
- package/dist/agent-src/skills/agent-docs-writing/SKILL.md +18 -0
- package/dist/agent-src/skills/agent-security-review/SKILL.md +1 -1
- package/dist/agent-src/skills/ai-council/SKILL.md +14 -1
- package/dist/agent-src/skills/blameless-post-mortem/SKILL.md +0 -3
- package/dist/agent-src/skills/brand/SKILL.md +1 -1
- package/dist/agent-src/skills/brand-identity/SKILL.md +3 -3
- package/dist/agent-src/skills/brand-strategy/SKILL.md +1 -1
- package/dist/agent-src/skills/brand-to-tokens/SKILL.md +3 -3
- package/dist/agent-src/skills/canvas-design/SKILL.md +6 -0
- package/dist/agent-src/skills/check-refs/SKILL.md +7 -4
- package/dist/agent-src/skills/code-review/SKILL.md +1 -0
- package/dist/agent-src/skills/complexity-first-planning/SKILL.md +6 -5
- package/dist/agent-src/skills/condense-memory/SKILL.md +11 -11
- package/dist/agent-src/skills/context-document/SKILL.md +17 -0
- package/dist/agent-src/skills/corpus-grounding/SKILL.md +3 -3
- package/dist/agent-src/skills/decision-record/SKILL.md +6 -0
- package/dist/agent-src/skills/decision-review/SKILL.md +5 -3
- package/dist/agent-src/skills/deep-reading-analyst/SKILL.md +6 -1
- package/dist/agent-src/skills/design-intelligence/SKILL.md +5 -2
- package/dist/agent-src/skills/design-intelligence/references/design-languages.md +1 -1
- package/dist/agent-src/skills/design-tokens/SKILL.md +10 -4
- package/dist/agent-src/skills/design-variations/SKILL.md +127 -0
- package/dist/agent-src/skills/design-variations/evals/triggers.json +17 -0
- package/dist/agent-src/skills/emit-tickets/SKILL.md +4 -4
- package/dist/agent-src/skills/fe-design/SKILL.md +20 -0
- package/dist/agent-src/skills/html-deck/SKILL.md +123 -0
- package/dist/agent-src/skills/html-deck/evals/triggers.json +17 -0
- package/dist/agent-src/skills/html-deck/templates/deck-shell.html +77 -0
- package/dist/agent-src/skills/judge-code-quality/SKILL.md +1 -0
- package/dist/agent-src/skills/laravel/SKILL.md +0 -1
- package/dist/agent-src/skills/learning-to-rule-or-skill/SKILL.md +46 -0
- package/dist/agent-src/skills/lint-skills/SKILL.md +6 -6
- package/dist/agent-src/skills/md-language-check/SKILL.md +3 -3
- package/dist/agent-src/skills/memory-consolidation/SKILL.md +66 -1
- package/dist/agent-src/skills/migration-architect/SKILL.md +1 -0
- package/dist/agent-src/skills/module-detect-on-the-fly/SKILL.md +2 -2
- package/dist/agent-src/skills/performance-analysis/SKILL.md +2 -0
- package/dist/agent-src/skills/prediction-pool-optimizer/SKILL.md +4 -4
- package/dist/agent-src/skills/premortem/SKILL.md +0 -3
- package/dist/agent-src/skills/project-analysis-core/SKILL.md +16 -0
- package/dist/agent-src/skills/reasoning-orchestrator/SKILL.md +3 -1
- package/dist/agent-src/skills/release-comms/SKILL.md +46 -45
- package/dist/agent-src/skills/roadmap-management/SKILL.md +21 -0
- package/dist/agent-src/skills/roadmap-writing/SKILL.md +32 -2
- package/dist/agent-src/skills/root-cause-frameworks/SKILL.md +0 -3
- package/dist/agent-src/skills/security-audit/SKILL.md +1 -0
- package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +4 -0
- package/dist/agent-src/skills/source-discovery/SKILL.md +22 -3
- package/dist/agent-src/skills/subagent-orchestration/SKILL.md +33 -14
- package/dist/agent-src/skills/subagent-orchestration/prompts/README.md +11 -0
- package/dist/agent-src/skills/subagent-orchestration/prompts/do-in-steps.md +8 -0
- package/dist/agent-src/skills/systematic-debugging/SKILL.md +29 -0
- package/dist/agent-src/skills/threat-modeling/SKILL.md +2 -2
- package/dist/agent-src/skills/typography-system/SKILL.md +2 -2
- package/dist/agent-src/skills/verify-completion-evidence/SKILL.md +2 -0
- package/dist/agent-src/skills/wireframe/SKILL.md +118 -0
- package/dist/agent-src/skills/wireframe/evals/triggers.json +17 -0
- package/dist/agent-src/templates/agent-settings.md +22 -1
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/agent-src/templates/command.md +2 -2
- package/dist/agent-src/templates/contexts/knowledge-pages.md +116 -0
- package/dist/agent-src/templates/hooks/pre-commit-frontmatter +1 -1
- package/dist/agent-src/templates/roadmaps.md +70 -2
- package/dist/agent-src/templates/rule.md +1 -1
- package/dist/agent-src/templates/scripts/README.md +3 -3
- package/dist/agent-src/templates/scripts/work_engine/_lib/agent_settings.ts +109 -0
- package/dist/agent-src/templates/tickets.md +8 -8
- package/dist/cli/commands/recordTriggerEval.test.js +1 -1
- package/dist/cli/commands/recordTriggerEval.test.js.map +1 -1
- package/dist/cli/initRouting.js +4 -2
- package/dist/cli/initRouting.js.map +1 -1
- package/dist/cli/registry.js +1 -0
- package/dist/cli/registry.js.map +1 -1
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +718 -240
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +8 -8
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +43 -28
- package/dist/discovery/trust-report.md +12 -11
- package/dist/discovery/workspaces.json +29 -18
- package/dist/install/preflight.js +173 -0
- package/dist/install/preflight.js.map +1 -0
- package/dist/mcp/registry-manifest.json +4 -4
- package/dist/router.json +1 -1
- package/dist/server/routes/settings.js +4 -0
- package/dist/server/routes/settings.js.map +1 -1
- package/dist/server/schemas/settings.js +3 -1
- package/dist/server/schemas/settings.js.map +1 -1
- package/docs/CLAIMS.md +108 -0
- package/docs/MIGRATION.md +3 -3
- package/docs/architecture.md +5 -5
- package/docs/archive/CHANGELOG-pre-8.0.0.md +301 -0
- package/docs/benchmark.md +133 -2
- package/docs/benchmark.pinned.yml +31 -0
- package/docs/capability-matrix.md +1 -0
- package/docs/catalog.md +70 -60
- package/docs/command-flows.md +15 -3
- package/docs/comparison.yaml +35 -0
- package/docs/contracts/agents-layout.md +148 -0
- package/docs/contracts/brand-token-consumption.md +5 -0
- package/docs/contracts/capability-boundary.md +5 -0
- package/docs/contracts/command-category-governance.md +5 -0
- package/docs/contracts/command-clusters.md +1 -0
- package/docs/contracts/command-surface-tiers.md +1 -1
- package/docs/contracts/conformance.md +84 -0
- package/docs/contracts/creative-pack-boundary.md +5 -0
- package/docs/contracts/discovery-manifest.schema.json +5 -4
- package/docs/contracts/file-ownership-matrix.json +4605 -985
- package/docs/contracts/governance-enforcement-projection.md +5 -0
- package/docs/contracts/gui-wizard.md +1 -1
- package/docs/contracts/hook-architecture-v1.md +2 -2
- package/docs/contracts/implement-ticket-flow.md +1 -1
- package/docs/contracts/kernel-membership.md +13 -0
- package/docs/contracts/mcp-tool-inventory.md +23 -23
- package/docs/contracts/no-runtime-boundary.md +6 -1
- package/docs/contracts/review-lens-schema.md +5 -0
- package/docs/contracts/rule-router.md +102 -8
- package/docs/contracts/skill-bundled-assets.md +1 -1
- package/docs/contracts/skill-dry-run.md +1 -1
- package/docs/contracts/subagent-boundary.md +5 -0
- package/docs/contracts/ticket-bundle-format.md +9 -4
- package/docs/contracts/tier-3-contrib-plugin.md +2 -2
- package/docs/contracts/write-engine.md +3 -0
- package/docs/customization.md +87 -15
- package/docs/decisions/ADR-107-legal-domain-pack-adoption.md +1 -1
- package/docs/decisions/ADR-109-subagent-v1-contract.md +246 -0
- package/docs/decisions/ADR-110-discipline-profile-resolution-locus.md +105 -0
- package/docs/decisions/INDEX.md +2 -0
- package/docs/distribution/awesome-list-submission.md +46 -0
- package/docs/distribution/launch-story-draft.md +58 -0
- package/docs/end-to-end-walkthroughs.md +2 -2
- package/docs/getting-started.md +2 -2
- package/docs/guidelines/agent-infra/asking-and-brevity-examples.md +24 -0
- package/docs/guidelines/agent-infra/corpus-grounding-authoring.md +1 -1
- package/docs/guidelines/agent-infra/linked-projects-onboarding-gate.md +2 -2
- package/docs/guidelines/agent-infra/missing-tool-handling.md +3 -3
- package/docs/guidelines/agent-infra/verify-before-complete-demos.md +2 -2
- package/docs/guidelines/augment-portability-patterns.md +1 -1
- package/docs/guidelines/code-clarity.md +19 -0
- package/docs/guidelines/design-antipatterns-triggers.json +2 -1
- package/docs/guidelines/design-antipatterns.md +10 -1
- package/docs/guidelines/design-modes.md +6 -0
- package/docs/guidelines/php/general.md +9 -1
- package/docs/guidelines/php/php-coding-patterns.md +7 -0
- package/docs/guides/cross-repo-retrieval.md +1 -1
- package/docs/guides/frontend-design-corpus-refresh.md +2 -2
- package/docs/guides/local-analytics.md +4 -4
- package/docs/guides/skill-discovery.md +1 -1
- package/docs/guides/skill-preview.md +1 -1
- package/docs/hook-payload-capture.md +6 -6
- package/docs/install-friction-report.md +66 -0
- package/docs/installation.md +1 -1
- package/docs/maintainers/optional-media-deps.md +50 -0
- package/docs/mcp-server.md +11 -12
- package/docs/media/proof-demo.cast +14 -0
- package/docs/media/proof-demo.gif +0 -0
- package/docs/migration/consumer-template-consumption-model.md +1 -1
- package/docs/migration/divergences/bench-stats-float-precision.md +1 -1
- package/docs/migration/node-floor.md +1 -1
- package/docs/migration/yaml-roundtrip-spike.md +1 -1
- package/docs/personas.md +16 -5
- package/docs/positioning-evidence.md +86 -0
- package/docs/proof.md +86 -0
- package/docs/skills-catalog.md +1 -1
- package/docs/troubleshooting.md +8 -8
- package/docs/wedge/production-validator/README.md +57 -0
- package/docs/wedge/production-validator/production-validator.md +56 -0
- package/docs/wizard.md +2 -2
- package/package.json +1 -1
- package/src/config/agent-settings.template.yml +59 -4
- package/src/config/agents-paths.yml +254 -0
- package/src/config/budgets.yml +16 -0
- package/src/config/discovery/packs.yml +1 -0
- package/src/config/discovery/unassigned-artefacts.yml +2 -0
- package/src/config/gitignore-block.txt +25 -0
- package/src/config/host-capabilities.yml +31 -0
- package/src/config/profiles/balanced.ini +4 -0
- package/src/config/profiles/full.ini +4 -0
- package/src/config/profiles/minimal.ini +4 -0
- package/src/scripts/_cli/cmd_conformance.ts +716 -0
- package/src/scripts/_cli/cmd_doctor.ts +23 -2
- package/src/scripts/_cli/cmd_fleet.ts +401 -0
- package/src/scripts/_cli/cmd_preflight.ts +159 -0
- package/src/scripts/_dispatch.bash +10 -0
- package/src/scripts/_lib/knowledge_events.ts +193 -0
- package/src/scripts/_lib/subagent_steering.ts +115 -3
- package/src/scripts/_lib/text_similarity.ts +75 -0
- package/src/scripts/ai-video/test-pipeline.sh +1 -1
- package/src/scripts/ai_council/clients.ts +19 -3
- package/src/scripts/append_contested.ts +112 -0
- package/src/scripts/audit_auto_rules.ts +11 -1
- package/src/scripts/audit_mcp_tools.ts +25 -11
- package/src/scripts/bench_ab_v2_run.ts +527 -40
- package/src/scripts/bench_ab_v2_stats.ts +6 -0
- package/src/scripts/bench_matrix.ts +266 -0
- package/src/scripts/bootstrap_knowledge.ts +267 -0
- package/src/scripts/build_discovery_manifest.ts +42 -2
- package/src/scripts/build_proof.ts +214 -0
- package/src/scripts/check_always_budget.ts +3 -0
- package/src/scripts/check_augment_description_cap.ts +2 -2
- package/src/scripts/check_claims.ts +270 -0
- package/src/scripts/check_comparison.ts +79 -0
- package/src/scripts/check_generated_artefact_headers.ts +109 -0
- package/src/scripts/check_generator_output_coverage.ts +142 -0
- package/src/scripts/check_gitignore_freshness.ts +127 -0
- package/src/scripts/check_knowledge_pages.ts +210 -0
- package/src/scripts/check_knowledge_sharing.ts +162 -0
- package/src/scripts/check_media_deps.ts +91 -0
- package/src/scripts/check_memory_contradiction.ts +280 -0
- package/src/scripts/check_memory_similarity.ts +134 -0
- package/src/scripts/check_quality_regression.ts +56 -10
- package/src/scripts/check_references.ts +3 -1
- package/src/scripts/check_release_pr_shape.ts +4 -0
- package/src/scripts/check_site_links.ts +135 -0
- package/src/scripts/check_skill_gaps.ts +99 -0
- package/src/scripts/check_token_quality_golden.ts +197 -11
- package/src/scripts/check_tracked_but_ignored.ts +67 -0
- package/src/scripts/cluster_near_miss_patterns.ts +0 -0
- package/src/scripts/compile_router.ts +30 -3
- package/src/scripts/condense.ts +350 -14
- package/src/scripts/consolidate_knowledge_events.ts +192 -0
- package/src/scripts/degrade_to_pointer.ts +136 -0
- package/src/scripts/design_slop_rules.test.ts +15 -0
- package/src/scripts/design_slop_rules.ts +28 -0
- package/src/scripts/emit_knowledge_event.ts +158 -0
- package/src/scripts/export_replay_corpus.ts +187 -0
- package/src/scripts/external_sources_denylist.json +7 -2
- package/src/scripts/fold_intake.ts +281 -0
- package/src/scripts/generate_capability_matrix.ts +9 -1
- package/src/scripts/generate_knowledge_index.ts +222 -0
- package/src/scripts/hook_manifest.yaml +26 -14
- package/src/scripts/hooks/dispatch_hook.ts +18 -0
- package/src/scripts/hot_context_hook.ts +372 -0
- package/src/scripts/install +47 -0
- package/src/scripts/install-hooks.sh +17 -0
- package/src/scripts/inventory_meta_layers.ts +11 -0
- package/src/scripts/janitor.ts +258 -0
- package/src/scripts/lint_agents_layout.ts +74 -15
- package/src/scripts/lint_bench_ab.ts +4 -1
- package/src/scripts/lint_featured_skills.ts +0 -0
- package/src/scripts/lint_framework_leakage_allowlist.json +26 -3
- package/src/scripts/lint_knowledge_scale.ts +250 -0
- package/src/scripts/lint_legal_pack.ts +67 -0
- package/src/scripts/lint_persona_governance.ts +8 -3
- package/src/scripts/lint_regression.ts +15 -0
- package/src/scripts/lint_roadmap_blockers.ts +202 -0
- package/src/scripts/lint_roadmap_complexity.ts +81 -2
- package/src/scripts/lint_subagent_determinism.ts +125 -0
- package/src/scripts/measure_augment_budget.ts +46 -6
- package/src/scripts/measure_patterns.ts +4 -3
- package/src/scripts/measure_skill_reduction.ts +6 -6
- package/src/scripts/migration_status.ts +6 -2
- package/src/scripts/mine_missing_guardrails.ts +189 -0
- package/src/scripts/parity/phase_gate.ts +1 -1
- package/src/scripts/parity/replay.ts +21 -0
- package/src/scripts/project_thin_rules.ts +120 -16
- package/src/scripts/release.ts +39 -1
- package/src/scripts/render_benchmark_composite.ts +378 -0
- package/src/scripts/roadmap_progress_hook.ts +101 -43
- package/src/scripts/schemas/skill.schema.json +27 -0
- package/src/scripts/schemas/subagent.schema.json +106 -0
- package/src/scripts/skill_linter.ts +1 -0
- package/src/scripts/smoke/kernel.sh +5 -4
- package/src/scripts/surface-tiers.yml +1 -0
- package/src/scripts/sync_gitignore.ts +4 -0
- package/src/scripts/update_skill_candidates.ts +172 -0
- package/src/scripts/validate_frontmatter.ts +1 -0
package/src/scripts/condense.ts
CHANGED
|
@@ -250,6 +250,8 @@ interface ModuleState {
|
|
|
250
250
|
PERSONAS_SOURCE: string;
|
|
251
251
|
USER_TYPES_SOURCE: string;
|
|
252
252
|
CLAUDE_SKILLS_DIR: string;
|
|
253
|
+
CLAUDE_AGENTS_DIR: string;
|
|
254
|
+
SUBAGENTS_SOURCE: string;
|
|
253
255
|
PLUGIN_SKILLS_DIR: string;
|
|
254
256
|
// Injectable multi-root helpers (monkeypatch seam).
|
|
255
257
|
iter_all_sources: () => Iterable<[string, string]>;
|
|
@@ -271,6 +273,12 @@ function _deriveState(root: string): ModuleState {
|
|
|
271
273
|
PERSONAS_SOURCE: path.join(root, 'dist/agent-src', 'personas'),
|
|
272
274
|
USER_TYPES_SOURCE: path.join(root, 'dist/agent-src', 'user-types'),
|
|
273
275
|
CLAUDE_SKILLS_DIR: path.join(root, '.claude', 'skills'),
|
|
276
|
+
// ADR-109: subagents project from src/ directly (NOT dist/) — a subagent
|
|
277
|
+
// is an executable system prompt Claude Code runs verbatim; telegraph
|
|
278
|
+
// condensation would alter its behaviour, and it is not routed through the
|
|
279
|
+
// pack/discovery condensation flow.
|
|
280
|
+
CLAUDE_AGENTS_DIR: path.join(root, '.claude', 'agents'),
|
|
281
|
+
SUBAGENTS_SOURCE: path.join(root, 'src', 'subagents'),
|
|
274
282
|
PLUGIN_SKILLS_DIR: path.join(root, '.claude-plugin', 'skills'),
|
|
275
283
|
iter_all_sources: _agent_src_iter_all_sources,
|
|
276
284
|
resolve_logical: _agent_src_resolve_logical,
|
|
@@ -922,11 +930,84 @@ export function _rewrite_paths(content: string, source_relative_path: string): s
|
|
|
922
930
|
// Expose the HRR marker for tests (mirrors condense._HRR_BANNER_MARKER access).
|
|
923
931
|
export { _HRR_BANNER_MARKER };
|
|
924
932
|
|
|
925
|
-
|
|
926
|
-
|
|
933
|
+
// ── Consumer-scoped rule projection (road-to-request-scoped-rule-load P1) ──
|
|
934
|
+
//
|
|
935
|
+
// Opt-in via `projection.rule_workspaces: [<workspace-id>, …]` in
|
|
936
|
+
// `.agent-settings.yml`. Absent / empty = legacy-all (every rule projects —
|
|
937
|
+
// today's behaviour, non-breaking). When set, a non-kernel rule projects
|
|
938
|
+
// only if its `workspaces:` frontmatter intersects the configured set.
|
|
939
|
+
// Kernel rules (`type: always` / `alwaysApply: true`) ALWAYS project —
|
|
940
|
+
// the kernel is unconditional and workspace-independent by definition
|
|
941
|
+
// (rule-router contract § Schema v2). Untagged rules fail safe: they ship.
|
|
942
|
+
// ADR-040: projection-time filtering only, no runtime resolver.
|
|
943
|
+
|
|
944
|
+
function _read_projection_list(key: string): string[] | null {
|
|
945
|
+
const data = load_agent_settings({ project_path: MODULE_STATE.SETTINGS_FILE });
|
|
946
|
+
const proj = data['projection'];
|
|
947
|
+
const value =
|
|
948
|
+
typeof proj === 'object' && proj !== null && !Array.isArray(proj)
|
|
949
|
+
? (proj as Record<string, unknown>)[key]
|
|
950
|
+
: null;
|
|
951
|
+
if (Array.isArray(value) && value.length > 0) {
|
|
952
|
+
return value.map((v) => String(v));
|
|
953
|
+
}
|
|
954
|
+
return null;
|
|
955
|
+
}
|
|
956
|
+
|
|
957
|
+
function _read_rule_workspaces(): string[] | null {
|
|
958
|
+
return _read_projection_list('rule_workspaces');
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
function _read_rule_packs(): string[] | null {
|
|
962
|
+
return _read_projection_list('rule_packs');
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
/**
|
|
966
|
+
* Whether a rule source file projects under the given workspace + pack
|
|
967
|
+
* scopes. Both scopes are independent constraints: when configured, the
|
|
968
|
+
* rule's frontmatter list must intersect (installed workspaces AND
|
|
969
|
+
* installed packs). Kernel always projects; untagged axes fail safe.
|
|
970
|
+
*/
|
|
971
|
+
export function rule_in_scope(
|
|
972
|
+
source_path: string,
|
|
973
|
+
scope: readonly string[] | null,
|
|
974
|
+
pack_scope: readonly string[] | null = null,
|
|
975
|
+
): boolean {
|
|
976
|
+
if (scope === null && pack_scope === null) {
|
|
977
|
+
return true;
|
|
978
|
+
}
|
|
979
|
+
const [meta] = _parse_frontmatter(_readText(source_path));
|
|
980
|
+
if (meta['type'] === 'always' || meta['alwaysApply'] === true) {
|
|
981
|
+
return true; // kernel always projects
|
|
982
|
+
}
|
|
983
|
+
const axis = (key: string, configured: readonly string[] | null): boolean => {
|
|
984
|
+
if (configured === null) {
|
|
985
|
+
return true;
|
|
986
|
+
}
|
|
987
|
+
const values = Array.isArray(meta[key])
|
|
988
|
+
? (meta[key] as unknown[]).map((w) => String(w))
|
|
989
|
+
: [];
|
|
990
|
+
if (values.length === 0) {
|
|
991
|
+
return true; // untagged → fail safe: ship it
|
|
992
|
+
}
|
|
993
|
+
return values.some((v) => configured.includes(v));
|
|
994
|
+
};
|
|
995
|
+
return axis('workspaces', scope) && axis('packs', pack_scope);
|
|
996
|
+
}
|
|
997
|
+
|
|
998
|
+
/** List rule basenames under RULES_SOURCE, workspace/pack scope applied. */
|
|
999
|
+
function _scoped_rule_basenames(): string[] {
|
|
1000
|
+
const scope = _read_rule_workspaces();
|
|
1001
|
+
const pack_scope = _read_rule_packs();
|
|
1002
|
+
return _iterdirSorted(MODULE_STATE.RULES_SOURCE)
|
|
927
1003
|
.filter((p) => p.endsWith('.md') && _isFile(p))
|
|
1004
|
+
.filter((p) => rule_in_scope(p, scope, pack_scope))
|
|
928
1005
|
.map((p) => path.basename(p))
|
|
929
1006
|
.sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
export function generate_rule_symlinks(): number {
|
|
1010
|
+
const rules = _scoped_rule_basenames();
|
|
930
1011
|
const tool_dirs = _filter_tool_dirs(TOOL_DIRS);
|
|
931
1012
|
|
|
932
1013
|
let thin_files: Record<string, string> | null = null;
|
|
@@ -980,10 +1061,7 @@ export function generate_rule_symlinks(): number {
|
|
|
980
1061
|
}
|
|
981
1062
|
|
|
982
1063
|
export function generate_windsurfrules(): number {
|
|
983
|
-
const rules =
|
|
984
|
-
.filter((p) => p.endsWith('.md') && _isFile(p))
|
|
985
|
-
.map((p) => path.basename(p))
|
|
986
|
-
.sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));
|
|
1064
|
+
const rules = _scoped_rule_basenames();
|
|
987
1065
|
const parts = ['# Auto-generated from dist/agent-src/rules/ — do not edit directly\n'];
|
|
988
1066
|
for (const rule of rules) {
|
|
989
1067
|
const p = path.join(MODULE_STATE.RULES_SOURCE, rule);
|
|
@@ -1036,14 +1114,44 @@ function _yaml_scalar(value: string): string {
|
|
|
1036
1114
|
return JSON.stringify(value);
|
|
1037
1115
|
}
|
|
1038
1116
|
|
|
1039
|
-
|
|
1117
|
+
/**
|
|
1118
|
+
* Derive host-native activation globs from a rule's `triggers:` frontmatter
|
|
1119
|
+
* (road-to-request-scoped-rule-load Phase 2). `file_pattern` triggers map
|
|
1120
|
+
* verbatim; `path_prefix` triggers map to `<prefix>**`. Keyword / phrase /
|
|
1121
|
+
* intent / command triggers produce no glob — those rules stay
|
|
1122
|
+
* description-activated (Cursor Agent-Requested / Windsurf model_decision).
|
|
1123
|
+
*/
|
|
1124
|
+
export function derive_trigger_globs(meta: Record<string, unknown>): string[] {
|
|
1125
|
+
const triggers = meta['triggers'];
|
|
1126
|
+
if (!Array.isArray(triggers)) {
|
|
1127
|
+
return [];
|
|
1128
|
+
}
|
|
1129
|
+
const globs: string[] = [];
|
|
1130
|
+
for (const t of triggers) {
|
|
1131
|
+
if (t === null || typeof t !== 'object' || Array.isArray(t)) continue;
|
|
1132
|
+
const obj = t as Record<string, unknown>;
|
|
1133
|
+
if (typeof obj['file_pattern'] === 'string' && obj['file_pattern']) {
|
|
1134
|
+
globs.push(obj['file_pattern']);
|
|
1135
|
+
} else if (typeof obj['path_prefix'] === 'string' && obj['path_prefix']) {
|
|
1136
|
+
const prefix = obj['path_prefix'] as string;
|
|
1137
|
+
globs.push(prefix.endsWith('/') ? `${prefix}**` : `${prefix}**`);
|
|
1138
|
+
}
|
|
1139
|
+
}
|
|
1140
|
+
// De-dup, keep declaration order (deterministic output).
|
|
1141
|
+
return [...new Set(globs)];
|
|
1142
|
+
}
|
|
1143
|
+
|
|
1144
|
+
export function _emit_cursor_mdc(source: string, target: string): void {
|
|
1040
1145
|
const [meta, body] = _parse_frontmatter(_readText(source));
|
|
1041
1146
|
const description = _strip(String(meta['description'] ?? '').replace(/\n/g, ' '));
|
|
1042
1147
|
const always_apply = Boolean(meta['alwaysApply'] || meta['type'] === 'always');
|
|
1148
|
+
// Path-shaped triggers become Cursor auto-attach globs; rules without
|
|
1149
|
+
// them keep `globs: ` empty and stay Agent-Requested via description.
|
|
1150
|
+
const globs = always_apply ? [] : derive_trigger_globs(meta);
|
|
1043
1151
|
const lines = [
|
|
1044
1152
|
'---',
|
|
1045
1153
|
`description: ${_yaml_scalar(description)}`,
|
|
1046
|
-
|
|
1154
|
+
`globs: ${globs.join(',')}`,
|
|
1047
1155
|
`alwaysApply: ${always_apply ? 'true' : 'false'}`,
|
|
1048
1156
|
'---',
|
|
1049
1157
|
'',
|
|
@@ -1053,16 +1161,19 @@ function _emit_cursor_mdc(source: string, target: string): void {
|
|
|
1053
1161
|
_writeText(target, lines.join('\n'));
|
|
1054
1162
|
}
|
|
1055
1163
|
|
|
1056
|
-
function _emit_windsurf_rule(source: string, target: string): void {
|
|
1164
|
+
export function _emit_windsurf_rule(source: string, target: string): void {
|
|
1057
1165
|
const [meta, body] = _parse_frontmatter(_readText(source));
|
|
1058
1166
|
const description = _strip(String(meta['description'] ?? '').replace(/\n/g, ' '));
|
|
1059
1167
|
const always_apply = Boolean(meta['alwaysApply'] || meta['type'] === 'always');
|
|
1060
|
-
|
|
1168
|
+
// Path-shaped triggers activate host-natively via Windsurf's `glob`
|
|
1169
|
+
// trigger; keyword/intent-only rules keep `model_decision`.
|
|
1170
|
+
const globs = always_apply ? [] : derive_trigger_globs(meta);
|
|
1171
|
+
const trigger = always_apply ? 'always_on' : globs.length > 0 ? 'glob' : 'model_decision';
|
|
1061
1172
|
const lines = [
|
|
1062
1173
|
'---',
|
|
1063
1174
|
`trigger: ${trigger}`,
|
|
1064
1175
|
`description: ${_yaml_scalar(description)}`,
|
|
1065
|
-
|
|
1176
|
+
`globs: ${globs.join(',')}`,
|
|
1066
1177
|
'---',
|
|
1067
1178
|
'',
|
|
1068
1179
|
_pyRstrip(body) + '\n',
|
|
@@ -1096,7 +1207,11 @@ function _clean_modern_dir(target_dir: string, valid_names: ReadonlySet<string>)
|
|
|
1096
1207
|
}
|
|
1097
1208
|
|
|
1098
1209
|
export function generate_cursor_mdc_rules(): number {
|
|
1099
|
-
const
|
|
1210
|
+
const scope = _read_rule_workspaces();
|
|
1211
|
+
const pack_scope = _read_rule_packs();
|
|
1212
|
+
const rules = _rglobSorted(MODULE_STATE.RULES_SOURCE, '*.md')
|
|
1213
|
+
.filter((p) => _isFile(p))
|
|
1214
|
+
.filter((p) => rule_in_scope(p, scope, pack_scope));
|
|
1100
1215
|
const stems = rules.map((r) => path.basename(r, '.md'));
|
|
1101
1216
|
const valid = new Set([
|
|
1102
1217
|
...stems.map((s) => `${s}.mdc`),
|
|
@@ -1111,7 +1226,11 @@ export function generate_cursor_mdc_rules(): number {
|
|
|
1111
1226
|
}
|
|
1112
1227
|
|
|
1113
1228
|
export function generate_windsurf_modern_rules(): number {
|
|
1114
|
-
const
|
|
1229
|
+
const scope = _read_rule_workspaces();
|
|
1230
|
+
const pack_scope = _read_rule_packs();
|
|
1231
|
+
const rules = _rglobSorted(MODULE_STATE.RULES_SOURCE, '*.md')
|
|
1232
|
+
.filter((p) => _isFile(p))
|
|
1233
|
+
.filter((p) => rule_in_scope(p, scope, pack_scope));
|
|
1115
1234
|
const valid = new Set(rules.map((r) => path.basename(r)));
|
|
1116
1235
|
_clean_modern_dir(_WINDSURF_RULES_DIR(), valid);
|
|
1117
1236
|
for (const rule of rules) {
|
|
@@ -1475,6 +1594,221 @@ export function generate_claude_commands(active_command_slugs: ReadonlySet<strin
|
|
|
1475
1594
|
return count;
|
|
1476
1595
|
}
|
|
1477
1596
|
|
|
1597
|
+
/**
|
|
1598
|
+
* Project `src/subagents/*.md` (subagent-v1, ADR-109) → `.claude/agents/*.md`
|
|
1599
|
+
* in Claude Code's native subagent format.
|
|
1600
|
+
*
|
|
1601
|
+
* The source frontmatter carries governance metadata (schema_version, trust,
|
|
1602
|
+
* lifecycle, discovery, source) that Claude Code does not understand; the native
|
|
1603
|
+
* `.claude/agents/` format wants only `{name, description, tools, model}` + the
|
|
1604
|
+
* system-prompt body. This is a **frontmatter transform**, not a symlink:
|
|
1605
|
+
*
|
|
1606
|
+
* - `model_tier` → native `model:` via `_TIER_TO_CLAUDE_MODEL` (ADR-034/035);
|
|
1607
|
+
* the `inherit` sentinel passes through to `model: inherit`.
|
|
1608
|
+
* - `tools` (a YAML list) → the comma-joined form Claude Code accepts.
|
|
1609
|
+
* - the body (everything after the closing `---`) is copied verbatim.
|
|
1610
|
+
*
|
|
1611
|
+
* Static projection only — Claude Code (or the user via `@<name>`) decides
|
|
1612
|
+
* dispatch; nothing here runs an agent. Reads from `src/` directly (subagent
|
|
1613
|
+
* prompts are not telegraph-condensed). Reaps stale generated `.claude/agents/`
|
|
1614
|
+
* files whose source no longer exists.
|
|
1615
|
+
*/
|
|
1616
|
+
export function generate_claude_subagents(): number {
|
|
1617
|
+
if (!_isDir(MODULE_STATE.SUBAGENTS_SOURCE)) {
|
|
1618
|
+
return 0;
|
|
1619
|
+
}
|
|
1620
|
+
_mkdirp(MODULE_STATE.CLAUDE_AGENTS_DIR);
|
|
1621
|
+
|
|
1622
|
+
const sources = _rglobSorted(MODULE_STATE.SUBAGENTS_SOURCE, '*.md').filter((p) => _isFile(p));
|
|
1623
|
+
const current = new Set<string>();
|
|
1624
|
+
let count = 0;
|
|
1625
|
+
|
|
1626
|
+
for (const src of sources) {
|
|
1627
|
+
const stem = path.basename(src, '.md');
|
|
1628
|
+
const text = _readText(src);
|
|
1629
|
+
if (!text.startsWith('---\n')) {
|
|
1630
|
+
continue;
|
|
1631
|
+
}
|
|
1632
|
+
const end = text.indexOf('\n---\n', 4);
|
|
1633
|
+
if (end === -1) {
|
|
1634
|
+
continue;
|
|
1635
|
+
}
|
|
1636
|
+
const fmBlock = text.slice(4, end);
|
|
1637
|
+
const body = text.slice(end + 5);
|
|
1638
|
+
const fm = _yamlParse(fmBlock) as Record<string, unknown> | null;
|
|
1639
|
+
if (fm === null) {
|
|
1640
|
+
continue;
|
|
1641
|
+
}
|
|
1642
|
+
const name = typeof fm['name'] === 'string' ? (fm['name'] as string) : stem;
|
|
1643
|
+
const description = typeof fm['description'] === 'string' ? (fm['description'] as string) : '';
|
|
1644
|
+
const toolsRaw = fm['tools'];
|
|
1645
|
+
const tools = Array.isArray(toolsRaw) ? toolsRaw.map((t) => String(t)).join(', ') : String(toolsRaw ?? '');
|
|
1646
|
+
const tier = typeof fm['model_tier'] === 'string' ? (fm['model_tier'] as string) : 'inherit';
|
|
1647
|
+
const model = tier === 'inherit' ? 'inherit' : (_TIER_TO_CLAUDE_MODEL[tier] ?? 'inherit');
|
|
1648
|
+
|
|
1649
|
+
const out =
|
|
1650
|
+
'---\n' +
|
|
1651
|
+
`name: ${name}\n` +
|
|
1652
|
+
`description: ${description}\n` +
|
|
1653
|
+
`tools: ${tools}\n` +
|
|
1654
|
+
`model: ${model}\n` +
|
|
1655
|
+
'---\n' +
|
|
1656
|
+
body;
|
|
1657
|
+
|
|
1658
|
+
const target = path.join(MODULE_STATE.CLAUDE_AGENTS_DIR, `${name}.md`);
|
|
1659
|
+
_writeText(target, out);
|
|
1660
|
+
current.add(`${name}.md`);
|
|
1661
|
+
count += 1;
|
|
1662
|
+
}
|
|
1663
|
+
|
|
1664
|
+
// Reap stale generated agent files (source removed). Only touch plain .md
|
|
1665
|
+
// files we would have generated; never follow into unrelated content.
|
|
1666
|
+
for (const item of _iterdirSorted(MODULE_STATE.CLAUDE_AGENTS_DIR)) {
|
|
1667
|
+
const base = path.basename(item);
|
|
1668
|
+
if (base === 'README.md' || current.has(base)) {
|
|
1669
|
+
continue;
|
|
1670
|
+
}
|
|
1671
|
+
if (_isFile(item) && base.endsWith('.md') && !_isSymlink(item)) {
|
|
1672
|
+
fs.unlinkSync(item);
|
|
1673
|
+
}
|
|
1674
|
+
}
|
|
1675
|
+
|
|
1676
|
+
info(` ✅ Created ${count} subagent entries in .claude/agents/`);
|
|
1677
|
+
return count;
|
|
1678
|
+
}
|
|
1679
|
+
|
|
1680
|
+
/**
|
|
1681
|
+
* Cross-host degradation for subagent-v1 (ADR-109 §4).
|
|
1682
|
+
*
|
|
1683
|
+
* Only Claude Code has native subagents (`generate_claude_subagents`). On the
|
|
1684
|
+
* other rules-surface hosts a subagent projects to a **loadable context file** —
|
|
1685
|
+
* a *passive reference*, honestly labelled: there is NO host-native `@`-dispatch
|
|
1686
|
+
* (faking it would need a runtime the package refuses to add). Council
|
|
1687
|
+
* (claude-sonnet-4-5 + gpt-4o, 2026-07-05) converged here over honest-null: the
|
|
1688
|
+
* body is 95% reusable review discipline, 5% dispatch syntax, so an advanced user
|
|
1689
|
+
* on Cursor / Windsurf / Cline loads it on intent and applies the discipline
|
|
1690
|
+
* manually. This is **governance parity, not feature parity** — trust / lifecycle
|
|
1691
|
+
* / model_tier stay legible; automation does not.
|
|
1692
|
+
*
|
|
1693
|
+
* Placement is reaper-safe by construction:
|
|
1694
|
+
* - Cursor / Windsurf → a dedicated `subagents/` subdir with its own reaper,
|
|
1695
|
+
* so it never collides with the aggressive `_clean_modern_dir` rule reapers.
|
|
1696
|
+
* - Cline → a flat real `<name>.subagent.md` in `.clinerules/` (whose reaper
|
|
1697
|
+
* only unlinks *symlinks*, so a real file survives).
|
|
1698
|
+
*
|
|
1699
|
+
* Copilot / Gemini are skipped (no per-file context surface), per ADR-109 §4.
|
|
1700
|
+
* Reads from `src/` directly (subagent prompts are not telegraph-condensed).
|
|
1701
|
+
*/
|
|
1702
|
+
export function generate_subagent_host_contexts(): number {
|
|
1703
|
+
if (!_isDir(MODULE_STATE.SUBAGENTS_SOURCE)) {
|
|
1704
|
+
return 0;
|
|
1705
|
+
}
|
|
1706
|
+
const sources = _rglobSorted(MODULE_STATE.SUBAGENTS_SOURCE, '*.md').filter((p) => _isFile(p));
|
|
1707
|
+
|
|
1708
|
+
// Build the passive-reference body once per subagent, keyed by projected name.
|
|
1709
|
+
const rendered: Array<{ name: string; text: string }> = [];
|
|
1710
|
+
for (const src of sources) {
|
|
1711
|
+
const stem = path.basename(src, '.md');
|
|
1712
|
+
const text = _readText(src);
|
|
1713
|
+
if (!text.startsWith('---\n')) {
|
|
1714
|
+
continue;
|
|
1715
|
+
}
|
|
1716
|
+
const end = text.indexOf('\n---\n', 4);
|
|
1717
|
+
if (end === -1) {
|
|
1718
|
+
continue;
|
|
1719
|
+
}
|
|
1720
|
+
const fm = _yamlParse(text.slice(4, end)) as Record<string, unknown> | null;
|
|
1721
|
+
if (fm === null) {
|
|
1722
|
+
continue;
|
|
1723
|
+
}
|
|
1724
|
+
const body = text.slice(end + 5);
|
|
1725
|
+
const name = typeof fm['name'] === 'string' ? (fm['name'] as string) : stem;
|
|
1726
|
+
const description = typeof fm['description'] === 'string' ? (fm['description'] as string) : '';
|
|
1727
|
+
// `trust` is either a flat string or the subagent-v1 nested object
|
|
1728
|
+
// {level, confidence, human_review_required}; surface the level either way.
|
|
1729
|
+
const trustRaw = fm['trust'];
|
|
1730
|
+
const trust =
|
|
1731
|
+
typeof trustRaw === 'string'
|
|
1732
|
+
? trustRaw
|
|
1733
|
+
: typeof trustRaw === 'object' && trustRaw !== null && typeof (trustRaw as Record<string, unknown>)['level'] === 'string'
|
|
1734
|
+
? ((trustRaw as Record<string, unknown>)['level'] as string)
|
|
1735
|
+
: 'unknown';
|
|
1736
|
+
const lifecycle = typeof fm['lifecycle'] === 'string' ? (fm['lifecycle'] as string) : 'unknown';
|
|
1737
|
+
const tier = typeof fm['model_tier'] === 'string' ? (fm['model_tier'] as string) : 'inherit';
|
|
1738
|
+
const toolsRaw = fm['tools'];
|
|
1739
|
+
const tools = Array.isArray(toolsRaw)
|
|
1740
|
+
? toolsRaw.map((t) => String(t)).join(', ')
|
|
1741
|
+
: String(toolsRaw ?? '');
|
|
1742
|
+
const out =
|
|
1743
|
+
'---\n' +
|
|
1744
|
+
`description: ${description}\n` +
|
|
1745
|
+
'---\n\n' +
|
|
1746
|
+
`# Subagent (passive reference): ${name}\n\n` +
|
|
1747
|
+
'> Passive subagent reference. This host has **no native subagent dispatch** —\n' +
|
|
1748
|
+
`> there is no \`@${name}\` here. Load this discipline manually and apply it.\n` +
|
|
1749
|
+
'> Governance parity (trust / lifecycle / model tier) is preserved below;\n' +
|
|
1750
|
+
'> feature parity is not (ADR-109 §4).\n\n' +
|
|
1751
|
+
`- trust: ${trust}\n` +
|
|
1752
|
+
`- lifecycle: ${lifecycle}\n` +
|
|
1753
|
+
`- model tier: ${tier}\n` +
|
|
1754
|
+
(tools ? `- tools: ${tools}\n` : '') +
|
|
1755
|
+
'\n' +
|
|
1756
|
+
_pyRstrip(body) +
|
|
1757
|
+
'\n';
|
|
1758
|
+
rendered.push({ name, text: out });
|
|
1759
|
+
}
|
|
1760
|
+
|
|
1761
|
+
// Host targets: [dir, filename(name)->basename, reaper-predicate].
|
|
1762
|
+
const targets: Array<{ active: boolean; dir: string; file: (n: string) => string; owns: (b: string) => boolean }> = [
|
|
1763
|
+
{
|
|
1764
|
+
active: _tool_active('cursor'),
|
|
1765
|
+
dir: path.join(MODULE_STATE.PROJECT_ROOT, '.cursor', 'subagents'),
|
|
1766
|
+
file: (n) => `${n}.md`,
|
|
1767
|
+
owns: (b) => b.endsWith('.md'),
|
|
1768
|
+
},
|
|
1769
|
+
{
|
|
1770
|
+
active: _tool_active('windsurf'),
|
|
1771
|
+
dir: path.join(MODULE_STATE.PROJECT_ROOT, '.windsurf', 'subagents'),
|
|
1772
|
+
file: (n) => `${n}.md`,
|
|
1773
|
+
owns: (b) => b.endsWith('.md'),
|
|
1774
|
+
},
|
|
1775
|
+
{
|
|
1776
|
+
active: _tool_active('cline'),
|
|
1777
|
+
dir: path.join(MODULE_STATE.PROJECT_ROOT, '.clinerules'),
|
|
1778
|
+
file: (n) => `${n}.subagent.md`,
|
|
1779
|
+
owns: (b) => b.endsWith('.subagent.md'),
|
|
1780
|
+
},
|
|
1781
|
+
];
|
|
1782
|
+
|
|
1783
|
+
let count = 0;
|
|
1784
|
+
for (const t of targets) {
|
|
1785
|
+
if (!t.active) {
|
|
1786
|
+
continue;
|
|
1787
|
+
}
|
|
1788
|
+
const current = new Set(rendered.map((r) => t.file(r.name)));
|
|
1789
|
+
_mkdirp(t.dir);
|
|
1790
|
+
for (const r of rendered) {
|
|
1791
|
+
_writeText(path.join(t.dir, t.file(r.name)), r.text);
|
|
1792
|
+
count += 1;
|
|
1793
|
+
}
|
|
1794
|
+
// Reap stale generated files we own whose source is gone. Never touch
|
|
1795
|
+
// symlinks (cline's rule symlinks) or a README.
|
|
1796
|
+
if (_exists(t.dir)) {
|
|
1797
|
+
for (const item of _iterdirSorted(t.dir)) {
|
|
1798
|
+
const base = path.basename(item);
|
|
1799
|
+
if (base === 'README.md' || current.has(base)) {
|
|
1800
|
+
continue;
|
|
1801
|
+
}
|
|
1802
|
+
if (_isFile(item) && !_isSymlink(item) && t.owns(base)) {
|
|
1803
|
+
fs.unlinkSync(item);
|
|
1804
|
+
}
|
|
1805
|
+
}
|
|
1806
|
+
}
|
|
1807
|
+
}
|
|
1808
|
+
info(` ✅ Projected ${count} passive subagent context file(s) to non-Claude-Code hosts`);
|
|
1809
|
+
return count;
|
|
1810
|
+
}
|
|
1811
|
+
|
|
1478
1812
|
export function generate_plugin_command_skills(): number {
|
|
1479
1813
|
if (!_isDir(path.join(MODULE_STATE.PROJECT_ROOT, 'src', 'domains'))) {
|
|
1480
1814
|
return 0;
|
|
@@ -1713,6 +2047,8 @@ function _generate_tools_inner(
|
|
|
1713
2047
|
}
|
|
1714
2048
|
const skills = _tool_active('claude-code') ? generate_claude_skills(skill_names) : 0;
|
|
1715
2049
|
const commands = _tool_active('claude-code') ? generate_claude_commands(cmd_slugs) : 0;
|
|
2050
|
+
const subagents = _tool_active('claude-code') ? generate_claude_subagents() : 0;
|
|
2051
|
+
const subagent_contexts = generate_subagent_host_contexts();
|
|
1716
2052
|
const plugin_cmd_skills = _tool_active('claude-code') ? generate_plugin_command_skills() : 0;
|
|
1717
2053
|
const plugin_hooks = _tool_active('claude-code') ? generate_plugin_hooks() : 0;
|
|
1718
2054
|
const personas = generate_persona_symlinks();
|
|
@@ -1723,7 +2059,7 @@ function _generate_tools_inner(
|
|
|
1723
2059
|
const windsurf_wf = _tool_active('windsurf') ? generate_windsurf_workflows(cmd_slugs) : 0;
|
|
1724
2060
|
const summary =
|
|
1725
2061
|
`✅ generate-tools — rules=${rules} skills=${skills} ` +
|
|
1726
|
-
`commands=${commands} plugin_cmd_skills=${plugin_cmd_skills} ` +
|
|
2062
|
+
`commands=${commands} subagents=${subagents} subagent_contexts=${subagent_contexts} plugin_cmd_skills=${plugin_cmd_skills} ` +
|
|
1727
2063
|
`plugin_hooks=${plugin_hooks} ` +
|
|
1728
2064
|
`personas=${personas} user_types=${user_types} ` +
|
|
1729
2065
|
`cursor_mdc=${cursor_mdc} windsurf_rules=${windsurf_modern} ` +
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
/**
|
|
3
|
+
* Consolidation report generator for `/team-knowledge consolidate` —
|
|
4
|
+
* road-to-knowledge-system Phase 5. Reads the pending typed-observation
|
|
5
|
+
* intake, aggregates by topic, and finds the nearest existing knowledge
|
|
6
|
+
* page for each aggregate (mechanical similarity only). It NEVER decides
|
|
7
|
+
* NEW/EXTEND/CONFIRM/CONFLICT and NEVER writes a page — per the council
|
|
8
|
+
* verdict, that triage is always a human-reviewed judgment call the
|
|
9
|
+
* command prose makes from this report.
|
|
10
|
+
*
|
|
11
|
+
* Default mode prints the report and exits — intake is untouched.
|
|
12
|
+
* `--commit` additionally clears the consumed intake AFTER printing,
|
|
13
|
+
* for use once the agent has written the reviewed batch (mirrors
|
|
14
|
+
* memory-consolidation's --preview / --commit-intake split).
|
|
15
|
+
*
|
|
16
|
+
* Usage:
|
|
17
|
+
* consolidate_knowledge_events.ts [--intake-dir <dir>] [--knowledge-dir <dir>] [--format text|json] [--commit]
|
|
18
|
+
*
|
|
19
|
+
* Exit codes: 0 = report printed (regardless of pending-event count), 1 = usage error.
|
|
20
|
+
*/
|
|
21
|
+
import * as fs from 'node:fs';
|
|
22
|
+
import * as path from 'node:path';
|
|
23
|
+
import process from 'node:process';
|
|
24
|
+
import { fileURLToPath } from 'node:url';
|
|
25
|
+
|
|
26
|
+
import { findMostSimilar, type Candidate } from './_lib/text_similarity.js';
|
|
27
|
+
import { clearAllEvents, readAllEvents, type KnowledgeEvent } from './_lib/knowledge_events.js';
|
|
28
|
+
|
|
29
|
+
const PROG = 'consolidate_knowledge_events.ts';
|
|
30
|
+
const DEFAULT_INTAKE_DIR = path.join('agents', 'knowledge', 'intake');
|
|
31
|
+
const DEFAULT_KNOWLEDGE_DIR = path.join('agents', 'knowledge');
|
|
32
|
+
const PAGE_DIRS = ['concepts', 'procedures'] as const;
|
|
33
|
+
|
|
34
|
+
/** Stable aggregation key per event type — events with the same key describe the same emerging topic. */
|
|
35
|
+
export function aggregationKey(event: KnowledgeEvent): string {
|
|
36
|
+
switch (event.type) {
|
|
37
|
+
case 'convention_detected':
|
|
38
|
+
return `convention:${event.pattern}`;
|
|
39
|
+
case 'mistake_made':
|
|
40
|
+
return `mistake:${event.recurrenceKey}`;
|
|
41
|
+
case 'api_shape_learned':
|
|
42
|
+
return `api:${event.method} ${event.endpoint}`;
|
|
43
|
+
case 'context_stale':
|
|
44
|
+
return `stale:${event.pagePath}#${event.field}`;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Short human-readable text representing the aggregate, used for the similarity scan against existing pages. */
|
|
49
|
+
function aggregateText(event: KnowledgeEvent): string {
|
|
50
|
+
switch (event.type) {
|
|
51
|
+
case 'convention_detected':
|
|
52
|
+
return event.pattern;
|
|
53
|
+
case 'mistake_made':
|
|
54
|
+
return `${event.errorCategory} ${event.correction}`;
|
|
55
|
+
case 'api_shape_learned':
|
|
56
|
+
return `${event.method} ${event.endpoint}`;
|
|
57
|
+
case 'context_stale':
|
|
58
|
+
return `${event.field} ${String(event.expected)} ${String(event.actual)}`;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export interface AggregateGroup {
|
|
63
|
+
key: string;
|
|
64
|
+
events: KnowledgeEvent[];
|
|
65
|
+
nearestPage: { path: string; score: number } | null;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function listMarkdownFiles(dirPath: string): string[] {
|
|
69
|
+
let entries: fs.Dirent[];
|
|
70
|
+
try {
|
|
71
|
+
entries = fs.readdirSync(dirPath, { withFileTypes: true });
|
|
72
|
+
} catch {
|
|
73
|
+
return [];
|
|
74
|
+
}
|
|
75
|
+
return entries.filter((e) => e.isFile() && e.name.endsWith('.md')).map((e) => e.name);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function loadPageCandidates(knowledgeDir: string): Candidate[] {
|
|
79
|
+
const out: Candidate[] = [];
|
|
80
|
+
for (const dir of PAGE_DIRS) {
|
|
81
|
+
const scanDir = path.join(knowledgeDir, dir);
|
|
82
|
+
for (const file of listMarkdownFiles(scanDir)) {
|
|
83
|
+
let text = '';
|
|
84
|
+
try {
|
|
85
|
+
text = fs.readFileSync(path.join(scanDir, file), 'utf8');
|
|
86
|
+
} catch {
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
out.push({ id: `${dir}/${file}`, text });
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return out;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/** Pure aggregation + similarity-scan step. Never touches disk beyond the passed-in candidates. */
|
|
96
|
+
export function buildReport(events: KnowledgeEvent[], pageCandidates: Candidate[]): AggregateGroup[] {
|
|
97
|
+
const groups = new Map<string, KnowledgeEvent[]>();
|
|
98
|
+
for (const event of events) {
|
|
99
|
+
const key = aggregationKey(event);
|
|
100
|
+
const bucket = groups.get(key) ?? [];
|
|
101
|
+
bucket.push(event);
|
|
102
|
+
groups.set(key, bucket);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const out: AggregateGroup[] = [];
|
|
106
|
+
for (const [key, groupEvents] of groups) {
|
|
107
|
+
const first = groupEvents[0];
|
|
108
|
+
if (first === undefined) continue;
|
|
109
|
+
const representative = aggregateText(first);
|
|
110
|
+
const match = findMostSimilar(representative, pageCandidates);
|
|
111
|
+
out.push({
|
|
112
|
+
key,
|
|
113
|
+
events: groupEvents,
|
|
114
|
+
nearestPage: match && match.classification !== 'create' ? { path: match.id, score: match.score } : null,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
return out.sort((a, b) => (a.key < b.key ? -1 : a.key > b.key ? 1 : 0));
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function renderText(report: AggregateGroup[]): string {
|
|
121
|
+
if (report.length === 0) return `${PROG}: no pending knowledge events.\n`;
|
|
122
|
+
const lines: string[] = [`${PROG}: ${report.length} topic(s) pending review.`, ''];
|
|
123
|
+
for (const group of report) {
|
|
124
|
+
lines.push(`## ${group.key} (${group.events.length} event(s))`);
|
|
125
|
+
if (group.nearestPage) {
|
|
126
|
+
lines.push(
|
|
127
|
+
` Nearest existing page: ${group.nearestPage.path} (${(group.nearestPage.score * 100).toFixed(0)}% similar) — triage EXTEND/CONFIRM/CONFLICT`,
|
|
128
|
+
);
|
|
129
|
+
} else {
|
|
130
|
+
lines.push(' No similar existing page found — triage NEW');
|
|
131
|
+
}
|
|
132
|
+
lines.push('');
|
|
133
|
+
}
|
|
134
|
+
return lines.join('\n');
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function printUsage(): void {
|
|
138
|
+
process.stdout.write(`usage: ${PROG} [--intake-dir DIR] [--knowledge-dir DIR] [--format text|json] [--commit]\n`);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export function main(argv: string[]): number {
|
|
142
|
+
let intakeDir = DEFAULT_INTAKE_DIR;
|
|
143
|
+
let knowledgeDir = DEFAULT_KNOWLEDGE_DIR;
|
|
144
|
+
let format: 'text' | 'json' = 'text';
|
|
145
|
+
let commit = false;
|
|
146
|
+
|
|
147
|
+
for (let i = 0; i < argv.length; i++) {
|
|
148
|
+
const arg = argv[i];
|
|
149
|
+
if (arg === '-h' || arg === '--help') {
|
|
150
|
+
printUsage();
|
|
151
|
+
return 0;
|
|
152
|
+
} else if (arg === '--intake-dir') {
|
|
153
|
+
intakeDir = argv[++i] ?? intakeDir;
|
|
154
|
+
} else if (arg === '--knowledge-dir') {
|
|
155
|
+
knowledgeDir = argv[++i] ?? knowledgeDir;
|
|
156
|
+
} else if (arg === '--format') {
|
|
157
|
+
const value = argv[++i];
|
|
158
|
+
if (value !== 'text' && value !== 'json') {
|
|
159
|
+
process.stderr.write(`${PROG}: error: --format must be text or json\n`);
|
|
160
|
+
return 1;
|
|
161
|
+
}
|
|
162
|
+
format = value;
|
|
163
|
+
} else if (arg === '--commit') {
|
|
164
|
+
commit = true;
|
|
165
|
+
} else {
|
|
166
|
+
process.stderr.write(`${PROG}: error: unrecognized argument: ${arg}\n`);
|
|
167
|
+
printUsage();
|
|
168
|
+
return 1;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const events = readAllEvents(intakeDir);
|
|
173
|
+
const candidates = loadPageCandidates(knowledgeDir);
|
|
174
|
+
const report = buildReport(events, candidates);
|
|
175
|
+
|
|
176
|
+
if (format === 'json') {
|
|
177
|
+
process.stdout.write(JSON.stringify(report, null, 2) + '\n');
|
|
178
|
+
} else {
|
|
179
|
+
process.stdout.write(renderText(report));
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (commit) {
|
|
183
|
+
clearAllEvents(intakeDir);
|
|
184
|
+
process.stdout.write(`${PROG}: intake cleared.\n`);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
return 0;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
if (fileURLToPath(import.meta.url) === path.resolve(process.argv[1] ?? '')) {
|
|
191
|
+
process.exit(main(process.argv.slice(2)));
|
|
192
|
+
}
|