@tyroneross/build-loop 0.30.3
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/.agents/plugins/marketplace.json +10 -0
- package/.claude-plugin/marketplace.json +38 -0
- package/.claude-plugin/plugin.json +30 -0
- package/.codex-plugin/plugin.json +41 -0
- package/.cursor/rules/build-loop-surface.mdc +22 -0
- package/AGENTS.md +498 -0
- package/LICENSE +202 -0
- package/README.md +403 -0
- package/agents/alignment-checker.md +124 -0
- package/agents/api-assessor.md +136 -0
- package/agents/architecture-scout.md +185 -0
- package/agents/assessment-orchestrator.md +163 -0
- package/agents/build-orchestrator.md +198 -0
- package/agents/database-assessor.md +133 -0
- package/agents/design-contract-specialist.md +239 -0
- package/agents/fact-checker.md +69 -0
- package/agents/fix-critique.md +161 -0
- package/agents/frontend-assessor.md +136 -0
- package/agents/implementer.md +185 -0
- package/agents/independent-auditor.md +143 -0
- package/agents/mock-scanner.md +78 -0
- package/agents/optimize-runner.md +112 -0
- package/agents/overfitting-reviewer.md +96 -0
- package/agents/performance-assessor.md +159 -0
- package/agents/plan-critic.md +85 -0
- package/agents/promotion-reviewer.md +121 -0
- package/agents/recurring-pattern-detector.md +248 -0
- package/agents/retrospective-synthesizer.md +109 -0
- package/agents/root-cause-investigator.md +285 -0
- package/agents/scope-auditor.md +121 -0
- package/agents/security-reviewer.md +151 -0
- package/agents/self-improvement-architect.md +125 -0
- package/agents/synthesis-critic.md +99 -0
- package/agents/transcript-pattern-miner.md +165 -0
- package/agents/ui-validator.md +193 -0
- package/codex-skills/build-loop/SKILL.md +20 -0
- package/codex-skills/debug-loop/SKILL.md +18 -0
- package/codex-skills/handoff/SKILL.md +22 -0
- package/codex-skills/knowledge/SKILL.md +21 -0
- package/codex-skills/optimize/SKILL.md +18 -0
- package/codex-skills/research/SKILL.md +18 -0
- package/commands/agent-rally-point.md +301 -0
- package/commands/assess.md +41 -0
- package/commands/debug.md +20 -0
- package/commands/debugger-detail.md +34 -0
- package/commands/debugger-scan.md +15 -0
- package/commands/debugger-status.md +20 -0
- package/commands/debugger.md +32 -0
- package/commands/handoff.md +113 -0
- package/commands/knowledge-review.md +16 -0
- package/commands/optimize.md +31 -0
- package/commands/plan-verify.md +39 -0
- package/commands/promote-experiment.md +129 -0
- package/commands/research.md +22 -0
- package/commands/run.md +12 -0
- package/commands/self-review.md +51 -0
- package/commands/start-prd.md +57 -0
- package/commands/test.md +34 -0
- package/dist/src/assessment-orchestrator.d.ts +78 -0
- package/dist/src/assessment-orchestrator.d.ts.map +1 -0
- package/dist/src/assessment-orchestrator.js +304 -0
- package/dist/src/assessment-orchestrator.js.map +1 -0
- package/dist/src/audit-miner.d.ts +21 -0
- package/dist/src/audit-miner.d.ts.map +1 -0
- package/dist/src/audit-miner.js +421 -0
- package/dist/src/audit-miner.js.map +1 -0
- package/dist/src/batch-operations.d.ts +30 -0
- package/dist/src/batch-operations.d.ts.map +1 -0
- package/dist/src/batch-operations.js +339 -0
- package/dist/src/batch-operations.js.map +1 -0
- package/dist/src/config.d.ts +83 -0
- package/dist/src/config.d.ts.map +1 -0
- package/dist/src/config.js +176 -0
- package/dist/src/config.js.map +1 -0
- package/dist/src/context-engine.d.ts +45 -0
- package/dist/src/context-engine.d.ts.map +1 -0
- package/dist/src/context-engine.js +135 -0
- package/dist/src/context-engine.js.map +1 -0
- package/dist/src/debug-wrapper.d.ts +58 -0
- package/dist/src/debug-wrapper.d.ts.map +1 -0
- package/dist/src/debug-wrapper.js +285 -0
- package/dist/src/debug-wrapper.js.map +1 -0
- package/dist/src/index.d.ts +31 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +149 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/interactive-verifier.d.ts +26 -0
- package/dist/src/interactive-verifier.d.ts.map +1 -0
- package/dist/src/interactive-verifier.js +435 -0
- package/dist/src/interactive-verifier.js.map +1 -0
- package/dist/src/lessons.d.ts +59 -0
- package/dist/src/lessons.d.ts.map +1 -0
- package/dist/src/lessons.js +172 -0
- package/dist/src/lessons.js.map +1 -0
- package/dist/src/log-reader.d.ts +39 -0
- package/dist/src/log-reader.d.ts.map +1 -0
- package/dist/src/log-reader.js +291 -0
- package/dist/src/log-reader.js.map +1 -0
- package/dist/src/logger.d.ts +59 -0
- package/dist/src/logger.d.ts.map +1 -0
- package/dist/src/logger.js +328 -0
- package/dist/src/logger.js.map +1 -0
- package/dist/src/parallel-retrieval.d.ts +52 -0
- package/dist/src/parallel-retrieval.d.ts.map +1 -0
- package/dist/src/parallel-retrieval.js +309 -0
- package/dist/src/parallel-retrieval.js.map +1 -0
- package/dist/src/pattern-extractor.d.ts +30 -0
- package/dist/src/pattern-extractor.d.ts.map +1 -0
- package/dist/src/pattern-extractor.js +386 -0
- package/dist/src/pattern-extractor.js.map +1 -0
- package/dist/src/result-aggregator.d.ts +44 -0
- package/dist/src/result-aggregator.d.ts.map +1 -0
- package/dist/src/result-aggregator.js +315 -0
- package/dist/src/result-aggregator.js.map +1 -0
- package/dist/src/retrieval.d.ts +139 -0
- package/dist/src/retrieval.d.ts.map +1 -0
- package/dist/src/retrieval.js +724 -0
- package/dist/src/retrieval.js.map +1 -0
- package/dist/src/setup/auto-setup.d.ts +15 -0
- package/dist/src/setup/auto-setup.d.ts.map +1 -0
- package/dist/src/setup/auto-setup.js +157 -0
- package/dist/src/setup/auto-setup.js.map +1 -0
- package/dist/src/setup/configure-hooks.d.ts +8 -0
- package/dist/src/setup/configure-hooks.d.ts.map +1 -0
- package/dist/src/setup/configure-hooks.js +16 -0
- package/dist/src/setup/configure-hooks.js.map +1 -0
- package/dist/src/setup/create-slash-commands.d.ts +8 -0
- package/dist/src/setup/create-slash-commands.d.ts.map +1 -0
- package/dist/src/setup/create-slash-commands.js +101 -0
- package/dist/src/setup/create-slash-commands.js.map +1 -0
- package/dist/src/setup/index.d.ts +8 -0
- package/dist/src/setup/index.d.ts.map +1 -0
- package/dist/src/setup/index.js +17 -0
- package/dist/src/setup/index.js.map +1 -0
- package/dist/src/setup/inject-claude-md.d.ts +10 -0
- package/dist/src/setup/inject-claude-md.d.ts.map +1 -0
- package/dist/src/setup/inject-claude-md.js +150 -0
- package/dist/src/setup/inject-claude-md.js.map +1 -0
- package/dist/src/setup/uninstall.d.ts +22 -0
- package/dist/src/setup/uninstall.d.ts.map +1 -0
- package/dist/src/setup/uninstall.js +235 -0
- package/dist/src/setup/uninstall.js.map +1 -0
- package/dist/src/storage.d.ts +192 -0
- package/dist/src/storage.d.ts.map +1 -0
- package/dist/src/storage.js +1037 -0
- package/dist/src/storage.js.map +1 -0
- package/dist/src/string-similarity.d.ts +8 -0
- package/dist/src/string-similarity.d.ts.map +1 -0
- package/dist/src/string-similarity.js +57 -0
- package/dist/src/string-similarity.js.map +1 -0
- package/dist/src/traces/adapters/browser.d.ts +69 -0
- package/dist/src/traces/adapters/browser.d.ts.map +1 -0
- package/dist/src/traces/adapters/browser.js +280 -0
- package/dist/src/traces/adapters/browser.js.map +1 -0
- package/dist/src/traces/adapters/index.d.ts +23 -0
- package/dist/src/traces/adapters/index.d.ts.map +1 -0
- package/dist/src/traces/adapters/index.js +67 -0
- package/dist/src/traces/adapters/index.js.map +1 -0
- package/dist/src/traces/adapters/langchain.d.ts +42 -0
- package/dist/src/traces/adapters/langchain.d.ts.map +1 -0
- package/dist/src/traces/adapters/langchain.js +151 -0
- package/dist/src/traces/adapters/langchain.js.map +1 -0
- package/dist/src/traces/adapters/opentelemetry.d.ts +46 -0
- package/dist/src/traces/adapters/opentelemetry.d.ts.map +1 -0
- package/dist/src/traces/adapters/opentelemetry.js +164 -0
- package/dist/src/traces/adapters/opentelemetry.js.map +1 -0
- package/dist/src/traces/adapters/sentry.d.ts +58 -0
- package/dist/src/traces/adapters/sentry.d.ts.map +1 -0
- package/dist/src/traces/adapters/sentry.js +212 -0
- package/dist/src/traces/adapters/sentry.js.map +1 -0
- package/dist/src/traces/index.d.ts +10 -0
- package/dist/src/traces/index.d.ts.map +1 -0
- package/dist/src/traces/index.js +45 -0
- package/dist/src/traces/index.js.map +1 -0
- package/dist/src/traces/storage.d.ts +78 -0
- package/dist/src/traces/storage.d.ts.map +1 -0
- package/dist/src/traces/storage.js +399 -0
- package/dist/src/traces/storage.js.map +1 -0
- package/dist/src/traces/summarizer.d.ts +83 -0
- package/dist/src/traces/summarizer.d.ts.map +1 -0
- package/dist/src/traces/summarizer.js +247 -0
- package/dist/src/traces/summarizer.js.map +1 -0
- package/dist/src/traces/types.d.ts +365 -0
- package/dist/src/traces/types.d.ts.map +1 -0
- package/dist/src/traces/types.js +14 -0
- package/dist/src/traces/types.js.map +1 -0
- package/dist/src/types.d.ts +495 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +27 -0
- package/dist/src/types.js.map +1 -0
- package/docs/agent-surface-policy.md +45 -0
- package/docs/memory-setup.md +226 -0
- package/hooks/_arch_scan_bg.py +88 -0
- package/hooks/_plugin_drift_check_bg.py +85 -0
- package/hooks/_session_start_lib.sh +42 -0
- package/hooks/git/pre-push +141 -0
- package/hooks/hooks.json +126 -0
- package/hooks/post-commit +30 -0
- package/hooks/pre-commit +29 -0
- package/hooks/pre-edit-apppulse.sh +6 -0
- package/hooks/pre-edit-architecture.sh +106 -0
- package/hooks/pre-edit-rally-point.sh +92 -0
- package/hooks/session-start-apppulse.sh +6 -0
- package/hooks/session-start-architecture.sh +10 -0
- package/hooks/session-start-git-hooks.sh +12 -0
- package/hooks/session-start-plugin-drift.sh +27 -0
- package/hooks/session-start-rally-point.sh +44 -0
- package/hooks/session-start-retrieval.sh +24 -0
- package/hooks/session-start-worktree-gc.sh +105 -0
- package/hooks/test_apppulse_hooks.sh +6 -0
- package/hooks/test_rally_point_hooks.sh +388 -0
- package/hooks/test_sec008_hooks.sh +66 -0
- package/package.json +111 -0
- package/scripts/README.md +301 -0
- package/scripts/_db_url.py +61 -0
- package/scripts/_paths.py +445 -0
- package/scripts/blm.py +162 -0
- package/scripts/blm_api.py +263 -0
- package/scripts/check_cache_sync.py +490 -0
- package/scripts/embed_backend.py +475 -0
- package/scripts/install_memory.py +556 -0
- package/scripts/lessons_index/__init__.py +77 -0
- package/scripts/lessons_index/__main__.py +135 -0
- package/scripts/lessons_index/ingest.py +288 -0
- package/scripts/lessons_index/query.py +285 -0
- package/scripts/lessons_index/schema.py +114 -0
- package/scripts/memory_context/__init__.py +610 -0
- package/scripts/memory_graph/__init__.py +393 -0
- package/scripts/project_resolver.py +172 -0
- package/scripts/prune_codex_plugin_cache.py +23 -0
- package/scripts/prune_plugin_cache.py +359 -0
- package/scripts/semantic_index/__init__.py +482 -0
- package/scripts/semantic_index/_bench_hybrid.py +175 -0
- package/scripts/semantic_index/backfill.py +263 -0
- package/scripts/semantic_index/hybrid.py +174 -0
- package/scripts/semantic_index/test_backfill.py +292 -0
- package/scripts/semantic_index/test_hybrid.py +541 -0
- package/scripts/sync_navgator_lessons.py +666 -0
- package/scripts/sync_plugin_cache.py +388 -0
- package/skills/agent-rally-point/SKILL.md +165 -0
- package/skills/agent-rally-watcher/SKILL.md +83 -0
- package/skills/api-registry-bridge/SKILL.md +59 -0
- package/skills/architecture/dead/SKILL.md +56 -0
- package/skills/architecture/impact/SKILL.md +88 -0
- package/skills/architecture/review/SKILL.md +227 -0
- package/skills/architecture/rules/SKILL.md +72 -0
- package/skills/architecture/scan/SKILL.md +79 -0
- package/skills/architecture/trace/SKILL.md +65 -0
- package/skills/attribution-standard/SKILL.md +122 -0
- package/skills/authentication/SKILL.md +81 -0
- package/skills/authentication/references/better-auth-magic-link.md +135 -0
- package/skills/authentication/references/better-auth-setup.md +224 -0
- package/skills/authentication/references/google-calendar-sync.md +278 -0
- package/skills/authentication/references/google-cloud-console.md +159 -0
- package/skills/authentication/references/google-geocoding-directions.md +126 -0
- package/skills/authentication/references/google-lessons-example-web-app.md +177 -0
- package/skills/authentication/references/google-maps.md +162 -0
- package/skills/authentication/references/google-oauth-setup.md +343 -0
- package/skills/authentication/references/google-places.md +173 -0
- package/skills/authentication/references/lessons-example-web-app-better-auth.md +126 -0
- package/skills/authentication/references/resend-email.md +227 -0
- package/skills/authentication/references/resend-otp-magic-link.md +153 -0
- package/skills/authentication/references/supabase-auth.md +172 -0
- package/skills/auto-decision-capture/SKILL.md +419 -0
- package/skills/build-loop/SKILL.md +516 -0
- package/skills/build-loop/detect-plugins.mjs +82 -0
- package/skills/build-loop/eval-guide.md +65 -0
- package/skills/build-loop/fallbacks.md +549 -0
- package/skills/build-loop/phases/fact-check.md +42 -0
- package/skills/build-loop/phases/ui-validation.md +267 -0
- package/skills/build-loop/references/apple-native-planning.md +439 -0
- package/skills/build-loop/references/capability-routing.md +181 -0
- package/skills/build-loop/references/codex-subagents.md +98 -0
- package/skills/build-loop/references/coordination.md +161 -0
- package/skills/build-loop/references/correction-aware-capture.md +177 -0
- package/skills/build-loop/references/independent-auditor.md +72 -0
- package/skills/build-loop/references/intent-capability-pack.md +170 -0
- package/skills/build-loop/references/intent-exploration-prompts.md +96 -0
- package/skills/build-loop/references/leadership.md +72 -0
- package/skills/build-loop/references/memory.md +284 -0
- package/skills/build-loop/references/modular-systems-pack.md +96 -0
- package/skills/build-loop/references/output-style.md +129 -0
- package/skills/build-loop/references/pay-it-forward-arch.md +98 -0
- package/skills/build-loop/references/phase-1-assess.md +218 -0
- package/skills/build-loop/references/phase-2-plan.md +77 -0
- package/skills/build-loop/references/phase-3-execute.md +47 -0
- package/skills/build-loop/references/phase-4-review.md +310 -0
- package/skills/build-loop/references/phase-5-iterate.md +71 -0
- package/skills/build-loop/references/phase-6-learn.md +56 -0
- package/skills/build-loop/references/recent-design-structures.md +274 -0
- package/skills/build-loop/references/refactor-history/ASSESSMENT.md +85 -0
- package/skills/build-loop/references/refactor-history/STANDALONE_TEST_RUN.md +149 -0
- package/skills/build-loop/references/refactor-history/scenarios/01-simple-bugfix.md +32 -0
- package/skills/build-loop/references/refactor-history/scenarios/02-ui-build-with-iteration.md +48 -0
- package/skills/build-loop/references/refactor-history/scenarios/03-multi-failure-escalation.md +60 -0
- package/skills/build-loop/references/refactor-history/scenarios/04-ui-build-ibr-absent.md +51 -0
- package/skills/build-loop/references/refactor-history/scenarios/05-refactor-navgator-absent.md +71 -0
- package/skills/build-loop/references/refactor-history/scenarios/06-recurring-bug-debugger-absent.md +52 -0
- package/skills/build-loop/references/refactor-history/trace-comparison.md +202 -0
- package/skills/build-loop/references/self-recursive-dev.md +77 -0
- package/skills/build-loop/references/self-review.md +232 -0
- package/skills/build-loop/references/ui-io-contract.md +116 -0
- package/skills/build-loop/scanners/audit-design-rules.mjs +476 -0
- package/skills/build-loop/scanners/require-visual-evidence.mjs +239 -0
- package/skills/build-loop/templates/backlog-item.md +35 -0
- package/skills/build-loop/templates/codex-worker-prompt.md +89 -0
- package/skills/build-loop/templates/ui-subagent-prompt.md +179 -0
- package/skills/build-loop/templates/ux-fix-plan.md +40 -0
- package/skills/building-with-deepagents/SKILL.md +195 -0
- package/skills/building-with-deepagents/references/anti-patterns.md +141 -0
- package/skills/building-with-deepagents/references/api-quick-reference.md +184 -0
- package/skills/capabilities/SKILL.md +91 -0
- package/skills/debug-loop/SKILL.md +278 -0
- package/skills/debug-loop/references/convergence-rules.md +145 -0
- package/skills/debug-loop/references/swiftui-macos-clunky-ui-debugger.html +823 -0
- package/skills/debugging/assess/SKILL.md +111 -0
- package/skills/debugging/debug-loop/SKILL.md +231 -0
- package/skills/debugging/memory/SKILL.md +147 -0
- package/skills/debugging/store/SKILL.md +153 -0
- package/skills/debugging-memory/SKILL.md +440 -0
- package/skills/debugging-memory/examples/incident-example.json +67 -0
- package/skills/debugging-memory/references/incident-documentation.md +280 -0
- package/skills/debugging-memory/references/ios-notification-alarm-playbook.md +300 -0
- package/skills/debugging-memory/references/pattern-extraction.md +163 -0
- package/skills/debugging-memory/references/subagent-integration.md +312 -0
- package/skills/defenseclaw-bridge/SKILL.md +156 -0
- package/skills/defenseclaw-bridge/references/dc-config-mapping.md +162 -0
- package/skills/defenseclaw-bridge/references/output-format.md +108 -0
- package/skills/handoff/SKILL.md +94 -0
- package/skills/ibr-bridge/SKILL.md +68 -0
- package/skills/knowledge/SKILL.md +127 -0
- package/skills/knowledge/references/recall-integration.md +83 -0
- package/skills/knowledge/templates/madr-minimal.md +56 -0
- package/skills/knowledge-review/SKILL.md +112 -0
- package/skills/logging-tracer/SKILL.md +202 -0
- package/skills/logging-tracer/references/log-analysis.md +128 -0
- package/skills/logging-tracer/references/stack-templates.md +274 -0
- package/skills/logging-tracer-bridge/SKILL.md +70 -0
- package/skills/mcp-builder/SKILL.md +278 -0
- package/skills/mcp-builder/references/mcp-security.md +106 -0
- package/skills/model-tiering/SKILL.md +216 -0
- package/skills/native-ax-driver/SKILL.md +220 -0
- package/skills/native-ax-driver/scripts/layout_fill.py +222 -0
- package/skills/native-ax-driver/scripts/native_driver.py +495 -0
- package/skills/native-ax-driver/swift/bl-ax-driver/Package.swift +20 -0
- package/skills/native-ax-driver/swift/bl-ax-driver/Sources/main.swift +542 -0
- package/skills/optimize/SKILL.md +202 -0
- package/skills/optimize/profiles.md +61 -0
- package/skills/plan-verify/SKILL.md +115 -0
- package/skills/plan-verify/test-fixtures/example-app-v20-findings.json +27 -0
- package/skills/plan-verify/test-fixtures/example-app-v20.md +42 -0
- package/skills/plan-verify/test-fixtures/example-app-v22-findings.json +15 -0
- package/skills/plan-verify/test-fixtures/example-app-v22.md +1608 -0
- package/skills/plan-verify/test-fixtures/unrelated-good-plan-findings.json +15 -0
- package/skills/plan-verify/test-fixtures/unrelated-good-plan.md +55 -0
- package/skills/plugin-builder/SKILL.md +329 -0
- package/skills/plugin-builder/references/authoritative-sources.md +104 -0
- package/skills/plugin-builder/references/build-loop-phase-guidance.md +94 -0
- package/skills/plugin-builder/references/components-guide.md +221 -0
- package/skills/plugin-builder/references/distribution.md +317 -0
- package/skills/plugin-builder/references/dual-host-claude-codex.md +220 -0
- package/skills/plugin-builder/references/hooks-reference.md +210 -0
- package/skills/plugin-builder/references/manifest-schema.md +111 -0
- package/skills/plugin-builder/references/plugin-hygiene-lessons.md +307 -0
- package/skills/plugin-tests/SKILL.md +94 -0
- package/skills/prd-bridge/SKILL.md +135 -0
- package/skills/research/SKILL.md +80 -0
- package/skills/security-methodology/SKILL.md +105 -0
- package/skills/security-methodology/references/cross-source-matrix.md +77 -0
- package/skills/security-methodology/references/mitre-atlas-starter.md +83 -0
- package/skills/security-methodology/references/nist-600-1-mapping.md +119 -0
- package/skills/security-methodology/references/owasp-agentic-top-10.md +157 -0
- package/skills/security-methodology/references/owasp-llm-top-10.md +144 -0
- package/skills/security-methodology/references/owasp-web-top-10.md +65 -0
- package/skills/self-improve/SKILL.md +298 -0
- package/skills/spec-writing/SKILL.md +548 -0
- package/skills/spec-writing/scripts/check_checklist.py +478 -0
- package/skills/sync-skills/SKILL.md +132 -0
- package/skills/telemetry/SKILL.md +66 -0
- package/skills/ui-design/SKILL.md +75 -0
- package/skills/ui-design/references/design-patterns-multi.md +165 -0
- package/skills/ui-design/references/design-preferences-from-owned-apps.md +150 -0
- package/skills/ui-design/references/evidence-capture-policy.md +55 -0
- package/skills/ui-design/references/ui-guidance-sources.md +330 -0
- package/skills/ui-design/references/universal-design-principles.alt.md +182 -0
- package/skills/ui-design/references/universal-design-principles.md +419 -0
- package/templates/memory/MEMORY.md.template +55 -0
- package/templates/memory/constitution.md.template +64 -0
- package/templates/memory/manifest.json +47 -0
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
<!-- SPDX-FileCopyrightText: 2025-2026 Tyrone Ross, Jr <46267523+tyroneross@users.noreply.github.com> | SPDX-License-Identifier: Apache-2.0 -->
|
|
2
|
+
# scripts/
|
|
3
|
+
|
|
4
|
+
Build-loop's deterministic scripts. Each script:
|
|
5
|
+
|
|
6
|
+
- Has an explicit exit-code contract (0 success / 1 validation / 2 fs).
|
|
7
|
+
- Logs to stderr; success output goes to stdout.
|
|
8
|
+
- Targets Python 3.11+ stdlib unless otherwise noted below.
|
|
9
|
+
- Has a sibling `test_<name>.py` with deterministic tests.
|
|
10
|
+
|
|
11
|
+
## Lifecycle & discovery (G5)
|
|
12
|
+
|
|
13
|
+
The orchestrator routes work by selecting from a **capability registry**
|
|
14
|
+
(`build_capability_registry.py` → `.build-loop/capability-registry.json`),
|
|
15
|
+
narrowed per dispatch by `capability_shortlist.py` to ≤8 candidates. A
|
|
16
|
+
registry polluted with completed one-shots, orphans, and mis-classified
|
|
17
|
+
scripts routes agents to dead code — a coordination failure, not adjacent
|
|
18
|
+
hygiene. The lifecycle below keeps the registry honest.
|
|
19
|
+
|
|
20
|
+
### The capability header (authored, not heuristic)
|
|
21
|
+
|
|
22
|
+
Every `scripts/*.py` should declare a `# capability:` header — a four-line
|
|
23
|
+
comment block immediately after the shebang. The registry reads it instead
|
|
24
|
+
of guessing the category from the filename.
|
|
25
|
+
|
|
26
|
+
```python
|
|
27
|
+
#!/usr/bin/env python3
|
|
28
|
+
# capability:
|
|
29
|
+
# purpose: One sentence — what this script does.
|
|
30
|
+
# application: coordination
|
|
31
|
+
# status: active
|
|
32
|
+
"""Module docstring follows as normal."""
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
| Field | Meaning |
|
|
36
|
+
|---|---|
|
|
37
|
+
| `purpose` | One-sentence description. Shown in the registry entry. |
|
|
38
|
+
| `application` | The coarse namespace (taxonomy below). Overrides the filename heuristic. |
|
|
39
|
+
| `status` | Lifecycle state — one of the four values below. |
|
|
40
|
+
|
|
41
|
+
**`status` values:**
|
|
42
|
+
|
|
43
|
+
| Status | Meaning | Registry / relevance effect |
|
|
44
|
+
|---|---|---|
|
|
45
|
+
| `active` | In live use. | Routable. `keep` verdict if referenced. |
|
|
46
|
+
| `experimental` | New, not yet load-bearing. | Routable; flagged experimental. |
|
|
47
|
+
| `deprecated` | Superseded; kept temporarily. | `attic` candidate — move to `_attic/`. |
|
|
48
|
+
| `oneshot-complete` | A migration/backfill that has run. | `attic` candidate. |
|
|
49
|
+
| _absent_ | No header authored. | `status: unknown` — `review` verdict. |
|
|
50
|
+
|
|
51
|
+
### The `application` namespace taxonomy
|
|
52
|
+
|
|
53
|
+
`application` is the coarse routing label. Today's namespaces:
|
|
54
|
+
`coordination`, `meta`, `architecture`, `debugging`, `validation`,
|
|
55
|
+
`planning`, `execution`, `observability`, `memory`, `testing`,
|
|
56
|
+
`deployment`, `ux-ui`, `optimization`.
|
|
57
|
+
|
|
58
|
+
When `scripts/` grows enough that a flat directory obscures purpose,
|
|
59
|
+
namespaces become physical subdirectories (`scripts/coordination/`,
|
|
60
|
+
`scripts/memory/`, …), migrated **opportunistically** — a script moves the
|
|
61
|
+
next time a build touches it, not in a big-bang reshuffle.
|
|
62
|
+
|
|
63
|
+
### Lifecycle: add → find → move → deprecate
|
|
64
|
+
|
|
65
|
+
**Add.** Create the script. Author the `# capability:` header in the same
|
|
66
|
+
commit — an absent header surfaces as `status: unknown` and a `review`
|
|
67
|
+
verdict in `script_relevance.py`.
|
|
68
|
+
|
|
69
|
+
**Find.** Agents do not browse `scripts/`. They route via the registry +
|
|
70
|
+
shortlist. After adding or renaming a script, the registry rebuilds on the
|
|
71
|
+
next Phase 1 Assess; rebuild manually with
|
|
72
|
+
`python3 scripts/build_capability_registry.py --workdir "$PWD"`.
|
|
73
|
+
|
|
74
|
+
**Move.** When a build touches a script and its `application` warrants a
|
|
75
|
+
subdirectory, move it then, update every importer (`git grep <name>.py`),
|
|
76
|
+
and rebuild the registry.
|
|
77
|
+
|
|
78
|
+
**Deprecate.** When a script is superseded or a one-shot has run:
|
|
79
|
+
|
|
80
|
+
1. Set its header `status` to `deprecated` or `oneshot-complete`.
|
|
81
|
+
2. Run `python3 scripts/script_relevance.py --workdir "$PWD"` to confirm it
|
|
82
|
+
is not still referenced.
|
|
83
|
+
3. Once the detector lists it under `attic_candidates`, move it to
|
|
84
|
+
`scripts/_attic/`. The registry crawler excludes `_attic/`, so the
|
|
85
|
+
script disappears from routing without being deleted.
|
|
86
|
+
|
|
87
|
+
### The relevance detector
|
|
88
|
+
|
|
89
|
+
`script_relevance.py` cross-references three signals per script — the
|
|
90
|
+
authored `status`, git last-touched age (`--stale-days`, default 120), and
|
|
91
|
+
whether any other tracked file references the script — and emits a JSON
|
|
92
|
+
report with a `keep` / `review` / `attic` verdict each. It is **read-only**:
|
|
93
|
+
it never moves a file. Run it before a deprecation sweep, or as a periodic
|
|
94
|
+
hygiene check as `scripts/` scales.
|
|
95
|
+
|
|
96
|
+
## Phase A: orchestrator + plan tooling (pre-existing)
|
|
97
|
+
|
|
98
|
+
| Script | Purpose |
|
|
99
|
+
|---|---|
|
|
100
|
+
| `write_run_entry.py` | Atomic Review-F writer for `state.json.runs[]` |
|
|
101
|
+
| `plan_verify.py` | Deterministic plan grep-rules verifier |
|
|
102
|
+
| `version_advisor.py` | Suggest semver bumps based on `release-pending.md` |
|
|
103
|
+
| `ux_triage.py` | Sub-step D Gates 7/8 UX triage and UI coverage-gap queueing |
|
|
104
|
+
| `ibr_quickpass.py` | Legacy explicit-only helper for user-requested IBR suite runs |
|
|
105
|
+
| `optimize_loop.py`, `optimize_doe.py`, `metric_runner.py` | Optimization runner + DOE |
|
|
106
|
+
| `systemic_rca_eval.py` | Experimental scorer for system-level RCA report shape: plain-language lead, failure-map depth, system-control terminal cause, evidence, tradeoffs/impact, and prevention control |
|
|
107
|
+
| `systemic_rca_doe.py` | Experimental packet builder and results scorer for the systemic RCA DOE matrix |
|
|
108
|
+
| `sync_skills.py`, `check_cache_sync.py`, `sync_plugin_cache.py` | Native-skill drift detector + cache hygiene; committed-HEAD plugin cache sync for Claude/Codex |
|
|
109
|
+
| `transcript-pattern-miner.py` | Read-only transcript miner |
|
|
110
|
+
| `archive_project_plan.py` | Archives ephemeral `.build-loop` project plans into build-loop-memory before optional local removal |
|
|
111
|
+
| `install_memory.py` | Bootstraps `build-loop-memory` from a manifest-backed public seed; `--guided` walks a terminal-first install and `--validate-seed` checks privacy/package safety |
|
|
112
|
+
| `research_trigger.py` | Classifies when Research plugin work is required, selects depth from trigger/risk/t-shirt signals, and caches the Phase 1 research gate |
|
|
113
|
+
| `dogfood_reload_checkpoint.py` | Detects runtime-changing self-work and records stop/reload/resume checkpoint ACKs or fallbacks |
|
|
114
|
+
| `task_surface.py` | Emits the canonical read-only active task view from existing execution state, local queues, and project memory backlog |
|
|
115
|
+
| `dispatch_identity.py` | Generates/validates `t-<8hex>` dispatch task ids for subagent briefs and cost-ledger joins |
|
|
116
|
+
| `model_overrides.py` | Resolves `thinking`/`code`/`pattern` tiers to concrete model ids from `.build-loop/config.json`, state, or fallback |
|
|
117
|
+
| `coordination_status.py` | Cheap multi-agent coordination sensor: Rally Point peers, overlaps, task-heartbeat health, latest verdicts, dirty files → `clear | warn | blocked` JSON |
|
|
118
|
+
| `coordination_rally.py` | Lightweight Rally Point rally publisher: presence + handoff without creating a coordination file |
|
|
119
|
+
| `coordination_watch.py` | Compatibility entrypoint for the embedded `agent_rally_watcher` loop; polls `coordination_status.py` and prints only state transitions, including direct/broadcast inbox unread count |
|
|
120
|
+
| `agent_rally_watcher/watch.py` | Namespaced watcher implementation for future `agent-rally-watcher` extraction |
|
|
121
|
+
| `rally_point/boundary.py` | Validates `rally_point/plugin_boundary.json`, the embedded agent-rally extraction contract |
|
|
122
|
+
| `rally_point/hooks.py` | Namespaced implementation behind the Rally Point shell hook wrappers |
|
|
123
|
+
| `rally_point/inbox.py` | Inbox API at `apps/<slug>/inbox/<tool>.jsonl` plus common `inbox/all.jsonl`, optional `changes.jsonl` mirror, and session ack cursors under `inbox/.acks/` |
|
|
124
|
+
| `rally_point/task_heartbeat.py` | Append-only long-running task check-ins that distinguish process liveness from still-on-task health |
|
|
125
|
+
|
|
126
|
+
## Phase B: repo-local memory, canonicalized outside the repo (added 2026-05-04)
|
|
127
|
+
|
|
128
|
+
The four-memory-types framework. Files canonical (markdown + JSONL +
|
|
129
|
+
YAML), Postgres + pgvector as the index/retrieval sidecar.
|
|
130
|
+
|
|
131
|
+
### Phase 1 — file foundation (stdlib only, no DB)
|
|
132
|
+
|
|
133
|
+
| Script | Purpose |
|
|
134
|
+
|---|---|
|
|
135
|
+
| `write_decision.py` | Atomic MADR writer; mirrors `write_run_entry.py` atomicity contract. Writes canonical decision file + INDEX + repo-local `.build-loop/events.jsonl` as a unit. |
|
|
136
|
+
| `regenerate_knowledge_index.py` | Legacy frontmatter-rollup helper for pre-cutover repo-local memory directories. New canonical decision indexes are regenerated by `write_decision.py`. |
|
|
137
|
+
| `validate_knowledge.py` | Frontmatter shape, controlled-vocab, supersession-link validation. |
|
|
138
|
+
| `migrate_feedback_to_decisions.py` | One-shot: `.build-loop/feedback.md` → canonical `build-loop-memory/projects/<project>/decisions/*.md` (confidence: confirmed, source: migration). |
|
|
139
|
+
| `migrate_playbooks_to_procedural.py` | Legacy one-shot for moving debugging-memory playbooks into the pre-cutover procedural store. |
|
|
140
|
+
| `test_write_decision.py`, `test_regenerate_knowledge_index.py`, `test_validate_knowledge.py` | Phase 1 tests. |
|
|
141
|
+
|
|
142
|
+
### Phase 2 — Postgres + pgvector + retrieval
|
|
143
|
+
|
|
144
|
+
DB-side scripts use `psycopg[binary]` (added 2026-05-04 during Phase 3
|
|
145
|
+
hardening) for a persistent connection per script invocation. The
|
|
146
|
+
helper module `scripts/db.py` wraps `psycopg.connect()` and caches the
|
|
147
|
+
connection at module scope; `atexit` closes it on process termination.
|
|
148
|
+
|
|
149
|
+
| Script | Purpose |
|
|
150
|
+
|---|---|
|
|
151
|
+
| `db.py` | psycopg helper. `get_connection()`, `execute()`, `execute_many()`, `query()`, `query_one()`, `vector_literal()`. Handles `~/.config/agent-memory/connection.env` resolution and `DATABASE_URL` env override. |
|
|
152
|
+
| `init_agent_memory_schema.sql` | Apply with `psql -d agent_memory -f scripts/init_agent_memory_schema.sql`. Idempotent. Creates `build_loop_memory` schema. Per-project copy this file and rename schema. |
|
|
153
|
+
| `recall.py` | Hybrid retrieval (cosine + pg_trgm + ts_rank). Embeds query via `embed_backend.embed`, returns ~500–1500 token summary. |
|
|
154
|
+
| `sync_db_from_files.py` | Rebuild Postgres state from canonical markdown. Idempotent. `--rebuild` truncates first. |
|
|
155
|
+
| `embed_backend.py` | Embedding abstraction. MLX `mxbai-embed-large-v1` default, Ollama `mxbai-embed-large` fallback, both 1024-dim. See "Embedding backend" below. |
|
|
156
|
+
| `migrate_schema_to_1024.sql` | One-shot schema migration from VECTOR(768) → VECTOR(1024). Idempotent. Run once per project, then `sync_db_from_files.py --rebuild` to repopulate. |
|
|
157
|
+
| `test_init_schema.py`, `test_recall.py`, `test_sync_db_from_files.py`, `test_embed_backend.py` | Phase 2 tests. Each uses a temporary test schema (`test_schema_*`) so they don't touch production data. |
|
|
158
|
+
|
|
159
|
+
### Phase 3 — live integration tests
|
|
160
|
+
|
|
161
|
+
Phase 3 (2026-05-04) replaced the prior `--mock-llm-output` test
|
|
162
|
+
fixtures with real ollama integration tests, plus added two new test
|
|
163
|
+
scripts:
|
|
164
|
+
|
|
165
|
+
| Script | Purpose |
|
|
166
|
+
|---|---|
|
|
167
|
+
| `test_dedup_path.py` | Live cosine-similarity dedup test. Seeds a known fact via psycopg, asserts a paraphrase classifies as duplicate (≥ 0.85) and an unrelated string does not. Uses `embed_backend.embed` (MLX default, Ollama fallback, 1024-dim). |
|
|
168
|
+
| `test_stop_hook_integration.py` | End-to-end test of the Stop hook. Synthesizes a transcript, invokes the exact command from `hooks/hooks.json` via `/bin/sh`, verifies the live `qwen3:8b-q4_K_M` extraction produces ≥ 1 captured artifact. |
|
|
169
|
+
| `test_scan_transcript_for_decisions.py` | Rewritten to call live `qwen3:8b-q4_K_M` via the ollama HTTP API rather than the legacy `--mock-llm-output` fixture. The script's `--mock-llm-output` flag remains for developer convenience but the test suite no longer uses it. |
|
|
170
|
+
|
|
171
|
+
### Database driver decision
|
|
172
|
+
|
|
173
|
+
**Choice (2026-05-04): `psycopg[binary]` with persistent connection.**
|
|
174
|
+
|
|
175
|
+
Rationale:
|
|
176
|
+
|
|
177
|
+
- Per-query latency: psycopg `SELECT 1` ≈ 0.2ms vs psql subprocess fork ≈ 20ms (measured on this host). Stop-hook tier-3 batches can write 10–30 decisions per session; the 100x speedup matters at scale.
|
|
178
|
+
- `db.py` exposes parameterized queries (`%s` placeholders) end-to-end. No more SQL-string interpolation of user-provided values.
|
|
179
|
+
- Native vector handling via `vector_literal()` + explicit `::vector` cast. No extra `pgvector-python` dep needed.
|
|
180
|
+
- Single dep adds 5 MB; install path is well-documented (uv or pip with PEP 668 override on Homebrew Python).
|
|
181
|
+
|
|
182
|
+
Connection config: `~/.config/agent-memory/connection.env` exports
|
|
183
|
+
`DATABASE_URL=postgresql://<local-user>@localhost:5432/agent_memory`.
|
|
184
|
+
|
|
185
|
+
#### Install
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
# Preferred: uv (matches the user's uv-by-default policy)
|
|
189
|
+
uv pip install --system -r requirements.txt
|
|
190
|
+
|
|
191
|
+
# Or pip with PEP 668 override (Homebrew Python)
|
|
192
|
+
pip3 install --break-system-packages -r requirements.txt
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### Embedding backend
|
|
196
|
+
|
|
197
|
+
Embeddings flow through `scripts/embed_backend.py`, which exposes a
|
|
198
|
+
single `embed(text)` function (single-string or list-of-strings) and
|
|
199
|
+
returns 1024-dim Python `list[float]`. Two backends are supported, both
|
|
200
|
+
producing the **same dimension and same base weights** so cross-backend
|
|
201
|
+
cosine similarity stays high (measured 0.9664–0.9697 on identical
|
|
202
|
+
text):
|
|
203
|
+
|
|
204
|
+
| Backend | Default model | Per-call (warm) | Batch=10 amortized |
|
|
205
|
+
|---|---|---|---|
|
|
206
|
+
| `mlx` (default) | `mlx-community/mxbai-embed-large-v1` | ~10ms | ~2ms |
|
|
207
|
+
| `ollama` (fallback) | `mxbai-embed-large` | ~15ms | ~15ms (no native batch) |
|
|
208
|
+
|
|
209
|
+
Selection: `$EMBED_BACKEND` ∈ {`mlx`, `ollama`}, default `mlx`. Override
|
|
210
|
+
the model with `$EMBED_MODEL`. On Linux (or wherever
|
|
211
|
+
`mlx-embeddings` cannot be imported), the module logs a warning and
|
|
212
|
+
falls through to Ollama for the rest of the process. Once fallen
|
|
213
|
+
through, MLX is not retried — keeps stop-hook latency predictable.
|
|
214
|
+
|
|
215
|
+
First-run model download (`mlx-community/mxbai-embed-large-v1`,
|
|
216
|
+
~9 files, ~150 MB) adds about 17 seconds one-time. Cold start with
|
|
217
|
+
warm cache is ~220 ms per process; production scripts amortize this
|
|
218
|
+
across many calls within one process.
|
|
219
|
+
|
|
220
|
+
The schema column is `VECTOR(1024)` for `episode_events.embedding`,
|
|
221
|
+
`semantic_facts.embedding`, and `procedures.embedding`. To migrate an
|
|
222
|
+
existing 768-dim project, run `migrate_schema_to_1024.sql` then
|
|
223
|
+
`sync_db_from_files.py --rebuild` to repopulate.
|
|
224
|
+
|
|
225
|
+
Why same-base-weights matters: if you embed query text with MLX while
|
|
226
|
+
the seeded rows were embedded with Ollama (or vice versa), cosine
|
|
227
|
+
distances stay in the same numerical regime. You can switch backends
|
|
228
|
+
mid-flight without re-embedding the whole DB. The 0.9664 baseline is
|
|
229
|
+
"different code paths producing the same embedding modulo bf16
|
|
230
|
+
quantization on the MLX side" — not "different models that happen to
|
|
231
|
+
agree."
|
|
232
|
+
|
|
233
|
+
The `scan_transcript_for_decisions.py` extraction step uses
|
|
234
|
+
`qwen3:8b-q4_K_M` via the ollama HTTP API (`POST /api/generate` with
|
|
235
|
+
`stream: false`, `think: false`). The HTTP path is preferred over
|
|
236
|
+
`ollama run <model>` because the CLI emits TTY-aware streaming output
|
|
237
|
+
(cursor-back / erase-line escape codes) that corrupt JSON spans even
|
|
238
|
+
when stdout is piped.
|
|
239
|
+
|
|
240
|
+
#### Stop-hook hardening contract
|
|
241
|
+
|
|
242
|
+
The Stop hook can never disrupt a coding session. The script enforces:
|
|
243
|
+
|
|
244
|
+
- **Wall-clock budget** — default 25s (override via env `SCAN_BUDGET_S`).
|
|
245
|
+
Checked before the LLM call and between writes; on overrun the script
|
|
246
|
+
logs `budget exceeded` and exits 0 with whatever was already written.
|
|
247
|
+
The Claude Code hook timeout (60s) is a backstop, not the primary control.
|
|
248
|
+
- **Single-flight lock** — Python `fcntl.flock` on
|
|
249
|
+
`/tmp/build-loop-scan.lock` (override via `--lock-file`). A second
|
|
250
|
+
concurrent scan exits 0 immediately with a log line. This is portable
|
|
251
|
+
on macOS (which doesn't ship `flock(1)`).
|
|
252
|
+
- **Output suppression** — the hook command in `hooks/hooks.json`
|
|
253
|
+
redirects both stdout and stderr to `/dev/null`. The durable record is
|
|
254
|
+
the log file at `${XDG_STATE_HOME:-$HOME/.local/state}/build-loop/scan.log`
|
|
255
|
+
(override via `--log-file`). The log auto-rotates when it exceeds
|
|
256
|
+
10 MB (last 1 MB kept).
|
|
257
|
+
- **Per-session opt-out** — `touch .build-loop/.no-capture` in the project
|
|
258
|
+
root to skip the auto-capture sweep for the current session. Remove
|
|
259
|
+
the file to re-enable.
|
|
260
|
+
|
|
261
|
+
### Required runtime services
|
|
262
|
+
|
|
263
|
+
All Phase 2 / Phase 3 tests require:
|
|
264
|
+
|
|
265
|
+
1. **Postgres 15+** with `vector` and `pg_trgm` extensions, and the
|
|
266
|
+
`agent_memory.build_loop_memory` schema initialized from
|
|
267
|
+
`scripts/init_agent_memory_schema.sql`.
|
|
268
|
+
2. **Ollama daemon** (`ollama serve`) running on
|
|
269
|
+
`http://127.0.0.1:11434` with these models pulled:
|
|
270
|
+
```bash
|
|
271
|
+
ollama pull qwen3:8b-q4_K_M # decision extraction
|
|
272
|
+
ollama pull mxbai-embed-large # embedding fallback (1024-dim)
|
|
273
|
+
```
|
|
274
|
+
3. **`psycopg[binary]`** installed (`uv pip install -r requirements.txt`).
|
|
275
|
+
4. **`mlx-embeddings`** (macOS only; default embedding backend):
|
|
276
|
+
```bash
|
|
277
|
+
uv pip install --system mlx-embeddings
|
|
278
|
+
# First call lazy-downloads mlx-community/mxbai-embed-large-v1 (~150 MB).
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
The tests do not skip if these are missing — they fail loud, because
|
|
282
|
+
silent skips hide real config problems in CI.
|
|
283
|
+
|
|
284
|
+
### Running everything
|
|
285
|
+
|
|
286
|
+
```bash
|
|
287
|
+
# Phase 1 tests (no DB needed)
|
|
288
|
+
for t in scripts/test_write_decision.py scripts/test_regenerate_knowledge_index.py scripts/test_validate_knowledge.py; do
|
|
289
|
+
python3 "$t"
|
|
290
|
+
done
|
|
291
|
+
|
|
292
|
+
# Phase 2 tests (require Postgres + Ollama)
|
|
293
|
+
for t in scripts/test_init_schema.py scripts/test_recall.py scripts/test_sync_db_from_files.py; do
|
|
294
|
+
python3 "$t"
|
|
295
|
+
done
|
|
296
|
+
|
|
297
|
+
# Phase 3 tests (require Postgres + Ollama with qwen3:8b-q4_K_M and nomic-embed-text)
|
|
298
|
+
for t in scripts/test_scan_transcript_for_decisions.py scripts/test_dedup_path.py scripts/test_stop_hook_integration.py; do
|
|
299
|
+
python3 "$t"
|
|
300
|
+
done
|
|
301
|
+
```
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# SPDX-FileCopyrightText: 2025-2026 Tyrone Ross, Jr <46267523+tyroneross@users.noreply.github.com>
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
"""Shared Postgres DB-URL resolver. Stdlib-only, import-safe.
|
|
5
|
+
|
|
6
|
+
Single source of truth for connection-string resolution across the repo's
|
|
7
|
+
DB-touching scripts. Deliberately imports only ``os`` and ``pathlib`` so it
|
|
8
|
+
is safe to import from modules that must stay stdlib-only at import time
|
|
9
|
+
(e.g. ``memory_facade.py``, which cannot import ``db.py`` because ``db.py``
|
|
10
|
+
imports ``psycopg`` at module top).
|
|
11
|
+
|
|
12
|
+
Resolution order (precedence is intentional):
|
|
13
|
+
1. ``$BUILD_LOOP_DATABASE_URL`` — build-loop-namespaced override, wins
|
|
14
|
+
when set so the in-progress env-var rename is forward-compatible.
|
|
15
|
+
2. ``$DATABASE_URL`` — legacy/default var; existing setups
|
|
16
|
+
keep working.
|
|
17
|
+
3. ``~/.config/agent-memory/connection.env`` line ``DATABASE_URL=...``
|
|
18
|
+
— file fallback for machines that configure the DSN there.
|
|
19
|
+
|
|
20
|
+
Returns ``""`` (never raises) when none are configured. Callers that need
|
|
21
|
+
raise-on-missing semantics (e.g. ``db.py:_read_db_url``) wrap the empty
|
|
22
|
+
return themselves.
|
|
23
|
+
"""
|
|
24
|
+
from __future__ import annotations
|
|
25
|
+
|
|
26
|
+
import os
|
|
27
|
+
from pathlib import Path
|
|
28
|
+
|
|
29
|
+
CONNECTION_ENV = Path(".config") / "agent-memory" / "connection.env"
|
|
30
|
+
|
|
31
|
+
# Human-readable cause used by non-raising callers when resolution fails.
|
|
32
|
+
NO_URL_REASON = (
|
|
33
|
+
"no DB URL (BUILD_LOOP_DATABASE_URL / DATABASE_URL / connection.env all unset)"
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def resolve_db_url() -> str:
|
|
38
|
+
"""Return a DSN per the documented precedence, or ``""`` if none set.
|
|
39
|
+
|
|
40
|
+
Never raises. Honors ``$HOME`` (via ``Path.home()``) so test fixtures
|
|
41
|
+
can isolate the ``connection.env`` probe with a temporary HOME.
|
|
42
|
+
"""
|
|
43
|
+
url = os.environ.get("BUILD_LOOP_DATABASE_URL", "").strip()
|
|
44
|
+
if url:
|
|
45
|
+
return url
|
|
46
|
+
|
|
47
|
+
url = os.environ.get("DATABASE_URL", "").strip()
|
|
48
|
+
if url:
|
|
49
|
+
return url
|
|
50
|
+
|
|
51
|
+
conn_env = Path.home() / CONNECTION_ENV
|
|
52
|
+
try:
|
|
53
|
+
if conn_env.exists():
|
|
54
|
+
for line in conn_env.read_text(encoding="utf-8").splitlines():
|
|
55
|
+
line = line.strip()
|
|
56
|
+
if line.startswith("DATABASE_URL="):
|
|
57
|
+
return line.split("=", 1)[1].strip()
|
|
58
|
+
except OSError:
|
|
59
|
+
return ""
|
|
60
|
+
|
|
61
|
+
return ""
|