@event4u/agent-config 6.0.0 → 6.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 +5 -5
- package/CHANGELOG.md +167 -440
- package/README.md +3 -3
- package/dist/agent-src/commands/agent-handoff.md +5 -4
- package/dist/agent-src/commands/agent-status.md +1 -0
- package/dist/agent-src/commands/agents/audit.md +1 -0
- package/dist/agent-src/commands/agents/init.md +3 -0
- package/dist/agent-src/commands/agents/optimize.md +1 -0
- package/dist/agent-src/commands/agents/user/accept.md +1 -0
- package/dist/agent-src/commands/agents/user/init.md +1 -0
- package/dist/agent-src/commands/agents/user/review.md +1 -0
- package/dist/agent-src/commands/agents/user/show.md +1 -0
- package/dist/agent-src/commands/agents/user/update.md +1 -0
- package/dist/agent-src/commands/agents/user.md +1 -0
- package/dist/agent-src/commands/agents.md +1 -0
- package/dist/agent-src/commands/analytics/prune.md +3 -2
- package/dist/agent-src/commands/analytics/show.md +3 -2
- package/dist/agent-src/commands/analytics.md +3 -2
- package/dist/agent-src/commands/analyze-reference-repo.md +1 -0
- package/dist/agent-src/commands/bug-fix.md +1 -0
- package/dist/agent-src/commands/bug-investigate.md +1 -0
- package/dist/agent-src/commands/challenge-me/vision.md +3 -2
- package/dist/agent-src/commands/challenge-me/with-docs.md +3 -2
- package/dist/agent-src/commands/challenge-me.md +3 -2
- package/dist/agent-src/commands/chat-history/import.md +9 -9
- package/dist/agent-src/commands/chat-history.md +32 -30
- package/dist/agent-src/commands/check-current-md.md +1 -0
- package/dist/agent-src/commands/commit/in-chunks.md +1 -0
- package/dist/agent-src/commands/commit.md +1 -0
- package/dist/agent-src/commands/condense.md +1 -0
- package/dist/agent-src/commands/context/create.md +1 -0
- package/dist/agent-src/commands/context/refactor.md +1 -0
- package/dist/agent-src/commands/context.md +1 -0
- package/dist/agent-src/commands/cost-report.md +5 -4
- package/dist/agent-src/commands/council/analysis.md +3 -2
- package/dist/agent-src/commands/council/debate.md +5 -4
- package/dist/agent-src/commands/council/default.md +3 -2
- package/dist/agent-src/commands/council/design.md +3 -2
- package/dist/agent-src/commands/council/optimize.md +3 -2
- package/dist/agent-src/commands/council/pr.md +3 -2
- package/dist/agent-src/commands/council.md +4 -3
- package/dist/agent-src/commands/e2e-heal.md +1 -0
- package/dist/agent-src/commands/e2e-plan.md +1 -0
- package/dist/agent-src/commands/estimate-ticket.md +1 -0
- package/dist/agent-src/commands/feature/dev.md +1 -0
- package/dist/agent-src/commands/feature/explore.md +1 -0
- package/dist/agent-src/commands/feature/plan.md +6 -6
- package/dist/agent-src/commands/feature/refactor.md +1 -0
- package/dist/agent-src/commands/feature/roadmap.md +1 -0
- package/dist/agent-src/commands/feature.md +1 -0
- package/dist/agent-src/commands/fix/ci.md +1 -0
- package/dist/agent-src/commands/fix/portability.md +1 -0
- package/dist/agent-src/commands/fix/pr-comments.md +147 -15
- package/dist/agent-src/commands/fix/refs.md +1 -0
- package/dist/agent-src/commands/fix/seeder.md +1 -0
- package/dist/agent-src/commands/fix.md +8 -8
- package/dist/agent-src/commands/ghostwriter/delete.md +1 -0
- package/dist/agent-src/commands/ghostwriter/fetch.md +1 -0
- package/dist/agent-src/commands/ghostwriter/list.md +1 -0
- package/dist/agent-src/commands/ghostwriter/show.md +1 -0
- package/dist/agent-src/commands/ghostwriter/write.md +1 -0
- package/dist/agent-src/commands/ghostwriter.md +1 -0
- package/dist/agent-src/commands/grill-me.md +3 -2
- package/dist/agent-src/commands/image/analyse.md +1 -0
- package/dist/agent-src/commands/image/create.md +1 -0
- package/dist/agent-src/commands/image/verify.md +1 -0
- package/dist/agent-src/commands/image.md +1 -0
- package/dist/agent-src/commands/implement-ticket.md +1 -0
- package/dist/agent-src/commands/jira-ticket.md +1 -0
- package/dist/agent-src/commands/judge/on-diff.md +1 -0
- package/dist/agent-src/commands/judge/solo.md +1 -0
- package/dist/agent-src/commands/judge/steps.md +1 -0
- package/dist/agent-src/commands/judge.md +1 -0
- package/dist/agent-src/commands/knowledge/cross-repo.md +1 -0
- package/dist/agent-src/commands/knowledge/forget.md +1 -0
- package/dist/agent-src/commands/knowledge/ingest.md +1 -0
- package/dist/agent-src/commands/knowledge/list.md +1 -0
- package/dist/agent-src/commands/knowledge.md +1 -0
- package/dist/agent-src/commands/memory/add.md +8 -6
- package/dist/agent-src/commands/memory/learn-low-impact.md +3 -2
- package/dist/agent-src/commands/memory/load.md +7 -7
- package/dist/agent-src/commands/memory/mine-session.md +39 -12
- package/dist/agent-src/commands/memory/promote.md +3 -2
- package/dist/agent-src/commands/memory/propose.md +7 -6
- package/dist/agent-src/commands/memory.md +3 -2
- package/dist/agent-src/commands/mode.md +1 -0
- package/dist/agent-src/commands/module/create.md +1 -0
- package/dist/agent-src/commands/module/explore.md +1 -0
- package/dist/agent-src/commands/module.md +1 -0
- package/dist/agent-src/commands/optimize/agents-dir.md +1 -0
- package/dist/agent-src/commands/optimize/augmentignore.md +1 -0
- package/dist/agent-src/commands/optimize/rtk.md +1 -0
- package/dist/agent-src/commands/optimize/skills.md +1 -0
- package/dist/agent-src/commands/optimize-prompt.md +1 -0
- package/dist/agent-src/commands/optimize.md +1 -0
- package/dist/agent-src/commands/orchestrate.md +1 -0
- package/dist/agent-src/commands/override/create.md +1 -0
- package/dist/agent-src/commands/override/manage.md +1 -0
- package/dist/agent-src/commands/override.md +1 -0
- package/dist/agent-src/commands/package-reset.md +1 -0
- package/dist/agent-src/commands/package-test.md +1 -0
- package/dist/agent-src/commands/post-as/ghostwriter.md +1 -0
- package/dist/agent-src/commands/post-as/me.md +1 -0
- package/dist/agent-src/commands/post-as.md +1 -0
- package/dist/agent-src/commands/pr/create/description-only.md +1 -0
- package/dist/agent-src/commands/pr/create.md +25 -0
- package/dist/agent-src/commands/prediction-pool.md +1 -0
- package/dist/agent-src/commands/prepare-for-review.md +1 -0
- package/dist/agent-src/commands/profile/activate.md +1 -0
- package/dist/agent-src/commands/profile/deactivate.md +1 -0
- package/dist/agent-src/commands/profile/show.md +1 -0
- package/dist/agent-src/commands/profile.md +1 -0
- package/dist/agent-src/commands/project-analyze.md +1 -0
- package/dist/agent-src/commands/project-health.md +1 -0
- package/dist/agent-src/commands/quality-fix.md +1 -0
- package/dist/agent-src/commands/refine-ticket.md +1 -0
- package/dist/agent-src/commands/research/deep.md +1 -0
- package/dist/agent-src/commands/research/report.md +1 -0
- package/dist/agent-src/commands/research.md +1 -0
- package/dist/agent-src/commands/review-changes.md +1 -0
- package/dist/agent-src/commands/review-routing.md +1 -0
- package/dist/agent-src/commands/roadmap/ai-council.md +1 -0
- package/dist/agent-src/commands/roadmap/create.md +1 -0
- package/dist/agent-src/commands/roadmap/process-full.md +1 -0
- package/dist/agent-src/commands/roadmap/process-phase.md +1 -0
- package/dist/agent-src/commands/roadmap/process-step.md +1 -0
- package/dist/agent-src/commands/roadmap.md +1 -0
- package/dist/agent-src/commands/rule-compliance-audit.md +1 -0
- package/dist/agent-src/commands/security-audit-config.md +84 -0
- package/dist/agent-src/commands/set-cost-profile.md +1 -0
- package/dist/agent-src/commands/skill/preview.md +1 -0
- package/dist/agent-src/commands/skill.md +1 -0
- package/dist/agent-src/commands/skills/discover.md +1 -0
- package/dist/agent-src/commands/skills.md +1 -0
- package/dist/agent-src/commands/sync-agent-settings.md +1 -0
- package/dist/agent-src/commands/sync-gitignore/fix.md +1 -0
- package/dist/agent-src/commands/sync-gitignore.md +1 -0
- package/dist/agent-src/commands/tests/create.md +1 -0
- package/dist/agent-src/commands/tests/execute.md +1 -0
- package/dist/agent-src/commands/tests.md +1 -0
- package/dist/agent-src/commands/threat-model.md +1 -0
- package/dist/agent-src/commands/update-form-request-messages.md +1 -0
- package/dist/agent-src/commands/upstream-contribute.md +1 -0
- package/dist/agent-src/commands/video/from-script.md +1 -0
- package/dist/agent-src/commands/video/from-song.md +1 -0
- package/dist/agent-src/commands/video/scene.md +1 -0
- package/dist/agent-src/commands/video/stitch.md +1 -0
- package/dist/agent-src/commands/video/storyboard.md +1 -0
- package/dist/agent-src/commands/video.md +1 -0
- package/dist/agent-src/commands/work.md +1 -0
- package/dist/agent-src/contexts/augment-infrastructure.md +1 -1
- package/dist/agent-src/contexts/communication/rules-auto/skill-quality-mechanics.md +1 -1
- package/dist/agent-src/contexts/communication/rules-auto/slash-command-routing-policy-mechanics.md +2 -2
- package/dist/agent-src/contexts/communication/rules-auto/think-before-action-mechanics.md +6 -6
- package/dist/agent-src/contexts/contracts/consumer-agents-md-guide.md +2 -2
- package/dist/agent-src/contexts/execution/rdp-gate.md +75 -0
- package/dist/agent-src/contexts/subagent-configuration.md +1 -0
- package/dist/agent-src/personas/advisors/contrarian.md +1 -1
- package/dist/agent-src/personas/advisors/executor.md +1 -1
- package/dist/agent-src/personas/advisors/expansionist.md +1 -1
- package/dist/agent-src/personas/advisors/first-principles.md +1 -1
- package/dist/agent-src/personas/advisors/outsider.md +1 -1
- package/dist/agent-src/rules/autonomous-execution.md +12 -0
- package/dist/agent-src/rules/external-reference-deep-dive.md +1 -1
- package/dist/agent-src/rules/git-history-discipline.md +47 -1
- package/dist/agent-src/rules/improve-before-implement.md +12 -0
- package/dist/agent-src/rules/lethal-trifecta-guard.md +80 -0
- package/dist/agent-src/rules/no-pr-progress-comments.md +3 -4
- package/dist/agent-src/rules/notes-first-reasoning.md +71 -0
- package/dist/agent-src/rules/roadmap-progress-sync.md +48 -31
- package/dist/agent-src/rules/security-sensitive-stop.md +14 -1
- package/dist/agent-src/rules/source-confidentiality.md +97 -0
- package/dist/agent-src/rules/think-before-action.md +9 -1
- package/dist/agent-src/rules/untrusted-input-defense.md +76 -0
- package/dist/agent-src/scripts/archive_completed_roadmaps.py +171 -0
- package/dist/agent-src/skills/adversarial-review/SKILL.md +14 -0
- package/dist/agent-src/skills/agent-security-review/SKILL.md +113 -0
- package/dist/agent-src/skills/agent-security-review/evals/triggers.json +51 -0
- package/dist/agent-src/skills/ai-council/SKILL.md +3 -3
- package/dist/agent-src/skills/async-python-patterns/SKILL.md +1 -1
- package/dist/agent-src/skills/blast-radius-analyzer/SKILL.md +12 -11
- package/dist/agent-src/skills/command-routing/SKILL.md +1 -1
- package/dist/agent-src/skills/complexity-first-planning/SKILL.md +96 -0
- package/dist/agent-src/skills/complexity-first-planning/evals/triggers.json +16 -0
- package/dist/agent-src/skills/copilot-config/SKILL.md +3 -4
- package/dist/agent-src/skills/defense-in-depth/SKILL.md +1 -1
- package/dist/agent-src/skills/developer-like-execution/SKILL.md +5 -4
- package/dist/agent-src/skills/error-handling-patterns/SKILL.md +1 -1
- package/dist/agent-src/skills/feature-planning/SKILL.md +2 -2
- package/dist/agent-src/skills/mcp-builder/SKILL.md +1 -1
- package/dist/agent-src/skills/memory-consolidation/SKILL.md +63 -17
- package/dist/agent-src/skills/prompt-engineering-patterns/SKILL.md +1 -1
- package/dist/agent-src/skills/readme-writing-package/SKILL.md +1 -1
- package/dist/agent-src/skills/reasoning-orchestrator/SKILL.md +119 -0
- package/dist/agent-src/skills/reasoning-orchestrator/evals/triggers.json +16 -0
- package/dist/agent-src/skills/receiving-code-review/SKILL.md +6 -6
- package/dist/agent-src/skills/refine-prompt/SKILL.md +1 -1
- package/dist/agent-src/skills/refine-ticket/SKILL.md +1 -1
- package/dist/agent-src/skills/repomix-packer/SKILL.md +1 -1
- package/dist/agent-src/skills/secrets-management/SKILL.md +1 -1
- package/dist/agent-src/skills/subagent-orchestration/SKILL.md +10 -3
- package/dist/agent-src/skills/testing-anti-patterns/SKILL.md +1 -1
- package/dist/agent-src/skills/testing-anti-patterns/process-anti-patterns.md +1 -1
- package/dist/agent-src/skills/token-optimizer/SKILL.md +1 -1
- package/dist/agent-src/templates/agents/.gitattributes.fragment +0 -1
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +4 -4
- package/dist/agent-src/templates/scripts/check_memory.py +1 -2
- package/dist/agent-src/templates/scripts/check_memory_proposal.py +1 -1
- package/dist/agent-src/templates/scripts/memory_lookup.py +148 -289
- package/dist/agent-src/templates/scripts/memory_report.py +132 -2
- package/dist/agent-src/templates/scripts/memory_signal.py +7 -9
- package/dist/agent-src/templates/scripts/memory_status.py +25 -206
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/memory.py +6 -6
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/_passthrough.py +3 -3
- package/dist/agent-src/templates/scripts/work_engine/scoring/memory_visibility.py +0 -1
- package/dist/cli/agent-config.js +31 -300
- package/dist/cli/agent-config.js.map +1 -1
- package/dist/cli/commands/commands.js +10 -5
- package/dist/cli/commands/commands.js.map +1 -1
- package/dist/cli/discovery/loadManifest.js.map +1 -1
- package/dist/cli/main.js +309 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +645 -342
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +8 -5
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +149 -37
- package/dist/discovery/trust-report.md +3 -3
- package/dist/discovery/workspaces.json +61 -36
- package/dist/mcp/registry-manifest.json +4 -4
- package/dist/router.json +1 -1
- package/dist/server/routes/wizard.js +4 -3
- package/dist/server/routes/wizard.js.map +1 -1
- package/dist/server/schemas/settings.js +18 -0
- package/dist/server/schemas/settings.js.map +1 -1
- package/docs/MIGRATION.md +1 -1
- package/docs/adrs/cost/0001-hard-stop-hook.md +5 -5
- package/docs/adrs/memory/0001-consumer-side-snapshot.md +15 -7
- package/docs/adrs/memory/README.md +6 -5
- package/docs/adrs/router/0001-three-tier-routing.md +2 -2
- package/docs/adrs/schema/0001-json-schema-frontmatter.md +2 -2
- package/docs/adrs/smoke/0001-per-tier-smoke-scripts.md +5 -5
- package/docs/adrs/telegraph/0001-default-off-until-bench.md +3 -3
- package/docs/architecture.md +9 -9
- package/docs/archive/CHANGELOG-pre-2.2.0.md +30 -30
- package/docs/archive/CHANGELOG-pre-2.25.0.md +1 -1
- package/docs/archive/CHANGELOG-pre-4.5.0.md +1 -1
- package/docs/archive/CHANGELOG-pre-6.0.0.md +473 -0
- package/docs/benchmark.md +54 -53
- package/docs/benchmarks.md +2 -2
- package/docs/case-studies/{frontend-design-vs-ui-ux-pro-max.md → frontend-design-positioning.md} +4 -4
- package/docs/catalog.md +20 -13
- package/docs/command-flows.md +90 -92
- package/docs/contracts/adr-layout.md +2 -3
- package/docs/contracts/adr-level-6-productization.md +1 -1
- package/docs/contracts/ai-council-config.md +42 -7
- package/docs/contracts/command-clusters.md +1 -1
- package/docs/contracts/cost-enforcement.md +1 -1
- package/docs/contracts/cost-summary-schema.md +1 -1
- package/docs/contracts/daily-workspace.md +1 -0
- package/docs/contracts/discovery-manifest.schema.json +4 -2
- package/docs/contracts/explain-modes.md +1 -1
- package/docs/contracts/implement-ticket-flow.md +6 -7
- package/docs/contracts/mcp-tool-inventory.md +10 -10
- package/docs/contracts/measurement-baseline.md +1 -1
- package/docs/contracts/memory-visibility-v1.md +1 -5
- package/docs/contracts/namespace.md +1 -1
- package/docs/contracts/persona-schema.md +1 -1
- package/docs/contracts/rule-interactions.md +1 -1
- package/docs/contracts/smoke-contracts.md +1 -1
- package/docs/contracts/universal-skills.md +0 -1
- package/docs/contracts/workspace-boundary.md +84 -0
- package/docs/customization.md +3 -3
- package/docs/decisions/ADR-009-event4u-namespace.md +1 -1
- package/docs/decisions/ADR-013-discovery-frontmatter-contract.md +1 -1
- package/docs/decisions/ADR-026-explain-mode-translation.md +1 -1
- package/docs/decisions/ADR-088-no-external-runtime-federation.md +26 -27
- package/docs/decisions/ADR-090-visibility-command-frontmatter-field.md +95 -0
- package/docs/decisions/ADR-091-split-meta-capability-packs.md +113 -0
- package/docs/decisions/ADR-092-defer-command-tier-alias-removal.md +93 -0
- package/docs/decisions/ADR-093-ai-council-config-user-global.md +111 -0
- package/docs/decisions/ADR-094-agent-memory-layer-removal.md +94 -0
- package/docs/decisions/ADR-095-workspace-boundary-contract.md +108 -0
- package/docs/decisions/INDEX.md +6 -0
- package/docs/development.md +5 -7
- package/docs/getting-started.md +4 -4
- package/docs/guidelines/agent-infra/5w2h-analysis.md +1 -1
- package/docs/guidelines/agent-infra/comparison-matrix.md +1 -1
- package/docs/guidelines/agent-infra/corpus-grounding-authoring.md +1 -1
- package/docs/guidelines/agent-infra/critical-thinking.md +1 -1
- package/docs/guidelines/agent-infra/engineering-memory-data-format.md +1 -5
- package/docs/guidelines/agent-infra/first-principles.md +1 -1
- package/docs/guidelines/agent-infra/frontier-reasoning-operating-profile.md +164 -0
- package/docs/guidelines/agent-infra/inversion-thinking.md +1 -1
- package/docs/guidelines/agent-infra/ios-simulator-guide.md +9 -14
- package/docs/guidelines/agent-infra/mcp-request-signing.md +19 -22
- package/docs/guidelines/agent-infra/memory-access.md +25 -31
- package/docs/guidelines/agent-infra/mental-models.md +1 -1
- package/docs/guidelines/agent-infra/model-recommendation.md +29 -0
- package/docs/guidelines/agent-infra/scqa-framework.md +3 -3
- package/docs/guidelines/agent-infra/security-lint-containment.md +81 -0
- package/docs/guidelines/agent-infra/six-hats.md +1 -1
- package/docs/guidelines/agent-infra/systems-thinking.md +1 -1
- package/docs/guidelines/agent-infra/untrusted-input-spotlighting.md +72 -0
- package/docs/installation.md +1 -1
- package/docs/mcp.md +2 -2
- package/docs/parity/{bench-ruflo.json → bench-external.json} +10 -10
- package/docs/parity/{ruflo.md → external-runtime.md} +9 -9
- package/docs/quality.md +3 -3
- package/docs/safety.md +3 -3
- package/docs/skills-catalog.md +4 -1
- package/llms.txt +3 -0
- package/package.json +1 -1
- package/src/config/agent-settings.template.yml +65 -3
- package/src/config/discovery/packs.yml +29 -0
- package/src/config/discovery/workspaces.yml +3 -1
- package/src/config/gitignore-block.txt +6 -0
- package/src/scripts/__pycache__/validate_frontmatter.cpython-312.pyc +0 -0
- package/src/scripts/_cli/cmd_doctor.py +99 -13
- package/src/scripts/_lib/__pycache__/__init__.cpython-312.pyc +0 -0
- package/src/scripts/_lib/__pycache__/agent_src.cpython-312.pyc +0 -0
- package/src/scripts/_lib/bench_ab_scoring_v2.py +227 -0
- package/src/scripts/_lib/global_deploy_inventory.py +39 -9
- package/src/scripts/_lib/link_crypto.py +206 -0
- package/src/scripts/_lib/security_lint.py +228 -0
- package/src/scripts/ai_council/clients.py +2 -2
- package/src/scripts/ai_council/config.py +55 -0
- package/src/scripts/audit_adr_coverage.py +0 -2
- package/src/scripts/audit_command_surface.py +18 -5
- package/src/scripts/audit_mcp_tools.py +2 -2
- package/src/scripts/audit_skill_descriptions.py +2 -2
- package/src/scripts/bench_ab_clone.py +62 -12
- package/src/scripts/bench_ab_task_runner.py +475 -30
- package/src/scripts/bench_ab_v2_run.py +247 -0
- package/src/scripts/bench_ab_v2_stats.py +347 -0
- package/src/scripts/bench_run.py +1 -1
- package/src/scripts/build_discovery_manifest.py +10 -0
- package/src/scripts/check_bite_sized_granularity.py +1 -2
- package/src/scripts/check_memory.py +49 -63
- package/src/scripts/check_memory_proposal.py +1 -1
- package/src/scripts/check_no_external_sources.py +101 -0
- package/src/scripts/check_references.py +2 -0
- package/src/scripts/cost_by_conversation.py +1 -1
- package/src/scripts/council_cli.py +28 -14
- package/src/scripts/external_sources_denylist.json +91 -0
- package/src/scripts/hook_manifest.yaml +14 -6
- package/src/scripts/injection_scan_hook.py +145 -0
- package/src/scripts/install-hooks.sh +11 -0
- package/src/scripts/install.py +88 -13
- package/src/scripts/lint_agent_security.py +112 -0
- package/src/scripts/lint_bench_ab.py +5 -4
- package/src/scripts/lint_command_tiers.py +63 -22
- package/src/scripts/lint_discovery_vocabulary.py +2 -0
- package/src/scripts/lint_empty_roadmaps.py +80 -0
- package/src/scripts/lint_hidden_unicode.py +132 -0
- package/src/scripts/lint_instruction_smuggling.py +107 -0
- package/src/scripts/lint_marketplace.py +1 -1
- package/src/scripts/lint_mcp_config_security.py +124 -0
- package/src/scripts/lint_skill_frontmatter_safety.py +144 -0
- package/src/scripts/lint_workspace_boundary.py +122 -0
- package/src/scripts/mcp_server/consumer_tool_catalog.json +2 -3
- package/src/scripts/mcp_server/tools.py +8 -32
- package/src/scripts/memory_lookup.py +27 -296
- package/src/scripts/memory_report.py +1 -23
- package/src/scripts/memory_signal.py +6 -53
- package/src/scripts/memory_status.py +25 -206
- package/src/scripts/mine_session.py +118 -41
- package/src/scripts/pack_dependency_allowlist.json +2 -2
- package/src/scripts/render_benchmark_md.py +141 -52
- package/src/scripts/schemas/command.schema.json +6 -1
- package/src/scripts/security_audit_config.py +153 -0
- package/dist/agent-src/commands/chat-history/learn.md +0 -184
- package/dist/agent-src/commands/chat-history/show.md +0 -113
- package/dist/agent-src/commands/fix/pr-bot-comments.md +0 -157
- package/dist/agent-src/commands/fix/pr-developer-comments.md +0 -163
- package/dist/agent-src/templates/agents/memory/architecture-decisions.example.yml +0 -95
- package/docs/contracts/agent-memory-contract.md +0 -159
|
@@ -34,7 +34,26 @@ MEMORY_ROOT = Path("agents/memory")
|
|
|
34
34
|
INTAKE_ROOT = MEMORY_ROOT / "intake"
|
|
35
35
|
CURATED_TYPES = (
|
|
36
36
|
"ownership", "historical-patterns", "domain-invariants",
|
|
37
|
-
"
|
|
37
|
+
"incident-learnings", "product-rules",
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
# Role-mode marker grepped from session captures / reports / handoffs.
|
|
41
|
+
# Matches `<!-- role-mode: <slug> | contract: ... -->` on any single line.
|
|
42
|
+
# See guidelines/agent-infra/role-contracts.md "Structured mode markers".
|
|
43
|
+
import re # noqa: E402
|
|
44
|
+
|
|
45
|
+
_MODE_MARKER_PATTERN = re.compile(
|
|
46
|
+
r"<!--\s*role-mode:\s*([a-z0-9][a-z0-9-]*)\s*\|"
|
|
47
|
+
r"\s*contract:[^>]*-->"
|
|
48
|
+
)
|
|
49
|
+
_MODE_SCAN_DIRS = (
|
|
50
|
+
Path("agents/sessions"),
|
|
51
|
+
Path("agents/runtime/reports"),
|
|
52
|
+
Path("agents/handoffs"),
|
|
53
|
+
Path("agents/learnings"),
|
|
54
|
+
)
|
|
55
|
+
_KNOWN_MODES = (
|
|
56
|
+
"developer", "reviewer", "tester", "po", "incident", "planner",
|
|
38
57
|
)
|
|
39
58
|
|
|
40
59
|
|
|
@@ -132,6 +151,93 @@ def _staleness_report() -> list[dict]:
|
|
|
132
151
|
return stale
|
|
133
152
|
|
|
134
153
|
|
|
154
|
+
def _quarter_of(d: dt.date | str) -> str:
|
|
155
|
+
if isinstance(d, str):
|
|
156
|
+
try:
|
|
157
|
+
d = dt.date.fromisoformat(d[:10])
|
|
158
|
+
except ValueError:
|
|
159
|
+
return "unknown"
|
|
160
|
+
if not isinstance(d, dt.date):
|
|
161
|
+
return "unknown"
|
|
162
|
+
return f"{d.year}Q{(d.month - 1) // 3 + 1}"
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def _quarterly_stats() -> dict:
|
|
166
|
+
"""Per-quarter breakdown: accepted curated entries, retired (supersede)
|
|
167
|
+
entries, and the curated-file staleness rate.
|
|
168
|
+
|
|
169
|
+
Feeds the Q2 outcome measurement for `road-to-agent-outcomes.md` /
|
|
170
|
+
`road-to-project-memory.md` Phase 5.
|
|
171
|
+
"""
|
|
172
|
+
accepted: Counter = Counter()
|
|
173
|
+
for _, _, entry in _iter_curated_entries():
|
|
174
|
+
created = entry.get("created") or entry.get("last_validated")
|
|
175
|
+
if created is not None:
|
|
176
|
+
accepted[_quarter_of(created)] += 1
|
|
177
|
+
retired: Counter = Counter()
|
|
178
|
+
if INTAKE_ROOT.is_dir():
|
|
179
|
+
for jsonl in sorted(INTAKE_ROOT.glob("*.jsonl")):
|
|
180
|
+
with jsonl.open(encoding="utf-8") as fh:
|
|
181
|
+
for line in fh:
|
|
182
|
+
line = line.strip()
|
|
183
|
+
if not line:
|
|
184
|
+
continue
|
|
185
|
+
try:
|
|
186
|
+
obj = json.loads(line)
|
|
187
|
+
except ValueError:
|
|
188
|
+
continue
|
|
189
|
+
if obj.get("type") != "supersede":
|
|
190
|
+
continue
|
|
191
|
+
ts = obj.get("ts")
|
|
192
|
+
if isinstance(ts, str):
|
|
193
|
+
retired[_quarter_of(ts)] += 1
|
|
194
|
+
# Staleness rate = overdue / total curated entries (0..1).
|
|
195
|
+
total = sum(1 for _ in _iter_curated_entries())
|
|
196
|
+
overdue = len(_staleness_report())
|
|
197
|
+
rate = (overdue / total) if total else 0.0
|
|
198
|
+
return {
|
|
199
|
+
"accepted_by_quarter": dict(accepted),
|
|
200
|
+
"retired_by_quarter": dict(retired),
|
|
201
|
+
"staleness_rate": round(rate, 3),
|
|
202
|
+
"curated_total": total,
|
|
203
|
+
"curated_overdue": overdue,
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
def _role_mode_stats() -> dict:
|
|
208
|
+
"""Count structured mode markers across session/report/handoff dirs.
|
|
209
|
+
|
|
210
|
+
Feeds `road-to-role-modes` Phase 4 (contract-conformance signal)
|
|
211
|
+
and `road-to-curated-self-improvement` Phase 3 (outcome measurement).
|
|
212
|
+
Missing directories are silently skipped — the repo may not have
|
|
213
|
+
session captures yet.
|
|
214
|
+
"""
|
|
215
|
+
counts: Counter[str] = Counter()
|
|
216
|
+
files_scanned = 0
|
|
217
|
+
unknown_modes: set[str] = set()
|
|
218
|
+
for root in _MODE_SCAN_DIRS:
|
|
219
|
+
if not root.exists():
|
|
220
|
+
continue
|
|
221
|
+
for md in root.rglob("*.md"):
|
|
222
|
+
try:
|
|
223
|
+
text = md.read_text(encoding="utf-8", errors="replace")
|
|
224
|
+
except OSError:
|
|
225
|
+
continue
|
|
226
|
+
files_scanned += 1
|
|
227
|
+
for match in _MODE_MARKER_PATTERN.finditer(text):
|
|
228
|
+
slug = match.group(1).lower()
|
|
229
|
+
counts[slug] += 1
|
|
230
|
+
if slug not in _KNOWN_MODES:
|
|
231
|
+
unknown_modes.add(slug)
|
|
232
|
+
total = sum(counts.values())
|
|
233
|
+
return {
|
|
234
|
+
"total_markers": total,
|
|
235
|
+
"files_scanned": files_scanned,
|
|
236
|
+
"by_mode": dict(counts),
|
|
237
|
+
"unknown_modes": sorted(unknown_modes),
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
|
|
135
241
|
def build_report() -> dict:
|
|
136
242
|
status = memory_status.status()
|
|
137
243
|
return {
|
|
@@ -139,10 +245,11 @@ def build_report() -> dict:
|
|
|
139
245
|
"status": status.status,
|
|
140
246
|
"backend": status.backend,
|
|
141
247
|
"reason": status.reason,
|
|
142
|
-
"cli_path": status.cli_path,
|
|
143
248
|
},
|
|
144
249
|
"intake": _intake_stats(),
|
|
145
250
|
"staleness": _staleness_report(),
|
|
251
|
+
"quarterly": _quarterly_stats(),
|
|
252
|
+
"role_modes": _role_mode_stats(),
|
|
146
253
|
}
|
|
147
254
|
|
|
148
255
|
|
|
@@ -166,6 +273,29 @@ def _print_text(report: dict) -> None:
|
|
|
166
273
|
f"+{row['overdue_days']}d {row['file']}")
|
|
167
274
|
if len(stale) > 5:
|
|
168
275
|
print(f" (+{len(stale) - 5} more)")
|
|
276
|
+
q = report["quarterly"]
|
|
277
|
+
print(f"Quarterly: staleness-rate={q['staleness_rate']:.1%} "
|
|
278
|
+
f"({q['curated_overdue']}/{q['curated_total']})")
|
|
279
|
+
if q["accepted_by_quarter"]:
|
|
280
|
+
acc = ", ".join(f"{k}:{v}" for k, v in
|
|
281
|
+
sorted(q["accepted_by_quarter"].items()))
|
|
282
|
+
print(f" accepted: {acc}")
|
|
283
|
+
if q["retired_by_quarter"]:
|
|
284
|
+
ret = ", ".join(f"{k}:{v}" for k, v in
|
|
285
|
+
sorted(q["retired_by_quarter"].items()))
|
|
286
|
+
print(f" retired: {ret}")
|
|
287
|
+
rm = report.get("role_modes") or {}
|
|
288
|
+
if rm.get("files_scanned"):
|
|
289
|
+
total = rm.get("total_markers", 0)
|
|
290
|
+
print(f"Role modes: {total} marker(s) in "
|
|
291
|
+
f"{rm['files_scanned']} file(s)")
|
|
292
|
+
if rm.get("by_mode"):
|
|
293
|
+
modes = ", ".join(f"{k}:{v}" for k, v in
|
|
294
|
+
sorted(rm["by_mode"].items()))
|
|
295
|
+
print(f" by mode: {modes}")
|
|
296
|
+
if rm.get("unknown_modes"):
|
|
297
|
+
print(f" unknown: {', '.join(rm['unknown_modes'])} "
|
|
298
|
+
"(not in the six reserved slugs)")
|
|
169
299
|
|
|
170
300
|
|
|
171
301
|
def main() -> int:
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
"""Write-side helper: drop an engineering-memory signal.
|
|
3
3
|
|
|
4
4
|
Shared by producers (`/bug-fix`, `/do-and-judge`, `/propose-memory`,
|
|
5
|
-
incident role exit).
|
|
6
|
-
`
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
incident role exit). Appends an intake line under
|
|
6
|
+
`agents/memory/intake/signals-YYYY-MM.jsonl` — append-only JSONL with
|
|
7
|
+
`merge=union` (see `road-to-memory-merge-safety.md`). Memory is entirely
|
|
8
|
+
file-backed (no external backend).
|
|
9
9
|
|
|
10
10
|
Rate limiting:
|
|
11
11
|
- Per-path, per-type, within a rolling window (default 7 days).
|
|
@@ -31,12 +31,12 @@ from pathlib import Path
|
|
|
31
31
|
from typing import Any
|
|
32
32
|
|
|
33
33
|
INTAKE_ROOT = Path("agents/memory/intake")
|
|
34
|
+
SETTINGS_FILE = Path(".agent-settings.yml")
|
|
34
35
|
VALID_TYPES = {
|
|
35
36
|
"historical-patterns",
|
|
36
37
|
"incident-learnings",
|
|
37
38
|
"ownership",
|
|
38
39
|
"domain-invariants",
|
|
39
|
-
"architecture-decisions",
|
|
40
40
|
"product-rules",
|
|
41
41
|
}
|
|
42
42
|
RATE_LIMIT_WINDOW_DAYS = 7
|
|
@@ -99,10 +99,8 @@ def emit(entry_type: str, path: str, body: str,
|
|
|
99
99
|
force: bool = False) -> dict[str, Any] | None:
|
|
100
100
|
"""Append a signal entry. Returns the written record, or None when skipped.
|
|
101
101
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
Phase 3. For now, the file path is the single source of truth so
|
|
105
|
-
merge-safety is preserved in every mode.
|
|
102
|
+
The intake JSONL file is the single source of truth — memory is
|
|
103
|
+
entirely file-backed (no external backend).
|
|
106
104
|
"""
|
|
107
105
|
if entry_type not in VALID_TYPES:
|
|
108
106
|
raise ValueError(f"unknown memory type: {entry_type}")
|
|
@@ -1,46 +1,27 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
|
-
"""
|
|
2
|
+
"""File-backed memory status (no external backend).
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
(`scripts/memory_lookup.py`)
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
* `absent` — package not installed or CLI not on PATH
|
|
11
|
-
* `misconfigured` — installed but `health()` fails within the timeout
|
|
12
|
-
* `present` — installed, healthy, usable now
|
|
13
|
-
|
|
14
|
-
Result is cached per process under `os.environ["AGENT_MEMORY_STATUS"]`
|
|
15
|
-
and (optionally) under `.agent-memory/status.cache` per session.
|
|
4
|
+
The optional `@event4u/agent-memory` package was removed; retrieval
|
|
5
|
+
(`scripts/memory_lookup.py`) and signal-writing (`scripts/memory_signal.py`)
|
|
6
|
+
are entirely file-backed now. `status()` / `health()` report the file
|
|
7
|
+
backend so the v1 retrieval-contract health envelope stays stable for
|
|
8
|
+
consumers (e.g. the MCP `memory_status` tool).
|
|
16
9
|
|
|
17
10
|
Usage:
|
|
18
11
|
python3 scripts/memory_status.py # human-readable line
|
|
19
12
|
python3 scripts/memory_status.py --format json # stable JSON
|
|
20
|
-
|
|
13
|
+
python3 scripts/memory_status.py --health # v1 health envelope
|
|
14
|
+
from scripts.memory_status import status, health # Python import
|
|
21
15
|
"""
|
|
22
16
|
|
|
23
17
|
from __future__ import annotations
|
|
24
18
|
|
|
25
19
|
import argparse
|
|
26
20
|
import json
|
|
27
|
-
import os
|
|
28
|
-
import shutil
|
|
29
|
-
import subprocess
|
|
30
21
|
import sys
|
|
31
|
-
import time
|
|
32
22
|
from dataclasses import dataclass, asdict
|
|
33
|
-
from pathlib import Path
|
|
34
|
-
from typing import Literal
|
|
35
23
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
_CLI_CANDIDATES = ("memory", "agent-memory", "agentmem")
|
|
39
|
-
_HEALTH_TIMEOUT_SECONDS = 2.0
|
|
40
|
-
_CACHE_ENV = "AGENT_MEMORY_STATUS"
|
|
41
|
-
_CACHE_FILE = Path(".agent-memory") / "status.cache"
|
|
42
|
-
|
|
43
|
-
# Retrieval contract version served by the file-backed fallback.
|
|
24
|
+
# Retrieval contract version served by the file-backed backend.
|
|
44
25
|
# Source of truth: internal/schemas/retrieval-v1.schema.json.
|
|
45
26
|
CONTRACT_VERSION = 1
|
|
46
27
|
_FILE_BACKEND_VERSION = "0.0.0-file"
|
|
@@ -49,184 +30,24 @@ _FILE_BACKEND_FEATURES = ("file-fallback",)
|
|
|
49
30
|
|
|
50
31
|
@dataclass
|
|
51
32
|
class Result:
|
|
52
|
-
status:
|
|
53
|
-
backend: str
|
|
54
|
-
reason: str
|
|
55
|
-
elapsed_ms: int
|
|
56
|
-
cli_path: str = "" # resolved CLI path, if any
|
|
57
|
-
# Populated only when status == "present" — sourced from the
|
|
58
|
-
# `health` CLI envelope so the v1 health() reports real package
|
|
59
|
-
# capabilities instead of file-fallback placeholders.
|
|
60
|
-
backend_version: str = ""
|
|
61
|
-
features: tuple = ()
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
def _find_cli() -> str:
|
|
65
|
-
for name in _CLI_CANDIDATES:
|
|
66
|
-
path = shutil.which(name)
|
|
67
|
-
if path:
|
|
68
|
-
return path
|
|
69
|
-
return ""
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
def _parse_health_envelope(stdout: str) -> dict | None:
|
|
73
|
-
"""Extract the v1 health envelope from `memory health` stdout.
|
|
74
|
-
|
|
75
|
-
The package emits a single JSON object on stdout (pino structured
|
|
76
|
-
logs go to stderr). We tolerate older builds that may have leaked
|
|
77
|
-
log lines into stdout by scanning for the first top-level object
|
|
78
|
-
that carries ``contract_version``.
|
|
79
|
-
"""
|
|
80
|
-
text = (stdout or "").strip()
|
|
81
|
-
if not text:
|
|
82
|
-
return None
|
|
83
|
-
try:
|
|
84
|
-
obj = json.loads(text)
|
|
85
|
-
except ValueError:
|
|
86
|
-
obj = None
|
|
87
|
-
if isinstance(obj, dict) and obj.get("contract_version"):
|
|
88
|
-
return obj
|
|
89
|
-
# Fallback: line-by-line scan for an envelope-shaped object — covers
|
|
90
|
-
# the case where structured logs accidentally share stdout.
|
|
91
|
-
for line in text.splitlines():
|
|
92
|
-
line = line.strip()
|
|
93
|
-
if not line.startswith("{"):
|
|
94
|
-
continue
|
|
95
|
-
try:
|
|
96
|
-
cand = json.loads(line)
|
|
97
|
-
except ValueError:
|
|
98
|
-
continue
|
|
99
|
-
if isinstance(cand, dict) and cand.get("contract_version"):
|
|
100
|
-
return cand
|
|
101
|
-
return None
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
def _probe_health(cli_path: str) -> tuple[bool, str, dict | None]:
|
|
105
|
-
"""Returns (healthy, reason, envelope).
|
|
106
|
-
|
|
107
|
-
On success ``envelope`` is the parsed v1 health envelope (may still
|
|
108
|
-
be ``None`` for very old CLIs that don't emit one). On failure it
|
|
109
|
-
is always ``None``.
|
|
110
|
-
"""
|
|
111
|
-
try:
|
|
112
|
-
out = subprocess.run(
|
|
113
|
-
[cli_path, "health"],
|
|
114
|
-
capture_output=True, text=True,
|
|
115
|
-
timeout=_HEALTH_TIMEOUT_SECONDS,
|
|
116
|
-
)
|
|
117
|
-
except subprocess.TimeoutExpired:
|
|
118
|
-
return False, f"health() timed out after {_HEALTH_TIMEOUT_SECONDS}s", None
|
|
119
|
-
except FileNotFoundError:
|
|
120
|
-
return False, "CLI vanished between which() and invoke", None
|
|
121
|
-
if out.returncode != 0:
|
|
122
|
-
# First line of combined output, capped, for the reason field.
|
|
123
|
-
msg = (out.stderr or out.stdout or "exit != 0").strip().splitlines()
|
|
124
|
-
head = msg[0][:120] if msg else "exit != 0"
|
|
125
|
-
return False, f"health() returned {out.returncode}: {head}", None
|
|
126
|
-
envelope = _parse_health_envelope(out.stdout)
|
|
127
|
-
return True, "ok", envelope
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
def _read_cache() -> Result | None:
|
|
131
|
-
cached = os.environ.get(_CACHE_ENV)
|
|
132
|
-
if cached:
|
|
133
|
-
try:
|
|
134
|
-
data = json.loads(cached)
|
|
135
|
-
return Result(**data)
|
|
136
|
-
except (ValueError, TypeError):
|
|
137
|
-
pass
|
|
138
|
-
if _CACHE_FILE.is_file():
|
|
139
|
-
try:
|
|
140
|
-
data = json.loads(_CACHE_FILE.read_text(encoding="utf-8"))
|
|
141
|
-
return Result(**data)
|
|
142
|
-
except (OSError, ValueError, TypeError):
|
|
143
|
-
pass
|
|
144
|
-
return None
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
def _write_cache(result: Result) -> None:
|
|
148
|
-
payload = json.dumps(asdict(result))
|
|
149
|
-
os.environ[_CACHE_ENV] = payload
|
|
150
|
-
try:
|
|
151
|
-
_CACHE_FILE.parent.mkdir(parents=True, exist_ok=True)
|
|
152
|
-
_CACHE_FILE.write_text(payload, encoding="utf-8")
|
|
153
|
-
except OSError:
|
|
154
|
-
# Best-effort cache; skills MUST still work without it.
|
|
155
|
-
pass
|
|
33
|
+
status: str = "file" # always "file" — no external backend
|
|
34
|
+
backend: str = "file"
|
|
35
|
+
reason: str = "file-backed memory (no external backend)"
|
|
36
|
+
elapsed_ms: int = 0
|
|
156
37
|
|
|
157
38
|
|
|
158
39
|
def status(refresh: bool = False) -> Result:
|
|
159
|
-
"""Return the
|
|
160
|
-
|
|
161
|
-
Always returns in well under ``_HEALTH_TIMEOUT_SECONDS`` seconds on
|
|
162
|
-
cache hit; bounded by the timeout on cache miss. Never raises —
|
|
163
|
-
probe failures degrade to ``absent`` / ``misconfigured`` rather than
|
|
164
|
-
surfacing exceptions.
|
|
165
|
-
"""
|
|
166
|
-
if not refresh:
|
|
167
|
-
cached = _read_cache()
|
|
168
|
-
if cached is not None:
|
|
169
|
-
cached.elapsed_ms = 0
|
|
170
|
-
return cached
|
|
171
|
-
t0 = time.monotonic()
|
|
172
|
-
cli = _find_cli()
|
|
173
|
-
if not cli:
|
|
174
|
-
result = Result("absent", "file",
|
|
175
|
-
"agent-memory CLI not on PATH", 0)
|
|
176
|
-
else:
|
|
177
|
-
healthy, reason, envelope = _probe_health(cli)
|
|
178
|
-
elapsed = int((time.monotonic() - t0) * 1000)
|
|
179
|
-
if healthy:
|
|
180
|
-
backend_version = ""
|
|
181
|
-
features: tuple = ()
|
|
182
|
-
if isinstance(envelope, dict):
|
|
183
|
-
bv = envelope.get("backend_version")
|
|
184
|
-
if isinstance(bv, str):
|
|
185
|
-
backend_version = bv
|
|
186
|
-
feats = envelope.get("features")
|
|
187
|
-
if isinstance(feats, list) and all(
|
|
188
|
-
isinstance(f, str) for f in feats
|
|
189
|
-
):
|
|
190
|
-
features = tuple(feats)
|
|
191
|
-
result = Result("present", "package", reason, elapsed, cli,
|
|
192
|
-
backend_version=backend_version,
|
|
193
|
-
features=features)
|
|
194
|
-
else:
|
|
195
|
-
result = Result("misconfigured", "file", reason, elapsed, cli)
|
|
196
|
-
_write_cache(result)
|
|
197
|
-
return result
|
|
40
|
+
"""Return the (constant) file-backend status. Never raises."""
|
|
41
|
+
return Result()
|
|
198
42
|
|
|
199
43
|
|
|
200
44
|
def health(refresh: bool = False) -> dict:
|
|
201
|
-
"""Return a v1 retrieval-contract health envelope.
|
|
202
|
-
|
|
203
|
-
Schema: ``internal/schemas/retrieval-v1.schema.json`` (HealthResponse).
|
|
204
|
-
Maps the three-state :func:`status` result onto the contract's
|
|
205
|
-
``ok | degraded | error`` so consumers can read
|
|
206
|
-
``contract_version`` without caring about the file-vs-package split.
|
|
207
|
-
|
|
208
|
-
When the package backs the call (``status == "present"``), the
|
|
209
|
-
envelope reports the package's own ``backend_version`` and
|
|
210
|
-
``features`` so consumers can feature-detect against real
|
|
211
|
-
capabilities. Otherwise the file-fallback markers are returned.
|
|
212
|
-
"""
|
|
213
|
-
r = status(refresh=refresh)
|
|
214
|
-
envelope_status = {
|
|
215
|
-
"present": "ok",
|
|
216
|
-
"misconfigured": "degraded",
|
|
217
|
-
"absent": "ok",
|
|
218
|
-
}[r.status]
|
|
219
|
-
if r.status == "present" and (r.backend_version or r.features):
|
|
220
|
-
backend_version = r.backend_version or _FILE_BACKEND_VERSION
|
|
221
|
-
features = list(r.features) if r.features else list(_FILE_BACKEND_FEATURES)
|
|
222
|
-
else:
|
|
223
|
-
backend_version = _FILE_BACKEND_VERSION
|
|
224
|
-
features = list(_FILE_BACKEND_FEATURES)
|
|
45
|
+
"""Return a v1 retrieval-contract health envelope (file backend)."""
|
|
225
46
|
return {
|
|
226
47
|
"contract_version": CONTRACT_VERSION,
|
|
227
|
-
"status":
|
|
228
|
-
"backend_version":
|
|
229
|
-
"features":
|
|
48
|
+
"status": "ok",
|
|
49
|
+
"backend_version": _FILE_BACKEND_VERSION,
|
|
50
|
+
"features": list(_FILE_BACKEND_FEATURES),
|
|
230
51
|
}
|
|
231
52
|
|
|
232
53
|
|
|
@@ -234,22 +55,20 @@ def main() -> int:
|
|
|
234
55
|
ap = argparse.ArgumentParser(description=__doc__)
|
|
235
56
|
ap.add_argument("--format", choices=["text", "json"], default="text")
|
|
236
57
|
ap.add_argument("--refresh", action="store_true",
|
|
237
|
-
help="
|
|
58
|
+
help="No-op (kept for back-compat); status is constant")
|
|
238
59
|
ap.add_argument("--health", action="store_true",
|
|
239
60
|
help="Emit a v1 retrieval-contract health envelope "
|
|
240
|
-
"instead of the
|
|
61
|
+
"instead of the status line")
|
|
241
62
|
args = ap.parse_args()
|
|
242
63
|
if args.health:
|
|
243
|
-
print(json.dumps(health(
|
|
64
|
+
print(json.dumps(health()))
|
|
244
65
|
return 0
|
|
245
|
-
r = status(
|
|
66
|
+
r = status()
|
|
246
67
|
if args.format == "json":
|
|
247
68
|
print(json.dumps(asdict(r)))
|
|
248
69
|
else:
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
f"elapsed={r.elapsed_ms}ms reason={r.reason}")
|
|
252
|
-
# `absent` is a valid operational state, not a failure.
|
|
70
|
+
print(f" ℹ️ backend={r.backend} status={r.status} "
|
|
71
|
+
f"reason={r.reason}")
|
|
253
72
|
return 0
|
|
254
73
|
|
|
255
74
|
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
"""``memory`` step — bounded retrieval over the
|
|
1
|
+
"""``memory`` step — bounded retrieval over the three allowed types.
|
|
2
2
|
|
|
3
3
|
Contract (see
|
|
4
4
|
``docs/contracts/implement-ticket-flow.md#memory-retrieval-contract``):
|
|
5
5
|
|
|
6
|
-
-
|
|
7
|
-
``
|
|
8
|
-
|
|
6
|
+
- Three allowed types: ``domain-invariants``, ``incident-learnings``,
|
|
7
|
+
``historical-patterns``. (Architectural rationale lives in ADRs —
|
|
8
|
+
``docs/decisions/`` — not in curated memory.)
|
|
9
|
+
- Hard cap of **12** hits total across the three types.
|
|
9
10
|
- Keys derive from the ticket — title tokens plus acceptance-criterion
|
|
10
11
|
tokens plus any already-known ``files`` hint. Tokenisation is
|
|
11
12
|
deliberately naive (whitespace split, lower-cased) so the retrieval
|
|
@@ -27,11 +28,10 @@ from ...delivery_state import DeliveryState, Outcome, StepResult
|
|
|
27
28
|
|
|
28
29
|
MEMORY_TYPES: tuple[str, ...] = (
|
|
29
30
|
"domain-invariants",
|
|
30
|
-
"architecture-decisions",
|
|
31
31
|
"incident-learnings",
|
|
32
32
|
"historical-patterns",
|
|
33
33
|
)
|
|
34
|
-
"""The
|
|
34
|
+
"""The three types allowed by the flow contract. No aliases, no extras."""
|
|
35
35
|
|
|
36
36
|
MAX_HITS: int = 12
|
|
37
37
|
"""Hard cap per the roadmap — never raise without amending the contract."""
|
|
@@ -4,9 +4,9 @@ Phase 6 of ``agents/roadmaps/road-to-product-ui-track.md`` retired the
|
|
|
4
4
|
Phase 3 deferral stub once design / apply / review / polish landed. Two
|
|
5
5
|
slots remain semantically empty for the UI track:
|
|
6
6
|
|
|
7
|
-
- ``memory`` — the UI track does not consult the
|
|
8
|
-
backend retrieves over (``domain-invariants``, ``
|
|
9
|
-
``
|
|
7
|
+
- ``memory`` — the UI track does not consult the memory types the
|
|
8
|
+
backend retrieves over (``domain-invariants``, ``incident-learnings``,
|
|
9
|
+
``historical-patterns``). UI work pivots on the
|
|
10
10
|
audit findings in ``state.ui_audit`` instead, which the audit gate has
|
|
11
11
|
already populated by the time this handler runs.
|
|
12
12
|
- ``plan`` — :mod:`.design` produces the locked design brief that
|