@event4u/agent-config 3.3.0 → 4.2.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/.agent-src/README.md +2 -2
- package/.agent-src/commands/agent-handoff.md +31 -2
- package/.agent-src/commands/agent-status.md +5 -5
- package/.agent-src/commands/agents/audit.md +8 -8
- package/.agent-src/commands/agents/init.md +25 -1
- package/.agent-src/commands/agents/optimize.md +3 -3
- package/.agent-src/commands/agents/user.md +1 -1
- package/.agent-src/commands/agents.md +1 -1
- package/.agent-src/commands/analyze-reference-repo.md +1 -1
- package/.agent-src/commands/check-current-md.md +8 -8
- package/.agent-src/commands/{compress.md → condense.md} +55 -55
- package/.agent-src/commands/context/create.md +7 -4
- package/.agent-src/commands/context/refactor.md +3 -1
- package/.agent-src/commands/feature/dev.md +1 -1
- package/.agent-src/commands/feature/explore.md +1 -1
- package/.agent-src/commands/feature/plan.md +10 -8
- package/.agent-src/commands/feature/refactor.md +3 -1
- package/.agent-src/commands/feature/roadmap.md +7 -4
- package/.agent-src/commands/fix/portability.md +3 -3
- package/.agent-src/commands/fix/refs.md +4 -4
- package/.agent-src/commands/ghostwriter.md +2 -2
- package/.agent-src/commands/memory/learn-low-impact.md +3 -3
- package/.agent-src/commands/module/explore.md +34 -8
- package/.agent-src/commands/optimize/agents-dir.md +9 -7
- package/.agent-src/commands/optimize/augmentignore.md +2 -2
- package/.agent-src/commands/optimize/skills.md +9 -9
- package/.agent-src/commands/post-as.md +1 -1
- package/.agent-src/commands/project-analyze.md +2 -2
- package/.agent-src/commands/project-health.md +3 -2
- package/.agent-src/commands/research/deep.md +1 -1
- package/.agent-src/commands/research/report.md +1 -1
- package/.agent-src/commands/research.md +1 -1
- package/.agent-src/commands/roadmap/ai-council.md +1 -1
- package/.agent-src/commands/roadmap/create.md +9 -4
- package/.agent-src/commands/rule-compliance-audit.md +1 -1
- package/.agent-src/commands/upstream-contribute.md +14 -14
- package/.agent-src/commands/video/from-script.md +1 -1
- package/.agent-src/commands/video/scene.md +1 -1
- package/.agent-src/commands/video/stitch.md +1 -1
- package/.agent-src/commands/video/storyboard.md +1 -1
- package/.agent-src/commands/video.md +1 -1
- package/.agent-src/contexts/augment-infrastructure.md +1 -1
- package/.agent-src/contexts/authority/commit-mechanics.md +15 -0
- package/.agent-src/contexts/authority/kernel-rule-edits.md +3 -3
- package/.agent-src/contexts/authority/scope-mechanics.md +1 -1
- package/.agent-src/contexts/communication/rules-auto/augment-source-of-truth-mechanics.md +28 -28
- package/.agent-src/contexts/communication/rules-auto/skill-quality-mechanics.md +4 -4
- package/.agent-src/contexts/communication/rules-auto/think-before-action-mechanics.md +2 -2
- package/.agent-src/contexts/contracts/artifact-engagement-flow.md +6 -6
- package/.agent-src/contexts/contracts/command-suggestion-flow.md +3 -3
- package/.agent-src/contexts/contracts/emergency-triage-block.md +4 -4
- package/.agent-src/contexts/contracts/frugality-charter.md +3 -3
- package/.agent-src/contexts/documentation-hierarchy.md +14 -7
- package/.agent-src/contexts/execution/autonomy-examples.md +1 -1
- package/.agent-src/contexts/execution/cheap-question-mechanics.md +39 -2
- package/.agent-src/contexts/execution/roadmap-process-loop.md +28 -5
- package/.agent-src/contexts/override-system.md +5 -5
- package/.agent-src/ghostwriter/fictional-fixture-v1.md +1 -1
- package/.agent-src/personas/advisors/first-principles.md +1 -1
- package/.agent-src/personas/hollywood-director.md +1 -1
- package/.agent-src/rules/architecture.md +5 -1
- package/.agent-src/rules/augment-edit-discipline.md +5 -5
- package/.agent-src/rules/augment-source-of-truth.md +15 -15
- package/.agent-src/rules/commit-conventions.md +1 -1
- package/.agent-src/rules/commit-policy.md +10 -0
- package/.agent-src/rules/domain-adoption-policy.md +3 -3
- package/.agent-src/rules/fast-path-marker-visibility.md +3 -3
- package/.agent-src/rules/finance-safety-floor.md +1 -1
- package/.agent-src/rules/framework-neutrality-in-generic-skills.md +8 -8
- package/.agent-src/rules/git-history-discipline.md +1 -1
- package/.agent-src/rules/improve-before-implement.md +2 -2
- package/.agent-src/rules/language-and-tone.md +2 -2
- package/.agent-src/rules/media-governance-routing.md +5 -5
- package/.agent-src/rules/no-attribution-footers.md +1 -0
- package/.agent-src/rules/no-cheap-questions.md +3 -0
- package/.agent-src/rules/no-decorative-emojis-in-git-surfaces.md +111 -0
- package/.agent-src/rules/no-pr-progress-comments.md +118 -0
- package/.agent-src/rules/no-roadmap-references.md +3 -3
- package/.agent-src/rules/non-destructive-by-default.md +1 -1
- package/.agent-src/rules/persona-governance.md +3 -3
- package/.agent-src/rules/preservation-guard.md +15 -15
- package/.agent-src/rules/roadmap-ci-steps-policy.md +7 -3
- package/.agent-src/rules/rule-type-governance.md +1 -1
- package/.agent-src/rules/skill-quality.md +1 -1
- package/.agent-src/rules/{caveman-speak.md → telegraph-speak.md} +15 -15
- package/.agent-src/rules/token-optimizer-maintenance.md +6 -6
- package/.agent-src/skills/agent-docs-writing/SKILL.md +17 -11
- package/.agent-src/skills/agents-md-thin-root/SKILL.md +9 -9
- package/.agent-src/skills/check-refs/SKILL.md +2 -2
- package/.agent-src/skills/code-refactoring/SKILL.md +2 -2
- package/.agent-src/skills/command-writing/SKILL.md +19 -19
- package/.agent-src/skills/comp-banding/SKILL.md +1 -1
- package/.agent-src/skills/condense-memory/SKILL.md +131 -0
- package/.agent-src/skills/context-authoring/SKILL.md +2 -2
- package/.agent-src/skills/context-document/SKILL.md +5 -3
- package/.agent-src/skills/copilot-agents-optimization/SKILL.md +3 -3
- package/.agent-src/skills/description-assist/SKILL.md +2 -2
- package/.agent-src/skills/git-workflow/SKILL.md +1 -1
- package/.agent-src/skills/guideline-writing/SKILL.md +5 -5
- package/.agent-src/skills/learning-to-rule-or-skill/SKILL.md +4 -4
- package/.agent-src/skills/lint-skills/SKILL.md +3 -3
- package/.agent-src/skills/md-language-check/SKILL.md +2 -2
- package/.agent-src/skills/module-detect-on-the-fly/SKILL.md +138 -0
- package/.agent-src/skills/module-management/SKILL.md +166 -94
- package/.agent-src/skills/override-management/SKILL.md +1 -1
- package/.agent-src/skills/persona-writing/SKILL.md +5 -5
- package/.agent-src/skills/positioning-strategy/SKILL.md +1 -1
- package/.agent-src/skills/project-docs/SKILL.md +6 -4
- package/.agent-src/skills/readme-reviewer/SKILL.md +2 -2
- package/.agent-src/skills/roadmap-management/SKILL.md +13 -1
- package/.agent-src/skills/roadmap-writing/SKILL.md +4 -2
- package/.agent-src/skills/rule-refactor/SKILL.md +5 -5
- package/.agent-src/skills/rule-writing/SKILL.md +18 -18
- package/.agent-src/skills/script-writing/SKILL.md +1 -1
- package/.agent-src/skills/skill-improvement-pipeline/SKILL.md +6 -6
- package/.agent-src/skills/skill-management/SKILL.md +21 -21
- package/.agent-src/skills/skill-reviewer/SKILL.md +2 -2
- package/.agent-src/skills/skill-writing/SKILL.md +8 -8
- package/.agent-src/skills/skill-writing/evals/triggers.json +1 -1
- package/.agent-src/skills/token-optimizer/SKILL.md +4 -4
- package/.agent-src/skills/unit-economics-modeling/SKILL.md +1 -1
- package/.agent-src/skills/upstream-contribute/SKILL.md +17 -17
- package/.agent-src/templates/AGENTS.md +1 -0
- package/.agent-src/templates/agent-settings.md +24 -13
- package/.agent-src/templates/agents/agent-project-settings.example.yml +61 -2
- package/.agent-src/templates/command.md +5 -5
- package/.agent-src/templates/contexts.md +1 -1
- package/.agent-src/templates/copilot-instructions.md +8 -8
- package/.agent-src/templates/features.md +1 -1
- package/.agent-src/templates/hooks/pre-commit-frontmatter +2 -2
- package/.agent-src/templates/hooks/pre-commit-roadmap-progress +3 -3
- package/.agent-src/templates/persona.md +2 -2
- package/.agent-src/templates/roadmaps.md +1 -1
- package/.agent-src/templates/rule.md +13 -13
- package/.agent-src/templates/scripts/memory_lookup.py +1 -1
- package/.agent-src/templates/scripts/memory_status.py +2 -2
- package/.agent-src/templates/scripts/work_engine/_lib/agent_settings.py +195 -1
- package/.agent-src/templates/scripts/work_engine/orchestration.py +1 -1
- package/.agent-src/templates/skill-archive-note.md +5 -5
- package/.agent-src/templates/skill.md +1 -1
- package/.claude-plugin/marketplace.json +4 -4
- package/AGENTS.md +16 -17
- package/CHANGELOG.md +216 -3
- package/CONTRIBUTING.md +31 -12
- package/README.md +21 -12
- package/config/agent-settings.template.yml +22 -2
- package/config/discovery/unassigned-artefacts.yml +24 -24
- package/config/profiles/full.ini +1 -1
- package/dist/cli/agent-config.js +52 -3
- package/dist/cli/agent-config.js.map +1 -1
- package/dist/cli/commands/uiServe.js +9 -0
- package/dist/cli/commands/uiServe.js.map +1 -1
- package/dist/cli/registry.js +2 -1
- package/dist/cli/registry.js.map +1 -1
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +649 -606
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +4 -4
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +439 -437
- package/dist/discovery/trust-report.md +5 -5
- package/dist/discovery/workspaces.json +450 -448
- package/dist/install/atomic.js +92 -0
- package/dist/install/atomic.js.map +1 -0
- package/dist/install/conflict.js +196 -0
- package/dist/install/conflict.js.map +1 -0
- package/dist/install/detect.js +218 -0
- package/dist/install/detect.js.map +1 -0
- package/dist/install/paths.js +82 -0
- package/dist/install/paths.js.map +1 -0
- package/dist/install/plan.js +157 -0
- package/dist/install/plan.js.map +1 -0
- package/dist/install/txlog.js +140 -0
- package/dist/install/txlog.js.map +1 -0
- package/dist/install/types.js +19 -0
- package/dist/install/types.js.map +1 -0
- package/dist/install/wizard-plan.js +184 -0
- package/dist/install/wizard-plan.js.map +1 -0
- package/dist/mcp/registry-manifest.json +4 -4
- package/dist/router.json +67 -19
- package/dist/server/app.js +6 -0
- package/dist/server/app.js.map +1 -1
- package/dist/server/routes/install.js +358 -0
- package/dist/server/routes/install.js.map +1 -0
- package/dist/server/routes/wizard.js +468 -32
- package/dist/server/routes/wizard.js.map +1 -1
- package/dist/server/routes/workspace.js +396 -0
- package/dist/server/routes/workspace.js.map +1 -0
- package/dist/server/schemas/settings.js +5 -3
- package/dist/server/schemas/settings.js.map +1 -1
- package/dist/ui/assets/index-BDAhhpDV.js +40 -0
- package/dist/ui/assets/index-BDAhhpDV.js.map +1 -0
- package/dist/ui/assets/index-BXZILUxe.css +1 -0
- package/dist/ui/index.html +2 -2
- package/docs/MIGRATION.md +1 -1
- package/docs/adrs/cost/0001-hard-stop-hook.md +1 -1
- package/docs/adrs/router/0001-three-tier-routing.md +4 -4
- package/docs/adrs/schema/0001-json-schema-frontmatter.md +1 -1
- package/docs/adrs/smoke/0001-per-tier-smoke-scripts.md +4 -4
- package/docs/adrs/{caveman → telegraph}/0001-default-off-until-bench.md +9 -9
- package/docs/adrs/telegraph/README.md +9 -0
- package/docs/architecture/augment-projection.md +4 -4
- package/docs/architecture/claude-bundle.md +1 -1
- package/docs/architecture/current-onboard-baseline.md +3 -3
- package/docs/architecture/multi-tool-projection.md +10 -10
- package/docs/architecture/source-projection.md +27 -27
- package/docs/architecture.md +19 -15
- package/docs/archive/CHANGELOG-pre-2.11.0.md +2 -2
- package/docs/archive/CHANGELOG-pre-2.15.0.md +3 -3
- package/docs/archive/CHANGELOG-pre-2.16.0.md +1 -1
- package/docs/archive/CHANGELOG-pre-2.2.0.md +70 -70
- package/docs/archive/CHANGELOG-pre-2.20.0.md +2 -2
- package/docs/archive/CHANGELOG-pre-2.25.0.md +15 -15
- package/docs/archive/CHANGELOG-pre-3.0.0.md +4 -4
- package/docs/archive/CHANGELOG-pre-3.1.0.md +2 -2
- package/docs/archive/CHANGELOG-pre-3.2.0.md +3 -3
- package/docs/benchmark.md +65 -0
- package/docs/benchmarks.md +16 -16
- package/docs/catalog.md +17 -15
- package/docs/contracts/CHANGELOG-conventions.md +1 -1
- package/docs/contracts/STABILITY.md +2 -2
- package/docs/contracts/adoption-signal-floor.md +110 -0
- package/docs/contracts/adr-chat-history-split.md +4 -4
- package/docs/contracts/adr-command-suggestion.md +4 -4
- package/docs/contracts/adr-gtm-context-spine.md +1 -1
- package/docs/contracts/adr-implement-ticket-runtime.md +4 -4
- package/docs/contracts/adr-install-user-type-axis.md +1 -1
- package/docs/contracts/adr-layout.md +2 -2
- package/docs/contracts/adr-product-ui-track.md +10 -10
- package/docs/contracts/adr-user-types-axis.md +3 -3
- package/docs/contracts/adr-wing4-context-spine.md +1 -1
- package/docs/contracts/agent-memory-contract.md +3 -3
- package/docs/contracts/agents-md-tech-stack.md +2 -2
- package/docs/contracts/ai-council-config.md +2 -2
- package/docs/contracts/at-rest-encryption.md +4 -0
- package/docs/contracts/audit-log-v1.md +1 -1
- package/docs/contracts/benchmark-ab-contract.md +101 -0
- package/docs/contracts/benchmark-corpus-spec.md +1 -1
- package/docs/contracts/branch-protection-policy.md +98 -0
- package/docs/contracts/ci-cost-budget.md +106 -0
- package/docs/contracts/ci-green-floor.md +141 -0
- package/docs/contracts/command-clusters.md +6 -6
- package/docs/contracts/command-surface-tiers.md +2 -2
- package/docs/contracts/command-taxonomy.md +2 -2
- package/docs/contracts/{compression-default-kill-criterion.md → condensation-default-kill-criterion.md} +29 -29
- package/docs/contracts/config-presets.md +1 -1
- package/docs/contracts/context-paths.md +3 -3
- package/docs/contracts/context-spine.md +1 -1
- package/docs/contracts/cost-summary-schema.md +12 -12
- package/docs/contracts/cross-wing-handoff.md +4 -4
- package/docs/contracts/daily-workspace.md +4 -0
- package/docs/contracts/decision-trace-v1.md +2 -2
- package/docs/contracts/discovery-manifest.md +4 -4
- package/docs/contracts/explain-modes.md +4 -0
- package/docs/contracts/file-ownership-matrix.json +3493 -3318
- package/docs/contracts/file-ownership-matrix.md +3 -3
- package/docs/contracts/frontmatter-contract.md +4 -4
- package/docs/contracts/ghostwriter-schema.md +3 -3
- package/docs/contracts/gui-wizard.md +110 -97
- package/docs/contracts/harness-expectations.md +123 -0
- package/docs/contracts/host-agent-protocol.md +4 -0
- package/docs/contracts/implement-ticket-flow.md +9 -9
- package/docs/contracts/install-scopes.md +77 -0
- package/docs/contracts/iron-law-overrides.txt +1 -1
- package/docs/contracts/kernel-membership.md +26 -26
- package/docs/contracts/linear-ai-rules-inclusion.md +1 -1
- package/docs/contracts/linter-structural-model.md +2 -2
- package/docs/contracts/load-context-budget-model.md +4 -4
- package/docs/contracts/load-context-schema.md +13 -13
- package/docs/contracts/local-analytics.md +4 -0
- package/docs/contracts/local-knowledge-ingestion.md +1 -1
- package/docs/contracts/mcp-cloud-scope.md +2 -2
- package/docs/contracts/mcp-phase-1-scope.md +3 -3
- package/docs/contracts/measurement-baseline.md +5 -5
- package/docs/contracts/mental-models.md +30 -30
- package/docs/contracts/multi-tool-projection-fidelity.md +4 -4
- package/docs/contracts/namespace.md +4 -4
- package/docs/contracts/orchestration-dsl-v1.md +7 -7
- package/docs/contracts/package-self-orientation.md +12 -12
- package/docs/contracts/persona-schema.md +6 -6
- package/docs/contracts/pilot/language-and-tone.md +1 -1
- package/docs/contracts/plain-language-surface.md +117 -0
- package/docs/contracts/profile-system.md +3 -3
- package/docs/contracts/release-pr-gating.md +103 -0
- package/docs/contracts/role-experience.md +3 -3
- package/docs/contracts/rule-classification.md +13 -13
- package/docs/contracts/rule-interactions.md +4 -4
- package/docs/contracts/rule-interactions.yml +30 -30
- package/docs/contracts/rule-priority-hierarchy.md +13 -13
- package/docs/contracts/rule-router.md +2 -2
- package/docs/contracts/safety-model.md +1 -1
- package/docs/contracts/skill-distribution-channels.md +61 -0
- package/docs/contracts/skill-domains.md +2 -2
- package/docs/contracts/smoke-contracts.md +5 -5
- package/docs/contracts/telegraph-telemetry.md +83 -0
- package/docs/contracts/trust-and-safety.md +5 -5
- package/docs/contracts/ui-stack-extension.md +7 -7
- package/docs/contracts/ui-track-flow.md +9 -9
- package/docs/contracts/user-type-schema.md +4 -4
- package/docs/contracts/workflow-packs.md +4 -4
- package/docs/contracts/workspace-documents.md +4 -0
- package/docs/customization.md +28 -8
- package/docs/decisions/ADR-001-kernel-swap-deferred.md +6 -6
- package/docs/decisions/ADR-002-kernel-bucket-overrides.md +11 -11
- package/docs/decisions/ADR-003-flat-cluster-subs-and-colon-syntax.md +2 -2
- package/docs/decisions/ADR-004-rule-governance-pruning.md +4 -4
- package/docs/decisions/ADR-005-subagent-worktrees.md +7 -7
- package/docs/decisions/ADR-011-domain-pack-readiness.md +6 -6
- package/docs/decisions/ADR-013-discovery-frontmatter-contract.md +3 -3
- package/docs/decisions/ADR-015-discovery-manifest-contract.md +3 -3
- package/docs/decisions/ADR-017-monorepo-physical-layout.md +10 -10
- package/docs/decisions/ADR-018-trust-and-safety-layer.md +6 -6
- package/docs/decisions/ADR-019-router-json-dist-location.md +2 -2
- package/docs/decisions/ADR-020-global-only-consumer-scope.md +2 -2
- package/docs/decisions/ADR-021-deployment-shape.md +3 -3
- package/docs/decisions/ADR-022-daily-workspace-decomposition.md +1 -1
- package/docs/decisions/ADR-027-changelog-machine-vs-manual.md +2 -2
- package/docs/decisions/ADR-028-root-layout.md +7 -7
- package/docs/decisions/ADR-029-multi-workspace-deferred.md +2 -2
- package/docs/decisions/ADR-rule-kernel-and-router.md +5 -5
- package/docs/deploy/connector-setup.md +2 -2
- package/docs/deploy/policy-cookbook.md +2 -2
- package/docs/deploy/team-deployment-posture.md +20 -0
- package/docs/development.md +17 -17
- package/docs/distribution/registries.md +32 -0
- package/docs/distribution/registry-submissions.md +85 -0
- package/docs/distribution/telemetry-schema.md +1 -1
- package/docs/getting-started-by-role.md +45 -3
- package/docs/getting-started.md +2 -2
- package/docs/guidelines/agent-infra/5w2h-analysis.md +3 -3
- package/docs/guidelines/agent-infra/ask-when-uncertain-demos.md +1 -1
- package/docs/guidelines/agent-infra/asking-and-brevity-examples.md +3 -3
- package/docs/guidelines/agent-infra/carve-out-predicates.md +3 -3
- package/docs/guidelines/agent-infra/critical-thinking.md +4 -4
- package/docs/guidelines/agent-infra/direct-answers-demos.md +1 -1
- package/docs/guidelines/agent-infra/first-principles.md +2 -2
- package/docs/guidelines/agent-infra/inversion-thinking.md +5 -5
- package/docs/guidelines/agent-infra/layered-settings.md +56 -2
- package/docs/guidelines/agent-infra/mental-models.md +3 -3
- package/docs/guidelines/agent-infra/roadmap-progress-mechanics.md +2 -2
- package/docs/guidelines/agent-infra/rule-type-governance.md +1 -1
- package/docs/guidelines/agent-infra/scqa-framework.md +5 -5
- package/docs/guidelines/agent-infra/self-improvement-pipeline.md +2 -2
- package/docs/guidelines/agent-infra/six-hats.md +3 -3
- package/docs/guidelines/agent-infra/skill-quality-checklist.md +5 -5
- package/docs/guidelines/agent-infra/systems-thinking.md +1 -1
- package/docs/guidelines/agent-infra/verify-before-complete-demos.md +1 -1
- package/docs/guidelines/augment-portability-patterns.md +4 -4
- package/docs/guidelines/cross-role-handoff.md +2 -2
- package/docs/guidelines/php/php-coding-patterns.md +1 -1
- package/docs/guidelines/prompt-templates.md +6 -6
- package/docs/maintainers/dev-mode.md +1 -1
- package/docs/mcp.md +1 -1
- package/docs/parity/bench.json +3 -3
- package/docs/parity/ruflo.md +2 -2
- package/docs/profiles.md +11 -11
- package/docs/quality.md +11 -11
- package/docs/safety.md +3 -3
- package/docs/setup/mcp-client-config.md +1 -1
- package/docs/setup/mcp-r2-bootstrap.md +1 -1
- package/docs/setup/mcp-server-docker.md +3 -3
- package/docs/setup/per-ide/windsurf.md +1 -1
- package/docs/skills-catalog.md +8 -7
- package/docs/troubleshooting.md +1 -1
- package/docs/walkthroughs/daily-workspace-a11y.md +87 -0
- package/llms.txt +7 -6
- package/package.json +1 -1
- package/scripts/__pycache__/validate_frontmatter.cpython-312.pyc +0 -0
- package/scripts/_archive/README.md +2 -2
- package/scripts/_archive/_backfill_skill_domains.py +3 -3
- package/scripts/_archive/_bootstrap_tier_frontmatter.py +3 -3
- package/scripts/_archive/_p43_bodies.py +10 -10
- package/scripts/_archive/{_p43_compress.py → _p43_condense.py} +5 -5
- package/scripts/_archive/_p4_migrate.py +7 -7
- package/scripts/_archive/_phase2_shim_helper.py +1 -1
- package/scripts/_archive/_pilot_council_question.py +5 -5
- package/scripts/_cli/explain_last/inputs.py +1 -1
- package/scripts/_lib/__pycache__/__init__.cpython-312.pyc +0 -0
- package/scripts/_lib/__pycache__/agent_src.cpython-312.pyc +0 -0
- package/scripts/_lib/agent_settings.py +195 -1
- package/scripts/_lib/agent_src.py +19 -19
- package/scripts/_lib/bench_ab_cache.py +162 -0
- package/scripts/_lib/bench_ab_scoring.py +209 -0
- package/scripts/_lib/{bench_caveman.py → bench_telegraph.py} +21 -21
- package/scripts/_lib/{bench_caveman_report.py → bench_telegraph_report.py} +21 -21
- package/scripts/_lib/claude_desktop_bundler.py +5 -5
- package/scripts/_lib/module_detection.py +223 -0
- package/scripts/_lib/scope_guard.sh +162 -0
- package/scripts/_phase4_bucket.py +3 -3
- package/scripts/_pilot_measure.py +4 -4
- package/scripts/_tmp_scan_framework_leakage.py +1 -1
- package/scripts/adoption_report.py +195 -0
- package/scripts/adoption_snapshot.py +219 -0
- package/scripts/adoption_status.py +166 -0
- package/scripts/ai-video/lib/parse-blueprint.sh +1 -1
- package/scripts/ai_council/advisors.py +5 -5
- package/scripts/ai_council/compile_corpus.py +1 -1
- package/scripts/ai_council/one_off_archive/2026-05/_one_off_budget_v2_audit.py +3 -3
- package/scripts/ai_council/one_off_archive/2026-05/_one_off_context_layer_v1_review.py +2 -2
- package/scripts/ai_council/one_off_archive/2026-05/_one_off_inject_quiet_flag.py +1 -1
- package/scripts/ai_council/one_off_archive/2026-05/_one_off_measure_v2.sh +1 -1
- package/scripts/ai_council/one_off_archive/2026-05/_one_off_measure_verbosity.sh +1 -1
- package/scripts/ai_council/one_off_archive/2026-05/_one_off_nondestructive_inline_audit.py +3 -3
- package/scripts/ai_council/one_off_archive/2026-05/_one_off_per_task.sh +1 -1
- package/scripts/ai_council/one_off_archive/2026-05/_one_off_phase6_trigger_jaccard.py +1 -1
- package/scripts/ai_council/one_off_archive/2026-05/_one_off_phase_2a_budget_rebalance.py +6 -6
- package/scripts/ai_council/one_off_archive/2026-05/_one_off_rebalancing_audit.py +1 -1
- package/scripts/ai_council/one_off_archive/2026-05/_one_off_tier_retrofit.py +6 -6
- package/scripts/annotate_discovery.py +13 -13
- package/scripts/apply_modules_config.py +290 -0
- package/scripts/audit_adr_coverage.py +2 -2
- package/scripts/audit_auto_rules.py +2 -2
- package/scripts/audit_cloud_compatibility.py +3 -3
- package/scripts/audit_command_surface.py +9 -9
- package/scripts/audit_likelihood.py +2 -2
- package/scripts/audit_user_type_axis.py +2 -2
- package/scripts/bench_ab_cache_dispatch.py +68 -0
- package/scripts/bench_ab_clone.py +170 -0
- package/scripts/bench_ab_diff.py +227 -0
- package/scripts/bench_ab_integrity.py +143 -0
- package/scripts/bench_ab_run.py +235 -0
- package/scripts/bench_ab_task_runner.py +369 -0
- package/scripts/bench_ab_tracka_run.py +202 -0
- package/scripts/{bench_compress_memory.py → bench_condense_memory.py} +16 -16
- package/scripts/bench_run.py +33 -33
- package/scripts/bench_runner.py +2 -2
- package/scripts/bootstrap.sh +99 -0
- package/scripts/build_cloud_bundle.py +6 -6
- package/scripts/build_discovery_manifest.py +7 -7
- package/scripts/build_linear_digest.py +3 -3
- package/scripts/build_rule_trigger_matrix.py +8 -8
- package/scripts/chat_history.py +5 -5
- package/scripts/check_always_budget.py +11 -5
- package/scripts/check_augment_description_cap.py +3 -3
- package/scripts/check_cluster_patterns.py +2 -2
- package/scripts/check_command_count_messaging.py +3 -3
- package/scripts/{check_compression.py → check_condensation.py} +34 -34
- package/scripts/{check_compressed_paths.py → check_condensed_paths.py} +8 -8
- package/scripts/check_context_paths.py +7 -7
- package/scripts/check_council_layout.py +2 -2
- package/scripts/check_council_references.py +9 -9
- package/scripts/check_iron_law_prominence.py +2 -2
- package/scripts/check_kernel_rule_bundle.py +2 -2
- package/scripts/check_module_management_neutral.py +149 -0
- package/scripts/check_no_roadmap_refs.py +9 -9
- package/scripts/check_portability.py +3 -3
- package/scripts/check_public_catalog_links.py +4 -4
- package/scripts/check_references.py +7 -6
- package/scripts/check_release_pr_shape.py +112 -0
- package/scripts/check_reply_consistency.py +3 -3
- package/scripts/check_safety_floor_untouched.py +1 -1
- package/scripts/check_template_pin_drift.py +5 -5
- package/scripts/check_token_optimizer_freshness.py +3 -3
- package/scripts/ci_status.py +301 -0
- package/scripts/ci_time_ratio.py +1 -1
- package/scripts/cleanup_other_scope.sh +146 -0
- package/scripts/compile_router.py +10 -10
- package/scripts/{compress.py → condense.py} +64 -64
- package/scripts/condense.sh +18 -0
- package/scripts/{compress_memory.py → condense_memory.py} +33 -33
- package/scripts/config/presets.py +2 -2
- package/scripts/config/profiles.py +1 -1
- package/scripts/cost_by_conversation.py +3 -3
- package/scripts/cost_summary.py +7 -7
- package/scripts/count_token_optimizer_usage.sh +1 -1
- package/scripts/gen_discovery_baseline.py +5 -5
- package/scripts/generate_index.py +6 -6
- package/scripts/generate_ownership_matrix.py +10 -10
- package/scripts/generate_pack_manifests.py +1 -1
- package/scripts/ghostwriter_fixture_allowlist.txt +1 -1
- package/scripts/install +3 -3
- package/scripts/install-hooks.sh +6 -6
- package/scripts/install.py +273 -45
- package/scripts/install.sh +187 -1
- package/scripts/inventory_frontmatter.py +2 -2
- package/scripts/iron_law_sha.py +3 -3
- package/scripts/lint_agents_layout.py +14 -7
- package/scripts/lint_agents_md.py +4 -4
- package/scripts/lint_archived_skills.py +3 -3
- package/scripts/lint_artefact_frontmatter.py +2 -2
- package/scripts/lint_bench_ab.py +172 -0
- package/scripts/lint_bench_corpus.py +1 -1
- package/scripts/lint_command_tiers.py +5 -5
- package/scripts/lint_context_spine_usage.py +1 -1
- package/scripts/lint_framework_leakage.py +7 -7
- package/scripts/lint_framework_leakage_allowlist.json +152 -84
- package/scripts/lint_ghostwriter_source.py +3 -3
- package/scripts/lint_handoffs.py +1 -1
- package/scripts/lint_load_context.py +11 -11
- package/scripts/lint_media_policy_linkage.py +5 -5
- package/scripts/lint_namespace.py +1 -1
- package/scripts/lint_no_new_atomic_commands.py +2 -2
- package/scripts/lint_orchestration_dsl.py +1 -1
- package/scripts/lint_pack_boundaries.py +2 -2
- package/scripts/lint_persona_governance.py +4 -4
- package/scripts/lint_role_experiences.py +237 -0
- package/scripts/lint_rule_interactions.py +2 -2
- package/scripts/lint_rule_tiers.py +1 -1
- package/scripts/lint_trust_coherence.py +2 -2
- package/scripts/mcp_registry_submit.sh +187 -0
- package/scripts/mcp_server/tools.py +1 -1
- package/scripts/measure_frugality_savings.py +10 -10
- package/scripts/measure_patterns.py +1 -1
- package/scripts/measure_projection_bytes.py +5 -5
- package/scripts/measure_rule_budget.py +3 -3
- package/scripts/measure_skill_reduction.py +1 -1
- package/scripts/memory_lookup.py +1 -1
- package/scripts/memory_status.py +2 -2
- package/scripts/migrate_command_suggestions.py +3 -3
- package/scripts/mine_session.py +1 -1
- package/scripts/move_artefact.py +3 -3
- package/scripts/new_skill.py +2 -2
- package/scripts/pack_mcp_content.py +9 -9
- package/scripts/plan_physical_move.py +6 -6
- package/scripts/print_required_checks.py +196 -0
- package/scripts/probe_skill_registration.py +413 -0
- package/scripts/propose_modules_config.py +145 -0
- package/scripts/prototype_lint_contradictions.py +1 -1
- package/scripts/recruit_preflight.sh +152 -0
- package/scripts/refine_ticket_detect.py +3 -3
- package/scripts/release.py +20 -0
- package/scripts/render_benchmark_md.py +308 -0
- package/scripts/roadmap_progress_hook.py +1 -1
- package/scripts/run_skill_evals.py +2 -2
- package/scripts/runtime_registry.py +4 -4
- package/scripts/schemas/command.schema.json +4 -4
- package/scripts/schemas/rule.schema.json +5 -5
- package/scripts/schemas/skill.schema.json +3 -3
- package/scripts/schemas/user-type.schema.json +1 -1
- package/scripts/score_skill_selection.py +1 -1
- package/scripts/skill_collision_clusters.py +2 -2
- package/scripts/skill_linter.py +81 -81
- package/scripts/skill_overlap.py +5 -5
- package/scripts/skill_tools/audit_persona_coverage.py +2 -2
- package/scripts/skill_tools/audit_user_type_coverage.py +2 -2
- package/scripts/skill_tools/run_block_d_eval.py +1 -1
- package/scripts/skill_tools/score_skill_relevance.py +1 -1
- package/scripts/skill_tools/suggest_skill_for_task.py +1 -1
- package/scripts/skill_trigger_eval.py +3 -3
- package/scripts/smoke/kernel.sh +7 -1
- package/scripts/smoke/router.sh +5 -5
- package/scripts/smoke/skills.sh +1 -1
- package/scripts/smoke_quickstart.py +1 -1
- package/scripts/snapshot_agent_outputs.py +3 -3
- package/scripts/spotcheck_thin_root.py +1 -1
- package/scripts/{caveman_stats.py → telegraph_stats.py} +18 -18
- package/scripts/update_counts.py +1 -1
- package/scripts/validate_decision_engine.py +1 -1
- package/scripts/validate_frontmatter.py +1 -1
- package/scripts/validate_safe_paths.py +3 -3
- package/scripts/{validate_caveman_carveouts.py → validate_telegraph_carveouts.py} +7 -7
- package/scripts/verify_roadmap_closure.py +6 -6
- package/templates/consumer-settings/ONBOARDING.md +41 -0
- package/.agent-src/commands/install-via-agent.md +0 -129
- package/.agent-src/skills/compress-memory/SKILL.md +0 -131
- package/dist/ui/assets/index-D-DY1ywI.js +0 -35
- package/dist/ui/assets/index-D-DY1ywI.js.map +0 -1
- package/dist/ui/assets/index-Dqfhmg-d.css +0 -1
- package/docs/adrs/caveman/README.md +0 -9
- package/docs/contracts/caveman-telemetry.md +0 -83
- package/scripts/compress.sh +0 -18
|
@@ -50,6 +50,7 @@ Contract — pure, read-only, tolerant:
|
|
|
50
50
|
"""
|
|
51
51
|
from __future__ import annotations
|
|
52
52
|
|
|
53
|
+
import copy
|
|
53
54
|
import logging
|
|
54
55
|
import os
|
|
55
56
|
from pathlib import Path
|
|
@@ -60,6 +61,7 @@ from . import user_global_paths
|
|
|
60
61
|
logger = logging.getLogger(__name__)
|
|
61
62
|
|
|
62
63
|
DEFAULT_PROJECT_FILE = ".agent-settings.yml"
|
|
64
|
+
DEFAULT_TEAM_FILE = ".agent-project-settings.yml"
|
|
63
65
|
USER_GLOBAL_FILENAME = "agent-settings.yml"
|
|
64
66
|
|
|
65
67
|
#: Canonical write target under the new ``~/.event4u/agent-config/``
|
|
@@ -86,11 +88,25 @@ MERGEABLE_KEYS: tuple[str, ...] = (
|
|
|
86
88
|
"cost_profile",
|
|
87
89
|
"personal.bot_icon",
|
|
88
90
|
"personal.autonomy",
|
|
89
|
-
"
|
|
91
|
+
"telegraph.speak_scope",
|
|
90
92
|
)
|
|
91
93
|
|
|
92
94
|
_DEFAULTS: dict[str, Any] = {}
|
|
93
95
|
|
|
96
|
+
#: Defaults applied by :func:`get_modules_config` when a key is absent
|
|
97
|
+
#: from both the team file and the developer cascade. The values mirror
|
|
98
|
+
#: the ``modules:`` block shipped in
|
|
99
|
+
#: ``templates/agents/agent-project-settings.example.yml``. Lists are
|
|
100
|
+
#: returned as fresh copies — callers may mutate the result safely.
|
|
101
|
+
MODULES_DEFAULTS: dict[str, Any] = {
|
|
102
|
+
"enabled": False,
|
|
103
|
+
"root_paths": [],
|
|
104
|
+
"namespace_template": "",
|
|
105
|
+
"agent_folder": "agents",
|
|
106
|
+
"skip_dirs": [".module-template", ".example"],
|
|
107
|
+
"detection_acknowledged": False,
|
|
108
|
+
}
|
|
109
|
+
|
|
94
110
|
|
|
95
111
|
#: Anchor identifier returned by :func:`find_project_root_with_anchor`.
|
|
96
112
|
ANCHOR_AGENT_SETTINGS = "agent-settings"
|
|
@@ -470,6 +486,184 @@ def load_agent_settings(
|
|
|
470
486
|
return merged
|
|
471
487
|
|
|
472
488
|
|
|
489
|
+
def get_modules_config(
|
|
490
|
+
project_root: Path | str | None = None,
|
|
491
|
+
team_path: Path | str | None = None,
|
|
492
|
+
project_path: Path | str | None = None,
|
|
493
|
+
cwd: Path | None = None,
|
|
494
|
+
) -> dict[str, Any]:
|
|
495
|
+
"""Return the merged ``modules:`` configuration with defaults applied.
|
|
496
|
+
|
|
497
|
+
Three-tier precedence (deepest wins) per the layered-settings model
|
|
498
|
+
documented in ``docs/guidelines/agent-infra/layered-settings.md``:
|
|
499
|
+
|
|
500
|
+
1. :data:`MODULES_DEFAULTS` — package-shipped defaults.
|
|
501
|
+
2. Team file — ``<project_root>/.agent-project-settings.yml``
|
|
502
|
+
(committed, all developers see the same values).
|
|
503
|
+
3. Developer cascade — every ``.agent-settings.yml`` walked by
|
|
504
|
+
:func:`_resolve_cascade_paths` (git-ignored local overrides).
|
|
505
|
+
|
|
506
|
+
The team layer may pin keys via a top-level ``locked_keys`` list of
|
|
507
|
+
dotted paths (e.g. ``[modules.root_paths]``). Locked keys discard any
|
|
508
|
+
matching override from the developer cascade and emit a ``logging``
|
|
509
|
+
INFO record. Locks are advisory — the team file always wins anyway —
|
|
510
|
+
but the explicit list makes the intent reviewable and gives the loader
|
|
511
|
+
a hook for the warning.
|
|
512
|
+
|
|
513
|
+
``project_root`` defaults to ``find_project_root(cwd or Path.cwd())``.
|
|
514
|
+
``team_path`` overrides the resolved team-file location for tests.
|
|
515
|
+
``project_path`` + ``cwd`` flow through to :func:`load_agent_settings`
|
|
516
|
+
unchanged.
|
|
517
|
+
|
|
518
|
+
Pure, read-only — no file is ever written. Missing files / malformed
|
|
519
|
+
YAML / absent ``modules:`` block all return the defaults.
|
|
520
|
+
"""
|
|
521
|
+
cwd_resolved = cwd if cwd is not None else Path.cwd()
|
|
522
|
+
|
|
523
|
+
if team_path is not None:
|
|
524
|
+
team_file = Path(team_path)
|
|
525
|
+
else:
|
|
526
|
+
if project_root is not None:
|
|
527
|
+
root = Path(project_root)
|
|
528
|
+
else:
|
|
529
|
+
root = find_project_root(cwd_resolved) or cwd_resolved
|
|
530
|
+
team_file = root / DEFAULT_TEAM_FILE
|
|
531
|
+
|
|
532
|
+
team_raw = _read_yaml(team_file) or {}
|
|
533
|
+
team_modules = team_raw.get("modules") if isinstance(team_raw.get("modules"), dict) else {}
|
|
534
|
+
locked_keys_raw = team_raw.get("locked_keys")
|
|
535
|
+
locked_keys: tuple[str, ...] = tuple(
|
|
536
|
+
k for k in (locked_keys_raw or []) if isinstance(k, str)
|
|
537
|
+
)
|
|
538
|
+
|
|
539
|
+
dev_merged = load_agent_settings(
|
|
540
|
+
project_path=project_path,
|
|
541
|
+
cwd=cwd,
|
|
542
|
+
)
|
|
543
|
+
dev_modules = dev_merged.get("modules") if isinstance(dev_merged.get("modules"), dict) else {}
|
|
544
|
+
|
|
545
|
+
merged: dict[str, Any] = copy.deepcopy(MODULES_DEFAULTS)
|
|
546
|
+
if team_modules:
|
|
547
|
+
_deep_merge(merged, team_modules)
|
|
548
|
+
|
|
549
|
+
if dev_modules:
|
|
550
|
+
for key, value in dev_modules.items():
|
|
551
|
+
dotted = f"modules.{key}"
|
|
552
|
+
if dotted in locked_keys and key in (team_modules or {}):
|
|
553
|
+
logger.info(
|
|
554
|
+
"agent_settings: ignoring developer override of locked key %s",
|
|
555
|
+
dotted,
|
|
556
|
+
)
|
|
557
|
+
continue
|
|
558
|
+
if isinstance(value, dict) and isinstance(merged.get(key), dict):
|
|
559
|
+
_deep_merge(merged[key], value)
|
|
560
|
+
else:
|
|
561
|
+
merged[key] = value
|
|
562
|
+
|
|
563
|
+
return merged
|
|
564
|
+
|
|
565
|
+
|
|
566
|
+
def enumerate_modules(
|
|
567
|
+
project_root: Path | str | None = None,
|
|
568
|
+
cwd: Path | None = None,
|
|
569
|
+
modules_config: dict[str, Any] | None = None,
|
|
570
|
+
) -> list[dict[str, Any]]:
|
|
571
|
+
"""Enumerate every module under ``modules.root_paths``.
|
|
572
|
+
|
|
573
|
+
Phase D Step 1 of road-to-configurable-modules. For each path in
|
|
574
|
+
``modules.root_paths`` (resolved relative to ``project_root``), lists
|
|
575
|
+
immediate subdirectories that survive the ``modules.skip_dirs`` filter
|
|
576
|
+
and reports whether each module ships a per-module agent folder
|
|
577
|
+
(``modules.agent_folder``, default ``agents``).
|
|
578
|
+
|
|
579
|
+
Returns a list of dicts \u2014 one per discovered module \u2014 sorted by
|
|
580
|
+
``(root_path, name)`` for deterministic output:
|
|
581
|
+
|
|
582
|
+
* ``name`` \u2014 directory name of the module
|
|
583
|
+
* ``root_path`` \u2014 repo-relative root containing the module
|
|
584
|
+
* ``module_path`` \u2014 repo-relative path to the module itself
|
|
585
|
+
* ``has_agent_folder`` \u2014 ``True`` iff a directory matching
|
|
586
|
+
``modules.agent_folder`` lives directly under the module
|
|
587
|
+
* ``agent_folder_path`` \u2014 repo-relative path to that folder
|
|
588
|
+
(``None`` when ``has_agent_folder`` is ``False``)
|
|
589
|
+
|
|
590
|
+
Contract:
|
|
591
|
+
|
|
592
|
+
* ``modules.enabled`` is **not** consulted \u2014 callers decide whether
|
|
593
|
+
to skip the call. Disabled projects normally yield ``[]`` because
|
|
594
|
+
``root_paths`` is empty by default.
|
|
595
|
+
* Missing roots are skipped silently (logged at INFO).
|
|
596
|
+
* Hidden directories (leading ``.``) and entries in
|
|
597
|
+
``modules.skip_dirs`` are filtered out.
|
|
598
|
+
* Symlinks are followed only when they resolve inside the project
|
|
599
|
+
root \u2014 same boundary as ``find_project_root``.
|
|
600
|
+
* Pure, read-only \u2014 no file or directory is ever written.
|
|
601
|
+
|
|
602
|
+
``modules_config`` lets tests inject a pre-built dict; when ``None``
|
|
603
|
+
the function calls :func:`get_modules_config` with the same
|
|
604
|
+
``project_root`` / ``cwd`` so the precedence chain matches.
|
|
605
|
+
"""
|
|
606
|
+
cwd_resolved = cwd if cwd is not None else Path.cwd()
|
|
607
|
+
if project_root is not None:
|
|
608
|
+
root = Path(project_root)
|
|
609
|
+
else:
|
|
610
|
+
root = find_project_root(cwd_resolved) or cwd_resolved
|
|
611
|
+
root = root.resolve()
|
|
612
|
+
|
|
613
|
+
if modules_config is None:
|
|
614
|
+
modules_config = get_modules_config(project_root=root, cwd=cwd)
|
|
615
|
+
|
|
616
|
+
root_paths_raw = modules_config.get("root_paths") or []
|
|
617
|
+
skip_dirs_raw = modules_config.get("skip_dirs") or MODULES_DEFAULTS["skip_dirs"]
|
|
618
|
+
agent_folder = str(modules_config.get("agent_folder") or MODULES_DEFAULTS["agent_folder"])
|
|
619
|
+
|
|
620
|
+
skip_dirs: set[str] = {str(s) for s in skip_dirs_raw if isinstance(s, str)}
|
|
621
|
+
|
|
622
|
+
discovered: list[dict[str, Any]] = []
|
|
623
|
+
for raw in root_paths_raw:
|
|
624
|
+
if not isinstance(raw, str) or not raw.strip():
|
|
625
|
+
continue
|
|
626
|
+
root_rel = raw.strip().strip("/")
|
|
627
|
+
root_abs = (root / root_rel).resolve()
|
|
628
|
+
try:
|
|
629
|
+
if not root_abs.is_dir() or not str(root_abs).startswith(str(root)):
|
|
630
|
+
logger.info("enumerate_modules: skipping missing/out-of-tree root %s", root_rel)
|
|
631
|
+
continue
|
|
632
|
+
except OSError:
|
|
633
|
+
logger.info("enumerate_modules: unreadable root %s", root_rel)
|
|
634
|
+
continue
|
|
635
|
+
|
|
636
|
+
try:
|
|
637
|
+
children = sorted(root_abs.iterdir(), key=lambda p: p.name)
|
|
638
|
+
except OSError:
|
|
639
|
+
logger.info("enumerate_modules: cannot list %s", root_rel)
|
|
640
|
+
continue
|
|
641
|
+
|
|
642
|
+
for child in children:
|
|
643
|
+
name = child.name
|
|
644
|
+
if name.startswith(".") or name in skip_dirs:
|
|
645
|
+
continue
|
|
646
|
+
if not child.is_dir():
|
|
647
|
+
continue
|
|
648
|
+
agent_dir = child / agent_folder
|
|
649
|
+
has_agent = agent_dir.is_dir()
|
|
650
|
+
try:
|
|
651
|
+
module_rel = child.resolve().relative_to(root)
|
|
652
|
+
except ValueError:
|
|
653
|
+
continue
|
|
654
|
+
entry: dict[str, Any] = {
|
|
655
|
+
"name": name,
|
|
656
|
+
"root_path": root_rel,
|
|
657
|
+
"module_path": str(module_rel),
|
|
658
|
+
"has_agent_folder": has_agent,
|
|
659
|
+
"agent_folder_path": str(module_rel / agent_folder) if has_agent else None,
|
|
660
|
+
}
|
|
661
|
+
discovered.append(entry)
|
|
662
|
+
|
|
663
|
+
discovered.sort(key=lambda m: (m["root_path"], m["name"]))
|
|
664
|
+
return discovered
|
|
665
|
+
|
|
666
|
+
|
|
473
667
|
def iter_setting_overrides(
|
|
474
668
|
project_path: Path | str | None = None,
|
|
475
669
|
user_global_path: Path | str | None = None,
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
"""Locate artefact source roots across the monorepo physical layout.
|
|
2
2
|
|
|
3
3
|
Phase 4 of the monorepo migration (ADR-017) physically moves source
|
|
4
|
-
artefacts out of the flat ``.agent-src.
|
|
5
|
-
``packages/core/.agent-src.
|
|
6
|
-
``packages/pack-*/.agent-src.
|
|
4
|
+
artefacts out of the flat ``.agent-src.uncondensed/`` directory into
|
|
5
|
+
``packages/core/.agent-src.uncondensed/`` and
|
|
6
|
+
``packages/pack-*/.agent-src.uncondensed/`` trees. This helper hides
|
|
7
7
|
that decision from every scanner so they keep working pre-move and
|
|
8
8
|
post-move with the same call shape.
|
|
9
9
|
|
|
10
10
|
Contract:
|
|
11
11
|
|
|
12
12
|
- ``artefact_roots()`` returns every directory that contains source
|
|
13
|
-
``.md`` artefacts. Pre-move that is ``.agent-src.
|
|
14
|
-
the repo root. Post-move it is every ``packages/*/.agent-src.
|
|
13
|
+
``.md`` artefacts. Pre-move that is ``.agent-src.uncondensed/`` at
|
|
14
|
+
the repo root. Post-move it is every ``packages/*/.agent-src.uncondensed/``.
|
|
15
15
|
Both can coexist during the migration window.
|
|
16
16
|
- ``iter_artefacts()`` yields every source ``.md`` path under those roots.
|
|
17
17
|
- ``logical_relpath(p)`` returns the artefact's stable identity path
|
|
@@ -19,7 +19,7 @@ Contract:
|
|
|
19
19
|
root contains it. This is what manifests, hash maps, and projections
|
|
20
20
|
use as the artefact key.
|
|
21
21
|
- ``strip_source_prefix(p)`` returns the same as ``logical_relpath``
|
|
22
|
-
but accepts repo-relative POSIX strings (used by the
|
|
22
|
+
but accepts repo-relative POSIX strings (used by the condenseor's
|
|
23
23
|
output-path computation and the LEGACY_SRC_PREFIX logic).
|
|
24
24
|
"""
|
|
25
25
|
from __future__ import annotations
|
|
@@ -28,22 +28,22 @@ from pathlib import Path
|
|
|
28
28
|
from typing import Iterator
|
|
29
29
|
|
|
30
30
|
ROOT = Path(__file__).resolve().parents[2]
|
|
31
|
-
LEGACY_SRC = ROOT / ".agent-src.
|
|
31
|
+
LEGACY_SRC = ROOT / ".agent-src.uncondensed"
|
|
32
32
|
PACKAGES = ROOT / "packages"
|
|
33
33
|
|
|
34
34
|
# Repo-relative POSIX path prefixes that anchor an artefact source tree.
|
|
35
35
|
# Order: legacy first (kept until the move lands), then packages/*. Each
|
|
36
36
|
# entry is the prefix that gets stripped to obtain the logical path.
|
|
37
|
-
_LEGACY_PREFIX = ".agent-src.
|
|
38
|
-
_PACKAGE_SUFFIX = "/.agent-src.
|
|
37
|
+
_LEGACY_PREFIX = ".agent-src.uncondensed/"
|
|
38
|
+
_PACKAGE_SUFFIX = "/.agent-src.uncondensed/"
|
|
39
39
|
|
|
40
40
|
|
|
41
41
|
def artefact_roots() -> list[Path]:
|
|
42
42
|
"""Every existing directory that contains source ``.md`` artefacts.
|
|
43
43
|
|
|
44
|
-
Returns at most one ``.agent-src.
|
|
44
|
+
Returns at most one ``.agent-src.uncondensed/`` root (legacy) plus
|
|
45
45
|
one root per ``packages/*/`` subdirectory that exposes its own
|
|
46
|
-
``.agent-src.
|
|
46
|
+
``.agent-src.uncondensed/`` tree. Order is stable: legacy first,
|
|
47
47
|
then ``packages/`` entries sorted alphabetically.
|
|
48
48
|
"""
|
|
49
49
|
roots: list[Path] = []
|
|
@@ -51,7 +51,7 @@ def artefact_roots() -> list[Path]:
|
|
|
51
51
|
roots.append(LEGACY_SRC)
|
|
52
52
|
if PACKAGES.exists():
|
|
53
53
|
for pkg in sorted(PACKAGES.iterdir()):
|
|
54
|
-
sub = pkg / ".agent-src.
|
|
54
|
+
sub = pkg / ".agent-src.uncondensed"
|
|
55
55
|
if sub.is_dir():
|
|
56
56
|
roots.append(sub)
|
|
57
57
|
return roots
|
|
@@ -111,11 +111,11 @@ def logical_relpath(path: Path) -> str:
|
|
|
111
111
|
"""Return the artefact's logical identity path (POSIX, no prefix).
|
|
112
112
|
|
|
113
113
|
Examples:
|
|
114
|
-
``.agent-src.
|
|
114
|
+
``.agent-src.uncondensed/skills/laravel/SKILL.md``
|
|
115
115
|
→ ``skills/laravel/SKILL.md``
|
|
116
|
-
``packages/pack-laravel/.agent-src.
|
|
116
|
+
``packages/pack-laravel/.agent-src.uncondensed/skills/laravel/SKILL.md``
|
|
117
117
|
→ ``skills/laravel/SKILL.md``
|
|
118
|
-
``packages/core/.agent-src.
|
|
118
|
+
``packages/core/.agent-src.uncondensed/rules/scope-control.md``
|
|
119
119
|
→ ``rules/scope-control.md``
|
|
120
120
|
|
|
121
121
|
Raises ``ValueError`` if ``path`` is not under any known source root.
|
|
@@ -130,15 +130,15 @@ def logical_relpath(path: Path) -> str:
|
|
|
130
130
|
|
|
131
131
|
|
|
132
132
|
def strip_source_prefix(rel: str) -> str | None:
|
|
133
|
-
"""Strip the ``.agent-src.
|
|
133
|
+
"""Strip the ``.agent-src.uncondensed/`` anchor from a repo-relative path.
|
|
134
134
|
|
|
135
135
|
Accepts both the legacy flat layout and the monorepo packages layout.
|
|
136
136
|
Returns ``None`` if the path is not under any source root.
|
|
137
137
|
|
|
138
138
|
Examples:
|
|
139
|
-
``".agent-src.
|
|
140
|
-
``"packages/core/.agent-src.
|
|
141
|
-
``"packages/pack-laravel/.agent-src.
|
|
139
|
+
``".agent-src.uncondensed/rules/foo.md"`` → ``"rules/foo.md"``
|
|
140
|
+
``"packages/core/.agent-src.uncondensed/rules/foo.md"`` → ``"rules/foo.md"``
|
|
141
|
+
``"packages/pack-laravel/.agent-src.uncondensed/skills/x/SKILL.md"``
|
|
142
142
|
→ ``"skills/x/SKILL.md"``
|
|
143
143
|
``"docs/architecture.md"`` → ``None``
|
|
144
144
|
"""
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
"""Baseline-cache helpers for the package-impact A/B bench.
|
|
2
|
+
|
|
3
|
+
Phase 2 Step 2 of `agents/roadmaps/road-to-package-impact-benchmark.md`.
|
|
4
|
+
|
|
5
|
+
A daily `task bench:ab` run wants to skip re-running the `without` arm when
|
|
6
|
+
nothing the model would see has changed. We define "changed" by a three-part
|
|
7
|
+
key:
|
|
8
|
+
|
|
9
|
+
(corpus_hash, claude_cli_version, target_shape_hash)
|
|
10
|
+
|
|
11
|
+
Cached `without` reports live under `internal/bench/reports/ab/`. Each report
|
|
12
|
+
header records the cache key inputs; this module reads the directory, picks
|
|
13
|
+
the latest matching report, and reports freshness.
|
|
14
|
+
"""
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import hashlib
|
|
18
|
+
import json
|
|
19
|
+
import os
|
|
20
|
+
import shutil
|
|
21
|
+
import subprocess
|
|
22
|
+
from dataclasses import dataclass
|
|
23
|
+
from pathlib import Path
|
|
24
|
+
|
|
25
|
+
REPO_ROOT = Path(__file__).resolve().parents[2]
|
|
26
|
+
REPORTS_DIR = REPO_ROOT / "internal" / "bench" / "reports" / "ab"
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@dataclass(frozen=True)
|
|
30
|
+
class CacheKey:
|
|
31
|
+
corpus_hash: str
|
|
32
|
+
claude_cli_version: str
|
|
33
|
+
target_shape_hash: str
|
|
34
|
+
|
|
35
|
+
def to_dict(self) -> dict[str, str]:
|
|
36
|
+
return {
|
|
37
|
+
"corpus_hash": self.corpus_hash,
|
|
38
|
+
"claude_cli_version": self.claude_cli_version,
|
|
39
|
+
"target_shape_hash": self.target_shape_hash,
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
@classmethod
|
|
43
|
+
def from_dict(cls, data: dict[str, str]) -> "CacheKey":
|
|
44
|
+
return cls(
|
|
45
|
+
corpus_hash=data.get("corpus_hash", ""),
|
|
46
|
+
claude_cli_version=data.get("claude_cli_version", ""),
|
|
47
|
+
target_shape_hash=data.get("target_shape_hash", ""),
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
@dataclass(frozen=True)
|
|
52
|
+
class CacheLookup:
|
|
53
|
+
found: bool
|
|
54
|
+
fresh: bool
|
|
55
|
+
report_path: Path | None
|
|
56
|
+
cached_key: CacheKey | None
|
|
57
|
+
reason: str # human-readable: "missing", "fresh", "stale: corpus", etc.
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def hash_file(path: Path) -> str:
|
|
61
|
+
"""SHA-256 of a single file (used for corpus_hash)."""
|
|
62
|
+
h = hashlib.sha256()
|
|
63
|
+
with path.open("rb") as fh:
|
|
64
|
+
for chunk in iter(lambda: fh.read(65536), b""):
|
|
65
|
+
h.update(chunk)
|
|
66
|
+
return h.hexdigest()[:16]
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def claude_cli_version() -> str:
|
|
70
|
+
"""Best-effort: `claude --version` or fallback to the env CLAUDE_CLI_VERSION.
|
|
71
|
+
|
|
72
|
+
When the CLI is missing, return "unavailable:<reason>" so the cache key
|
|
73
|
+
still varies meaningfully when the CLI is later installed.
|
|
74
|
+
"""
|
|
75
|
+
override = os.environ.get("CLAUDE_CLI_VERSION")
|
|
76
|
+
if override:
|
|
77
|
+
return override.strip()
|
|
78
|
+
if shutil.which("claude") is None:
|
|
79
|
+
return "unavailable:not-on-path"
|
|
80
|
+
try:
|
|
81
|
+
out = subprocess.run(
|
|
82
|
+
["claude", "--version"],
|
|
83
|
+
capture_output=True,
|
|
84
|
+
text=True,
|
|
85
|
+
timeout=10,
|
|
86
|
+
check=False,
|
|
87
|
+
)
|
|
88
|
+
except (OSError, subprocess.TimeoutExpired) as err:
|
|
89
|
+
return f"unavailable:{type(err).__name__}"
|
|
90
|
+
if out.returncode != 0:
|
|
91
|
+
return f"unavailable:exit-{out.returncode}"
|
|
92
|
+
return (out.stdout or out.stderr).strip().splitlines()[0] if out.stdout or out.stderr else "unknown"
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def target_shape_hash() -> str:
|
|
96
|
+
"""Re-export the shape hash from the clone script for a single source of truth."""
|
|
97
|
+
import importlib.util
|
|
98
|
+
|
|
99
|
+
spec = importlib.util.spec_from_file_location(
|
|
100
|
+
"bench_ab_clone", REPO_ROOT / "scripts" / "bench_ab_clone.py"
|
|
101
|
+
)
|
|
102
|
+
if spec is None or spec.loader is None:
|
|
103
|
+
return "unknown"
|
|
104
|
+
module = importlib.util.module_from_spec(spec)
|
|
105
|
+
spec.loader.exec_module(module)
|
|
106
|
+
return module.target_shape_hash() # type: ignore[no-any-return]
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def build_key(corpus_path: Path) -> CacheKey:
|
|
110
|
+
return CacheKey(
|
|
111
|
+
corpus_hash=hash_file(corpus_path),
|
|
112
|
+
claude_cli_version=claude_cli_version(),
|
|
113
|
+
target_shape_hash=target_shape_hash(),
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def iter_cached_reports(variant: str = "without") -> list[Path]:
|
|
118
|
+
"""Return all report JSON paths under reports/ab/ for the given variant.
|
|
119
|
+
|
|
120
|
+
Filenames follow `{stamp}-{corpus}-{variant}.json` (Phase 2 Step 3).
|
|
121
|
+
"""
|
|
122
|
+
if not REPORTS_DIR.exists():
|
|
123
|
+
return []
|
|
124
|
+
matches = sorted(REPORTS_DIR.glob(f"*-{variant}.json"))
|
|
125
|
+
return list(matches)
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def read_report_key(report_path: Path) -> CacheKey | None:
|
|
129
|
+
try:
|
|
130
|
+
data = json.loads(report_path.read_text())
|
|
131
|
+
except (OSError, json.JSONDecodeError):
|
|
132
|
+
return None
|
|
133
|
+
raw = data.get("cache_key")
|
|
134
|
+
if not isinstance(raw, dict):
|
|
135
|
+
return None
|
|
136
|
+
return CacheKey.from_dict({k: str(v) for k, v in raw.items()})
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def lookup(corpus_path: Path) -> CacheLookup:
|
|
140
|
+
"""Find the latest cached `without` report and report freshness vs. the current key."""
|
|
141
|
+
if not corpus_path.exists():
|
|
142
|
+
return CacheLookup(False, False, None, None, f"missing corpus: {corpus_path}")
|
|
143
|
+
current = build_key(corpus_path)
|
|
144
|
+
candidates = iter_cached_reports("without")
|
|
145
|
+
if not candidates:
|
|
146
|
+
return CacheLookup(False, False, None, None, "no cached `without` report")
|
|
147
|
+
# Reports sorted by filename — last is latest given UTC stamps
|
|
148
|
+
latest = candidates[-1]
|
|
149
|
+
cached_key = read_report_key(latest)
|
|
150
|
+
if cached_key is None:
|
|
151
|
+
return CacheLookup(True, False, latest, None, "cached report missing cache_key")
|
|
152
|
+
if cached_key == current:
|
|
153
|
+
return CacheLookup(True, True, latest, cached_key, "fresh")
|
|
154
|
+
# Diagnose which input drifted
|
|
155
|
+
drift_parts = []
|
|
156
|
+
if cached_key.corpus_hash != current.corpus_hash:
|
|
157
|
+
drift_parts.append("corpus")
|
|
158
|
+
if cached_key.claude_cli_version != current.claude_cli_version:
|
|
159
|
+
drift_parts.append("claude_cli_version")
|
|
160
|
+
if cached_key.target_shape_hash != current.target_shape_hash:
|
|
161
|
+
drift_parts.append("target_shape")
|
|
162
|
+
return CacheLookup(True, False, latest, cached_key, "stale: " + ",".join(drift_parts))
|