freeharness 0.4.1
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/LICENSE +21 -0
- package/NOTICE +108 -0
- package/README.md +134 -0
- package/canonical/HARVEST.yaml +858 -0
- package/canonical/PROVENANCE.yaml +740 -0
- package/canonical/agents/README.md +95 -0
- package/canonical/agents/agentic-architect.md +18 -0
- package/canonical/agents/database-reviewer.md +41 -0
- package/canonical/agents/explorer-ai-engineer-analyst.md +65 -0
- package/canonical/agents/pr-reviewer.md +96 -0
- package/canonical/agents/python-reviewer.md +55 -0
- package/canonical/agents/report-formatter.md +19 -0
- package/canonical/agents/security-reviewer.md +53 -0
- package/canonical/agents/test-writer.md +34 -0
- package/canonical/commands/fh-context.md +37 -0
- package/canonical/evals/promptfoo.redteam.yaml +108 -0
- package/canonical/hooks/cost-prices.json +14 -0
- package/canonical/hooks/freeharness-auto-memory.mjs +158 -0
- package/canonical/hooks/freeharness-config-guard.mjs +162 -0
- package/canonical/hooks/freeharness-context-monitor.mjs +198 -0
- package/canonical/hooks/freeharness-converge.mjs +227 -0
- package/canonical/hooks/freeharness-cost-tracker.mjs +1027 -0
- package/canonical/hooks/freeharness-memory-guard.mjs +57 -0
- package/canonical/hooks/freeharness-output-pruner.mjs +333 -0
- package/canonical/hooks/freeharness-precompact.mjs +323 -0
- package/canonical/hooks/freeharness-repeat-tool.mjs +208 -0
- package/canonical/hooks/freeharness-security-guidance.mjs +164 -0
- package/canonical/hooks/freeharness-session-start +583 -0
- package/canonical/hooks/hooks.auto-memory.claude-code.json +16 -0
- package/canonical/hooks/hooks.claude-code.json +17 -0
- package/canonical/hooks/hooks.config-guard.claude-code.json +16 -0
- package/canonical/hooks/hooks.context-monitor.claude-code.json +15 -0
- package/canonical/hooks/hooks.converge.claude-code.json +15 -0
- package/canonical/hooks/hooks.cost-tracker.claude-code.json +37 -0
- package/canonical/hooks/hooks.memory-guard.claude-code.json +16 -0
- package/canonical/hooks/hooks.output-pruner.claude-code.json +16 -0
- package/canonical/hooks/hooks.precompact.claude-code.json +15 -0
- package/canonical/hooks/hooks.repeat-tool.claude-code.json +25 -0
- package/canonical/hooks/hooks.security-guidance.claude-code.json +16 -0
- package/canonical/mcp/servers.json +20 -0
- package/canonical/openspec/config.base.yaml +89 -0
- package/canonical/openspec/schema.spec-driven.yaml +277 -0
- package/canonical/openspec/templates/data-contract.md +36 -0
- package/canonical/openspec/templates/design.md +84 -0
- package/canonical/openspec/templates/eval-plan.md +33 -0
- package/canonical/openspec/templates/follow-ups.md +2 -0
- package/canonical/openspec/templates/proposal.md +45 -0
- package/canonical/openspec/templates/spec.md +42 -0
- package/canonical/openspec/templates/tasks.md +38 -0
- package/canonical/profiles/local-llamacpp.LOCAL-MODELS.md +47 -0
- package/canonical/profiles/local-llamacpp.json +27 -0
- package/canonical/profiles/local-ollama.json +20 -0
- package/canonical/profiles/mcp.json +91 -0
- package/canonical/rules/CLAUDE.md +78 -0
- package/canonical/rules/project-CLAUDE.template.md +62 -0
- package/canonical/rules/routing.md +20 -0
- package/canonical/rules/safety.md +41 -0
- package/canonical/settings/settings.cache-hygiene.claude-code.json +5 -0
- package/canonical/skills/agent-evaluation/SKILL.md +102 -0
- package/canonical/skills/agent-evaluation/assets/evaluation_report_template.md +206 -0
- package/canonical/skills/agent-evaluation/evals/cases.yaml +106 -0
- package/canonical/skills/agent-evaluation/references/dataset-preparation.md +351 -0
- package/canonical/skills/agent-evaluation/references/scorers-constraints.md +165 -0
- package/canonical/skills/agent-evaluation/references/scorers.md +431 -0
- package/canonical/skills/agent-evaluation/references/setup-guide.md +252 -0
- package/canonical/skills/agent-evaluation/references/tracing-integration.md +164 -0
- package/canonical/skills/agent-evaluation/references/troubleshooting.md +514 -0
- package/canonical/skills/agent-evaluation/scripts/analyze_results.py +462 -0
- package/canonical/skills/agent-evaluation/scripts/create_dataset_template.py +382 -0
- package/canonical/skills/agent-evaluation/scripts/list_datasets.py +273 -0
- package/canonical/skills/agent-evaluation/scripts/run_evaluation_template.py +309 -0
- package/canonical/skills/agent-evaluation/scripts/setup_mlflow.py +353 -0
- package/canonical/skills/agent-evaluation/scripts/utils/__init__.py +27 -0
- package/canonical/skills/agent-evaluation/scripts/utils/env_validation.py +123 -0
- package/canonical/skills/agent-evaluation/scripts/utils/tracing_utils.py +108 -0
- package/canonical/skills/agent-evaluation/scripts/validate_agent_tracing.py +148 -0
- package/canonical/skills/agent-evaluation/scripts/validate_auth.py +240 -0
- package/canonical/skills/agent-evaluation/scripts/validate_environment.py +185 -0
- package/canonical/skills/agent-evaluation/scripts/validate_tracing_runtime.py +318 -0
- package/canonical/skills/agentic-architecture/SKILL.md +41 -0
- package/canonical/skills/agentic-architecture/evals/cases.yaml +94 -0
- package/canonical/skills/agentic-architecture/reference/context-engineering.md +75 -0
- package/canonical/skills/agentic-architecture/reference/patterns.md +76 -0
- package/canonical/skills/agentic-architecture/reference/reliability-observability.md +94 -0
- package/canonical/skills/agentic-architecture/reference/review-framework.md +59 -0
- package/canonical/skills/code-review/SKILL.md +52 -0
- package/canonical/skills/code-review/evals/cases.yaml +197 -0
- package/canonical/skills/git-workflow/SKILL.md +41 -0
- package/canonical/skills/git-workflow/evals/cases.yaml +92 -0
- package/canonical/skills/local-code/SKILL.md +24 -0
- package/canonical/skills/local-code/evals/cases.yaml +85 -0
- package/canonical/skills/local-code/scripts/query_llama.py +68 -0
- package/canonical/skills/report-formatting/SKILL.md +62 -0
- package/canonical/skills/report-formatting/evals/cases.yaml +83 -0
- package/canonical/skills/report-formatting/reference/ARCHITECTURE.md +135 -0
- package/canonical/skills/report-formatting/reference/HELPERS.md +120 -0
- package/canonical/skills/report-formatting/reference/PPTX.md +136 -0
- package/canonical/skills/report-formatting/reference/RELEASE.md +99 -0
- package/canonical/skills/report-formatting/reference/TEMPLATES.md +48 -0
- package/canonical/skills/report-formatting/reference/authoring.md +66 -0
- package/canonical/skills/report-formatting/scripts/architecture-template.md +271 -0
- package/canonical/skills/report-formatting/scripts/assets/claro-logo.png +0 -0
- package/canonical/skills/report-formatting/scripts/assets/claro-wordmark.svg +1 -0
- package/canonical/skills/report-formatting/scripts/build-architecture.js +57 -0
- package/canonical/skills/report-formatting/scripts/build-md-claro.js +224 -0
- package/canonical/skills/report-formatting/scripts/build-release.js +51 -0
- package/canonical/skills/report-formatting/scripts/check-env.js +58 -0
- package/canonical/skills/report-formatting/scripts/docmodel.js +283 -0
- package/canonical/skills/report-formatting/scripts/example-build.js +119 -0
- package/canonical/skills/report-formatting/scripts/example_build_ArchitectureReview_docx.js +195 -0
- package/canonical/skills/report-formatting/scripts/example_build_ExecutiveReport_docx.js +114 -0
- package/canonical/skills/report-formatting/scripts/package.json +17 -0
- package/canonical/skills/report-formatting/scripts/pptx/example_build_StatusReport_pptx.py +223 -0
- package/canonical/skills/report-formatting/scripts/pptx/example_build_WeeklyStatus_pptx.py +245 -0
- package/canonical/skills/report-formatting/scripts/pptx/pptx_office.py +144 -0
- package/canonical/skills/report-formatting/scripts/pptx/requirements.txt +7 -0
- package/canonical/skills/report-formatting/scripts/pptx/status_report_blocks.py +193 -0
- package/canonical/skills/report-formatting/scripts/pptx/theme_claro_pptx.py +473 -0
- package/canonical/skills/report-formatting/scripts/release-template.md +80 -0
- package/canonical/skills/report-formatting/scripts/render-mermaid.js +105 -0
- package/canonical/skills/report-formatting/scripts/theme-claro.js +403 -0
- package/canonical/skills/subagent-driven-development/SKILL.md +60 -0
- package/canonical/skills/subagent-driven-development/evals/cases.yaml +208 -0
- package/canonical/skills/subagent-driven-development/reference/brief.md +91 -0
- package/canonical/skills/subagent-driven-development/reference/handoff.md +118 -0
- package/canonical/skills/subagent-driven-development/scripts/validate-handoff.mjs +850 -0
- package/canonical/skills/systematic-debugging/SKILL.md +44 -0
- package/canonical/skills/systematic-debugging/evals/cases.yaml +90 -0
- package/canonical/skills/test-driven-development/SKILL.md +42 -0
- package/canonical/skills/test-driven-development/evals/cases.yaml +86 -0
- package/canonical/skills/test-driven-development/reference/writing-good-tests.md +52 -0
- package/canonical/skills/verification-before-completion/SKILL.md +53 -0
- package/canonical/skills/verification-before-completion/evals/cases.yaml +107 -0
- package/dist/adapters/content/language-lint.d.ts +46 -0
- package/dist/adapters/content/language-lint.js +191 -0
- package/dist/adapters/harness/claude-code.d.ts +57 -0
- package/dist/adapters/harness/claude-code.js +385 -0
- package/dist/adapters/harness/index.d.ts +3 -0
- package/dist/adapters/harness/index.js +17 -0
- package/dist/adapters/harness/opencode.d.ts +7 -0
- package/dist/adapters/harness/opencode.js +166 -0
- package/dist/adapters/harness/plugin.d.ts +22 -0
- package/dist/adapters/harness/plugin.js +257 -0
- package/dist/adapters/memory/doctor.d.ts +480 -0
- package/dist/adapters/memory/doctor.js +1217 -0
- package/dist/adapters/memory/vendored.d.ts +150 -0
- package/dist/adapters/memory/vendored.js +487 -0
- package/dist/adapters/package/node.d.ts +9 -0
- package/dist/adapters/package/node.js +20 -0
- package/dist/adapters/prompt/readline.d.ts +19 -0
- package/dist/adapters/prompt/readline.js +53 -0
- package/dist/adapters/sync/diff.d.ts +43 -0
- package/dist/adapters/sync/diff.js +380 -0
- package/dist/cli/cleanup.d.ts +86 -0
- package/dist/cli/cleanup.js +382 -0
- package/dist/cli/cost.d.ts +304 -0
- package/dist/cli/cost.js +501 -0
- package/dist/cli/doctor.d.ts +205 -0
- package/dist/cli/doctor.js +654 -0
- package/dist/cli/executor.d.ts +5 -0
- package/dist/cli/executor.js +48 -0
- package/dist/cli/plugin-validate.d.ts +37 -0
- package/dist/cli/plugin-validate.js +256 -0
- package/dist/cli/prefix.d.ts +68 -0
- package/dist/cli/prefix.js +218 -0
- package/dist/cli/profile.d.ts +170 -0
- package/dist/cli/profile.js +285 -0
- package/dist/cli/runner.d.ts +10 -0
- package/dist/cli/runner.js +27 -0
- package/dist/cli/uninstall.d.ts +65 -0
- package/dist/cli/uninstall.js +147 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +989 -0
- package/dist/infra/dogfood.d.ts +31 -0
- package/dist/infra/dogfood.js +51 -0
- package/dist/infra/fsutil.d.ts +40 -0
- package/dist/infra/fsutil.js +143 -0
- package/dist/infra/manifest.d.ts +76 -0
- package/dist/infra/manifest.js +92 -0
- package/dist/infra/paths.d.ts +19 -0
- package/dist/infra/paths.js +74 -0
- package/dist/infra/routing.d.ts +4 -0
- package/dist/infra/routing.js +7 -0
- package/node_modules/@freeharness/core/dist/context.d.ts +30 -0
- package/node_modules/@freeharness/core/dist/context.js +1 -0
- package/node_modules/@freeharness/core/dist/index.d.ts +5 -0
- package/node_modules/@freeharness/core/dist/index.js +6 -0
- package/node_modules/@freeharness/core/dist/planner.d.ts +13 -0
- package/node_modules/@freeharness/core/dist/planner.js +18 -0
- package/node_modules/@freeharness/core/dist/ports.d.ts +90 -0
- package/node_modules/@freeharness/core/dist/ports.js +1 -0
- package/node_modules/@freeharness/core/dist/registry.d.ts +41 -0
- package/node_modules/@freeharness/core/dist/registry.js +124 -0
- package/node_modules/@freeharness/core/dist/tiers.d.ts +30 -0
- package/node_modules/@freeharness/core/dist/tiers.js +99 -0
- package/node_modules/@freeharness/core/package.json +34 -0
- package/node_modules/@freeharness/sdd/PROVENANCE.yaml +175 -0
- package/node_modules/@freeharness/sdd/dist/src/bin/openspec.d.ts +2 -0
- package/node_modules/@freeharness/sdd/dist/src/bin/openspec.js +166 -0
- package/node_modules/@freeharness/sdd/dist/src/index.d.ts +14 -0
- package/node_modules/@freeharness/sdd/dist/src/index.js +11 -0
- package/node_modules/@freeharness/sdd/dist/src/init.d.ts +39 -0
- package/node_modules/@freeharness/sdd/dist/src/init.js +190 -0
- package/node_modules/@freeharness/sdd/dist/src/root-resolver.d.ts +8 -0
- package/node_modules/@freeharness/sdd/dist/src/root-resolver.js +32 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/archive.d.ts +81 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/archive.js +483 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/context.d.ts +4 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/context.js +48 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/follow-up.d.ts +57 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/follow-up.js +279 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/instructions.d.ts +67 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/instructions.js +460 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/list.d.ts +5 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/list.js +95 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/new-change.d.ts +6 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/new-change.js +150 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/schemas.d.ts +4 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/schemas.js +23 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/shared.d.ts +56 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/shared.js +140 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/status.d.ts +8 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/status.js +85 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/validate.d.ts +6 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/validate.js +229 -0
- package/node_modules/@freeharness/sdd/dist/src/validate-change.d.ts +40 -0
- package/node_modules/@freeharness/sdd/dist/src/validate-change.js +114 -0
- package/node_modules/@freeharness/sdd/dist/src/validate.d.ts +24 -0
- package/node_modules/@freeharness/sdd/dist/src/validate.js +72 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/apply/specs-apply.d.ts +130 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/apply/specs-apply.js +981 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/change-metadata.d.ts +46 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/change-metadata.js +128 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/change-status-policy.d.ts +26 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/change-status-policy.js +32 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/file-system.d.ts +50 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/file-system.js +394 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/global-config.d.ts +15 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/global-config.js +49 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/graph.d.ts +71 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/graph.js +164 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/index.d.ts +11 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/index.js +21 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/instruction-loader.d.ts +102 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/instruction-loader.js +230 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/outputs.d.ts +18 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/outputs.js +138 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/resolver.d.ts +82 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/resolver.js +333 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/schema.d.ts +12 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/schema.js +110 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/state.d.ts +11 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/state.js +32 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/task-progress.d.ts +33 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/task-progress.js +149 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/types.d.ts +39 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/types.js +49 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/adapters/claude.d.ts +12 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/adapters/claude.js +31 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/adapters/index.d.ts +10 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/adapters/index.js +10 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/adapters/opencode.d.ts +12 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/adapters/opencode.js +26 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/generator.d.ts +28 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/generator.js +41 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/index.d.ts +23 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/index.js +25 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/invocation.d.ts +72 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/invocation.js +76 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/registry.d.ts +39 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/registry.js +53 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/types.d.ts +62 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/types.js +7 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/yaml.d.ts +35 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/yaml.js +47 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-references.d.ts +33 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-references.js +55 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/shared/allowed-tools.d.ts +11 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/shared/allowed-tools.js +11 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/shared/skill-generation.d.ts +48 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/shared/skill-generation.js +99 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/skill-templates.d.ts +19 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/skill-templates.js +18 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/types.d.ts +18 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/types.js +4 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/apply-change.d.ts +19 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/apply-change.js +207 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/archive-change.d.ts +12 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/archive-change.js +409 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/bulk-archive-change.d.ts +9 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/bulk-archive-change.js +673 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/continue-change.d.ts +9 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/continue-change.js +230 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/explore.d.ts +12 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/explore.js +550 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/feedback.d.ts +8 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/feedback.js +107 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/ff-change.d.ts +12 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/ff-change.js +228 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/new-change.d.ts +9 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/new-change.js +147 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/onboard.d.ts +9 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/onboard.js +571 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/propose.d.ts +12 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/propose.js +322 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/store-selection.d.ts +7 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/store-selection.js +7 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/sync-specs.d.ts +9 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/sync-specs.js +518 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/update-change.d.ts +9 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/update-change.js +176 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/verify-change.d.ts +9 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/verify-change.js +344 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/constants.d.ts +39 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/constants.js +54 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/delta-resolution.d.ts +35 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/delta-resolution.js +171 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/change-parser.d.ts +27 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/change-parser.js +210 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/code-fence.d.ts +14 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/code-fence.js +48 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/markdown-parser.d.ts +22 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/markdown-parser.js +186 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/requirement-blocks.d.ts +65 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/requirement-blocks.js +409 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/requirement-text.d.ts +55 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/requirement-text.js +98 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/spec-structure.d.ts +8 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/spec-structure.js +77 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/purpose-placeholder.d.ts +44 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/purpose-placeholder.js +116 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/schemas/base.schema.d.ts +12 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/schemas/base.schema.js +17 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/schemas/change.schema.d.ts +72 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/schemas/change.schema.js +30 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/schemas/index.d.ts +3 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/schemas/index.js +3 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/schemas/spec.schema.d.ts +17 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/schemas/spec.schema.js +14 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/spec-discovery.d.ts +39 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/spec-discovery.js +114 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/task-lines.d.ts +45 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/task-lines.js +105 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/task-numbering.d.ts +15 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/task-numbering.js +56 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/types.d.ts +17 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/types.js +1 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/validator.d.ts +94 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/validator.js +756 -0
- package/node_modules/@freeharness/sdd/package.json +57 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/LICENSE.upstream +22 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/schema.upstream.yaml +232 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/README.md +19 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-apply-change/SKILL.md +187 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-archive-change/SKILL.md +181 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-bulk-archive-change/SKILL.md +338 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-continue-change/SKILL.md +117 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-explore/SKILL.md +342 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-ff-change/SKILL.md +116 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-new-change/SKILL.md +76 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-onboard/SKILL.md +560 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-propose/SKILL.md +162 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-sync-specs/SKILL.md +261 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-update-change/SKILL.md +90 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-verify-change/SKILL.md +174 -0
- package/package.json +70 -0
- package/provenance/canonical.PROVENANCE.yaml +740 -0
- package/provenance/claude-mem.LICENSE.upstream +202 -0
- package/provenance/memory.PROVENANCE.yaml +399 -0
- package/provenance/sdd.PROVENANCE.yaml +175 -0
- package/vendor-licenses/caveman.LICENSE +27 -0
- package/vendor-licenses/deepseek-harness.LICENSE +21 -0
- package/vendor-licenses/ecc.LICENSE +21 -0
- package/vendor-licenses/pi.LICENSE +21 -0
- package/vendor-licenses/superpowers.LICENSE +21 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"""Utilities for environment variable validation and MLflow configuration."""
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
|
|
5
|
+
from packaging import version
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def get_env_vars() -> dict[str, str | None]:
|
|
9
|
+
"""Get MLflow environment variables.
|
|
10
|
+
|
|
11
|
+
Returns:
|
|
12
|
+
Dictionary with tracking_uri and experiment_id (may be None)
|
|
13
|
+
"""
|
|
14
|
+
return {
|
|
15
|
+
"tracking_uri": os.getenv("MLFLOW_TRACKING_URI"),
|
|
16
|
+
"experiment_id": os.getenv("MLFLOW_EXPERIMENT_ID"),
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def validate_env_vars(
|
|
21
|
+
require_tracking_uri: bool = True, require_experiment_id: bool = True
|
|
22
|
+
) -> list[str]:
|
|
23
|
+
"""Validate required environment variables are set.
|
|
24
|
+
|
|
25
|
+
Args:
|
|
26
|
+
require_tracking_uri: If True, MLFLOW_TRACKING_URI must be set
|
|
27
|
+
require_experiment_id: If True, MLFLOW_EXPERIMENT_ID must be set
|
|
28
|
+
|
|
29
|
+
Returns:
|
|
30
|
+
List of error messages (empty if valid)
|
|
31
|
+
"""
|
|
32
|
+
errors = []
|
|
33
|
+
env_vars = get_env_vars()
|
|
34
|
+
|
|
35
|
+
if require_tracking_uri and not env_vars["tracking_uri"]:
|
|
36
|
+
errors.append("MLFLOW_TRACKING_URI is not set")
|
|
37
|
+
|
|
38
|
+
if require_experiment_id and not env_vars["experiment_id"]:
|
|
39
|
+
errors.append("MLFLOW_EXPERIMENT_ID is not set")
|
|
40
|
+
|
|
41
|
+
return errors
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def validate_mlflow_version(min_version: str = "3.8.0") -> tuple[bool, str]:
|
|
45
|
+
"""Check MLflow version compatibility.
|
|
46
|
+
|
|
47
|
+
Args:
|
|
48
|
+
min_version: Minimum required MLflow version
|
|
49
|
+
|
|
50
|
+
Returns:
|
|
51
|
+
Tuple of (is_valid, version_string)
|
|
52
|
+
"""
|
|
53
|
+
try:
|
|
54
|
+
import mlflow
|
|
55
|
+
|
|
56
|
+
current_version = mlflow.__version__
|
|
57
|
+
|
|
58
|
+
# Remove dev/rc suffixes for comparison
|
|
59
|
+
clean_version = current_version.split("dev")[0].split("rc")[0]
|
|
60
|
+
|
|
61
|
+
is_valid = version.parse(clean_version) >= version.parse(min_version)
|
|
62
|
+
return is_valid, current_version
|
|
63
|
+
except ImportError:
|
|
64
|
+
return False, "not installed"
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def test_mlflow_connection(tracking_uri: str, experiment_id: str) -> tuple[bool, str]:
|
|
68
|
+
"""Test connection to MLflow tracking server.
|
|
69
|
+
|
|
70
|
+
Args:
|
|
71
|
+
tracking_uri: MLflow tracking URI
|
|
72
|
+
experiment_id: MLflow experiment ID
|
|
73
|
+
|
|
74
|
+
Returns:
|
|
75
|
+
Tuple of (success, error_message_or_experiment_name)
|
|
76
|
+
"""
|
|
77
|
+
try:
|
|
78
|
+
from mlflow import MlflowClient
|
|
79
|
+
|
|
80
|
+
client = MlflowClient()
|
|
81
|
+
experiment = client.get_experiment(experiment_id)
|
|
82
|
+
|
|
83
|
+
if experiment:
|
|
84
|
+
return True, experiment.name
|
|
85
|
+
else:
|
|
86
|
+
return False, f"Experiment {experiment_id} not found"
|
|
87
|
+
except Exception as e:
|
|
88
|
+
return False, str(e)[:100]
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def check_databricks_config() -> tuple[bool, str | None]:
|
|
92
|
+
"""Check if running with Databricks configuration.
|
|
93
|
+
|
|
94
|
+
Returns:
|
|
95
|
+
Tuple of (is_databricks, profile_or_error_message)
|
|
96
|
+
"""
|
|
97
|
+
tracking_uri = os.getenv("MLFLOW_TRACKING_URI", "")
|
|
98
|
+
|
|
99
|
+
# Check if tracking URI indicates Databricks
|
|
100
|
+
if "databricks" in tracking_uri.lower():
|
|
101
|
+
# Extract profile if present
|
|
102
|
+
if "databricks://" in tracking_uri:
|
|
103
|
+
profile = tracking_uri.split("databricks://")[1] if len(tracking_uri.split("databricks://")) > 1 else "DEFAULT"
|
|
104
|
+
return True, profile
|
|
105
|
+
return True, "databricks"
|
|
106
|
+
|
|
107
|
+
# Check for Databricks SDK/CLI
|
|
108
|
+
try:
|
|
109
|
+
import subprocess
|
|
110
|
+
|
|
111
|
+
result = subprocess.run(
|
|
112
|
+
["databricks", "auth", "profiles"],
|
|
113
|
+
capture_output=True,
|
|
114
|
+
text=True,
|
|
115
|
+
timeout=5,
|
|
116
|
+
)
|
|
117
|
+
if result.returncode == 0:
|
|
118
|
+
profiles = [line.strip() for line in result.stdout.strip().split("\n") if line.strip()]
|
|
119
|
+
return True, profiles[0] if profiles else None
|
|
120
|
+
except (subprocess.TimeoutExpired, FileNotFoundError, subprocess.CalledProcessError):
|
|
121
|
+
pass
|
|
122
|
+
|
|
123
|
+
return False, None
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"""Utilities for tracing-related validation.
|
|
2
|
+
|
|
3
|
+
The coding agent should use Grep tool for discovery:
|
|
4
|
+
- Find autolog calls: grep -r "mlflow.*autolog" . --include="*.py"
|
|
5
|
+
- Find trace decorators: grep -r "@mlflow.trace" . --include="*.py"
|
|
6
|
+
- Find MLflow imports: grep -r "import mlflow" . --include="*.py"
|
|
7
|
+
|
|
8
|
+
This module provides validation helpers used by validation scripts.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import re
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def check_import_order(file_path: str, import_pattern: str = None) -> tuple[bool, str]:
|
|
16
|
+
"""Verify autolog is called before library/module imports.
|
|
17
|
+
|
|
18
|
+
Args:
|
|
19
|
+
file_path: Path to file containing autolog call
|
|
20
|
+
import_pattern: Optional regex pattern to match imports (e.g., r"from .* import")
|
|
21
|
+
If None, checks for any "from ... import" after autolog
|
|
22
|
+
|
|
23
|
+
Returns:
|
|
24
|
+
Tuple of (is_correct, message)
|
|
25
|
+
"""
|
|
26
|
+
try:
|
|
27
|
+
content = Path(file_path).read_text()
|
|
28
|
+
lines = content.split("\n")
|
|
29
|
+
|
|
30
|
+
autolog_line = None
|
|
31
|
+
first_import_line = None
|
|
32
|
+
|
|
33
|
+
for i, line in enumerate(lines, 1):
|
|
34
|
+
if "autolog()" in line:
|
|
35
|
+
autolog_line = i
|
|
36
|
+
# After finding autolog, look for any imports (customizable via pattern)
|
|
37
|
+
if autolog_line and "from" in line and "import" in line:
|
|
38
|
+
if import_pattern:
|
|
39
|
+
if re.search(import_pattern, line):
|
|
40
|
+
first_import_line = i
|
|
41
|
+
break
|
|
42
|
+
else:
|
|
43
|
+
first_import_line = i
|
|
44
|
+
break
|
|
45
|
+
|
|
46
|
+
if autolog_line and first_import_line:
|
|
47
|
+
if autolog_line < first_import_line:
|
|
48
|
+
return True, f"Autolog (line {autolog_line}) before imports (line {first_import_line})"
|
|
49
|
+
else:
|
|
50
|
+
return (
|
|
51
|
+
False,
|
|
52
|
+
f"Autolog (line {autolog_line}) after imports (line {first_import_line})",
|
|
53
|
+
)
|
|
54
|
+
elif autolog_line:
|
|
55
|
+
return True, f"Autolog found at line {autolog_line}"
|
|
56
|
+
else:
|
|
57
|
+
return False, "Autolog not found"
|
|
58
|
+
|
|
59
|
+
except Exception as e:
|
|
60
|
+
return True, f"Could not check import order: {e}" # Don't fail on errors
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def check_session_id_capture(file_path: str) -> bool:
|
|
66
|
+
"""Check if file has session ID tracking code.
|
|
67
|
+
|
|
68
|
+
Looks for: get_last_active_trace_id(), set_trace_tag(), session_id
|
|
69
|
+
|
|
70
|
+
Args:
|
|
71
|
+
file_path: Path to file to check
|
|
72
|
+
|
|
73
|
+
Returns:
|
|
74
|
+
True if all patterns found
|
|
75
|
+
"""
|
|
76
|
+
try:
|
|
77
|
+
content = Path(file_path).read_text()
|
|
78
|
+
|
|
79
|
+
session_patterns = [
|
|
80
|
+
r"mlflow\.get_last_active_trace_id\(\)",
|
|
81
|
+
r"mlflow\.set_trace_tag\(",
|
|
82
|
+
r"session_id",
|
|
83
|
+
]
|
|
84
|
+
|
|
85
|
+
return all(re.search(pattern, content) for pattern in session_patterns)
|
|
86
|
+
except Exception:
|
|
87
|
+
return False
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def verify_mlflow_imports(file_paths: list[str]) -> dict[str, bool]:
|
|
91
|
+
"""Check mlflow is imported in given files.
|
|
92
|
+
|
|
93
|
+
Args:
|
|
94
|
+
file_paths: List of file paths to check
|
|
95
|
+
|
|
96
|
+
Returns:
|
|
97
|
+
Dictionary mapping file_path to has_mlflow_import
|
|
98
|
+
"""
|
|
99
|
+
results = {}
|
|
100
|
+
|
|
101
|
+
for file_path in file_paths:
|
|
102
|
+
try:
|
|
103
|
+
content = Path(file_path).read_text()
|
|
104
|
+
results[file_path] = "import mlflow" in content
|
|
105
|
+
except Exception:
|
|
106
|
+
results[file_path] = False
|
|
107
|
+
|
|
108
|
+
return results
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
Validate MLflow tracing for your agent.
|
|
5
|
+
|
|
6
|
+
This is a template script. Fill in the TODO sections before running:
|
|
7
|
+
1. Update the import statement with your agent's module and function
|
|
8
|
+
2. Configure any dependencies (LLM providers, config, etc.)
|
|
9
|
+
3. Adjust the function call to match your agent's signature
|
|
10
|
+
4. Verify environment variables are set correctly
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
import os
|
|
14
|
+
import sys
|
|
15
|
+
import mlflow
|
|
16
|
+
from mlflow import MlflowClient
|
|
17
|
+
|
|
18
|
+
# TODO: Update these imports with your agent's module and entry point
|
|
19
|
+
# Example: from my_agent.agent import run_agent
|
|
20
|
+
from YOUR_MODULE import YOUR_ENTRY_POINT # <-- UPDATE THIS LINE
|
|
21
|
+
|
|
22
|
+
# Configuration
|
|
23
|
+
TEST_QUERY = "What is MLflow?"
|
|
24
|
+
TEST_SESSION_ID = "test-session-123"
|
|
25
|
+
|
|
26
|
+
# Verify environment variables
|
|
27
|
+
tracking_uri = os.getenv("MLFLOW_TRACKING_URI")
|
|
28
|
+
experiment_id = os.getenv("MLFLOW_EXPERIMENT_ID")
|
|
29
|
+
|
|
30
|
+
if not tracking_uri or not experiment_id:
|
|
31
|
+
print("✗ Missing required environment variables:")
|
|
32
|
+
print(" MLFLOW_TRACKING_URI:", tracking_uri or "(not set)")
|
|
33
|
+
print(" MLFLOW_EXPERIMENT_ID:", experiment_id or "(not set)")
|
|
34
|
+
print("\nRun scripts/setup_mlflow.py first")
|
|
35
|
+
sys.exit(1)
|
|
36
|
+
|
|
37
|
+
print("=" * 60)
|
|
38
|
+
print("MLflow Tracing Validation")
|
|
39
|
+
print("=" * 60)
|
|
40
|
+
print()
|
|
41
|
+
print(f"Tracking URI: {tracking_uri}")
|
|
42
|
+
print(f"Experiment ID: {experiment_id}")
|
|
43
|
+
print()
|
|
44
|
+
|
|
45
|
+
# TODO: Configure your agent's dependencies here
|
|
46
|
+
# IMPORTANT: Add any required setup before calling your agent
|
|
47
|
+
# Examples:
|
|
48
|
+
# from your_agent.llm import LLMConfig, LLMProvider
|
|
49
|
+
# llm_config = LLMConfig(model="gpt-4", temperature=0.0)
|
|
50
|
+
# llm_provider = LLMProvider(config=llm_config)
|
|
51
|
+
#
|
|
52
|
+
# from your_agent.config import AgentConfig
|
|
53
|
+
# agent_config = AgentConfig.from_env()
|
|
54
|
+
|
|
55
|
+
print("Running test query...")
|
|
56
|
+
print(f" Query: {TEST_QUERY}")
|
|
57
|
+
print(f" Session ID: {TEST_SESSION_ID}")
|
|
58
|
+
print()
|
|
59
|
+
|
|
60
|
+
try:
|
|
61
|
+
# TODO: Update this function call to match your agent's signature
|
|
62
|
+
# Examples:
|
|
63
|
+
# response = YOUR_ENTRY_POINT(TEST_QUERY, llm_provider)
|
|
64
|
+
# response = YOUR_ENTRY_POINT(TEST_QUERY, session_id=TEST_SESSION_ID)
|
|
65
|
+
# response = YOUR_ENTRY_POINT(TEST_QUERY, config=agent_config)
|
|
66
|
+
|
|
67
|
+
response = YOUR_ENTRY_POINT(TEST_QUERY) # <-- UPDATE THIS LINE
|
|
68
|
+
|
|
69
|
+
print("✓ Agent executed successfully")
|
|
70
|
+
print()
|
|
71
|
+
|
|
72
|
+
# Capture trace
|
|
73
|
+
trace_id = mlflow.get_last_active_trace_id()
|
|
74
|
+
if not trace_id:
|
|
75
|
+
print("✗ FAILED: No trace ID captured!")
|
|
76
|
+
print(" Check that mlflow.autolog() is called before agent execution")
|
|
77
|
+
sys.exit(1)
|
|
78
|
+
|
|
79
|
+
print(f"✓ Trace captured: {trace_id}")
|
|
80
|
+
|
|
81
|
+
# Get trace details
|
|
82
|
+
client = MlflowClient()
|
|
83
|
+
trace = client.get_trace(trace_id)
|
|
84
|
+
|
|
85
|
+
# Verify trace structure
|
|
86
|
+
print()
|
|
87
|
+
print("Verifying trace structure...")
|
|
88
|
+
|
|
89
|
+
if not trace.data.spans:
|
|
90
|
+
print("✗ FAILED: No spans found in trace")
|
|
91
|
+
sys.exit(1)
|
|
92
|
+
|
|
93
|
+
print(f"✓ Top-level span: {trace.data.spans[0].name} ({trace.data.spans[0].span_type})")
|
|
94
|
+
|
|
95
|
+
# Count total spans (including nested)
|
|
96
|
+
def count_spans(spans):
|
|
97
|
+
count = len(spans)
|
|
98
|
+
for span in spans:
|
|
99
|
+
if hasattr(span, 'spans') and span.spans:
|
|
100
|
+
count += count_spans(span.spans)
|
|
101
|
+
return count
|
|
102
|
+
|
|
103
|
+
total_spans = count_spans(trace.data.spans)
|
|
104
|
+
print(f"✓ Total spans: {total_spans}")
|
|
105
|
+
|
|
106
|
+
if total_spans < 2:
|
|
107
|
+
print("⚠ WARNING: Only 1 span found - autolog may not be working")
|
|
108
|
+
print(" Expected: @mlflow.trace decorator span + autolog library spans")
|
|
109
|
+
else:
|
|
110
|
+
print("✓ Multiple spans detected - autolog appears to be working")
|
|
111
|
+
|
|
112
|
+
# Print trace hierarchy
|
|
113
|
+
def print_hierarchy(spans, indent=0):
|
|
114
|
+
for span in spans:
|
|
115
|
+
prefix = " " + " " * indent
|
|
116
|
+
print(f"{prefix}- {span.name} ({span.span_type})")
|
|
117
|
+
if hasattr(span, 'spans') and span.spans:
|
|
118
|
+
print_hierarchy(span.spans, indent + 1)
|
|
119
|
+
|
|
120
|
+
print()
|
|
121
|
+
print(" Trace hierarchy:")
|
|
122
|
+
print_hierarchy(trace.data.spans)
|
|
123
|
+
|
|
124
|
+
# Check session ID (optional)
|
|
125
|
+
if "session_id" in trace.info.tags:
|
|
126
|
+
actual_session_id = trace.info.tags["session_id"]
|
|
127
|
+
print()
|
|
128
|
+
if actual_session_id == TEST_SESSION_ID:
|
|
129
|
+
print(f"✓ Session ID tagged: {actual_session_id}")
|
|
130
|
+
else:
|
|
131
|
+
print(f"⚠ Session ID mismatch: expected {TEST_SESSION_ID}, got {actual_session_id}")
|
|
132
|
+
else:
|
|
133
|
+
print()
|
|
134
|
+
print(" ℹ Note: No session_id tag found (optional for single-turn agents)")
|
|
135
|
+
|
|
136
|
+
print()
|
|
137
|
+
print("=" * 60)
|
|
138
|
+
print("✓ VALIDATION PASSED")
|
|
139
|
+
print("=" * 60)
|
|
140
|
+
print()
|
|
141
|
+
print("Your agent is properly integrated with MLflow tracing!")
|
|
142
|
+
print()
|
|
143
|
+
|
|
144
|
+
except Exception as e:
|
|
145
|
+
print(f"✗ FAILED: {str(e)}")
|
|
146
|
+
import traceback
|
|
147
|
+
traceback.print_exc()
|
|
148
|
+
sys.exit(1)
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Validate authentication for agent evaluation.
|
|
3
|
+
|
|
4
|
+
This script tests authentication to required services:
|
|
5
|
+
- MLflow tracking server (Databricks or local)
|
|
6
|
+
- LLM provider (if configured)
|
|
7
|
+
|
|
8
|
+
Performs lightweight API calls to verify credentials before expensive operations.
|
|
9
|
+
|
|
10
|
+
Usage:
|
|
11
|
+
python scripts/validate_auth.py
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
import os
|
|
15
|
+
import sys
|
|
16
|
+
|
|
17
|
+
from utils import check_databricks_config, validate_env_vars
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def check_databricks_auth():
|
|
21
|
+
"""Test Databricks authentication."""
|
|
22
|
+
print("Testing Databricks authentication...")
|
|
23
|
+
|
|
24
|
+
is_databricks, profile = check_databricks_config()
|
|
25
|
+
|
|
26
|
+
if not is_databricks:
|
|
27
|
+
print(" ⊘ Not using Databricks (skipped)")
|
|
28
|
+
print()
|
|
29
|
+
return []
|
|
30
|
+
|
|
31
|
+
# Check for auth credentials
|
|
32
|
+
token = os.getenv("DATABRICKS_TOKEN")
|
|
33
|
+
host = os.getenv("DATABRICKS_HOST")
|
|
34
|
+
|
|
35
|
+
if not token and not host:
|
|
36
|
+
# Try using databricks SDK (more robust) or fallback to CLI
|
|
37
|
+
try:
|
|
38
|
+
# Try new Databricks SDK first
|
|
39
|
+
try:
|
|
40
|
+
from databricks import sdk
|
|
41
|
+
|
|
42
|
+
print(" ↻ Using Databricks SDK...")
|
|
43
|
+
|
|
44
|
+
# Try to create workspace client
|
|
45
|
+
try:
|
|
46
|
+
w = sdk.WorkspaceClient()
|
|
47
|
+
# Test with a simple API call
|
|
48
|
+
current_user = w.current_user.me()
|
|
49
|
+
print(f" ✓ Authenticated as: {current_user.user_name}")
|
|
50
|
+
print()
|
|
51
|
+
return []
|
|
52
|
+
|
|
53
|
+
except AttributeError as e:
|
|
54
|
+
# Handle NoneType error gracefully
|
|
55
|
+
if "'NoneType'" in str(e):
|
|
56
|
+
print(" ✗ Databricks configuration incomplete or corrupted")
|
|
57
|
+
print()
|
|
58
|
+
return ["Run: databricks auth login --profile DEFAULT"]
|
|
59
|
+
raise
|
|
60
|
+
|
|
61
|
+
except ImportError:
|
|
62
|
+
# Fall back to old databricks-cli
|
|
63
|
+
from databricks_cli.sdk.api_client import ApiClient
|
|
64
|
+
|
|
65
|
+
print(" ↻ Using Databricks CLI profile...")
|
|
66
|
+
|
|
67
|
+
try:
|
|
68
|
+
api_client = ApiClient()
|
|
69
|
+
|
|
70
|
+
# Check if api_client is properly initialized
|
|
71
|
+
if api_client is None or not hasattr(api_client, "host"):
|
|
72
|
+
print(" ✗ Databricks CLI profile not configured")
|
|
73
|
+
print()
|
|
74
|
+
return ["Run: databricks auth login --profile DEFAULT"]
|
|
75
|
+
|
|
76
|
+
except (AttributeError, TypeError) as e:
|
|
77
|
+
print(f" ✗ Profile configuration error: {str(e)[:80]}")
|
|
78
|
+
print()
|
|
79
|
+
return ["Run: databricks auth login --profile DEFAULT"]
|
|
80
|
+
|
|
81
|
+
# Test with MLflow client
|
|
82
|
+
from mlflow import MlflowClient
|
|
83
|
+
|
|
84
|
+
client = MlflowClient()
|
|
85
|
+
client.search_experiments(max_results=1)
|
|
86
|
+
print(" ✓ Databricks profile authenticated")
|
|
87
|
+
print()
|
|
88
|
+
return []
|
|
89
|
+
|
|
90
|
+
except ImportError:
|
|
91
|
+
print(" ✗ Neither databricks-sdk nor databricks-cli installed")
|
|
92
|
+
print()
|
|
93
|
+
return ["Install databricks SDK: pip install databricks-sdk"]
|
|
94
|
+
except Exception as e:
|
|
95
|
+
print(f" ✗ Authentication failed: {str(e)[:100]}")
|
|
96
|
+
print()
|
|
97
|
+
return ["Run: databricks auth login --profile DEFAULT"]
|
|
98
|
+
|
|
99
|
+
# Test with environment variables
|
|
100
|
+
try:
|
|
101
|
+
from mlflow import MlflowClient
|
|
102
|
+
|
|
103
|
+
client = MlflowClient()
|
|
104
|
+
client.search_experiments(max_results=1)
|
|
105
|
+
|
|
106
|
+
print(" ✓ Databricks token valid")
|
|
107
|
+
print()
|
|
108
|
+
return []
|
|
109
|
+
|
|
110
|
+
except Exception as e:
|
|
111
|
+
print(f" ✗ Token validation failed: {str(e)[:100]}")
|
|
112
|
+
print()
|
|
113
|
+
return [
|
|
114
|
+
"Check DATABRICKS_TOKEN is set correctly",
|
|
115
|
+
"Run: databricks auth login --host <workspace-url>",
|
|
116
|
+
]
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def check_mlflow_tracking():
|
|
120
|
+
"""Test MLflow tracking server connectivity."""
|
|
121
|
+
print("Testing MLflow tracking server...")
|
|
122
|
+
|
|
123
|
+
# Use utility to validate env vars
|
|
124
|
+
errors = validate_env_vars()
|
|
125
|
+
|
|
126
|
+
if errors:
|
|
127
|
+
for error in errors:
|
|
128
|
+
print(f" ✗ {error}")
|
|
129
|
+
print()
|
|
130
|
+
return [f"Set environment variable: {error}" for error in errors]
|
|
131
|
+
|
|
132
|
+
tracking_uri = os.getenv("MLFLOW_TRACKING_URI")
|
|
133
|
+
experiment_id = os.getenv("MLFLOW_EXPERIMENT_ID")
|
|
134
|
+
|
|
135
|
+
try:
|
|
136
|
+
from mlflow import MlflowClient
|
|
137
|
+
|
|
138
|
+
client = MlflowClient()
|
|
139
|
+
|
|
140
|
+
# Test connectivity by getting experiment
|
|
141
|
+
experiment = client.get_experiment(experiment_id)
|
|
142
|
+
|
|
143
|
+
print(f" ✓ Connected to: {tracking_uri}")
|
|
144
|
+
print(f" ✓ Experiment: {experiment.name}")
|
|
145
|
+
print()
|
|
146
|
+
return []
|
|
147
|
+
|
|
148
|
+
except Exception as e:
|
|
149
|
+
error_msg = str(e)
|
|
150
|
+
print(f" ✗ Connection failed: {error_msg[:100]}")
|
|
151
|
+
print()
|
|
152
|
+
|
|
153
|
+
if "404" in error_msg or "not found" in error_msg.lower():
|
|
154
|
+
return [f"Experiment {experiment_id} not found - check MLFLOW_EXPERIMENT_ID"]
|
|
155
|
+
elif "401" in error_msg or "403" in error_msg or "authentication" in error_msg.lower():
|
|
156
|
+
return ["Authentication failed - check credentials"]
|
|
157
|
+
else:
|
|
158
|
+
return [f"Cannot connect to {tracking_uri} - check tracking URI and network"]
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def check_llm_provider():
|
|
162
|
+
"""Check LLM provider configuration (optional)."""
|
|
163
|
+
print("Checking LLM provider configuration...")
|
|
164
|
+
|
|
165
|
+
# Check for common LLM provider env vars
|
|
166
|
+
providers_found = []
|
|
167
|
+
|
|
168
|
+
if os.getenv("OPENAI_API_KEY"):
|
|
169
|
+
providers_found.append("OpenAI")
|
|
170
|
+
|
|
171
|
+
if os.getenv("ANTHROPIC_API_KEY"):
|
|
172
|
+
providers_found.append("Anthropic")
|
|
173
|
+
|
|
174
|
+
if os.getenv("DATABRICKS_TOKEN") or os.getenv("DATABRICKS_HOST"):
|
|
175
|
+
providers_found.append("Databricks")
|
|
176
|
+
|
|
177
|
+
if providers_found:
|
|
178
|
+
print(f" ✓ Found credentials for: {', '.join(providers_found)}")
|
|
179
|
+
print()
|
|
180
|
+
else:
|
|
181
|
+
print(" ⚠ No LLM provider credentials detected")
|
|
182
|
+
print(" This is OK if your agent uses Databricks profile auth")
|
|
183
|
+
print()
|
|
184
|
+
|
|
185
|
+
return [] # Warning only, not blocking
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
def main():
|
|
189
|
+
"""Main validation workflow."""
|
|
190
|
+
print("=" * 60)
|
|
191
|
+
print("Authentication Validation")
|
|
192
|
+
print("=" * 60)
|
|
193
|
+
print()
|
|
194
|
+
|
|
195
|
+
all_issues = []
|
|
196
|
+
|
|
197
|
+
# Check 1: MLflow tracking
|
|
198
|
+
tracking_issues = check_mlflow_tracking()
|
|
199
|
+
all_issues.extend(tracking_issues)
|
|
200
|
+
|
|
201
|
+
# Check 2: Databricks auth (if using Databricks)
|
|
202
|
+
databricks_issues = check_databricks_auth()
|
|
203
|
+
all_issues.extend(databricks_issues)
|
|
204
|
+
|
|
205
|
+
# Check 3: LLM provider (optional check)
|
|
206
|
+
llm_issues = check_llm_provider()
|
|
207
|
+
all_issues.extend(llm_issues)
|
|
208
|
+
|
|
209
|
+
# Summary
|
|
210
|
+
print("=" * 60)
|
|
211
|
+
print("Validation Report")
|
|
212
|
+
print("=" * 60)
|
|
213
|
+
print()
|
|
214
|
+
|
|
215
|
+
if not all_issues:
|
|
216
|
+
print("✓ ALL AUTHENTICATION CHECKS PASSED")
|
|
217
|
+
print()
|
|
218
|
+
print("Your authentication is configured correctly.")
|
|
219
|
+
print()
|
|
220
|
+
print("Next steps:")
|
|
221
|
+
print(" 1. Integrate tracing: See references/tracing-integration.md")
|
|
222
|
+
print(" 2. Test runtime tracing: Edit and run scripts/validate_agent_tracing.py")
|
|
223
|
+
print()
|
|
224
|
+
else:
|
|
225
|
+
print(f"✗ Found {len(all_issues)} issue(s):")
|
|
226
|
+
print()
|
|
227
|
+
for i, issue in enumerate(all_issues, 1):
|
|
228
|
+
print(f" {i}. {issue}")
|
|
229
|
+
print()
|
|
230
|
+
print("=" * 60)
|
|
231
|
+
print("Fix the authentication issues above before proceeding.")
|
|
232
|
+
print("=" * 60)
|
|
233
|
+
print()
|
|
234
|
+
sys.exit(1)
|
|
235
|
+
|
|
236
|
+
print("=" * 60)
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
if __name__ == "__main__":
|
|
240
|
+
main()
|