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,185 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Validate MLflow environment setup for agent evaluation.
|
|
3
|
+
|
|
4
|
+
This script runs `mlflow doctor` and adds custom checks for:
|
|
5
|
+
- Environment variables (MLFLOW_TRACKING_URI, MLFLOW_EXPERIMENT_ID)
|
|
6
|
+
- MLflow version compatibility (>=3.8.0)
|
|
7
|
+
- Agent package installation
|
|
8
|
+
- Basic connectivity test
|
|
9
|
+
|
|
10
|
+
Usage:
|
|
11
|
+
python scripts/validate_environment.py
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
import importlib.util
|
|
15
|
+
import subprocess
|
|
16
|
+
import sys
|
|
17
|
+
|
|
18
|
+
from utils import test_mlflow_connection, validate_env_vars, validate_mlflow_version
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def run_mlflow_doctor():
|
|
22
|
+
"""Run mlflow doctor and return output."""
|
|
23
|
+
print("Running MLflow diagnostics...")
|
|
24
|
+
print()
|
|
25
|
+
|
|
26
|
+
try:
|
|
27
|
+
result = subprocess.run(["mlflow", "doctor"], capture_output=True, text=True, timeout=10)
|
|
28
|
+
|
|
29
|
+
# Print output (mlflow doctor goes to stderr)
|
|
30
|
+
output = result.stderr + result.stdout
|
|
31
|
+
print(output)
|
|
32
|
+
|
|
33
|
+
return result.returncode == 0
|
|
34
|
+
except subprocess.TimeoutExpired:
|
|
35
|
+
print("⚠ mlflow doctor timed out")
|
|
36
|
+
return False
|
|
37
|
+
except FileNotFoundError:
|
|
38
|
+
print("✗ mlflow command not found")
|
|
39
|
+
print(" Install: pip install mlflow")
|
|
40
|
+
return False
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def check_environment_variables():
|
|
44
|
+
"""Check that required environment variables are set."""
|
|
45
|
+
print("Checking environment variables...")
|
|
46
|
+
|
|
47
|
+
errors = validate_env_vars()
|
|
48
|
+
|
|
49
|
+
if not errors:
|
|
50
|
+
env_vars = {}
|
|
51
|
+
import os
|
|
52
|
+
|
|
53
|
+
tracking_uri = os.getenv("MLFLOW_TRACKING_URI")
|
|
54
|
+
experiment_id = os.getenv("MLFLOW_EXPERIMENT_ID")
|
|
55
|
+
|
|
56
|
+
if tracking_uri:
|
|
57
|
+
print(f" ✓ MLFLOW_TRACKING_URI: {tracking_uri}")
|
|
58
|
+
if experiment_id:
|
|
59
|
+
print(f" ✓ MLFLOW_EXPERIMENT_ID: {experiment_id}")
|
|
60
|
+
else:
|
|
61
|
+
for error in errors:
|
|
62
|
+
print(f" ✗ {error}")
|
|
63
|
+
|
|
64
|
+
print()
|
|
65
|
+
return ["Set environment variables" for _ in errors] if errors else []
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def check_mlflow_version():
|
|
69
|
+
"""Check MLflow version is compatible."""
|
|
70
|
+
print("Checking MLflow version...")
|
|
71
|
+
|
|
72
|
+
is_valid, version_str = validate_mlflow_version("3.8.0")
|
|
73
|
+
|
|
74
|
+
if is_valid:
|
|
75
|
+
print(f" ✓ MLflow {version_str} (>=3.8.0)")
|
|
76
|
+
print()
|
|
77
|
+
return []
|
|
78
|
+
elif version_str == "not installed":
|
|
79
|
+
print(f" ✗ MLflow not installed")
|
|
80
|
+
print()
|
|
81
|
+
return ["Install MLflow: pip install mlflow"]
|
|
82
|
+
else:
|
|
83
|
+
print(f" ✗ MLflow {version_str} (need >=3.8.0)")
|
|
84
|
+
print()
|
|
85
|
+
return ["Upgrade MLflow: pip install --upgrade 'mlflow>=3.8.0'"]
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def check_agent_package():
|
|
89
|
+
"""Remind user to verify agent package is importable."""
|
|
90
|
+
print("Agent package check...")
|
|
91
|
+
print(" ℹ Verify your agent is importable:")
|
|
92
|
+
print(" python -c 'from your_module import your_agent'")
|
|
93
|
+
print(" Replace 'your_module' and 'your_agent' with your actual package/function names")
|
|
94
|
+
print()
|
|
95
|
+
return [] # Informational only, not blocking
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def test_connectivity():
|
|
99
|
+
"""Test basic connectivity to MLflow tracking server."""
|
|
100
|
+
print("Testing MLflow connectivity...")
|
|
101
|
+
|
|
102
|
+
import os
|
|
103
|
+
|
|
104
|
+
tracking_uri = os.getenv("MLFLOW_TRACKING_URI")
|
|
105
|
+
experiment_id = os.getenv("MLFLOW_EXPERIMENT_ID")
|
|
106
|
+
|
|
107
|
+
if not tracking_uri or not experiment_id:
|
|
108
|
+
print(" ⊘ Skipped (environment variables not set)")
|
|
109
|
+
print()
|
|
110
|
+
return []
|
|
111
|
+
|
|
112
|
+
success, result = test_mlflow_connection(tracking_uri, experiment_id)
|
|
113
|
+
|
|
114
|
+
if success:
|
|
115
|
+
print(f" ✓ Connected to experiment: {result}")
|
|
116
|
+
print()
|
|
117
|
+
return []
|
|
118
|
+
else:
|
|
119
|
+
print(f" ✗ Connection failed: {result}")
|
|
120
|
+
print()
|
|
121
|
+
return [f"Check connectivity and authentication to {tracking_uri}"]
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def main():
|
|
125
|
+
"""Main validation workflow."""
|
|
126
|
+
print("=" * 60)
|
|
127
|
+
print("MLflow Environment Validation")
|
|
128
|
+
print("=" * 60)
|
|
129
|
+
print()
|
|
130
|
+
|
|
131
|
+
all_issues = []
|
|
132
|
+
|
|
133
|
+
# Check 1: Run mlflow doctor
|
|
134
|
+
doctor_ok = run_mlflow_doctor()
|
|
135
|
+
if not doctor_ok:
|
|
136
|
+
all_issues.append("mlflow doctor reported issues")
|
|
137
|
+
|
|
138
|
+
# Check 2: Environment variables
|
|
139
|
+
env_issues = check_environment_variables()
|
|
140
|
+
all_issues.extend(env_issues)
|
|
141
|
+
|
|
142
|
+
# Check 3: MLflow version
|
|
143
|
+
version_issues = check_mlflow_version()
|
|
144
|
+
all_issues.extend(version_issues)
|
|
145
|
+
|
|
146
|
+
# Check 4: Agent package
|
|
147
|
+
agent_issues = check_agent_package()
|
|
148
|
+
all_issues.extend(agent_issues)
|
|
149
|
+
|
|
150
|
+
# Check 5: Connectivity (only if env vars set)
|
|
151
|
+
connectivity_issues = test_connectivity()
|
|
152
|
+
all_issues.extend(connectivity_issues)
|
|
153
|
+
|
|
154
|
+
# Summary
|
|
155
|
+
print("=" * 60)
|
|
156
|
+
print("Validation Report")
|
|
157
|
+
print("=" * 60)
|
|
158
|
+
print()
|
|
159
|
+
|
|
160
|
+
if not all_issues:
|
|
161
|
+
print("✓ ALL CHECKS PASSED")
|
|
162
|
+
print()
|
|
163
|
+
print("Your environment is ready for agent evaluation.")
|
|
164
|
+
print()
|
|
165
|
+
print("Next steps:")
|
|
166
|
+
print(" 1. Integrate tracing: See references/tracing-integration.md")
|
|
167
|
+
print(" 2. Prepare dataset: python scripts/list_datasets.py")
|
|
168
|
+
print()
|
|
169
|
+
else:
|
|
170
|
+
print(f"✗ Found {len(all_issues)} issue(s):")
|
|
171
|
+
print()
|
|
172
|
+
for i, issue in enumerate(all_issues, 1):
|
|
173
|
+
print(f" {i}. {issue}")
|
|
174
|
+
print()
|
|
175
|
+
print("=" * 60)
|
|
176
|
+
print("Fix the issues above and re-run this script.")
|
|
177
|
+
print("=" * 60)
|
|
178
|
+
print()
|
|
179
|
+
sys.exit(1)
|
|
180
|
+
|
|
181
|
+
print("=" * 60)
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
if __name__ == "__main__":
|
|
185
|
+
main()
|
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
Validate MLflow tracing by running the agent (RUNTIME VALIDATION).
|
|
4
|
+
|
|
5
|
+
CRITICAL: This script REQUIRES valid authentication and LLM access.
|
|
6
|
+
If this validation fails, the evaluation workflow MUST STOP until auth issues are resolved.
|
|
7
|
+
|
|
8
|
+
The coding agent should discover module/entry-point/autolog using Grep first,
|
|
9
|
+
then pass the discovered information to this script for runtime validation.
|
|
10
|
+
|
|
11
|
+
This script verifies by actually running the agent:
|
|
12
|
+
1. Traces are captured successfully
|
|
13
|
+
2. Complete trace hierarchy is present (decorator + autolog spans)
|
|
14
|
+
3. Session ID is tagged (if applicable)
|
|
15
|
+
4. Agent execution completes without errors
|
|
16
|
+
|
|
17
|
+
Usage:
|
|
18
|
+
python validate_tracing_runtime.py \
|
|
19
|
+
--module my_agent.agent \
|
|
20
|
+
--entry-point run_agent \
|
|
21
|
+
--autolog-file src/agent/__init__.py
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
import argparse
|
|
25
|
+
import importlib
|
|
26
|
+
import sys
|
|
27
|
+
|
|
28
|
+
from utils import validate_env_vars
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def run_test_query(
|
|
32
|
+
module_name: str,
|
|
33
|
+
entry_point_name: str,
|
|
34
|
+
test_query: str = "What is MLflow?",
|
|
35
|
+
test_session_id: str = "test-session-123",
|
|
36
|
+
):
|
|
37
|
+
"""Run a test query and verify trace capture."""
|
|
38
|
+
print("\nRunning test query...")
|
|
39
|
+
print(f" Module: {module_name}")
|
|
40
|
+
print(f" Entry point: {entry_point_name}")
|
|
41
|
+
print(f" Query: {test_query}")
|
|
42
|
+
print(f" Session ID: {test_session_id}")
|
|
43
|
+
|
|
44
|
+
try:
|
|
45
|
+
# Import mlflow first
|
|
46
|
+
import mlflow
|
|
47
|
+
from mlflow import MlflowClient
|
|
48
|
+
|
|
49
|
+
# Try to import the agent module
|
|
50
|
+
try:
|
|
51
|
+
agent_module = importlib.import_module(module_name)
|
|
52
|
+
except ImportError as e:
|
|
53
|
+
print(f" ✗ Could not import module '{module_name}': {e}")
|
|
54
|
+
print(" Try: pip install -e . (from project root)")
|
|
55
|
+
return None
|
|
56
|
+
|
|
57
|
+
# Get the entry point function
|
|
58
|
+
if not hasattr(agent_module, entry_point_name):
|
|
59
|
+
print(f" ✗ Function '{entry_point_name}' not found in {module_name}")
|
|
60
|
+
available = [name for name in dir(agent_module) if not name.startswith("_")]
|
|
61
|
+
if available:
|
|
62
|
+
print(f" Available functions: {', '.join(available[:5])}")
|
|
63
|
+
return None
|
|
64
|
+
|
|
65
|
+
entry_point = getattr(agent_module, entry_point_name)
|
|
66
|
+
print(f" ✓ Found entry point: {entry_point_name}")
|
|
67
|
+
|
|
68
|
+
# Try to call the entry point (be flexible with signatures)
|
|
69
|
+
print("\n Executing agent...")
|
|
70
|
+
try:
|
|
71
|
+
# Try different call signatures
|
|
72
|
+
try:
|
|
73
|
+
entry_point(test_query, session_id=test_session_id)
|
|
74
|
+
except TypeError:
|
|
75
|
+
try:
|
|
76
|
+
entry_point(test_query)
|
|
77
|
+
except TypeError:
|
|
78
|
+
# Might need LLM provider or other args
|
|
79
|
+
print(f" ⚠ Could not call {entry_point_name} with simple args")
|
|
80
|
+
print(
|
|
81
|
+
" You may need to run this validation manually with proper configuration"
|
|
82
|
+
)
|
|
83
|
+
return None
|
|
84
|
+
|
|
85
|
+
print(" ✓ Agent executed successfully")
|
|
86
|
+
|
|
87
|
+
# Get trace
|
|
88
|
+
trace_id = mlflow.get_last_active_trace_id()
|
|
89
|
+
if not trace_id:
|
|
90
|
+
print(" ✗ No trace ID captured!")
|
|
91
|
+
return None
|
|
92
|
+
|
|
93
|
+
print(f" ✓ Trace captured: {trace_id}")
|
|
94
|
+
|
|
95
|
+
# Get trace details
|
|
96
|
+
client = MlflowClient()
|
|
97
|
+
return client.get_trace(trace_id)
|
|
98
|
+
|
|
99
|
+
except Exception as e:
|
|
100
|
+
print(f" ✗ Error executing agent: {e}")
|
|
101
|
+
import traceback
|
|
102
|
+
|
|
103
|
+
traceback.print_exc()
|
|
104
|
+
return None
|
|
105
|
+
|
|
106
|
+
except Exception as e:
|
|
107
|
+
print(f" ✗ Error: {e}")
|
|
108
|
+
import traceback
|
|
109
|
+
|
|
110
|
+
traceback.print_exc()
|
|
111
|
+
return None
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def verify_trace_structure(trace) -> tuple[bool, list[str]]:
|
|
115
|
+
"""Verify the trace has the expected structure."""
|
|
116
|
+
print("\nVerifying trace structure...")
|
|
117
|
+
|
|
118
|
+
issues = []
|
|
119
|
+
|
|
120
|
+
# Check for top-level span (from @mlflow.trace decorator)
|
|
121
|
+
if not trace.data.spans:
|
|
122
|
+
issues.append("No spans found in trace")
|
|
123
|
+
return False, issues
|
|
124
|
+
|
|
125
|
+
top_span = trace.data.spans[0]
|
|
126
|
+
print(f" ✓ Top-level span: {top_span.name} ({top_span.span_type})")
|
|
127
|
+
|
|
128
|
+
# Check for library spans (from autolog)
|
|
129
|
+
def count_spans(spans):
|
|
130
|
+
count = len(spans)
|
|
131
|
+
for span in spans:
|
|
132
|
+
if hasattr(span, "spans") and span.spans:
|
|
133
|
+
count += count_spans(span.spans)
|
|
134
|
+
return count
|
|
135
|
+
|
|
136
|
+
total_spans = count_spans(trace.data.spans)
|
|
137
|
+
print(f" ✓ Total spans in hierarchy: {total_spans}")
|
|
138
|
+
|
|
139
|
+
if total_spans < 2:
|
|
140
|
+
issues.append("Only one span found - autolog may not be working")
|
|
141
|
+
else:
|
|
142
|
+
print(" ✓ Multiple spans detected - autolog appears to be working")
|
|
143
|
+
|
|
144
|
+
# Print hierarchy
|
|
145
|
+
def print_hierarchy(spans, indent=0):
|
|
146
|
+
for span in spans:
|
|
147
|
+
prefix = " " + " " * indent
|
|
148
|
+
print(f"{prefix}- {span.name} ({span.span_type})")
|
|
149
|
+
if hasattr(span, "spans") and span.spans:
|
|
150
|
+
print_hierarchy(span.spans, indent + 1)
|
|
151
|
+
|
|
152
|
+
print("\n Trace hierarchy:")
|
|
153
|
+
print_hierarchy(trace.data.spans)
|
|
154
|
+
|
|
155
|
+
return len(issues) == 0, issues
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def verify_session_id(trace, expected_session_id: str) -> tuple[bool, str]:
|
|
159
|
+
"""Verify session ID is captured in trace."""
|
|
160
|
+
print("\nVerifying session ID capture...")
|
|
161
|
+
|
|
162
|
+
if "session_id" not in trace.info.tags:
|
|
163
|
+
print(" ✗ Session ID not found in trace tags")
|
|
164
|
+
return False, "Session ID not captured"
|
|
165
|
+
|
|
166
|
+
actual_session_id = trace.info.tags["session_id"]
|
|
167
|
+
print(f" ✓ Session ID found: {actual_session_id}")
|
|
168
|
+
|
|
169
|
+
if actual_session_id == expected_session_id:
|
|
170
|
+
print(" ✓ Session ID matches expected value")
|
|
171
|
+
return True, ""
|
|
172
|
+
else:
|
|
173
|
+
print(" ✗ Session ID mismatch!")
|
|
174
|
+
print(f" Expected: {expected_session_id}")
|
|
175
|
+
print(f" Got: {actual_session_id}")
|
|
176
|
+
return (
|
|
177
|
+
False,
|
|
178
|
+
f"Session ID mismatch: expected {expected_session_id}, got {actual_session_id}",
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def main():
|
|
183
|
+
"""Main validation workflow."""
|
|
184
|
+
# Parse command-line arguments
|
|
185
|
+
parser = argparse.ArgumentParser(
|
|
186
|
+
description="Validate MLflow tracing integration with an agent",
|
|
187
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
188
|
+
epilog="""
|
|
189
|
+
Examples:
|
|
190
|
+
python validate_tracing_runtime.py # Auto-detect everything
|
|
191
|
+
python validate_tracing_runtime.py --module my_agent.agent # Specify module
|
|
192
|
+
python validate_tracing_runtime.py --entry-point process # Specify entry point
|
|
193
|
+
python validate_tracing_runtime.py --module my_agent --entry-point process # Both
|
|
194
|
+
""",
|
|
195
|
+
)
|
|
196
|
+
parser.add_argument("--module", help='Agent module name (e.g., "mlflow_agent.agent")')
|
|
197
|
+
parser.add_argument("--entry-point", help='Entry point function name (e.g., "run_agent")')
|
|
198
|
+
parser.add_argument(
|
|
199
|
+
"--autolog-file", help='File containing autolog() call (e.g., "src/agent/__init__.py")'
|
|
200
|
+
)
|
|
201
|
+
args = parser.parse_args()
|
|
202
|
+
|
|
203
|
+
print("=" * 60)
|
|
204
|
+
print("MLflow Tracing Validation")
|
|
205
|
+
print("=" * 60)
|
|
206
|
+
print()
|
|
207
|
+
|
|
208
|
+
# Track issues
|
|
209
|
+
all_issues = []
|
|
210
|
+
|
|
211
|
+
# Step 1: Check environment
|
|
212
|
+
print("Checking environment...")
|
|
213
|
+
env_errors = validate_env_vars()
|
|
214
|
+
if env_errors:
|
|
215
|
+
print()
|
|
216
|
+
print("✗ Environment issues:")
|
|
217
|
+
for error in env_errors:
|
|
218
|
+
print(f" - {error}")
|
|
219
|
+
all_issues.extend(env_errors)
|
|
220
|
+
else:
|
|
221
|
+
import os
|
|
222
|
+
|
|
223
|
+
tracking_uri = os.getenv("MLFLOW_TRACKING_URI")
|
|
224
|
+
experiment_id = os.getenv("MLFLOW_EXPERIMENT_ID")
|
|
225
|
+
print(f" ✓ MLFLOW_TRACKING_URI={tracking_uri}")
|
|
226
|
+
print(f" ✓ MLFLOW_EXPERIMENT_ID={experiment_id}")
|
|
227
|
+
|
|
228
|
+
# Step 2: Get agent module (must be specified manually)
|
|
229
|
+
module_name = args.module
|
|
230
|
+
if not module_name:
|
|
231
|
+
print("\n✗ Agent module not specified")
|
|
232
|
+
print(" Use --module to specify your agent module")
|
|
233
|
+
print(" Example: --module my_agent.agent")
|
|
234
|
+
print("\n To find your agent module:")
|
|
235
|
+
print(" grep -r 'def.*agent' . --include='*.py'")
|
|
236
|
+
sys.exit(1)
|
|
237
|
+
else:
|
|
238
|
+
print(f"\n✓ Using specified module: {module_name}")
|
|
239
|
+
|
|
240
|
+
# Step 3: Check autolog (optional - for informational purposes)
|
|
241
|
+
print("\nChecking autolog configuration...")
|
|
242
|
+
if args.autolog_file:
|
|
243
|
+
from pathlib import Path
|
|
244
|
+
|
|
245
|
+
if Path(args.autolog_file).exists():
|
|
246
|
+
print(f" ✓ Autolog file specified: {args.autolog_file}")
|
|
247
|
+
else:
|
|
248
|
+
print(f" ✗ Autolog file not found: {args.autolog_file}")
|
|
249
|
+
all_issues.append(f"Autolog file not found: {args.autolog_file}")
|
|
250
|
+
else:
|
|
251
|
+
print(" ⚠ No autolog file specified (use --autolog-file)")
|
|
252
|
+
print(" This is optional but recommended for full validation")
|
|
253
|
+
print("\n To find autolog calls:")
|
|
254
|
+
print(" grep -r 'mlflow.*autolog' . --include='*.py'")
|
|
255
|
+
|
|
256
|
+
# Step 4: Get entry point (must be specified manually)
|
|
257
|
+
print("\nChecking entry point...")
|
|
258
|
+
entry_point_name = args.entry_point
|
|
259
|
+
|
|
260
|
+
if not entry_point_name:
|
|
261
|
+
print(" ✗ Entry point not specified")
|
|
262
|
+
print(" Use --entry-point to specify your agent's main function")
|
|
263
|
+
print(" Example: --entry-point run_agent")
|
|
264
|
+
print("\n To find entry points with @mlflow.trace:")
|
|
265
|
+
print(" grep -r '@mlflow.trace' . --include='*.py'")
|
|
266
|
+
all_issues.append("No entry point specified")
|
|
267
|
+
sys.exit(1)
|
|
268
|
+
else:
|
|
269
|
+
print(f" ✓ Using specified entry point: {entry_point_name}")
|
|
270
|
+
|
|
271
|
+
# Step 5: Run test query
|
|
272
|
+
trace = None
|
|
273
|
+
if entry_point_name:
|
|
274
|
+
trace = run_test_query(module_name, entry_point_name)
|
|
275
|
+
if not trace:
|
|
276
|
+
all_issues.append("Could not capture test trace")
|
|
277
|
+
else:
|
|
278
|
+
# Step 6: Verify trace structure
|
|
279
|
+
structure_ok, structure_issues = verify_trace_structure(trace)
|
|
280
|
+
if not structure_ok:
|
|
281
|
+
all_issues.extend(structure_issues)
|
|
282
|
+
|
|
283
|
+
# Step 7: Verify session ID (optional)
|
|
284
|
+
session_ok, session_issue = verify_session_id(trace, "test-session-123")
|
|
285
|
+
if not session_ok:
|
|
286
|
+
# Session ID is optional, so just warn
|
|
287
|
+
print(f"\n⚠ Note: {session_issue}")
|
|
288
|
+
print(" Session ID tracking is optional. Skip if not needed.")
|
|
289
|
+
|
|
290
|
+
# Final report
|
|
291
|
+
print("\n" + "=" * 60)
|
|
292
|
+
print("Validation Report")
|
|
293
|
+
print("=" * 60)
|
|
294
|
+
|
|
295
|
+
if not all_issues:
|
|
296
|
+
print("\n✓ ALL CHECKS PASSED!")
|
|
297
|
+
print("\nYour agent is properly integrated with MLflow tracing.")
|
|
298
|
+
print("You can proceed with evaluation.")
|
|
299
|
+
else:
|
|
300
|
+
print(f"\n✗ Found {len(all_issues)} issue(s):")
|
|
301
|
+
for i, issue in enumerate(all_issues, 1):
|
|
302
|
+
print(f"\n{i}. {issue}")
|
|
303
|
+
|
|
304
|
+
print("\n" + "=" * 60)
|
|
305
|
+
print("Next Steps")
|
|
306
|
+
print("=" * 60)
|
|
307
|
+
print("\n1. Fix the issues listed above")
|
|
308
|
+
print("2. Refer to references/tracing-integration.md for detailed guidance")
|
|
309
|
+
print("3. Run this script again to verify fixes")
|
|
310
|
+
print("\nDO NOT proceed with evaluation until all issues are resolved.")
|
|
311
|
+
|
|
312
|
+
print("=" * 60)
|
|
313
|
+
|
|
314
|
+
sys.exit(0 if not all_issues else 1)
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
if __name__ == "__main__":
|
|
318
|
+
main()
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agentic-architecture
|
|
3
|
+
description: Use when designing or evaluating an AI agent system: topology (single agent, supervisor, subgraphs), orchestration pattern, context engineering, state schema, memory, tool contracts, reliability and observability. Standalone or inside the OpenSpec /opsx design phase with the agentic-architect agent.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Agentic Architecture Protocol
|
|
7
|
+
|
|
8
|
+
<philosophy>
|
|
9
|
+
System capabilities stem from orchestration, context boundaries, data contracts, and state management, never from larger model parameter sizes alone. Start simple; add complexity only when mathematically justified.
|
|
10
|
+
</philosophy>
|
|
11
|
+
|
|
12
|
+
<modes>
|
|
13
|
+
## Mode 1: Design Loop
|
|
14
|
+
1. Clarify Constraints: Document goals, consumer contracts, required deterministic control, latency/cost budgets, and safety boundaries. Stop and ask before planning.
|
|
15
|
+
2. Separation of Concerns: Allocate stochastic tasks to LLMs; allocate deterministic validation, business rules, auth, and calculations to standard code.
|
|
16
|
+
3. Pattern Selection: Prefer simplest pattern (Deterministic Code > Single Agent + Tools > Router > Supervisor > Multi-Agent Graph). Single-agent with skills is ~10-15x cheaper than multi-agent. Document choice as an ADR.
|
|
17
|
+
4. Context Strategy: Define per-step context payloads; eliminate starvation and bloat; set model-tiering (SLM for narrow/repetitive steps, LLM for open reasoning).
|
|
18
|
+
5. Reliability & Observability: Implement exponential backoff, circuit breakers, strict output schema verification, and fallback routes. Instrument traces via OpenTelemetry/LangFuse.
|
|
19
|
+
6. Blueprint Generation: Output blueprint using the output template.
|
|
20
|
+
|
|
21
|
+
## Mode 2: Review Framework
|
|
22
|
+
1. Audit Architecture: Inspect topology, tool calling sandboxes, and context boundaries. Check for the Lethal Trifecta (sensitive data + open communication + unverified execution).
|
|
23
|
+
2. Report Findings: Categorize issues by severity:
|
|
24
|
+
- P0 (Blocker): Unbounded loops, untrusted execution, credential exposure.
|
|
25
|
+
- P1 (Concern): Missing circuit breakers, model tier mismatch, lack of retry backoff.
|
|
26
|
+
- P2 (Optimization): Minor schema redundancy, excessive prompt verbiage.
|
|
27
|
+
3. Diagrams: Produce Mermaid C4 Component and StateGraph diagrams. End with `OK` or `FAIL`.
|
|
28
|
+
</modes>
|
|
29
|
+
|
|
30
|
+
<blueprint_template>
|
|
31
|
+
### Architecture Blueprint
|
|
32
|
+
1. Scope & Non-Goals: Explicit system boundaries.
|
|
33
|
+
2. Component Architecture: Responsibilities, state schemas (Pydantic/TypedDict), and directional dependencies.
|
|
34
|
+
3. Pattern Rationale: Selected pattern vs rejected alternatives.
|
|
35
|
+
4. Context & Tiering: Context window budgets, memory retention strategy, and model tier allocation.
|
|
36
|
+
5. Reliability & Fallbacks: Guardrails against failures, timeouts, and tool errors.
|
|
37
|
+
6. Observability & SLIs: Instrumented spans, metrics, and LangFuse/OTel attributes.
|
|
38
|
+
7. Security Boundaries: Trust zones, input sanitization, and permission barriers.
|
|
39
|
+
8. Diagrams: Mermaid system context and component diagrams.
|
|
40
|
+
9. Verification & Evals: Quantitative thresholds and gate criteria.
|
|
41
|
+
</blueprint_template>
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# Eval cases for the agentic-architecture skill. Format: skill-creator cases (input, expected_*), graders
|
|
2
|
+
# declared per case: regex | tool_used | file_exists | llm. `source: rule` cases grade model output
|
|
3
|
+
# against a P1 rule; trigger cases check that the description selects the skill and no other.
|
|
4
|
+
# Runner: scripts/skill-evals.mjs. `source: dogfood` cases carry `dogfood: <date> <project>` (the
|
|
5
|
+
# .freeharness/dogfood.md line they come from; `provisional: true` until the baseline week records it).
|
|
6
|
+
skill: agentic-architecture
|
|
7
|
+
cases:
|
|
8
|
+
- id: trigger-agentic-architecture
|
|
9
|
+
source: rule
|
|
10
|
+
rule: skill-trigger
|
|
11
|
+
input: "Design the supervisor topology for the copilot: a deterministic routing gate, one recommendation subgraph and a fallback node; compare two approaches and name the reliability mechanisms."
|
|
12
|
+
expected_skill: agentic-architecture
|
|
13
|
+
not_expected_skills:
|
|
14
|
+
- agent-evaluation
|
|
15
|
+
- code-review
|
|
16
|
+
- git-workflow
|
|
17
|
+
- local-code
|
|
18
|
+
- report-formatting
|
|
19
|
+
- subagent-driven-development
|
|
20
|
+
- systematic-debugging
|
|
21
|
+
- test-driven-development
|
|
22
|
+
- verification-before-completion
|
|
23
|
+
graders:
|
|
24
|
+
- type: tool_used
|
|
25
|
+
expected: "Skill:agentic-architecture"
|
|
26
|
+
- type: tool_used
|
|
27
|
+
not_expected:
|
|
28
|
+
- "Skill:agent-evaluation"
|
|
29
|
+
- "Skill:code-review"
|
|
30
|
+
- "Skill:git-workflow"
|
|
31
|
+
- "Skill:local-code"
|
|
32
|
+
- "Skill:report-formatting"
|
|
33
|
+
- "Skill:subagent-driven-development"
|
|
34
|
+
- "Skill:systematic-debugging"
|
|
35
|
+
- "Skill:test-driven-development"
|
|
36
|
+
- "Skill:verification-before-completion"
|
|
37
|
+
ablation: false
|
|
38
|
+
|
|
39
|
+
- id: dogfood-agentic-architecture-deterministic-gate
|
|
40
|
+
source: dogfood
|
|
41
|
+
dogfood: 2026-09-06 Copiloto
|
|
42
|
+
provisional: true
|
|
43
|
+
input: "Design the LangGraph supervisor for the Copiloto recommendation flow: the routing must be deterministic (the engine decides final_node), the LLM classifies the contact reason only when it is ambiguous and writes the phrase. Give the topology, the state schema and where the deterministic-first gate sits."
|
|
44
|
+
expected: "A thin supervisor with a deterministic-first gate before any LLM node, a typed state schema, the LLM confined to classification-on-ambiguity and phrasing, and the boundary stated explicitly."
|
|
45
|
+
graders:
|
|
46
|
+
- type: regex
|
|
47
|
+
flags: i
|
|
48
|
+
expected: "deterministic"
|
|
49
|
+
- type: regex
|
|
50
|
+
flags: i
|
|
51
|
+
expected: "state schema|TypedDict|StateGraph"
|
|
52
|
+
- type: regex
|
|
53
|
+
flags: i
|
|
54
|
+
expected: "supervisor"
|
|
55
|
+
- type: llm
|
|
56
|
+
rubric: "Pass when the design keeps the business decision in the deterministic engine, places the gate before the LLM nodes, and names the state fields; fail when the LLM chooses the final_node or the topology has no gate."
|
|
57
|
+
ablation: true
|
|
58
|
+
|
|
59
|
+
- id: dogfood-agentic-architecture-error-contract
|
|
60
|
+
source: dogfood
|
|
61
|
+
dogfood: 2026-09-06 Copiloto
|
|
62
|
+
provisional: true
|
|
63
|
+
input: "Review the tool contract of the HubGPU LLM adapter: what does the caller receive on a timeout, on an HTTP 500 and on malformed JSON from the model? Today it raises a bare Exception in all three cases."
|
|
64
|
+
expected: "An error contract with a stable code plus next action per outcome, the three outcomes as independent fields (never nested), and a degrade-to-business-error path instead of an opaque 500."
|
|
65
|
+
graders:
|
|
66
|
+
- type: regex
|
|
67
|
+
flags: i
|
|
68
|
+
expected: "code"
|
|
69
|
+
- type: regex
|
|
70
|
+
flags: i
|
|
71
|
+
expected: "next action|retry|fallback|degrade"
|
|
72
|
+
- type: regex
|
|
73
|
+
flags: i
|
|
74
|
+
expected: "timeout"
|
|
75
|
+
- type: llm
|
|
76
|
+
rubric: "Pass when each of timeout, HTTP 500 and malformed JSON gets its own code and next action and the answer rejects the bare Exception; fail when the outcomes are collapsed into one error or nested in one another."
|
|
77
|
+
ablation: true
|
|
78
|
+
|
|
79
|
+
- id: dogfood-agentic-architecture-memory-placement
|
|
80
|
+
source: dogfood
|
|
81
|
+
dogfood: 2026-09-06 STT
|
|
82
|
+
provisional: true
|
|
83
|
+
input: "The STT pipeline needs per-speaker context across segments. Should it live in the graph state or in an external store? Recommend one and give the trade-offs."
|
|
84
|
+
expected: "One recommendation with explicit trade-offs (latency, size, persistence, testability) and the consequence for the state schema, not a list of options without a choice."
|
|
85
|
+
graders:
|
|
86
|
+
- type: regex
|
|
87
|
+
flags: i
|
|
88
|
+
expected: "trade-?offs?"
|
|
89
|
+
- type: regex
|
|
90
|
+
flags: i
|
|
91
|
+
expected: "recommend"
|
|
92
|
+
- type: llm
|
|
93
|
+
rubric: "Pass when exactly one option is recommended with at least two trade-offs and the state-schema consequence; fail when both options are described without a decision."
|
|
94
|
+
ablation: true
|